@commercengine/seo in the browser for page head data, generate the discovery assets before the Vite build, and register @commercengine/ai from app bootstrap or a root effect.
1. Share site and route configuration
src/lib/commerce-seo.config.ts
2. Create the SEO instance
A browser-only SPA can use the canonical Storefront factory directly:src/lib/seo.ts
src/lib/use-commerce-seo.tsx
3. Render the head model
React 19 hoists<title>, <meta>, and <link> into <head>. JSON-LD can remain inline in the page tree.
src/components/Seo.tsx
data-seo-default pattern that removes only overridden defaults and restores them on unmount.
4. Generate SEO assets before Vite builds
A SPA cannot answerAccept: text/markdown or generate robots.txt on demand. Write physical files into public/ before vite build.
Run the prebuild as TypeScript so it can import the exact same pure configuration used by the app and AI tools. Add a TypeScript executor and a small env loader:
scripts/generate-seo-assets.ts
package.json
indexable: true in this shared build script. With the option omitted, Vercel, Netlify, Cloudflare, and generic Node production/preview signals remain authoritative. A local build with no reliable deployment signal is intentionally generated as non-indexable.
Generated files are build artifacts. Ignore them instead of committing them:
index.html. Static files such as .md, robots.txt, and sitemap.xml are normally matched before that rewrite.
5. Register AI tools
Registration does not need to wait for the session. Mount it from app startup or a root effect and abort it on teardown.src/lib/register-agent-tools.ts
registerCommerceWebMcp() returns null when the capability is unavailable. The root effect/bootstrap that calls registerAgentTools() should keep the returned controller and call .abort() during cleanup so a late registration cannot survive unmount.
Production checklist
- build outputs
/robots.txt,/sitemap.xml,/llms.txt,/sitemap.md, and product/category.mdfiles - product pages render one product schema, not a package schema plus a hand-written duplicate
- static Open Graph defaults do not override page-specific metadata
- deep product/category URLs work on a hard reload
- development console shows a Commerce AI registration diagnostic
- AI and SEO both import the same
siteandroutesconfiguration
Reference starter
See the Soja React/Vite storefront for the complete production pattern.