> ## Documentation Index
> Fetch the complete documentation index at: https://www.commercengine.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# SEO & AI for Storefronts

> Make Commerce Engine storefronts search-ready, answer-engine friendly, and agent-actionable with @commercengine/seo and @commercengine/ai.

Commerce Engine splits storefront discoverability and agent capabilities into two focused packages:

<CardGroup cols={2}>
  <Card title="@commercengine/seo" icon="magnifying-glass" href="/docs/seo-ai/seo">
    Everything machines **read**: metadata, JSON-LD, canonical URLs, `robots.txt`, XML sitemaps, `llms.txt`, and Markdown mirrors.
  </Card>

  <Card title="@commercengine/ai" icon="wand-magic-sparkles" href="/docs/seo-ai/ai">
    Everything agents can **do**: search the catalog, inspect products and variants, work with the shopper's real cart, and navigate the storefront through WebMCP.
  </Card>
</CardGroup>

The packages are deliberately separate. Search engines and answer engines need stable, server- or build-generated representations. Browser agents need client-side tools tied to the shopper's session. You can use either package alone, but they are designed to share one route configuration so a crawler and an agent always resolve the same public URLs.

## Install

<CodeGroup>
  ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark"}}
  npm install @commercengine/seo @commercengine/ai @commercengine/storefront
  ```

  ```bash pnpm theme={"theme":{"light":"github-light","dark":"github-dark"}}
  pnpm add @commercengine/seo @commercengine/ai @commercengine/storefront
  ```

  ```bash yarn theme={"theme":{"light":"github-light","dark":"github-dark"}}
  yarn add @commercengine/seo @commercengine/ai @commercengine/storefront
  ```
</CodeGroup>

`@commercengine/checkout` is optional. Add it only when you want AI tools to open Hosted Checkout's login, cart, or checkout drawers.

## One public configuration

Keep public site identity and routes in a storefront-free module. This file is safe to import from both server and browser code.

```typescript src/lib/commerce-seo.config.ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { defineCommerceSeoConfig } from "@commercengine/seo/config";

export const commerceSeo = defineCommerceSeoConfig({
  site: {
    name: "Acme",
    url: "https://acme.example",
    brandName: "Acme",
    description: "Acme's official online store.",
    locale: "en_US",
  },
  routes: {
    // The package default is /products/:slug. Configure /product only when
    // that is the storefront's actual public route convention.
    productBase: "/product",
    categoryBase: "/category",
  },
});

export const { site, routes } = commerceSeo;
```

<Warning>
  `site.url` must be the public origin, such as `https://acme.example`. Do not include a path like `/shop`. Canonicals, sitemaps, breadcrumbs, Markdown mirrors, and agent navigation all derive from this value.
</Warning>

`site.url`, `routes.search`, and the route bases are validated when `createCommerceSeo` runs, not on first use — a sub-path, an `ftp://` scheme, embedded credentials, a bare domain with no scheme, or a base that resolves off-site all throw a `RangeError` at construction. The instance carries the **parsed** origin, so read `seo.config.site.url` rather than the raw environment variable; they are not the same string.

