SvelteKit-powered personal site that renders pages from Contentful and deploys to Cloudflare Workers.
24.14.1 via .nvmrc, .node-version, and package.json10+682 on Svelte 5The repository uses an open-source-only quality pipeline for formatting, linting, type checking, dependency hygiene, tests, and security scanning. When a PR changes behavior, tooling, workflows, or contributor rules, update README.md, AGENTS.md, .github/copilot-instructions.md, and any relevant docs in the same change.
Component-scoped styles should live in colocated *.module.css files rather than inline <style> blocks inside .svelte components. Keep shared design tokens and global styles in src/lib/main.css, and continue using CSS custom properties for color values.
src/routes/+layout.server.ts loads the global navigation using NavigationService.src/routes/[...catchall]/+page.server.ts resolves the current slug (with home fallback in the Contentful query) and fetches page data.src/lib/services/cms/contentful.ts calls Contentful APIs, builds breadcrumbs recursively from parent pages, and converts Rich Text to HTML.src/routes/[...catchall]/+page.svelte renders page title, breadcrumbs, and body content ({@html ...} output from Contentful rich text rendering).+layout.svelte renders Header, Nav, page content, and footer.src/lib/services/**.src/routes/library/+page.svelte renders a curated bookshelf-style library from local seed data in src/lib/services/library/library.ts.src/lib/** with Storybook stories and docs.@sveltejs/adapter-cloudflare and Worker config is in wrangler.toml.Optional local security tooling for npm run security:*:
osv-scannergitleakssemgrepCI installs those tools automatically. For local use, install them with your preferred package manager before running the security scripts.
npm install
cp .env.example .env
.env (or your shell/CI environment):CONTENTFUL_API_KEY=<your_contentful_delivery_or_preview_token>
# Optional, defaults to cdn.contentful.com:
CONTENTFUL_HOST=cdn.contentful.com
# Optional, defaults to master:
CONTENTFUL_ENVIRONMENT=master
Notes:
- Preview environment uses
preview.contentful.comviawrangler.toml.- Preview API mode now activates only when requests originate from Contentful Live Preview (Contentful app iframe context), not via URL query flags.
- If
CONTENTFUL_ENVIRONMENTis not set, the app defaults Contentful environment tomaster.- The Contentful Live Preview SDK is loaded only when the page is embedded in Contentful Live Preview.
- If
CONTENTFUL_API_KEYis missing, server-side page and nav fetches will fail.
npx playwright install
npm install
npm run dev
Start local dev server (Vite + SvelteKit).
npm run build
npm run preview
Build and serve the production artifact locally.
npm run check:types
Runs svelte-kit sync and svelte-check.
npm run check:deps
Runs knip to catch unused files, exports, and dependencies.
npm run lint
npm run format
lint runs Prettier, ESLint, and Markdown linting.format applies Prettier formatting.You can also run the stages individually:
npm run lint:format
npm run lint:code
npm run lint:docs
npm run test:unit
Runs the dedicated unit Vitest project for src/**/*.{test,spec}.{js,ts} (no Storybook browser runner).
npm run test:integration
Runs Playwright tests in tests/ against a built+previewed app.
npm run storybook
npm run build-storybook
npm run test:storybook
storybook: local component explorer on port 6006.build-storybook: static Storybook build.test:storybook: Vitest Storybook project (browser mode).npm test
Runs unit tests, Storybook browser tests, and Playwright integration tests.
npm run security:deps
npm run security:secrets
npm run security:sast
security:deps runs osv-scanner against the project source and lockfiles.security:secrets runs gitleaks.security:sast runs Semgrep Community Edition with open-source JavaScript, TypeScript, and Node.js rules.npm run ci
Runs formatting, linting, type checking, dependency hygiene, app build, Storybook build, tests, and security checks in the same order as the repository quality pipeline.
Before handing a branch over for review or merge, run npm run check, npm run lint, and npm run security locally at minimum. Prefer npm run ci so local validation matches the required GitHub checks as closely as possible. If you can only run a subset locally, call out exactly what was skipped and why in the PR.
svelte.config.js.wrangler.toml..svelte-kit/cloudflare per wrangler assets config.src/routes/robots.txt/+server.ts serves crawler guidance dynamically: only the canonical production origin https://www.chrisipowell.co.uk allows crawling and advertises the sitemap, while preview, branch, staging, and local origins return Disallow: /.src/routes/sitemap.xml/+server.ts serves a canonical XML sitemap built from first-class public routes plus published Contentful pages and blog posts, with 24-hour edge-friendly caching. When a new public route or indexable content type launches, update src/lib/services/seo/sitemap.ts in the same change so it stays discoverable..github/workflows/ci.yml runs the OSS validation pipeline on pull requests and pushes to main..github/workflows/security.yml runs a scheduled weekly security scan and supports manual dispatch..github/workflows/contentful-migrations.yml validates and applies Contentful migrations, and now follows the same Node runtime baseline as the rest of the repo.main are expected to be blocked until the required GitHub checks pass, including Lint, build, and test and Security checks.