adapter-static. Use the server hook when requests reach SvelteKit in production; use the prebuild asset writer when the deployment is static.
1. Shared config and SEO instance
src/lib/commerce-seo.config.ts
src/lib/server/seo.ts
2. Build product/category head data in load
src/routes/product/[slug]/+page.server.ts
<svelte:head>:
src/routes/product/[slug]/+page.svelte
seo.productUrl() and seo.categoryUrl().
3A. Server deployment: use the SvelteKit handle
src/hooks.server.ts
handle, compose the SEO handle with SvelteKit’s sequence() helper rather than replacing the existing hook.
The handler owns Markdown mirrors, content negotiation, llms.txt, sitemap.md, robots, and XML sitemap routes.
3B. adapter-static: prebuild into static/
Static hosting cannot inspect Accept at runtime and cannot build arbitrary /search.md?q=... queries. Generate explicit discovery files before the SvelteKit build:
Reuse the shared commerceSeo declaration from step 1 and load local env files before SvelteKit/Vite starts. Running the prebuild as TypeScript keeps that config as a single source of truth:
scripts/generate-seo-assets.ts
package.json
indexable unset in this shared script. Deployment detection then keeps preview builds non-indexable and marks only proven production deployments indexable.
Generated SEO files should be gitignored.
Vercel and adapter-static
SvelteKit static output can emit route files such as privacy-policy.html. On Vercel, enable clean URLs so sitemap-advertised extensionless routes resolve:
vercel.json
/foo.html works but /foo returns 404 in production, the Svelte build succeeded and only host routing is missing.
4. Register WebMCP in root onMount
src/routes/+layout.svelte
Production checklist
- choose server hook or static prebuild from the adapter/deployment target
- static build outputs go to
static/, notpublic/ vercel.jsonusescleanUrlsfor adapter-static deployments on Vercel- generic layout metadata yields to page
seoHead - root
onMountactually reaches the WebMCP registration block - development diagnostics prove registration ran
- cleanup aborts the registration
- production deep links and
.mdmirrors both return 200
Reference starter
Full SvelteKit adapter-static storefront using both packages.