<Info>
  **Does one product have one public page, or several?** If a CMS owns the URLs and several landing pages can sell the same catalog product, configure [route records](/docs/seo-ai/seo#custom-routes-and-cms-owned-slugs) instead of route bases. A resolver returns one URL per product, so the other landing pages never reach a sitemap — and product cards that build `/products/{catalog-slug}` by hand link to a route the CMS never renders.
</Info>

Then create the SEO instance next to the storefront. This module is server/build-bound in framework applications because it holds a storefront client.

```typescript src/lib/seo.ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { createCommerceSeo } from "@commercengine/seo";
import { commerceSeo } from "./commerce-seo.config";
import { storefront } from "./storefront";

export const seo = createCommerceSeo({
  ...commerceSeo,
  storefront,
});
```

Client code such as AI registration imports `site` and `routes` from `commerce-seo.config.ts`, **not** the module exporting `seo`.

## What SEO gives you

With the package wired once, a storefront can expose:

| Surface                    | Purpose                                                                                                         |
| -------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Product/category head data | Titles, descriptions, canonical URLs, Open Graph, Twitter, Markdown alternates                                  |
| JSON-LD                    | `Product`, `ProductGroup`, offers, variants, attributes, collections, organization, website search, breadcrumbs |
| `/robots.txt`              | Crawler policy and sitemap discovery; opt in with `robots: true` in server mode                                 |
| `/sitemap.xml`             | Search-engine URL index, automatically sharded beyond 50,000 URLs; opt in with `sitemap: true` in server mode   |
| `/llms.txt`                | Compact storefront guide for AI systems                                                                         |
| `/sitemap.md`              | Markdown index of machine-readable storefront pages                                                             |
| `{productBase}/{slug}.md`  | Product representation optimized for agents and answer engines                                                  |
| `{categoryBase}/{slug}.md` | Category representation with product links                                                                      |
| `Accept: text/markdown`    | Content negotiation on canonical HTML URLs when a server runs at request time                                   |

The only deployment decision that matters is whether a server exists at request time. Server deployments mount one handler. Static deployments run one prebuild script. See [Deployment and indexability](/docs/seo-ai/deployment).

## What AI gives you

`@commercengine/ai` publishes browser-native WebMCP tools. The default catalog tools are always available when WebMCP is supported. Session/cart tools are included when the storefront exposes a browser session client; registration itself does not wait for session bootstrap, and those tools return a retryable not-ready result until the session is usable.

A typical storefront can expose:

* catalog search, product lookup, category browsing, and variant lookup
* the shopper's session state without revealing identity
* cart read, add, absolute quantity update, and removal
* navigation to a product, orders page, cart drawer, login screen, or checkout
* optional store policy/FAQ search

The package intentionally stops before purchase completion. It cannot enter credentials, addresses, payment details, or place an order. The shopper completes checkout. See [Agent tools and security](/docs/seo-ai/agent-security).

## Register the agent tools

Registration is client-only and is safe to run before the anonymous session is ready. Each session-dependent tool reports a retryable failure until the session exists.

```typescript theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { registerCommerceWebMcp } from "@commercengine/ai/webmcp";
import { routes, site } from "./commerce-seo.config";
import { storefront } from "./storefront";

const registration = await registerCommerceWebMcp({
  storefront,
  siteUrl: site.url,
  routes,
  diagnostics: (event) =>
    console.info("[commerce-ai]", event.code, event.message ?? ""),
});

// Save the controller and abort every tool installed by this call on teardown.
// registration?.abort();
```

<Info>
  WebMCP is an evolving browser capability. In browsers without `document.modelContext`, registration returns `null`; your storefront continues normally. Development diagnostics tell you whether your registration code actually ran.
</Info>

## Framework map

| Framework      | SEO head                                           | SEO serving                             | AI registration                                 |
| -------------- | -------------------------------------------------- | --------------------------------------- | ----------------------------------------------- |
| React / Vite   | `createProductHead` / `createCategoryHead`         | static prebuild to `public/`            | root effect, in parallel with session/bootstrap |
| Next.js        | `createProductMetadata` / `createCategoryMetadata` | `createNextjsSeoProxy`                  | root Client Component                           |
| TanStack Start | `createTanStackStartProductHead`                   | request middleware                      | root `useEffect`                                |
| Astro          | `createAstroProductHead`                           | middleware for SSR, prebuild for static | `astro:page-load` client runtime                |
| SvelteKit      | `createSvelteKitProductHead`                       | server hook or prebuild to `static/`    | root `onMount`                                  |

<CardGroup cols={2}>
  <Card title="React / Vite" icon="react" href="/docs/seo-ai/react">
    SPA and static-site setup
  </Card>

  <Card title="Next.js" icon="n" href="/docs/seo-ai/nextjs">
    App Router setup
  </Card>

  <Card title="TanStack Start" icon="code" href="/docs/seo-ai/tanstack-start">
    Request middleware and head setup
  </Card>

  <Card title="Astro" icon="star" href="/docs/seo-ai/astro">
    Static and server deployment recipes
  </Card>

  <Card title="SvelteKit" icon="code" href="/docs/seo-ai/sveltekit">
    Server adapter and adapter-static recipes
  </Card>
</CardGroup>

## Production examples

The Commerce Engine starter repository uses both packages across React SPA, Next.js, Astro, SvelteKit, and TanStack Start implementations. Treat those projects as executable reference integrations when you want to see the complete app-level wiring.

<Card title="Commerce Engine Starter Projects" icon="github" href="https://github.com/tark-ai/ce-starter-projects">
  Production reference storefronts using `@commercengine/seo` and `@commercengine/ai` across five frameworks.
</Card>
