diff --git a/AGENTS.md b/AGENTS.md index d381ef4598..ad9b072e75 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # AGENTS.md — AI Guidance for Sitecore Content SDK -> **Claude Code users:** This file does not include detailed coding rules. Read all `.cursor/rules/*.mdc` files at the start of your session for code style, naming conventions, Sitecore patterns, testing, and safety rules. +> **Claude Code users:** Start with this file. Open `.cursor/rules/*.mdc` **when a task touches that area** (e.g. `safety.mdc`, `testing.mdc`) — do not load every rule file by default. See root [`CLAUDE.md`](CLAUDE.md). ## Project Overview diff --git a/CLAUDE.md b/CLAUDE.md index f525b4a75d..afde92ff85 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,17 +1,10 @@ # Claude Code — Sitecore Content SDK -At the start of every session, read these files for full project guidance: +**Start here:** [`AGENTS.md`](AGENTS.md) — monorepo overview, commands, boundaries, and where to edit. -1. **`AGENTS.md`** — Canonical source of truth: project overview, commands, package structure, boundaries, DO/DON'T rules, example tasks, git workflow -2. **`.cursor/rules/`** — Detailed coding rules (not auto-loaded by Claude Code): - - `code-style.mdc` — Vibe-coding principles, code quality, error handling, imports, lint - - `javascript.mdc` — Naming conventions, code layout, security, performance, JSDoc - - `sitecore.mdc` — XM Cloud integration, component development, content management - - `general.mdc` — DRY, SOLID, architecture patterns, development standards - - `testing.mdc` — Mocha/Sinon/Chai, test commands - - `safety.mdc` — Safety rules for compiled artifacts and secrets - - `cli.mdc` — CLI behavior, init flow, backwards compatibility - - `project-context.mdc` — Project-wide context and constraints - - `repo-structure.mdc` — Repository structure and templates policy - - `agent-tasks.mdc` — Example workflows (add utility, fix test, change template) -3. **`Skills.md`** and **`.agents/skills/`** — For capability-specific guidance (component registration, data fetching, editing, i18n, etc.), when your tool supports the [Agent Skills](https://agentskills.io) standard. +**Add detail only when needed:** + +- **Coding rules:** [`.cursor/rules/`](.cursor/rules/) — open the relevant `.mdc` file for the task (e.g. `safety.mdc`, `sitecore.mdc`, `testing.mdc`). Do **not** load every rule file by default. +- **Capabilities:** [`Skills.md`](Skills.md) lists task → skill names. If your tool supports [Agent Skills](https://agentskills.io), read **one** matching skill under `.agents/skills//SKILL.md` (skills for scaffolded apps live in the Next.js templates under `packages/create-content-sdk-app/src/templates/`). + +This repo is the **Content SDK monorepo**. For a **generated head app**, use that app’s `AGENTS.md` (not this file’s folder) as the primary guide. diff --git a/Skills.md b/Skills.md index 618b255dc0..63959f4e81 100644 --- a/Skills.md +++ b/Skills.md @@ -9,6 +9,6 @@ Capability groupings and Agent Skills are **maintained in the scaffolding templa | **App Router** | [Skills.md](packages/create-content-sdk-app/src/templates/nextjs-app-router/Skills.md) · [.agents/skills/](packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/) | | **Pages Router** | [Skills.md](packages/create-content-sdk-app/src/templates/nextjs/Skills.md) · [.agents/skills/](packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/) | -Each template’s `Skills.md` lists the same capability groupings (component scaffold, registration, data fetching, editing, i18n, etc.) with template-specific details. Each template’s `.agents/skills/` contains one folder per capability with a `SKILL.md` (when-to-use, how to perform, hard rules, stop conditions). Tools that support [Agent Skills](https://agentskills.io) can load skills from the template path when working in a generated app or in the template source. +Each template’s `Skills.md` lists capability groupings (component scaffold, registration, data fetching, editing, i18n, etc.) with template-specific details. Each template’s `.agents/skills/` has one folder per capability with a compact `SKILL.md` that points to that template’s `AGENTS.md` for full detail. Tools that support [Agent Skills](https://agentskills.io) should load **one** skill that matches the task, not the whole tree. For monorepo-level instructions (commands, structure, DO/DON’T), see [AGENTS.md](AGENTS.md). For official APIs and guides, see the [Content SDK documentation](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-key-concepts.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-key-concepts.md new file mode 100644 index 0000000000..3c2970bfe4 --- /dev/null +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-key-concepts.md @@ -0,0 +1,37 @@ +# Key concepts (App Router) + +Optional, on-demand detail for this scaffolded head app. The compact guide is [AGENTS.md](../../AGENTS.md); open this file when you need middleware, client, catch-all, locale, and related concepts. + +## Key concepts for this app + +These are the main head-app–specific concepts. Details are in the sections below. + +### Middleware (Edge proxy) + +- **Where:** `src/proxy.ts`. Next.js runs middleware from `middleware.ts` at root or in `src/` — if the app only has `proxy.ts`, add `src/middleware.ts` that re-exports it. +- **What it does:** Runs on each request (respecting the `matcher`). Chain order is **fixed:** LocaleProxy → AppRouterMultisiteProxy → RedirectsProxy → PersonalizeProxy. Locale must run first so i18n and multisite see the correct locale. +- **Config:** Uses `sitecore.config.ts` (multisite, redirects, personalize), `.sitecore/sites.json`, and `src/i18n/routing.ts` (locales). **Do not change proxy order.** Keep the matcher excluding API, `_next/`, sitemap, robots, and static assets so the proxy stays lightweight. + +### SitecoreClient + +- **Where:** Single shared instance in `src/lib/sitecore-client.ts` — `new SitecoreClient({ ...scConfig })` with config from `sitecore.config.ts`. +- **Use for:** `getPage`, `getDictionary`, `getErrorPage`, `getPreview`, `getDesignLibraryData`, `getAppRouterStaticParams`. All Sitecore data fetching in the app goes through this client. +- **Do not:** Create a second client or instantiate SitecoreClient elsewhere. Pass `site` and `locale` from route params (or `parseRewriteHeader` in not-found), not from global state. + +### Catch-all route + +- **Where:** `src/app/[site]/[locale]/[[...path]]/page.tsx`. This is the **only** page component that renders Sitecore content; the optional `[[...path]]` segment captures the content path. +- **Flow:** `params` is a Promise (Next.js 15+) — `await params` to get `{ site, locale, path? }`. Call `client.getPage(path ?? [], { site, locale })`. For preview, use `draftMode()` and `client.getPreview(editingParams)` or `client.getDesignLibraryData(editingParams)` from `searchParams`. Call `setRequestLocale(\`${site}_${locale}\`)` at the top of the page for next-intl. +- **Do not:** Add another catch-all or page at a different path for Sitecore pages; keep this single entry point. + +### How locale works + +- **In the URL:** All content routes are `/[site]/[locale]/...path` (e.g. `/default/en`, `/default/en/about`). Middleware (LocaleProxy, then AppRouterMultisiteProxy) rewrites incoming requests into this shape. +- **In the app:** next-intl uses a single `requestLocale` per request. This app encodes both site and locale as `requestLocale = \`${site}_${locale}\``. In the page, call `setRequestLocale(\`${site}_${locale}\`)` so next-intl and `src/i18n/request.ts` see it. In `request.ts`, parse `requestLocale` (e.g. `split('_')`) to get site and locale, then load the dictionary with `client.getDictionary({ locale, site })`. +- **Config:** `src/i18n/routing.ts` defines `locales` and `defaultLocale`; align these with Sitecore languages (e.g. from `sitecore.config.ts`). **Do not** change the `{site}_{locale}` convention without updating request.ts and all pages that call `setRequestLocale`. + +### More (component maps, editing, env) + +- **Component maps:** `.sitecore/component-map.ts` (Server) and `.sitecore/component-map.client.ts` (Client). Register every Sitecore component here; keep in sync with `src/components/`. +- **Editing/preview:** Use `draftMode()` in Server Components; when enabled, use `client.getPreview(searchParams)` or `client.getDesignLibraryData(searchParams)`. Editing API routes live under `src/app/api/editing/`. +- **Env:** All config via environment variables in `sitecore.config.ts`. Document vars in `.env.example` (or `.env.remote.example` / `.env.container.example`); never commit `.env` or `.env.local`. diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-overview.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-overview.md new file mode 100644 index 0000000000..0d688d8cd8 --- /dev/null +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-overview.md @@ -0,0 +1,9 @@ +# Project overview (App Router) + +Optional, on-demand detail for this scaffolded head app. The compact guide is [AGENTS.md](../../AGENTS.md); open this file when you need scope and orientation beyond that file. + +## Project Overview + +This is a **Sitecore Content SDK** application built with **Next.js (App Router)** and **TypeScript**. AI agents work as developer assistants within this scaffolded head application. The app integrates with Sitecore XM Cloud for content, uses **file-based routing with `[site]` and `[locale]`**, next-intl for i18n, and Edge middleware for multisite, redirects, and personalization. + +**Scope:** This file applies to **this application only** (a scaffolded head app). Here we edit app code and config (app router, components, API routes, i18n); we do not modify SDK packages or CI. diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-router-specifics.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-router-specifics.md new file mode 100644 index 0000000000..828bd9bfd4 --- /dev/null +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-router-specifics.md @@ -0,0 +1,62 @@ +# Next.js App Router specifics + +Optional, on-demand detail for this scaffolded head app. The compact guide is [AGENTS.md](../../AGENTS.md); open this file for routing, data fetching, API routes, component maps, and layout depth. + +## Next.js App Router specifics + +### Routing: `[site]` / `[locale]` / `[[...path]]` + +- **URL shape:** `/[site]/[locale]/...path` (e.g. `/default/en`, `/default/en/about`). Site and locale are **in the path**; the Edge proxy rewrites incoming requests to this shape. +- **Page component:** `src/app/[site]/[locale]/[[...path]]/page.tsx`. Receives `params: Promise<{ site, locale, path? }>`. Use `await params`; pass `site` and `locale` to `client.getPage(path ?? [], { site, locale })`. +- **Layout hierarchy:** `app/layout.tsx` → `app/[site]/layout.tsx` (per-site; runs Bootstrap with `siteName={site}` and `draftMode()`) → page. Do not put site/locale-specific data fetching in the root layout; use the `[site]` or page layout. + +### i18n (next-intl) + +- **Config:** `src/i18n/routing.ts` — `defineRouting({ locales, defaultLocale, localePrefix })`. Align `locales` with Sitecore languages; often sourced from `sitecore.config.ts` (e.g. `defaultLanguage`). +- **Request config:** `src/i18n/request.ts` — `getRequestConfig` receives `requestLocale`. The app uses `{site}_{locale}` (e.g. set by `setRequestLocale(\`${site}_${locale}\`)` in the page). Parse with `requested?.split('_')` to get `parsedSite` and `parsedLocale`; load dictionary with `client.getDictionary({ locale, site: parsedSite })` and return `{ locale, messages }`. +- **In pages:** Call `setRequestLocale(\`${site}_${locale}\`)` at the top of the page so next-intl and request config see the correct locale. + +### Multisite and Edge middleware (proxy) + +- **Site list:** `.sitecore/sites.json` — typically generated by the Sitecore CLI or deployment. Used by middleware and API route handlers. Avoid hand-editing unless you know the format. +- **Edge middleware:** Implemented in **`src/proxy.ts`**. Next.js only runs middleware from a file named `middleware.ts` at root or in `src/`. If this app has only `proxy.ts`, add `src/middleware.ts` that re-exports it (e.g. `export { default } from './proxy';`) so the proxy runs. +- **Proxy chain (order is critical):** `defineProxy(locale, multisite, redirects, personalize).exec(req)`: + - **LocaleProxy** — runs first; uses `sites` and `routing.locales` from `src/i18n/routing.ts`. Required for App Router so locale is set before multisite. + - **AppRouterMultisiteProxy** — rewrites to `/[site]/[locale]/[...path]`; uses `scConfig.multisite`. + - **RedirectsProxy** — redirects; uses `scConfig.redirects`, `scConfig.api.edge`, `scConfig.api.local`. + - **PersonalizeProxy** — personalization; uses `scConfig.personalize`; often disabled in dev. +- **Matcher:** Exclude API routes, `_next/`, sitemap, robots, healthz, Sitecore paths, and static assets so middleware does not run on every static request. The matcher is defined in `config` in `proxy.ts` (or in `middleware.ts` if it re-exports the proxy). +- **Config:** `sitecore.config.ts` → `multisite`, `redirects`, `personalize`; never commit secrets. + +### Data fetching and preview + +- **Page data:** In the page (or a Server Component), use `client.getPage(path ?? [], { site, locale })`. For preview, use `draftMode()`; if `draft.isEnabled`, use `client.getPreview(editingParams)` or `client.getDesignLibraryData(editingParams)` from `searchParams`; otherwise use `getPage` with `site` and `locale`. +- **SSG:** `generateStaticParams` — use `client.getAppRouterStaticParams(sites, routing.locales)` (sites from `.sitecore/sites.json`). Return at least one default param when not generating full paths (e.g. dev or when `generateStaticPaths` is off). +- **Metadata:** `generateMetadata` in the same segment can call `client.getPage(path ?? [], { site, locale })` and derive `title` (e.g. from route fields). Next.js will cache as appropriate. + +### Server vs Client components + +- **Default:** Components are Server Components. Use `'use client'` only for interactivity (e.g. hooks, event handlers). +- **draftMode:** Used in layout and page; call `await draftMode()` in Server Components that need to know preview state. + +### Not-found and error page + +- **Segment not-found:** `src/app/[site]/[locale]/[[...path]]/not-found.tsx`. Uses `getCachedPageParams()` from `@sitecore-content-sdk/nextjs` for site/locale, then `client.getErrorPage(ErrorPage.NotFound, { site, locale })` and renders layout if a page is returned. +- **Root not-found:** `src/app/not-found.tsx` — minimal fallback when no segment handles the route. + +### API route handlers + +- **Sitemap:** `src/app/api/sitemap/route.ts` — `createSitemapRouteHandler({ client, sites })`. Export `{ GET }`; use `sites` from `.sitecore/sites.json`. Set `export const dynamic = 'force-dynamic'` if the handler relies on request. +- **Robots:** `src/app/api/robots/route.ts` — `createRobotsRouteHandler({ client, sites })`. Same pattern. +- **Editing:** `src/app/api/editing/config/route.ts` and `editing/render/route.ts` — use `createEditingConfigRouteHandler` and the appropriate render handler with `components`, `clientComponents` (`.sitecore/component-map.client.ts`), `metadata`, and `client`. Set `dynamic = 'force-dynamic'` where needed. +- **Rewrites:** `next.config.ts` → rewrites for `/sitemap*.xml`, `/robots.txt` with `locale: false` so they are not localized. + +### Sitecore client and config + +- **Client:** `src/lib/sitecore-client.ts` — `new SitecoreClient({ ...scConfig })`. Use for `getPage`, `getDictionary`, `getErrorPage`, `getPreview`, `getAppRouterStaticParams`, etc. +- **Config:** `sitecore.config.ts` — `defineConfig({ api, defaultSite, defaultLanguage, editingSecret, redirects, multisite, personalize })`. Use env vars only; no hardcoded secrets. + +### Component maps and layout + +- **Server/client components:** `.sitecore/component-map.ts` (Server); `.sitecore/component-map.client.ts` (Client). Register all Sitecore components; keep in sync with `src/components/`. +- **Layout:** `Layout.tsx` renders page layout and placeholders; `Providers` wrap page and component context; `Bootstrap` in `[site]/layout.tsx` receives `siteName={site}` and preview state. diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-workflows-and-boundaries.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-workflows-and-boundaries.md new file mode 100644 index 0000000000..645ddc49f3 --- /dev/null +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/AGENTS-workflows-and-boundaries.md @@ -0,0 +1,20 @@ +# Example tasks and boundaries (App Router) + +Optional, on-demand detail for this scaffolded head app. The compact guide is [AGENTS.md](../../AGENTS.md); open this file for concrete task examples and edit boundaries. + +## Example agent tasks + +- **Add a new Sitecore component:** Create the component under `src/components/`, register it in `.sitecore/component-map.ts` and `.sitecore/component-map.client.ts` as appropriate (client components in the client map), and ensure it is rendered in the layout/placeholder as in existing components. +- **Add an API route:** Create the route under `src/app/api/` (e.g. `src/app/api/my-route/route.ts`), add a rewrite in `next.config.ts` if the route should be reached from a public URL, and ensure the proxy `matcher` in `proxy.ts` still excludes it (e.g. `api/` is already excluded). + +--- + +## Boundaries + +**Never edit:** `.next/`, `node_modules/`. + +**Environment variables:** You may add new env vars when needed. Do it carefully: add the variable to `.env.example` (or `.env.remote.example` / `.env.container.example` in this template) with a placeholder or comment; never put real secrets in example files. If editing `.env.local` for local dev, add only the variable name and tell the user to set the value. **Never commit** `.env` or `.env.local` — they are gitignored. + +**Edit with care:** `next.config.ts` (rewrites, next-intl plugin), `sitecore.config.ts` (env only), `proxy.ts` (matcher and proxy order), `src/i18n/routing.ts` and `request.ts`. When adding routes or rewrites, keep middleware `matcher` and rewrite rules consistent. + +**Focus on:** `src/app/`, `src/components/`, `src/lib/`, `src/i18n/`, `Layout.tsx`, `Providers.tsx`, `sitecore.config.ts`, `next.config.ts`, `proxy.ts`, `.sitecore/component-map.ts`, `.sitecore/component-map.client.ts`. diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/README.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/README.md new file mode 100644 index 0000000000..7409002394 --- /dev/null +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/docs/README.md @@ -0,0 +1,12 @@ +# Layered AI docs (App Router) + +Use [AGENTS.md](../../AGENTS.md) first (compact). Open **one** file below when you need depth. + +| File | Use when | +|------|----------| +| [AGENTS-overview.md](AGENTS-overview.md) | Project scope and what this head app is | +| [AGENTS-key-concepts.md](AGENTS-key-concepts.md) | Middleware, SitecoreClient, catch-all, locale, component map teaser | +| [AGENTS-router-specifics.md](AGENTS-router-specifics.md) | App Router routing, next-intl, proxy, data fetching, API routes, component maps, layout | +| [AGENTS-workflows-and-boundaries.md](AGENTS-workflows-and-boundaries.md) | Example tasks (new component, API route) and edit boundaries | + +Skills: [.agents/skills/](../skills/) — load **one** [SKILL.md](https://agentskills.io) per task. See [Skills.md](../../Skills.md). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-data-strategy/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-data-strategy/SKILL.md index feab5497fa..919b460109 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-data-strategy/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-data-strategy/SKILL.md @@ -1,37 +1,25 @@ --- name: content-sdk-component-data-strategy -description: Component data for App Router: layout data from getPage (or getPreview/getDesignLibraryData in editing). No getComponentData; pass site and locale from route params. Server Components use the client in server context; Client Components receive serializable props. Use when wiring component data or BYOC. +description: Component data for App Router: layout from getPage (or preview handlers in editing). Pass site and locale from route params; Server Components fetch with the client; Client Components get serializable props. BYOC must be registered in the component map. Use when wiring component data. --- -# Content SDK Component Data Strategy (App Router) +# Component data (App Router) -This app does **not** use getComponentData. Page and layout data come from **getPage** (or getPreview/getDesignLibraryData in editing). Component props are derived from the layout/placeholders; pass site and locale from route params. +**Detail:** [AGENTS-key-concepts.md](../../docs/AGENTS-key-concepts.md#catch-all-route), [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#server-vs-client-components); **content-sdk-graphql-data-fetching**. -## When to Use +**Read code first:** `src/app/[site]/[locale]/[[...path]]/page.tsx`, `.sitecore/component-map.ts`, `.sitecore/component-map.client.ts`. -- User asks how to pass data to components, wire component props, or integrate custom/BYOC components. -- Task involves component props, server vs client components, or BYOC. -- User mentions "component data," "props," "BYOC," "server component," or "client component." +## When -## How to perform +- Passing props from page/layout to components, BYOC, or RSC vs client boundaries. -- Fetch at page/layout with getPage (or getPreview/getDesignLibraryData in draft). Pass site and locale from route params. Server Components use the client in server context; Client Components receive serializable props only. Register BYOC in the correct component map and pass props from layout. +## Rules -## Hard Rules +- Fetch Sitecore layout/page data in Server Components / page; pass serializable props to client children. +- BYOC must be registered in the correct map; do not re-fetch layout in client components unless the app already does. -- **Data source:** Page and layout from `client.getPage(path ?? [], { site, locale })` in the catch-all page (or getPreview/getDesignLibraryData when draftMode() is enabled). All Sitecore-driven data flows from this single fetch at the route level. -- **Server Components:** Use the same SitecoreClient in server context (e.g. in the page or layout). Pass data as props to children. -- **Client Components:** Receive **serializable** props from parent (no functions or non-serializable values). Do not create a new client inside components. Pass data from page/layout level into components. -- **BYOC or custom components:** Must be registered in the appropriate component map (.sitecore/component-map.ts or component-map.client.ts) and receive props in the shape the layout expects (e.g. fields, params). -- Do not fetch layout or page data inside a child component (e.g. another getPage call); fetch at page/layout level and pass props. +## Stop -## Stop Conditions +- Reject patterns that duplicate `getPage` across many client components for the same request. -- Stop if the user wants to fetch page/layout data inside a child component; recommend fetching at page/layout level and passing props. -- Stop if server/client boundary is ambiguous and the change could cause "use client" or serialization issues; clarify and follow Next.js and app conventions. -- Do not introduce getComponentData or duplicate getPage logic; this app uses getPage-only data flow. - -## References - -- content-sdk-graphql-data-fetching and [AGENTS.md](../../../AGENTS.md) for getPage and data flow. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-registration/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-registration/SKILL.md index ce37a9490d..373f17d64f 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-registration/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-registration/SKILL.md @@ -1,38 +1,25 @@ --- name: content-sdk-component-registration -description: Registers Sitecore components in the component map so layout and editing can resolve them. App Router uses .sitecore/component-map.ts (Server) and .sitecore/component-map.client.ts (Client). Use when registering a new component or when layout/editor cannot find a component. +description: Registers Sitecore components in .sitecore/component-map.ts (Server) and .sitecore/component-map.client.ts (Client). Required for layout and editing. App Router uses separate server and client maps. Use when registering a new component or when layout/editor cannot find a component. --- -# Content SDK Component Registration (App Router) +# Component registration (App Router) -Register components in the Sitecore component maps so the layout and editing pipeline can resolve and render them. This app has **two** maps: server and client. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#component-maps-and-layout), [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#api-route-handlers). -## When to Use +**Read code first:** `.sitecore/component-map.ts`, `.sitecore/component-map.client.ts`. -- After scaffolding or adding a new Sitecore component (must be registered). -- User reports a component not rendering, "component not found," or layout/placeholder showing raw component name. -- Task involves `.sitecore/component-map.ts` or `.sitecore/component-map.client.ts`. -- User asks how to register a component or fix component resolution. +## When -## How to perform +- Missing component in editor/layout, or task touches server/client maps. -- Open `.sitecore/component-map.ts` (Server) or `.sitecore/component-map.client.ts` (Client). Add an entry mapping the layout component name to the React component import. Keep keys consistent with layout and existing map entries. +## Rules -## Hard Rules +- Server components → `.sitecore/component-map.ts`; interactive/client → `.sitecore/component-map.client.ts` when required by editing. +- Keep map keys aligned with layout names and with `createEditingConfigRouteHandler` wiring. -- Every component rendered from Sitecore layout must be registered. Keep the maps in sync with `src/components/`. -- **Server components** (no `'use client'`): Register in `.sitecore/component-map.ts` only. -- **Client components** (`'use client'`): Register in `.sitecore/component-map.client.ts` only. Editing API routes use both maps (e.g. `clientComponents` from the client map). -- Use consistent component names (same key in map as used in layout). Follow existing naming in the maps. -- Do not remove or rename registrations without updating all references (layout, editing routes). +## Stop -## Stop Conditions +- Escalate if renaming entries would break published layout without a Sitecore-side update. -- Stop if it is unclear whether the new component is Server or Client; ask or follow app convention. -- Stop if modifying the maps would break existing layout or editing; suggest a safe change or ask for confirmation. -- Do not edit `.sitecore/metadata.json` or import-map unless the task explicitly requires it. - -## References - -- [AGENTS.md](../../../AGENTS.md) for component maps and editing routes. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-scaffold/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-scaffold/SKILL.md index 7fdde7c063..ef1bfffb2e 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-scaffold/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-scaffold/SKILL.md @@ -1,38 +1,26 @@ --- name: content-sdk-component-scaffold -description: Creates new Sitecore components with correct file structure, props interface, and placement under src/components/. Use when adding a new component from scratch or scaffolding a component. App Router: decide Server vs Client and register in the appropriate map. +description: Creates new Sitecore components with correct file structure, props interface, and placement under src/components/. Use when adding a new component from scratch. App Router: register server components in .sitecore/component-map.ts and client components in .sitecore/component-map.client.ts as appropriate. --- -# Content SDK Component Scaffold (App Router) +# Component scaffold (App Router) -Scaffold new Sitecore components so they integrate with the layout and editing pipeline. This app uses App Router with separate server and client component maps. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#component-maps-and-layout), [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#server-vs-client-components), [AGENTS-workflows-and-boundaries.md](../../docs/AGENTS-workflows-and-boundaries.md#example-agent-tasks). -## When to Use +**Read code first:** `.sitecore/component-map.ts`, `.sitecore/component-map.client.ts`, `src/lib/component-props/index.ts`, and one existing component under `src/components/`. -- User asks to add a new Sitecore component, create a component from scratch, or scaffold a component. -- Task involves creating a new React component that will be rendered from Sitecore layout/placeholders. -- User mentions "new component," "add component," or "component file structure." +## When -## How to perform +- New Sitecore-driven component; need to choose Server vs Client and registration targets. -- Create a new file under `src/components/` (or existing feature folder). Define props (fields, params), export a single default component. -- Decide Server vs Client: default Server; add `'use client'` only if the component needs hooks or event handlers. -- Register the component in the correct map (content-sdk-component-registration). Run `npm run build` to verify. +## Rules -## Hard Rules +- Default Server Component; `'use client'` only when hooks/events require it. +- Register in `.sitecore/component-map.ts` and/or `.sitecore/component-map.client.ts` per existing patterns. +- Run `npm run build` to verify. -- Place components under `src/components/`. Use existing folder conventions. -- Define a props interface with the component's fields (e.g. `fields: { title: Field; ... }`) and any params. Use types from `@sitecore-content-sdk/react` or the app's types. -- Export a single default component; one component per file unless the app pattern differs. -- **Server vs Client:** Use Server Components by default. Add `'use client'` only for interactivity (hooks, event handlers). Register Server components in `.sitecore/component-map.ts`; Client components in `.sitecore/component-map.client.ts`. -- After creating the component file, register it in the correct component map (see content-sdk-component-registration). Do not leave the component unregistered. +## Stop -## Stop Conditions +- Do not scaffold under `.next/`, `node_modules/`, or build output. -- Stop and ask if the component should be a Server or Client Component when the app does not have a clear convention. -- Do not create components in `.next/`, `node_modules/`, or build output. - -## References - -- [AGENTS.md](../../../AGENTS.md) for app structure and component maps. -- [Skills.md](../../../Skills.md) for capability map. [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-variants/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-variants/SKILL.md index ce192b8f4b..02c6a68645 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-variants/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-component-variants/SKILL.md @@ -1,36 +1,23 @@ --- name: content-sdk-component-variants -description: Implements component variants: different renderings or data-driven variants of the same component type. App Router: register in component-map.ts or component-map.client.ts as appropriate. Use when one component has multiple presentations. +description: Component variants: different renderings or data-driven variants. App Router: register in the correct server/client component map. Use when one component has multiple presentations. --- -# Content SDK Component Variants (App Router) +# Component variants (App Router) -One component definition can have multiple presentations or data-driven variants. Keep registration and layout aligned. This app does not use getComponentData; layout/placeholder data comes from getPage. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#component-maps-and-layout), [AGENTS-key-concepts.md](../../docs/AGENTS-key-concepts.md#more-component-maps-editing-env). -## When to Use +## When -- User asks for different "variants," "versions," or "presentations" of a component. -- Task involves rendering the same component type with different layouts or props based on data (e.g. variant field or style). -- User mentions "component variants," "variations," or "multiple renderings." +- Multiple presentations of one component type (variant field, style param, etc.). -## How to perform +## Rules -- Prefer one component that accepts variant/style via props and branches internally; or multiple map entries if the app pattern uses one key per variant. Use layout/fields/params for variant; register in the correct component map (Server or Client). Align with existing app convention. +- Prefer one component + variant props from layout over many map entries unless the app already uses separate keys. +- Register variants in server map, client map, or both per component type and editing needs. -## Hard Rules +## Stop -- Prefer a single component registration that accepts variant/style data (e.g. params or fields) and branches internally, over multiple map entries for the same logical component unless the app pattern uses separate registrations per variant. -- Use props (fields, params) from layout to decide variant; do not rely on global state or URL for variant selection when data comes from Sitecore. -- Register in `.sitecore/component-map.ts` (Server) or `.sitecore/component-map.client.ts` (Client) as appropriate. If the app uses one key per variant, register each; if one key with variant param, single registration. Follow existing app convention. -- Keep component maps in sync with src/components/. +- If layout does not expose variant data, fix content model/layout before hacking URLs or globals. -## Stop Conditions - -- Stop if the variant model (one registration vs many) is unclear; ask or follow the app's existing pattern. -- Do not add new component map entries without ensuring layout and editing can provide the corresponding data. -- Do not assume variant field names (e.g. "variant," "style") without checking the layout definition. - -## References - -- [AGENTS.md](../../../AGENTS.md) and content-sdk-component-registration for maps. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md index ae110a6025..5276e50e86 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md @@ -1,37 +1,23 @@ --- name: content-sdk-dictionary-and-i18n -description: Dictionary and i18n for App Router: next-intl with src/i18n/routing.ts and request.ts. Request locale is site_locale; call setRequestLocale in the page; in request.ts parse and load dictionary with client.getDictionary. Use when adding or changing translated content or locale behavior. +description: Dictionary and i18n: next-intl with src/i18n/routing.ts and src/i18n/request.ts. Request locale is ${site}_${locale}; call setRequestLocale in the page; in request.ts parse and load dictionary with client.getDictionary({ locale, site }). Use when changing translations or locale behavior. --- -# Content SDK Dictionary and i18n (App Router) +# Dictionary & i18n (App Router) -This app uses **next-intl**. Locale is in the URL as [locale]. Request locale is encoded as `${site}_${locale}` for next-intl. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#i18n-next-intl), [AGENTS-key-concepts.md](../../docs/AGENTS-key-concepts.md#how-locale-works). -## When to Use +## When -- User asks to add or change translated content, locale, or dictionary. -- Task involves getDictionary, next-intl, or locale in URL/request. -- User mentions "dictionary," "i18n," "locale," "translation," or "next-intl." +- Dictionary messages, locales, or `src/i18n/request.ts` / `routing.ts`. -## How to perform +## Rules -- Locales and routing: `src/i18n/routing.ts`. Request config: `src/i18n/request.ts` — parse `requestLocale` (e.g. `${site}_${locale}`), call `client.getDictionary({ locale, site })`, return `{ locale, messages }`. In the page, call `setRequestLocale(\`${site}_${locale}\`)` at the top. Use a single getDictionary per request. +- Keep `${site}_${locale}` consistent: set in page via `setRequestLocale`; parse in `request.ts` and load `getDictionary({ site, locale })`. +- Align `routing.ts` locales with Sitecore languages / `sitecore.config.ts`. -## Hard Rules +## Stop -- **Config:** `src/i18n/routing.ts` — `defineRouting({ locales, defaultLocale, localePrefix })`. Align `locales` with Sitecore languages (e.g. from sitecore.config.ts defaultLanguage). -- **Request config:** `src/i18n/request.ts` — `getRequestConfig` receives `requestLocale`. This app uses `${site}_${locale}` (set by `setRequestLocale(\`${site}_${locale}\`)` in the page). Parse requestLocale (e.g. `split('_')`) to get site and locale; load dictionary with `client.getDictionary({ locale, site })` and return `{ locale, messages }`. -- **In the page:** Call `setRequestLocale(\`${site}_${locale}\`)` at the **top** of the page so next-intl and request config see the correct locale. Do not omit when adding new page branches. -- **Do not** change the `${site}_${locale}` convention without updating request.ts and all pages that call setRequestLocale. -- Use a single client.getDictionary per request for the active site/locale. Never assume locale from headers or global state; use route params (site, locale). +- Do not change the `${site}_${locale}` convention without updating `request.ts` and all callers. -## Stop Conditions - -- Stop if the user wants to change to a different encoding for requestLocale; this affects request.ts and all setRequestLocale call sites. -- Stop if adding a new locale without confirming it exists in Sitecore and in routing.ts. -- Do not duplicate dictionary fetching (e.g. in layout and page) without a clear need. - -## References - -- [AGENTS.md](../../../AGENTS.md) for next-intl, setRequestLocale, and getDictionary usage. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-editing-safe-rendering/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-editing-safe-rendering/SKILL.md index 3d4a9d4f32..eb50a3d9e2 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-editing-safe-rendering/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-editing-safe-rendering/SKILL.md @@ -3,35 +3,22 @@ name: content-sdk-editing-safe-rendering description: Ensures components render safely in XM Cloud editing and preview. App Router uses draftMode() and getPreview/getDesignLibraryData from searchParams. Use when making components work in the Sitecore editor or fixing preview/editing behavior. --- -# Content SDK Editing-Safe Rendering (App Router) +# Editing / preview (App Router) -Ensure components behave correctly in XM Cloud editing, preview, and design library. This app uses **draftMode()** and **searchParams** for editing data. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#data-fetching-and-preview), [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#api-route-handlers). -## When to Use +## When -- User asks about editing, preview, design library, or "component not working in editor." -- Task involves draft mode, editing chromes, or design library integration. -- Fixing issues where components render differently or break in editor vs published. -- User mentions getPreview, getDesignLibraryData, or editing API routes. +- Editor, preview, design library, or chromes behave incorrectly. -## How to perform +## Rules -- In the page or layout: call `draftMode()`; when enabled, read editing params from searchParams, use `isDesignLibraryPreviewData(editingParams)` to choose getDesignLibraryData vs getPreview; otherwise use getPage. Editing routes: config route uses `createEditingConfigRouteHandler`, render route uses `createEditingRenderRouteHandlers`; set `dynamic = 'force-dynamic'` on both. +- `await draftMode()`; when enabled, read editing params from `searchParams`, use `isDesignLibraryPreviewData` to pick `getDesignLibraryData` vs `getPreview`; otherwise `getPage(path ?? [], { site, locale })`. +- Config/render routes: `createEditingConfigRouteHandler` / `createEditingRenderRouteHandlers` with both component maps + `dynamic = 'force-dynamic'` where required. +- Secrets only via env; document in `.env.example`. -## Hard Rules +## Stop -- Use `draftMode()` in Server Components (e.g. in the page or [site] layout). When `draft.isEnabled`, get editing params from **searchParams** and use `isDesignLibraryPreviewData(editingParams)` to distinguish: if true, use `client.getDesignLibraryData(editingParams)`; otherwise use `client.getPreview(editingParams)`. When not in draft mode, use `getPage(path ?? [], { site, locale })`. -- Do not assume editing/preview context in components that might run in static or non-editing contexts; guard on `draftMode()`. -- Editing API routes: `src/app/api/editing/config/route.ts` uses `createEditingConfigRouteHandler({ components, clientComponents, metadata })` (import from `.sitecore/component-map`, `.sitecore/component-map.client`, `.sitecore/metadata.json`). `src/app/api/editing/render/route.ts` uses `createEditingRenderRouteHandlers({})`. Set `export const dynamic = 'force-dynamic'` on both. Do not duplicate client creation; config and render routes use the same component maps as the app. -- Never commit editing secrets; use environment variables and document in .env.example only. +- Do not reorder Edge proxy to “fix” editing; do not disable secret checks without explicit user consent. -## Stop Conditions - -- Stop and clarify if the issue is preview vs design library vs published; behavior differs. -- Do not change proxy or middleware order to "fix" editing; editing is driven by API routes and draft/preview data. -- Do not recommend disabling secret validation without explicit user request and warning. - -## References - -- [AGENTS.md](../../../AGENTS.md) for data fetching, preview flow, and editing routes. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md index 1b2031ca56..a5034bf640 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md @@ -3,34 +3,21 @@ name: content-sdk-field-usage-image-link-text description: Renders Sitecore fields using SDK field components (Text, RichText, Image, Link) with proper validation and fallbacks. Use when rendering content fields or when the user mentions Text, RichText, Image, Link, or field components. --- -# Content SDK Field Usage (App Router) +# Field components (App Router) -Use SDK field components to render Sitecore fields with proper validation and fallbacks. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#server-vs-client-components). -## When to Use +## When -- User asks how to render a title, body, image, or link from Sitecore. -- Task involves displaying content fields, fixing empty/broken images or links, or using RichText/Text/Image/Link components. -- User mentions "field," "Image," "Link," "Text," "RichText," or "field value." +- Rendering titles, rich text, images, links from Sitecore fields. -## How to perform +## Rules -- Use SDK field components: ``, ``, ``, ``. Guard with `fields?.` when optional; use tag prop on Text when needed. Do not hardcode media or link URLs from Sitecore. +- Prefer ``, ``, ``, `` with guarded `fields?.…`. +- Do not hardcode media URLs when Sitecore fields should drive resolution. -## Hard Rules +## Stop -- Prefer SDK field components over manual field value extraction: ``, ``, ``, ``. Use tag prop for Text when needed (e.g. tag="h1"). -- Validate or guard field existence before rendering when fields can be optional (e.g. `fields?.title`). Handle null/undefined and empty fields gracefully. -- Do not hardcode image or link URLs when the data comes from Sitecore; use the field components or helpers that resolve media/URLs. -- Follow the app's import pattern (e.g. from lib or components). +- If field names/types are unknown, confirm against layout/data before guessing. -## Stop Conditions - -- Stop if the field structure (name or type) is unknown; suggest checking the layout/data shape or asking the user. -- Do not assume field names (e.g. "title") without confirmation when the template might use different names. -- Do not commit or log raw field values that might contain PII or secrets. - -## References - -- [AGENTS.md](../../../AGENTS.md) for component and Sitecore patterns. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-graphql-data-fetching/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-graphql-data-fetching/SKILL.md index 5b0ee4a36f..c10db35500 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-graphql-data-fetching/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-graphql-data-fetching/SKILL.md @@ -1,37 +1,24 @@ --- name: content-sdk-graphql-data-fetching -description: Fetches page data and dictionary via the single Sitecore client. App Router: getPage(path ?? [], { site, locale }), getDictionary, getAppRouterStaticParams; for preview use draftMode() and getPreview/getDesignLibraryData from searchParams. Use when fetching page or dictionary content. +description: Page and dictionary fetching via the single Sitecore client in src/lib/sitecore-client.ts. App Router: getPage(path ?? [], { site, locale }), getDictionary, getAppRouterStaticParams for SSG; preview uses draftMode() and getPreview/getDesignLibraryData from searchParams. Use when fetching page or dictionary content. --- -# Content SDK GraphQL Data Fetching (App Router) +# Data fetching (App Router) -All Sitecore data fetching goes through the single client in `src/lib/sitecore-client.ts`. Use getPage, getDictionary, and related methods correctly. This app does **not** use getComponentData; layout data comes from getPage. +**Detail:** [AGENTS-key-concepts.md](../../docs/AGENTS-key-concepts.md#catch-all-route), [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#data-fetching-and-preview). -## When to Use +## When -- User asks how to fetch page data, layout, or dictionary phrases. -- Task involves getPage, getDictionary, getErrorPage, getPreview, getDesignLibraryData, or getAppRouterStaticParams. -- User mentions "sitecore client," "Layout Service," "page data," or "dictionary." +- `getPage`, `getDictionary`, static params, preview, or metadata from Sitecore. -## How to perform +## Rules -- Use the client from `src/lib/sitecore-client.ts` only. In the catch-all page: `await params`, then `client.getPage(path ?? [], { site, locale })`. For SSG use `generateStaticParams` and `client.getAppRouterStaticParams(siteNames, locales)`. For preview use `draftMode()` and `getPreview`/`getDesignLibraryData` from searchParams. +- Use only `src/lib/sitecore-client.ts`. `await params` (Next 15+); pass `{ site, locale }` into `getPage` / dictionary calls. +- At the top of content pages, call `setRequestLocale` with the template `` `${site}_${locale}` `` (see [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#i18n-next-intl)). +- SSG: `getAppRouterStaticParams(sites, routing.locales)`; preview via `draftMode` + search params. -## Hard Rules +## Stop -- Use the single SitecoreClient instance in `src/lib/sitecore-client.ts`. Do not create a second client or instantiate SitecoreClient elsewhere. -- Pass **site** and **locale** from route params (e.g. `await params` in the page). Do not rely on global state for site/locale in server code. -- **Catch-all page:** `client.getPage(path ?? [], { site, locale })`. Params are a Promise (Next.js 15+); use `await params` to get `{ site, locale, path? }`. -- **Preview:** Use `draftMode()`; if `draft.isEnabled`, use `client.getPreview(editingParams)` or `client.getDesignLibraryData(editingParams)` from **searchParams**. Otherwise use getPage with site and locale. -- **SSG:** `generateStaticParams` — use `client.getAppRouterStaticParams(siteNames, locales)` where site names come from `.sitecore/sites.json` (e.g. `sites.map((s) => s.name)`), locales from `src/i18n/routing.ts` (e.g. `routing.locales.slice()`). Return at least one default param when not generating full paths (e.g. `{ site, locale, path: [] }`). -- Config for the client comes from `sitecore.config.ts`; use environment variables, never hardcode secrets. +- Do not create a second client or fetch layout data in client components when SSR/RSC is intended. -## Stop Conditions - -- Stop if the task requires moving the client to another folder without clear requirement; suggest keeping a single instance in lib. -- Do not add direct GraphQL or fetch to Layout Service bypassing the client unless the task explicitly requires it. - -## References - -- [AGENTS.md](../../../AGENTS.md) for SitecoreClient, getPage, getDictionary, and SSG. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-multisite-management/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-multisite-management/SKILL.md index 452b3a52ea..55a1f93bcb 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-multisite-management/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-multisite-management/SKILL.md @@ -1,37 +1,24 @@ --- name: content-sdk-multisite-management -description: Handles multisite: site resolution, .sitecore/sites.json, and proxy in src/proxy.ts. App Router proxy order is fixed: LocaleProxy → AppRouterMultisiteProxy → RedirectsProxy → PersonalizeProxy. Use when working with multiple sites or hostnames. +description: Handles multisite: .sitecore/sites.json and proxy in src/proxy.ts. App Router proxy order is fixed: LocaleProxy → AppRouterMultisiteProxy → RedirectsProxy → PersonalizeProxy. Use when working with multiple sites or hostnames. --- -# Content SDK Multisite Management (App Router) +# Multisite / proxy (App Router) -Site resolution from request (e.g. hostname or cookie); proxy rewrites to /[site]/[locale]/...path. **Locale must run first** so next-intl and multisite see the correct locale. +**Detail:** [AGENTS-key-concepts.md](../../docs/AGENTS-key-concepts.md#middleware-edge-proxy), [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#multisite-and-edge-middleware-proxy). -## When to Use +## When -- User asks about multiple sites, hostnames, or site resolution. -- Task involves .sitecore/sites.json, multisite config, or proxy/middleware for site. -- User mentions "multisite," "site resolution," "hostname," or "sites.json." +- Multiple sites, hostnames, `sites.json`, or `src/proxy.ts` / matcher. -## How to perform +## Rules -- Site list: `.sitecore/sites.json`. Proxy logic lives in `src/proxy.ts`; ensure `src/middleware.ts` re-exports it if present. Keep chain order: LocaleProxy → AppRouterMultisiteProxy → RedirectsProxy → PersonalizeProxy. Exclude API, _next, static assets in the matcher. +- Sites list: `.sitecore/sites.json` (usually generated); avoid manual edits unless you know the format. +- Ensure `middleware.ts` re-exports `proxy.ts` if that is how the template ships. +- **Order:** LocaleProxy → AppRouterMultisiteProxy → RedirectsProxy → PersonalizeProxy (do not reorder). Skip API, `_next`, sitemap/robots/static. -## Hard Rules +## Stop -- Site list is in `.sitecore/sites.json` (typically generated by Sitecore CLI or deployment). Avoid hand-editing unless the format is known. -- **Proxy:** Implemented in `src/proxy.ts`. Next.js runs middleware from `middleware.ts` at root or in `src/` — if the app only has `proxy.ts`, add `src/middleware.ts` that re-exports it. -- **Chain order is fixed:** LocaleProxy → AppRouterMultisiteProxy → RedirectsProxy → PersonalizeProxy. **Do not change this order.** LocaleProxy runs first so i18n and multisite see the correct locale. AppRouterMultisiteProxy rewrites to /[site]/[locale]/[...path]. -- **Matcher:** Exclude API routes, _next/, sitemap, robots, healthz, Sitecore paths, and static assets so the proxy stays lightweight. -- Config: sitecore.config.ts → multisite, redirects, personalize. Single SitecoreClient; pass resolved site and locale from route params into getPage, getDictionary, etc. +- Do not add a parallel site-resolution mechanism. -## Stop Conditions - -- Stop if the user wants to reorder the proxy chain; explain that LocaleProxy must run first for App Router. -- Stop if sites.json format is unknown and the change could break resolution; suggest checking SDK docs or CLI output. -- Do not add a second site resolution mechanism; use the existing proxy and config. - -## References - -- [AGENTS.md](../../../AGENTS.md) for proxy chain, matcher, and multisite config. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-route-configuration/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-route-configuration/SKILL.md index 03b4216c0e..a49f259f1e 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-route-configuration/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-route-configuration/SKILL.md @@ -3,36 +3,22 @@ name: content-sdk-route-configuration description: Configures routing and layout for App Router. Single catch-all at src/app/[site]/[locale]/[[...path]]/page.tsx; call setRequestLocale at top of page. Use when changing routing, placeholders, or Layout. --- -# Content SDK Route Configuration (App Router) +# Routing (App Router) -Single catch-all route and layout hierarchy. Site and locale are **in the path**; proxy rewrites incoming requests to /[site]/[locale]/...path. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md) (routing, layouts, not-found); [AGENTS-key-concepts.md](../../docs/AGENTS-key-concepts.md#catch-all-route). -## When to Use +## When -- User asks to change routing, add a route, or fix 404/not-found behavior. -- Task involves catch-all route, placeholders, root layout, or Layout.tsx. -- User mentions "[site]," "[locale]," "[[...path]]," "placeholder," or "layout hierarchy." +- Changing catch-all segment, layouts, placeholders, or route params handling. -## How to perform +## Rules -- Single Sitecore page: `src/app/[site]/[locale]/[[...path]]/page.tsx`. Use `await params` for `{ site, locale, path? }`; pass to getPage and call `setRequestLocale(\`${site}_${locale}\`)` at the top. Layout: app/layout.tsx → app/[site]/layout.tsx (Bootstrap, draftMode) → page. Not-found: use getCachedPageParams and getErrorPage in the route's not-found.tsx. +- **Only** `src/app/[site]/[locale]/[[...path]]/page.tsx` is the Sitecore content entry. `await params`; call `setRequestLocale` with `` `${site}_${locale}` `` at the top of the page. +- Layout chain: `app/layout.tsx` → `app/[site]/layout.tsx` → page; avoid root-layout Sitecore fetches. +- Proxy order stays: LocaleProxy → AppRouterMultisiteProxy → Redirects → Personalize. -## Hard Rules +## Stop -- **Single Sitecore page:** `src/app/[site]/[locale]/[[...path]]/page.tsx`. This is the **only** page that renders Sitecore content. Do not add another page or catch-all for Sitecore content. -- **Params:** Next.js 15+ — `params` is a Promise. Use `await params` to get `{ site, locale, path? }`. Pass `site` and `locale` to `client.getPage(path ?? [], { site, locale })`. -- **Locale for next-intl:** Call `setRequestLocale(\`${site}_${locale}\`)` at the **top** of the page so next-intl and `src/i18n/request.ts` see the correct locale. Do not omit when adding new page branches. -- **Layout hierarchy:** `app/layout.tsx` → `app/[site]/layout.tsx` (Bootstrap with `siteName={site}` and `draftMode()`) → page. Do not put site/locale-specific data fetching in the root layout. -- Placeholders are rendered by the layout (e.g. Placeholder component); do not change placeholder names or structure without aligning with Sitecore layout definition. -- **Not-found:** `src/app/[site]/[locale]/[[...path]]/not-found.tsx`. For Sitecore-driven 404 use `getCachedPageParams()` from `@sitecore-content-sdk/nextjs` for site/locale, then `client.getErrorPage(ErrorPage.NotFound, { site, locale })`. +- If the user wants a second Sitecore entry route, explain the single-entry constraint. -## Stop Conditions - -- Stop if the user wants to add a second catch-all or a different URL shape for Sitecore pages; explain single-entry-point constraint. -- Stop if changing proxy/middleware order; order is fixed (LocaleProxy → AppRouterMultisiteProxy → RedirectsProxy → PersonalizeProxy). -- Do not move or rename the catch-all file without updating all references. - -## References - -- [AGENTS.md](../../../AGENTS.md) for exact paths, params, and layout hierarchy. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-site-setup-and-env/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-site-setup-and-env/SKILL.md index 3c7ea80d2f..a310a82fce 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-site-setup-and-env/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-site-setup-and-env/SKILL.md @@ -3,34 +3,21 @@ name: content-sdk-site-setup-and-env description: Configures site and environment: sitecore.config.ts, environment variables, default site and language. Use when configuring the app or adding env vars. Document in .env.example only; never commit .env or .env.local. --- -# Content SDK Site Setup and Environment (App Router) +# Config & env (App Router) -Central config in sitecore.config.ts; all secrets and environment-specific values via env vars. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#sitecore-client-and-config), [AGENTS-workflows-and-boundaries.md](../../docs/AGENTS-workflows-and-boundaries.md#boundaries). -## When to Use +## When -- User asks to configure site, default language, API host, or environment. -- Task involves sitecore.config.ts, .env, or defaultSite/defaultLanguage. -- User mentions "config," "environment variables," "API key," or "default site." +- `sitecore.config.ts`, API endpoints, default site/language, or new env vars. -## How to perform +## Rules -- Edit `sitecore.config.ts` with `defineConfig`; read all secrets and env-specific values from `process.env.*`. Add or change vars in `.env.example` (or `.env.remote.example` / `.env.container.example`) with placeholders; never commit `.env` or `.env.local`. +- `defineConfig` + `process.env` only for secrets and hosts; never hardcode production keys. +- Document every var in `.env.example` (or template `*.example`); never commit `.env` / `.env.local`. -## Hard Rules +## Stop -- Use `sitecore.config.ts` with `defineConfig` from the SDK. Expose api (edge, local), defaultSite, defaultLanguage, editingSecret, multisite, redirects, personalize as needed. -- All sensitive or environment-specific values must come from environment variables (e.g. process.env.SITECORE_API_KEY). Never hardcode API keys, secrets, or production URLs in source. -- Document every new or changed env var in `.env.example` (or `.env.remote.example` / `.env.container.example`). Use placeholder or empty value and a short comment; never put real secrets in example files. -- Never commit `.env` or `.env.local`; they are gitignored. Example files are the source of truth for which vars exist. +- Refuse to commit real secrets; flag if deployment/CI must change to accept new vars. -## Stop Conditions - -- Stop if the user wants to commit real secrets or production values; insist on env vars and .env.example only. -- Stop if adding a new env var would require CI or deployment changes without explicit instruction; document the var and note that deployment must set it. -- Do not edit .next/, node_modules/, or lockfiles unless the task explicitly requires it. - -## References - -- [AGENTS.md](../../../AGENTS.md) for boundaries and env rules. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-sitemap-robots/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-sitemap-robots/SKILL.md index 2e662e4282..f862629523 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-sitemap-robots/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-sitemap-robots/SKILL.md @@ -1,37 +1,23 @@ --- name: content-sdk-sitemap-robots -description: Sitemap and robots.txt for App Router: src/app/api/sitemap/route.ts and src/app/api/robots/route.ts with createSitemapRouteHandler and createRobotsRouteHandler. Rewrites in next.config.ts. Use when configuring sitemap, robots.txt, or SEO. +description: Sitemap and robots for App Router: src/app/api/sitemap/route.ts and src/app/api/robots/route.ts with createSitemapRouteHandler and createRobotsRouteHandler. Rewrites in next.config.ts. Use when configuring sitemap, robots.txt, or SEO. --- -# Content SDK Sitemap and Robots (App Router) +# Sitemap & robots (App Router) -Sitemap and robots.txt are served via **route handlers** and rewrites. Use the SDK route handler helpers and sites from .sitecore/sites.json. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#api-route-handlers). -## When to Use +## When -- User asks to add or change sitemap or robots.txt. -- Task involves SEO, sitemap.xml, or robots route. -- User mentions "sitemap," "robots," "SEO," or "rewrites." +- `sitemap.xml`, `robots.txt`, or SEO routing changes. -## How to perform +## Rules -- Sitemap: `src/app/api/sitemap/route.ts` with `createSitemapRouteHandler({ client, sites })`; robots: `src/app/api/robots/route.ts` with `createRobotsRouteHandler({ client, sites })`. Use sites from `.sitecore/sites.json`. Add rewrites in `next.config.ts` for `/sitemap*.xml` and `/robots.txt` with `locale: false`. Set `dynamic = 'force-dynamic'` if needed. +- Use `createSitemapRouteHandler` / `createRobotsRouteHandler` with shared client + `sites` from `.sitecore/sites.json`. +- Keep `next.config.ts` rewrites and `locale: false` rules aligned with public URLs; set `dynamic` appropriately. -## Hard Rules +## Stop -- **Sitemap:** `src/app/api/sitemap/route.ts` — use `createSitemapRouteHandler({ client, sites })`. Export `{ GET }`. Use `sites` from `.sitecore/sites.json`. Set `export const dynamic = 'force-dynamic'` if the handler relies on request. -- **Robots:** `src/app/api/robots/route.ts` — use `createRobotsRouteHandler({ client, sites })`. Same pattern. -- **Rewrites:** In `next.config.ts`, add rewrites for `/sitemap*.xml` and `/robots.txt` to these route handlers. Use `locale: false` so they are not localized. -- Use the same SitecoreClient instance as the rest of the app; do not create a dedicated client for sitemap/robots. -- Avoid hardcoding the site list; use .sitecore/sites.json. +- Do not hardcode site lists if `sites.json` is the source of truth. -## Stop Conditions - -- Stop if the user wants to serve sitemap/robots from a different origin or with different auth; document and suggest proxy or edge config. -- Do not add new env vars for sitemap/robots without documenting them in .env.example. -- Do not change rewrite paths without updating docs and any references. - -## References - -- [AGENTS.md](../../../AGENTS.md) for API routes and rewrites. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-troubleshoot-editing/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-troubleshoot-editing/SKILL.md index a07b7ed115..72d3e30c30 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-troubleshoot-editing/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-troubleshoot-editing/SKILL.md @@ -1,39 +1,23 @@ --- name: content-sdk-troubleshoot-editing -description: Troubleshoots XM Cloud editing, preview, and design library for App Router. Check draftMode(), getPreview/getDesignLibraryData from searchParams, setRequestLocale, and component maps. Use when editing or preview does not behave as expected. +description: Troubleshoots XM Cloud editing, preview, and design library for App Router. Check draftMode(), searchParams, and editing API routes. Use when editing or preview does not behave as expected. --- -# Content SDK Troubleshoot Editing (App Router) +# Troubleshoot editing (App Router) -This skill focuses on **diagnosing** editing, preview, and design library issues. For implementing editing-safe rendering (draftMode, getPreview/getDesignLibraryData, API routes), use the **content-sdk-editing-safe-rendering** skill; the two are complementary (implementation vs. troubleshooting). +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#api-route-handlers); fixes with **content-sdk-editing-safe-rendering**. -Diagnose and fix editing, preview, and design library issues without breaking the single client or proxy order. This app uses **draftMode()** and **searchParams** for preview data. +## When -## When to Use +- Editor/preview/design library issues, missing chromes, wrong preview data. -- User reports that editing, preview, or design library is broken or inconsistent. -- Task involves debugging "not working in editor," missing chromes, or wrong data in preview. -- User mentions "editing broken," "preview not working," "design library," or "editor issues." +## Rules -## How to perform +- Verify `draftMode`, searchParams → `getPreview` / `getDesignLibraryData`, both component maps, and `dynamic = 'force-dynamic'` on editing routes. +- Ensure matcher skips `/api` and env (`editingSecret`, API) is set and documented. -- Confirm `draftMode()` and searchParams-based getPreview/getDesignLibraryData; ensure `setRequestLocale` is called at the top of the page. Verify editing API routes are not rewritten (check proxy matcher) and both component maps include the component. Check env (editingSecret, API config) and .env.example documentation. +## Stop -## Hard Rules +- If root cause is XM Cloud project/CI, stop after listing required external changes. -- **Preview flow:** Use `draftMode()` in Server Components; when enabled, use `client.getPreview(editingParams)` or `client.getDesignLibraryData(editingParams)` from **searchParams**. Ensure site/locale are passed correctly (e.g. from route params or editingParams). -- **next-intl:** Ensure `setRequestLocale(\`${site}_${locale}\`)` is called at the top of the page; missing setRequestLocale can cause locale or dictionary issues in editor. -- Editing API routes (`src/app/api/editing/config/route.ts`, `editing/render/route.ts`) must be reachable and use the same component maps (component-map.ts and component-map.client.ts) and config as the app. Check matcher in proxy.ts so /api/editing is not rewritten or blocked. -- Check that both component maps include all components used in the layout; missing registration causes "component not found" in editor. -- Environment: editingSecret and API config must be set (in env); document in .env.example only. Do not log or commit secrets. - -## Stop Conditions - -- Stop if the fix would require changing CI, deployment, or XM Cloud project settings; suggest the user do that and document the required env or config. -- Stop if the issue might be in Sitecore (layout, template) rather than the app; suggest checking layout and content in XM Cloud. -- Do not recommend disabling security (e.g. skipping secret validation) without explicit user request and warning. - -## References - -- content-sdk-editing-safe-rendering skill and [AGENTS.md](../../../AGENTS.md) for preview and editing flow. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-upgrade-assistant/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-upgrade-assistant/SKILL.md index 25aa812535..d6dff3efab 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-upgrade-assistant/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.agents/skills/content-sdk-upgrade-assistant/SKILL.md @@ -3,34 +3,22 @@ name: content-sdk-upgrade-assistant description: Guides upgrading @sitecore-content-sdk/* packages: version bumps, breaking changes, migration steps. Use when moving to a newer SDK or package version. Check Content SDK repo CHANGELOG and upgrade guides. --- -# Content SDK Upgrade Assistant (App Router) +# Upgrade SDK packages (App Router) -Upgrade @sitecore-content-sdk/* packages safely; follow the Content SDK repo changelog and migration guides. +**Detail:** [AGENTS-overview.md](../../docs/AGENTS-overview.md#project-overview); doc site migration docs; Content SDK repo CHANGELOG. -## When to Use +## When -- User asks to upgrade SDK packages, update to a new version, or apply a migration. -- Task involves version bumps, @sitecore-content-sdk/* dependencies, or breaking changes. -- User mentions "upgrade," "migration," "new version," or "breaking change." +- Bumping `@sitecore-content-sdk/*` or applying a migration. -## How to perform +## Rules -- Bump all @sitecore-content-sdk/* to consistent versions; read the Content SDK repo CHANGELOG (and MIGRATION/upgrade docs) for breaking changes and migration steps. Update package.json, run `npm install` and `npm run build`; test editing and preview after upgrade. +- Keep all `@sitecore-content-sdk/*` on compatible versions; run `npm install` + `npm run build`; re-test editing/preview. +- Apply breaking-change steps from the upstream CHANGELOG before shipping. +- Retrieve relevant version upgrade guides from [Product Docs MCP](https://sitecore.mcp.kapa.ai) -## Hard Rules +## Stop -- Prefer upgrading all @sitecore-content-sdk/* packages together to a consistent set of versions unless the user requests a partial upgrade. Check peer dependencies and compatibility. -- Update dependencies in package.json; run `npm install` and `npm run build`. Test editing and preview after upgrade. -- Read the **Content SDK repository** CHANGELOG (and any MIGRATION.md or upgrade guide) for breaking changes and required code/config updates. Apply migration steps before or with the version bump. -- Do not edit .next/, node_modules/, or lockfiles unless required for the upgrade. Do not change CI or root tooling unless the task explicitly includes it. +- If target version or required infra (new env vars) is unclear, ask before editing lockfiles or CI. -## Stop Conditions - -- Stop if the target version is not specified or unclear; ask or suggest checking the Content SDK CHANGELOG and supported versions. -- Stop if a breaking change requires product or deployment decisions (e.g. new env vars, config schema); list required changes and ask the user to confirm. - -## References - -- Content SDK repo [CHANGELOG](https://github.com/Sitecore/content-sdk/blob/dev/CHANGELOG.md) and upgrade docs. -- [AGENTS.md](../../../AGENTS.md) for build commands. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK CHANGELOG](https://github.com/Sitecore/content-sdk/blob/dev/CHANGELOG.md) · [Product docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.cursor/rules/app-router-setup.mdc b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.cursor/rules/app-router-setup.mdc index aa57e0612d..918624b422 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.cursor/rules/app-router-setup.mdc +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.cursor/rules/app-router-setup.mdc @@ -4,113 +4,12 @@ alwaysApply: true globs: [] --- -# Sitecore Content SDK Next.js App Router Project +# Sitecore Content SDK — App Router -## Project Overview +Next.js App Router + TypeScript + next-intl. **Commands:** `npm install`, `npm run dev`, `npm run build`, `npm run lint`, `npm run type-check`. Copy `.env.example` → `.env.local` (never commit secrets). -This is a Sitecore Content SDK application built with Next.js App Router. This project uses the latest Next.js features for improved performance and developer experience. +**Structure:** `src/app/[site]/[locale]/[[...path]]/`, `src/app/api/`, `src/components/`, `src/lib/sitecore-client.ts`, `src/i18n/`, `src/proxy.ts`, `.sitecore/`, `sitecore.config.ts`, `next.config.ts`. -Key Technologies: +**Detail:** Guardrails stay in [`AGENTS.md`](../../AGENTS.md). For proxy order (`LocaleProxy` first), `setRequestLocale`, and `draftMode` depth, see [`.agents/docs/`](../../.agents/docs/) (e.g. [`AGENTS-key-concepts.md`](../../.agents/docs/AGENTS-key-concepts.md), [`AGENTS-router-specifics.md`](../../.agents/docs/AGENTS-router-specifics.md)). -- Next.js App Router (React Server Components) -- Sitecore Content SDK -- TypeScript -- Sitecore XM Cloud -- next-intl for internationalization - -## Getting Started - -Development Workflow: - -1. Install dependencies: `npm install` -2. Configure environment variables (copy `.env.example` to `.env.local`) -3. Start development server: `npm run dev` -4. Build for production: `npm run build` - -App Router Specifics: - -- Server Components by default -- Client Components when interactivity needed -- File-based routing in `src/app/` directory -- Layout files for shared UI elements - -## Project Structure - -``` -src/ - app/ # App Router pages and layouts - components/ # React-specific SDK - lib/ # Configuration and utilities - i18n/ # Internationalization setup -``` - -Component Development: - -- Server Components for data fetching and static content -- Client Components for interactivity (use 'use client') -- Shared components in `src/components/` -- Follow Sitecore field handling patterns - -## App Router Best Practices - -Server vs Client Components: - -- Use Server Components for Sitecore content rendering -- Use Client Components for user interactions -- Minimize client-side JavaScript -- Leverage server-side data fetching - -Routing and Layouts: - -- Use layout.tsx for shared page structure -- Implement loading.tsx for loading states -- Create error.tsx for error boundaries -- Use page.tsx for route content - -## Sitecore Integration - -Content Rendering: - -- Fetch Sitecore data in Server Components -- Use layout service for page structure -- Handle content preview scenarios -- Implement proper error handling - -Performance: - -- Leverage Server Components for better performance -- Use streaming for improved loading experience -- Implement proper caching strategies -- Optimize images with Next.js Image component - -## Development Commands - -```bash -npm run dev # Start development server -npm run build # Build for production -npm run start # Start production server -npm run lint # Run ESLint -npm run type-check # Run TypeScript compiler -``` - -## Environment Configuration - -- Copy `.env.example` to `.env.local` -- Add your Sitecore API endpoint and key -- Configure site name and locale settings -- Set up internationalization if needed - -## Next Steps - -1. Configure your Sitecore connection -2. Set up internationalization (if needed) -3. Create your first Server Component -4. Add content types and templates -5. Implement your layout structure -6. Deploy to your hosting platform - -Referenced: -@src/app/ -@src/components/ -@sitecore.config.ts -@src/i18n/ +Referenced: `@sitecore.config.ts`, `@package.json`, `@.env.example` diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.cursor/rules/general.mdc b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.cursor/rules/general.mdc index de7c02a7de..7996fcd9f8 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.cursor/rules/general.mdc +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.cursor/rules/general.mdc @@ -4,77 +4,10 @@ alwaysApply: true globs: [] --- -# General Coding Principles +# General principles -## Universal Standards +- **DRY / clarity:** Reuse helpers and types; names reflect intent; prefer explicit behavior. +- **Structure:** Small focused modules; validate at boundaries; handle errors near the source. +- **Quality:** Test behavior; meaningful commits; document public APIs; profile before micro-optimizing. -DRY Principle: - -- Don't Repeat Yourself - extract common functionality -- Create reusable utilities and helper functions -- Use composition over inheritance -- Share types and interfaces across modules - -SOLID Principles: - -- Single Responsibility: each function/class has one purpose -- Open/Closed: extend functionality through composition -- Dependency Inversion: depend on abstractions, not implementations - -Code Clarity: - -- Write self-documenting code with clear intent -- Use meaningful names that express business concepts -- Prefer explicit over implicit behavior -- Make dependencies and requirements obvious - -## Architecture Patterns - -Modular Design: - -- Organize code into focused, cohesive modules -- Minimize coupling between modules -- Use clear interfaces between layers -- Follow established patterns consistently - -Data Flow: - -- Prefer unidirectional data flow -- Validate inputs at system boundaries -- Transform data at appropriate layers -- Handle errors close to their source - -Testing: - -- Write testable code with minimal dependencies -- Use dependency injection for better testability -- Mock external services and side effects -- Test behavior, not implementation details - -## Development Standards - -Version Control: - -- Write descriptive commit messages -- Keep commits focused and atomic -- Use branching strategies appropriate to team size -- Review code before merging - -Documentation: - -- Document public APIs and interfaces -- Include usage examples for complex functionality -- Keep documentation close to code -- Update documentation with code changes - -Performance: - -- Optimize for readability first, performance second -- Profile before optimizing -- Cache expensive operations appropriately -- Consider memory usage and cleanup - -Referenced: -@src/app/ -@src/components/ -@src/lib/ +Referenced: `@src/app/`, `@src/components/`, `@src/lib/` diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.windsurfrules b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.windsurfrules index 615491a7aa..99ee2ef413 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/.windsurfrules +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/.windsurfrules @@ -1,290 +1,11 @@ -# Sitecore Content SDK Next.js App Router Project - Windsurf AI Rules +# Sitecore Content SDK — Next.js (App Router) -## Project Purpose and Tech Stack +**Primary:** [AGENTS.md](AGENTS.md) — compact guide (commands, structure, best practices, guardrails). -This is a **Sitecore Content SDK** application built with **Next.js App Router** and **TypeScript**. The project follows Sitecore best practices for XM Cloud development and leverages the latest Next.js App Router features for improved performance and developer experience. +**Depth:** [.agents/docs/](.agents/docs/) — one layer file when needed (`[site]`/`[locale]`, proxy, next-intl, etc.). [README](.agents/docs/README.md) indexes layers. -### Key Technologies +**Optional:** [Skills.md](Skills.md) → one folder under [.agents/skills/](.agents/skills/) for the task. [CLAUDE.md](CLAUDE.md) — layered reading. [.cursor/rules/](.cursor/rules/) — same rules as Cursor. -- **Next.js App Router** - React framework with Server Components and modern routing -- **Sitecore Content SDK** - Official SDK for Sitecore XM Cloud integration -- **TypeScript** - Type-safe JavaScript development -- **Sitecore XM Cloud** - Headless CMS platform -- **React Server Components** - Server-side rendering for better performance -- **next-intl** - Internationalization support +**Commands:** `npm install`, `npm run dev`, `npm run build`, `npm run lint`, `npm run type-check`. Copy `.env.example` → `.env.local`; never commit secrets. -## Coding Standards - -### TypeScript Standards - -- Use **strict mode** in tsconfig.json -- Prefer type assertions over `any`: `value as ContentItem` -- Use discriminated unions for complex state management -- Enable strict null checks and strict function types - -### Naming Conventions - -- **Variables/Functions**: camelCase (`getUserData()`, `isLoading`, `currentUser`) -- **Components**: PascalCase (`SitecoreComponent`, `PageLayout`, `ContentBlock`) -- **Constants**: UPPER_SNAKE_CASE (`API_ENDPOINT`, `DEFAULT_TIMEOUT`) -- **Directories**: kebab-case (`src/components`, `src/api-clients`) -- **Types/Interfaces**: PascalCase (`ContentItem`, `LayoutProps`, `SitecoreConfig`) - -### Modular Layout (App Router) - -``` -src/ - app/ # App Router pages and layouts - components/ # UI components (React) - lib/ # Configuration and utilities - i18n/ # Internationalization setup - types/ # TypeScript type definitions - hooks/ # Custom React hooks -``` - -## Library Usage - -### @sitecore-content-sdk - -- Use `SitecoreClient` for content fetching -- Implement proper error handling with try/catch blocks -- Cache API responses using React Query or SWR -- Handle content preview vs. published content scenarios - -```typescript -import { SitecoreClient } from '@sitecore-content-sdk/nextjs/client'; -import scConfig from 'sitecore.config'; - -const client = new SitecoreClient({ - ...scConfig, -}); -``` - -### React App Router Patterns - -- Use **Server Components** for data fetching and static content (default) -- Use **Client Components** for interactivity (use 'use client' directive) -- Implement proper error boundaries with error.tsx -- Use loading.tsx for loading states -- Leverage layout.tsx for shared page structure - -### Sitecore Field Components - -- Always use Sitecore field components: ``, ``, `` -- Validate field existence before rendering -- Handle empty/null fields gracefully -- Prefer Sitecore field components over manual rendering - -```typescript -// Good: Using Sitecore field components - - - - -// Avoid: Manual field value extraction unless necessary -``` - -## Example Patterns and Prompts - -### Server Component Development - -```typescript -// Server Component example (default in App Router) -import { SitecoreClient } from '@sitecore-content-sdk/nextjs/client'; -import scConfig from 'sitecore.config'; - -const client = new SitecoreClient({ - ...scConfig, -}); - -export default async function SitecorePage({ params }: { params: { path: string[] } }) { - try { - const pageData = await client.getPage(params.path.join('/')); - return ; - } catch (error) { - return
Content not found
; - } -} -``` - -### Client Component Integration - -Interactive Sitecore Components: - -- Use 'use client' directive when needed -- Keep client components focused on interactivity -- Pass server-fetched data as props -- Handle hydration mismatches carefully - -```typescript -'use client'; - -interface InteractiveSitecoreComponentProps { - fields: { - title: Field; - content: Field; - }; -} - -export default function InteractiveSitecoreComponent({ - fields, -}: InteractiveSitecoreComponentProps) { - // Client-side interactivity here - return ( -
- - -
- ); -} -``` - -### Component Development - -```typescript -// Component props interface -interface HeroProps { - fields: { - title: Field; - subtitle: Field; - backgroundImage: Field; - }; -} - -export default function Hero({ fields }: HeroProps) { - return ( -
- - - -
- ); -} -``` - -### Error Handling - -API Calls: - -- Always wrap in try/catch blocks -- Throw custom errors with context: `SitecoreFetchError`, `ConfigurationError` -- Handle edge cases with guard clauses - -```typescript -async function fetchPageData(path: string): Promise { - if (!path) { - throw new Error('Page path is required'); - } - - try { - const pageData = await client.getPage(path); - return pageData; - } catch (error) { - throw new SitecoreFetchError(`Failed to fetch page data for ${path}`, error); - } -} -``` - -### Configuration - -```typescript -// sitecore.config.ts -import { defineConfig } from '@sitecore-content-sdk/nextjs/config'; - -export default defineConfig({ - api: { - edge: { - contextId: process.env.SITECORE_EDGE_CONTEXT_ID || '', - clientContextId: process.env.NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID, - edgeUrl: - process.env.NEXT_PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME || - process.env.SITECORE_EDGE_PLATFORM_HOSTNAME || - 'https://edge-platform.sitecorecloud.io', - }, - local: { - apiKey: process.env.SITECORE_API_KEY || '', - apiHost: process.env.SITECORE_API_HOST || '', - }, - }, - defaultSite: process.env.NEXT_PUBLIC_DEFAULT_SITE_NAME || 'default', - defaultLanguage: process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE || 'en', - editingSecret: process.env.SITECORE_EDITING_SECRET, -}); -``` - -### Internationalization - -Multi-language Support: - -- Configure next-intl for language routing -- Handle Sitecore language contexts -- Implement language switching -- Use proper locale-based data fetching - -```typescript -// Language-aware data fetching -import { getTranslations } from 'next-intl/server'; - -export default async function LocalizedPage() { - const t = await getTranslations('common'); - // Fetch Sitecore content for current locale -} -``` - -## Development Workflow - -1. **Install dependencies**: `npm install` -2. **Configure environment**: Copy `.env.example` to `.env.local` -3. **Start development**: `npm run dev` -4. **Build for production**: `npm run build` - -## App Router Best Practices - -### Server vs Client Components - -- Use Server Components for Sitecore content rendering (default) -- Use Client Components for user interactions -- Minimize client-side JavaScript -- Leverage server-side data fetching - -### Routing and Layouts - -- Use layout.tsx for shared page structure -- Implement loading.tsx for loading states -- Create error.tsx for error boundaries -- Use page.tsx for route content -- Use [...path] for Sitecore catch-all routes - -### Performance Optimization - -- Leverage Server Components for better performance -- Use streaming for improved loading experience -- Implement proper caching strategies -- Optimize images with Next.js Image component - -## Best Practices - -### Performance - -- Optimize images using Next.js Image component -- Implement proper loading states -- Cache expensive operations appropriately -- Consider server-side rendering implications -- Lazy-load non-critical modules -- Use Server Components for better performance - -### Security - -- Sanitize user inputs before processing -- Validate data at application boundaries -- Use HTTPS for all Sitecore connections -- Never expose sensitive configuration in client-side code -- Escape content when rendering to prevent XSS - -### Code Quality - -- Follow DRY principle - extract common functionality -- Use SOLID principles for maintainable code -- Write self-documenting code with clear intent -- Implement proper error boundaries -- Test behavior, not implementation details +**Product docs:** [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html) diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/AGENTS.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/AGENTS.md index f32dcb9ee3..f64894bf87 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/AGENTS.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/AGENTS.md @@ -1,10 +1,6 @@ # AGENTS.md — AI Guidance for Sitecore Content SDK Next.js (App Router) App -## Project Overview - -This is a **Sitecore Content SDK** application built with **Next.js (App Router)** and **TypeScript**. AI agents work as developer assistants within this scaffolded head application. The app integrates with Sitecore XM Cloud for content, uses **file-based routing with `[site]` and `[locale]`**, next-intl for i18n, and Edge middleware for multisite, redirects, and personalization. - -**Scope:** This file applies to **this application only** (a scaffolded head app). It is **not** the Content SDK monorepo — for SDK package development use that repo's `AGENTS.md`. Here we edit app code and config (app router, components, API routes, i18n); we do not modify SDK packages or CI. +> **Context:** This file is the **compact** guide (commands, repo layout, best practices, guardrails, references). Deeper topics live under [.agents/docs/](.agents/docs/) — start with [README](.agents/docs/README.md) or open the layer you need: [AGENTS-overview.md](.agents/docs/AGENTS-overview.md), [AGENTS-key-concepts.md](.agents/docs/AGENTS-key-concepts.md), [AGENTS-router-specifics.md](.agents/docs/AGENTS-router-specifics.md), [AGENTS-workflows-and-boundaries.md](.agents/docs/AGENTS-workflows-and-boundaries.md). Use [Skills.md](Skills.md) to pick **one** [.agents/skills/](.agents/skills/) skill when needed; [CLAUDE.md](CLAUDE.md) explains layered reading. Cursor applies [.cursor/rules/](.cursor/rules/) by glob — you do not need every rule in chat context at once. --- @@ -52,103 +48,6 @@ next.config.ts # next-intl plugin, rewrites, images --- -## Key concepts for this app - -These are the main head-app–specific concepts. Details are in the sections below. - -### Middleware (Edge proxy) - -- **Where:** `src/proxy.ts`. Next.js runs middleware from `middleware.ts` at root or in `src/` — if the app only has `proxy.ts`, add `src/middleware.ts` that re-exports it. -- **What it does:** Runs on each request (respecting the `matcher`). Chain order is **fixed:** LocaleProxy → AppRouterMultisiteProxy → RedirectsProxy → PersonalizeProxy. Locale must run first so i18n and multisite see the correct locale. -- **Config:** Uses `sitecore.config.ts` (multisite, redirects, personalize), `.sitecore/sites.json`, and `src/i18n/routing.ts` (locales). **Do not change proxy order.** Keep the matcher excluding API, `_next/`, sitemap, robots, and static assets so the proxy stays lightweight. - -### SitecoreClient - -- **Where:** Single shared instance in `src/lib/sitecore-client.ts` — `new SitecoreClient({ ...scConfig })` with config from `sitecore.config.ts`. -- **Use for:** `getPage`, `getDictionary`, `getErrorPage`, `getPreview`, `getDesignLibraryData`, `getAppRouterStaticParams`. All Sitecore data fetching in the app goes through this client. -- **Do not:** Create a second client or instantiate SitecoreClient elsewhere. Pass `site` and `locale` from route params (or `parseRewriteHeader` in not-found), not from global state. - -### Catch-all route - -- **Where:** `src/app/[site]/[locale]/[[...path]]/page.tsx`. This is the **only** page component that renders Sitecore content; the optional `[[...path]]` segment captures the content path. -- **Flow:** `params` is a Promise (Next.js 15+) — `await params` to get `{ site, locale, path? }`. Call `client.getPage(path ?? [], { site, locale })`. For preview, use `draftMode()` and `client.getPreview(editingParams)` or `client.getDesignLibraryData(editingParams)` from `searchParams`. Call `setRequestLocale(\`${site}_${locale}\`)` at the top of the page for next-intl. -- **Do not:** Add another catch-all or page at a different path for Sitecore pages; keep this single entry point. - -### How locale works - -- **In the URL:** All content routes are `/[site]/[locale]/...path` (e.g. `/default/en`, `/default/en/about`). Middleware (LocaleProxy, then AppRouterMultisiteProxy) rewrites incoming requests into this shape. -- **In the app:** next-intl uses a single `requestLocale` per request. This app encodes both site and locale as `requestLocale = \`${site}_${locale}\``. In the page, call `setRequestLocale(\`${site}_${locale}\`)` so next-intl and `src/i18n/request.ts` see it. In `request.ts`, parse `requestLocale` (e.g. `split('_')`) to get site and locale, then load the dictionary with `client.getDictionary({ locale, site })`. -- **Config:** `src/i18n/routing.ts` defines `locales` and `defaultLocale`; align these with Sitecore languages (e.g. from `sitecore.config.ts`). **Do not** change the `{site}_{locale}` convention without updating request.ts and all pages that call `setRequestLocale`. - -### More (component maps, editing, env) - -- **Component maps:** `.sitecore/component-map.ts` (Server) and `.sitecore/component-map.client.ts` (Client). Register every Sitecore component here; keep in sync with `src/components/`. -- **Editing/preview:** Use `draftMode()` in Server Components; when enabled, use `client.getPreview(searchParams)` or `client.getDesignLibraryData(searchParams)`. Editing API routes live under `src/app/api/editing/`. -- **Env:** All config via environment variables in `sitecore.config.ts`. Document vars in `.env.example` (or `.env.remote.example` / `.env.container.example`); never commit `.env` or `.env.local`. - ---- - -## Next.js App Router specifics - -### Routing: `[site]` / `[locale]` / `[[...path]]` - -- **URL shape:** `/[site]/[locale]/...path` (e.g. `/default/en`, `/default/en/about`). Site and locale are **in the path**; the Edge proxy rewrites incoming requests to this shape. -- **Page component:** `src/app/[site]/[locale]/[[...path]]/page.tsx`. Receives `params: Promise<{ site, locale, path? }>`. Use `await params`; pass `site` and `locale` to `client.getPage(path ?? [], { site, locale })`. -- **Layout hierarchy:** `app/layout.tsx` → `app/[site]/layout.tsx` (per-site; runs Bootstrap with `siteName={site}` and `draftMode()`) → page. Do not put site/locale-specific data fetching in the root layout; use the `[site]` or page layout. - -### i18n (next-intl) - -- **Config:** `src/i18n/routing.ts` — `defineRouting({ locales, defaultLocale, localePrefix })`. Align `locales` with Sitecore languages; often sourced from `sitecore.config.ts` (e.g. `defaultLanguage`). -- **Request config:** `src/i18n/request.ts` — `getRequestConfig` receives `requestLocale`. The app uses `{site}_{locale}` (e.g. set by `setRequestLocale(\`${site}_${locale}\`)` in the page). Parse with `requested?.split('_')` to get `parsedSite` and `parsedLocale`; load dictionary with `client.getDictionary({ locale, site: parsedSite })` and return `{ locale, messages }`. -- **In pages:** Call `setRequestLocale(\`${site}_${locale}\`)` at the top of the page so next-intl and request config see the correct locale. - -### Multisite and Edge middleware (proxy) - -- **Site list:** `.sitecore/sites.json` — typically generated by the Sitecore CLI or deployment. Used by middleware and API route handlers. Avoid hand-editing unless you know the format. -- **Edge middleware:** Implemented in **`src/proxy.ts`**. Next.js only runs middleware from a file named `middleware.ts` at root or in `src/`. If this app has only `proxy.ts`, add `src/middleware.ts` that re-exports it (e.g. `export { default } from './proxy';`) so the proxy runs. -- **Proxy chain (order is critical):** `defineProxy(locale, multisite, redirects, personalize).exec(req)`: - - **LocaleProxy** — runs first; uses `sites` and `routing.locales` from `src/i18n/routing.ts`. Required for App Router so locale is set before multisite. - - **AppRouterMultisiteProxy** — rewrites to `/[site]/[locale]/[...path]`; uses `scConfig.multisite`. - - **RedirectsProxy** — redirects; uses `scConfig.redirects`, `scConfig.api.edge`, `scConfig.api.local`. - - **PersonalizeProxy** — personalization; uses `scConfig.personalize`; often disabled in dev. -- **Matcher:** Exclude API routes, `_next/`, sitemap, robots, healthz, Sitecore paths, and static assets so middleware does not run on every static request. The matcher is defined in `config` in `proxy.ts` (or in `middleware.ts` if it re-exports the proxy). -- **Config:** `sitecore.config.ts` → `multisite`, `redirects`, `personalize`; never commit secrets. - -### Data fetching and preview - -- **Page data:** In the page (or a Server Component), use `client.getPage(path ?? [], { site, locale })`. For preview, use `draftMode()`; if `draft.isEnabled`, use `client.getPreview(editingParams)` or `client.getDesignLibraryData(editingParams)` from `searchParams`; otherwise use `getPage` with `site` and `locale`. -- **SSG:** `generateStaticParams` — use `client.getAppRouterStaticParams(sites, routing.locales)` (sites from `.sitecore/sites.json`). Return at least one default param when not generating full paths (e.g. dev or when `generateStaticPaths` is off). -- **Metadata:** `generateMetadata` in the same segment can call `client.getPage(path ?? [], { site, locale })` and derive `title` (e.g. from route fields). Next.js will cache as appropriate. - -### Server vs Client components - -- **Default:** Components are Server Components. Use `'use client'` only for interactivity (e.g. hooks, event handlers). -- **draftMode:** Used in layout and page; call `await draftMode()` in Server Components that need to know preview state. - -### Not-found and error page - -- **Segment not-found:** `src/app/[site]/[locale]/[[...path]]/not-found.tsx`. Uses `getCachedPageParams()` from `@sitecore-content-sdk/nextjs` for site/locale, then `client.getErrorPage(ErrorPage.NotFound, { site, locale })` and renders layout if a page is returned. -- **Root not-found:** `src/app/not-found.tsx` — minimal fallback when no segment handles the route. - -### API route handlers - -- **Sitemap:** `src/app/api/sitemap/route.ts` — `createSitemapRouteHandler({ client, sites })`. Export `{ GET }`; use `sites` from `.sitecore/sites.json`. Set `export const dynamic = 'force-dynamic'` if the handler relies on request. -- **Robots:** `src/app/api/robots/route.ts` — `createRobotsRouteHandler({ client, sites })`. Same pattern. -- **Editing:** `src/app/api/editing/config/route.ts` and `editing/render/route.ts` — use `createEditingConfigRouteHandler` and the appropriate render handler with `components`, `clientComponents` (`.sitecore/component-map.client.ts`), `metadata`, and `client`. Set `dynamic = 'force-dynamic'` where needed. -- **Rewrites:** `next.config.ts` → rewrites for `/sitemap*.xml`, `/robots.txt` with `locale: false` so they are not localized. - -### Sitecore client and config - -- **Client:** `src/lib/sitecore-client.ts` — `new SitecoreClient({ ...scConfig })`. Use for `getPage`, `getDictionary`, `getErrorPage`, `getPreview`, `getAppRouterStaticParams`, etc. -- **Config:** `sitecore.config.ts` — `defineConfig({ api, defaultSite, defaultLanguage, editingSecret, redirects, multisite, personalize })`. Use env vars only; no hardcoded secrets. - -### Component maps and layout - -- **Server/client components:** `.sitecore/component-map.ts` (Server); `.sitecore/component-map.client.ts` (Client). Register all Sitecore components; keep in sync with `src/components/`. -- **Layout:** `Layout.tsx` renders page layout and placeholders; `Providers` wrap page and component context; `Bootstrap` in `[site]/layout.tsx` receives `siteName={site}` and preview state. - ---- - ## Best practices - **Quick checks:** If locale or dictionary is wrong, ensure `setRequestLocale(\`${site}_${locale}\`)` is called at the top of the page and `src/i18n/request.ts` parses `requestLocale` and calls `client.getDictionary`. If not-found doesn't show Sitecore content, use `parseRewriteHeader(headers())` for site/locale. Always `await params` (Next.js 15+). @@ -186,30 +85,11 @@ These are the main head-app–specific concepts. Details are in the sections bel --- -## Example agent tasks - -- **Add a new Sitecore component:** Create the component under `src/components/`, register it in `.sitecore/component-map.ts` and `.sitecore/component-map.client.ts` as appropriate (client components in the client map), and ensure it is rendered in the layout/placeholder as in existing components. -- **Add an API route:** Create the route under `src/app/api/` (e.g. `src/app/api/my-route/route.ts`), add a rewrite in `next.config.ts` if the route should be reached from a public URL, and ensure the proxy `matcher` in `proxy.ts` still excludes it (e.g. `api/` is already excluded). - ---- - -## Boundaries - -**Never edit:** `.next/`, `node_modules/`. - -**Environment variables:** You may add new env vars when needed. Do it carefully: add the variable to `.env.example` (or `.env.remote.example` / `.env.container.example` in this template) with a placeholder or comment; never put real secrets in example files. If editing `.env.local` for local dev, add only the variable name and tell the user to set the value. **Never commit** `.env` or `.env.local` — they are gitignored. - -**Edit with care:** `next.config.ts` (rewrites, next-intl plugin), `sitecore.config.ts` (env only), `proxy.ts` (matcher and proxy order), `src/i18n/routing.ts` and `request.ts`. When adding routes or rewrites, keep middleware `matcher` and rewrite rules consistent. - -**Focus on:** `src/app/`, `src/components/`, `src/lib/`, `src/i18n/`, `Layout.tsx`, `Providers.tsx`, `sitecore.config.ts`, `next.config.ts`, `proxy.ts`, `.sitecore/component-map.ts`, `.sitecore/component-map.client.ts`. - ---- - ## References -- **Skills.md** — Capability groupings for this app; [.agents/skills/](.agents/skills/) provides each capability as an Agent Skill (when-to-use, hard rules, stop conditions) for tools that support the [Agent Skills](https://agentskills.io) standard. -- **CLAUDE.md** — Full coding standards and Sitecore patterns for this template. -- **.cursor/rules/** — App Router and Sitecore rules. +- **Skills.md** — Capability index; [.agents/skills/](.agents/skills/) — load **one** skill per task ([Agent Skills](https://agentskills.io)). +- **CLAUDE.md** — How to layer AI context for this template. +- **.cursor/rules/** — Editor rules (applied by glob / always-apply). - [Sitecore Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html) — Official docs. - [Next.js App Router](https://nextjs.org/docs/app) — Routing, Server Components, data fetching. - [next-intl](https://next-intl.dev/docs) — i18n routing and request config. @@ -218,4 +98,4 @@ These are the main head-app–specific concepts. Details are in the sections bel --- -**Remember:** When in doubt, follow existing patterns in this app and refer to `CLAUDE.md` and `.cursor/rules/` for Sitecore and code standards. +**Remember:** When in doubt, follow existing patterns in this app; open `.cursor/rules/` or a single skill when you need extra constraints beyond this file. diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/CLAUDE.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/CLAUDE.md index 95b3bb8b16..73cfca2153 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/CLAUDE.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/CLAUDE.md @@ -1,9 +1,11 @@ # Claude Code — Sitecore Content SDK Next.js (App Router) App -At the start of every session, read these files for full project guidance: +**Start here:** [`AGENTS.md`](AGENTS.md) — compact guide (commands, structure, best practices, guardrails, references). -1. **`AGENTS.md`** — Canonical source of truth for this app: overview, commands, App Router structure, middleware, SitecoreClient, [site]/[locale]/[[...path]], next-intl, DO/DON'T, guardrails, boundaries -2. **`.cursor/rules/`** — Coding rules for this template: general, javascript, sitecore, app-router-setup -3. **`Skills.md`** and **`.agents/skills/`** — Capability-specific guidance (component registration, data fetching, editing, i18n, etc.) for tools that support the [Agent Skills](https://agentskills.io) standard. +**Add detail only when needed:** -This file applies to **this scaffolded head application only**. For the Content SDK monorepo (packages, CLI, templates source), use that repo's root `AGENTS.md` and `.cursor/rules/`. +- **Layered docs:** [`.agents/docs/`](.agents/docs/) — optional depth ([README](.agents/docs/README.md): overview, key concepts, router specifics, workflows/boundaries). Open **one** layer file for the topic you are working on; guardrails stay in `AGENTS.md`. +- **Cursor rules:** [`.cursor/rules/`](.cursor/rules/) — Cursor applies globs/`alwaysApply` automatically; otherwise open the rule that matches the file type or task. +- **Capabilities:** [`Skills.md`](Skills.md) maps tasks to skill folders. If your tool supports [Agent Skills](https://agentskills.io), read **only** [`.agents/skills//SKILL.md`](.agents/skills/) for the capability you need — not every skill at session start. + +This scaffolded head app only. For the Content SDK monorepo (packages, CLI), use that repo’s root `AGENTS.md`. diff --git a/packages/create-content-sdk-app/src/templates/nextjs-app-router/Skills.md b/packages/create-content-sdk-app/src/templates/nextjs-app-router/Skills.md index 03a35d07f9..91896bd9eb 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs-app-router/Skills.md +++ b/packages/create-content-sdk-app/src/templates/nextjs-app-router/Skills.md @@ -1,79 +1,69 @@ # Skills.md — Capability groupings for this app (Next.js App Router) -This file describes **this application** in terms of **capability-style groupings**: high-level areas that help AI tools and developers map tasks to the right part of the app. This is an App Router app with `[site]`/`[locale]` segments, next-intl, and separate server/client component maps. For concrete steps and patterns, see [AGENTS.md](AGENTS.md) and the [official Content SDK documentation](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +This file maps tasks to **one** skill folder under [.agents/skills/](.agents/skills/). For essentials use compact [AGENTS.md](AGENTS.md); for depth open a layer under [.agents/docs/](.agents/docs/) (see [README](.agents/docs/README.md)). [CLAUDE.md](CLAUDE.md) explains layered reading. [Official Content SDK documentation](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html) covers APIs. -**Agent Skills:** Each grouping is also available as a skill in [.agents/skills/](.agents/skills/) in the standard [Agent Skills](https://agentskills.io) format (`SKILL.md` per capability). Tools that support this standard load skills from `.agents/skills/`; Cursor's built-in skills use `.cursor/skills/` unless it also supports the Agent Skills standard. The skills here are tailored for **App Router** (e.g. setRequestLocale, draftMode(), component-map.ts + component-map.client.ts). - ---- - -## Why capability grouping - -Grouping related capabilities makes it easier to know which area of the app applies to a given task and to point to the right docs and patterns. Map the task to one or more of the groupings below; use AGENTS.md and the official docs for concrete steps. - ---- +**Agent Skills:** [.agents/skills/](.agents/skills/) ([Agent Skills](https://agentskills.io)). **Load only the skill that matches the task.** ## Capability groupings ### content-sdk-component-scaffold -Creating new Sitecore components: file structure, props interface, and placement under `src/components/`. Use when adding a new component from scratch. In App Router, decide Server vs Client and register in the appropriate map. +New component from scratch → [.agents/skills/content-sdk-component-scaffold/SKILL.md](.agents/skills/content-sdk-component-scaffold/SKILL.md) ### content-sdk-component-registration -Registering components in `.sitecore/component-map.ts` (Server) and `.sitecore/component-map.client.ts` (Client). Required so layout and editing can resolve and render components. App Router has separate server and client maps. +Server/client component maps → [.agents/skills/content-sdk-component-registration/SKILL.md](.agents/skills/content-sdk-component-registration/SKILL.md) ### content-sdk-editing-safe-rendering -Safe rendering in XM Cloud editing and preview: `draftMode()`, editing chromes, and design library. Use when ensuring components work in the Sitecore editor and preview. Use `client.getPreview(searchParams)` or `client.getDesignLibraryData(searchParams)` when draft mode is enabled. +`draftMode()`, XM Cloud editing / preview → [.agents/skills/content-sdk-editing-safe-rendering/SKILL.md](.agents/skills/content-sdk-editing-safe-rendering/SKILL.md) ### content-sdk-field-usage-image-link-text -Using SDK field components: ``, ``, ``, ``, with proper validation and fallbacks. Use when rendering Sitecore fields. +``, ``, ``, `` → [.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md](.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md) ### content-sdk-graphql-data-fetching -Page and dictionary fetching via the single Sitecore client in `src/lib/sitecore-client.ts`. Use `getPage(path ?? [], { site, locale })`, `getDictionary`, `getAppRouterStaticParams` for SSG. For preview use `draftMode()` and `getPreview`/`getDesignLibraryData` from searchParams. +`getPage`, dictionary, static params, preview, metadata → [.agents/skills/content-sdk-graphql-data-fetching/SKILL.md](.agents/skills/content-sdk-graphql-data-fetching/SKILL.md) ### content-sdk-route-configuration -Routing: single catch-all at `src/app/[site]/[locale]/[[...path]]/page.tsx`. Layout: app/layout.tsx → app/[site]/layout.tsx → page. Call `setRequestLocale(\`${site}_${locale}\`)` at top of page. Use placeholders and Layout.tsx as in AGENTS.md. +`[site]` / `[locale]` / `[[...path]]`, layouts, not-found → [.agents/skills/content-sdk-route-configuration/SKILL.md](.agents/skills/content-sdk-route-configuration/SKILL.md) ### content-sdk-site-setup-and-env -Site and environment: `sitecore.config.ts`, environment variables, default site and language. Document vars in `.env.example` only; never commit `.env` or `.env.local`. +`sitecore.config.ts`, env vars, `.env.example` → [.agents/skills/content-sdk-site-setup-and-env/SKILL.md](.agents/skills/content-sdk-site-setup-and-env/SKILL.md) ### content-sdk-multisite-management -Multisite: `.sitecore/sites.json`, proxy in `src/proxy.ts`. Chain order is **fixed:** LocaleProxy → AppRouterMultisiteProxy → RedirectsProxy → PersonalizeProxy. Do not change proxy order. +`sites.json`, proxy chain (Locale first) → [.agents/skills/content-sdk-multisite-management/SKILL.md](.agents/skills/content-sdk-multisite-management/SKILL.md) ### content-sdk-dictionary-and-i18n -Dictionary and i18n: next-intl with `src/i18n/routing.ts` and `src/i18n/request.ts`. Request locale is `${site}_${locale}`; call `setRequestLocale(\`${site}_${locale}\`)` in the page; in request.ts parse and load dictionary with `client.getDictionary({ locale, site })`. +next-intl, `requestLocale`, dictionary → [.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md](.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md) ### content-sdk-sitemap-robots -Sitemap and robots: `src/app/api/sitemap/route.ts` and `src/app/api/robots/route.ts` with `createSitemapRouteHandler` and `createRobotsRouteHandler`. Rewrites in next.config.ts for /sitemap*.xml and /robots.txt. +Sitemap / robots route handlers → [.agents/skills/content-sdk-sitemap-robots/SKILL.md](.agents/skills/content-sdk-sitemap-robots/SKILL.md) ### content-sdk-component-variants -Component variants: different renderings or data-driven variants of the same component type. Use when one component has multiple presentations. Register in the appropriate component map (server or client). +Variants / multiple presentations → [.agents/skills/content-sdk-component-variants/SKILL.md](.agents/skills/content-sdk-component-variants/SKILL.md) ### content-sdk-troubleshoot-editing -Troubleshooting XM Cloud editing, preview, and design library. Use when editing or preview does not behave as expected. Check draftMode(), getPreview/getDesignLibraryData from searchParams, and component maps. +Editing or preview misbehaves → [.agents/skills/content-sdk-troubleshoot-editing/SKILL.md](.agents/skills/content-sdk-troubleshoot-editing/SKILL.md) ### content-sdk-upgrade-assistant -Upgrading @sitecore-content-sdk/* packages: version bumps, breaking changes, migration steps. Use when moving to a newer SDK version. Check the Content SDK repo CHANGELOG and upgrade guides. +Bump `@sitecore-content-sdk/*` → [.agents/skills/content-sdk-upgrade-assistant/SKILL.md](.agents/skills/content-sdk-upgrade-assistant/SKILL.md) ### content-sdk-component-data-strategy -Component data: layout data from getPage (or getPreview/getDesignLibraryData in editing). Pass site and locale from route params; Server Components use the client in server context; Client Components receive serializable props from parent. BYOC must be registered in the component map. +Layout data, server vs client props → [.agents/skills/content-sdk-component-data-strategy/SKILL.md](.agents/skills/content-sdk-component-data-strategy/SKILL.md) --- ## How to use this -Map the task to one or more groupings above. Use [AGENTS.md](AGENTS.md) for app-level instructions and the [official documentation](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html) for APIs. - -**If your tool supports Agent Skills:** Load skills from [.agents/skills/](.agents/skills/) (one folder per capability). They provide when-to-use, hard rules, and stop conditions tailored for this App Router app. +Pick **one** skill above. Use [AGENTS.md](AGENTS.md) for compact rules; use [.agents/docs/](.agents/docs/) when you need full patterns for a topic. diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-key-concepts.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-key-concepts.md new file mode 100644 index 0000000000..7c80dad4fb --- /dev/null +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-key-concepts.md @@ -0,0 +1,37 @@ +# Key concepts (Pages Router) + +Optional, on-demand detail for this scaffolded head app. The compact guide is [AGENTS.md](../../AGENTS.md); open this file when you need middleware, client, catch-all, locale, and related concepts. + +## Key concepts for this app + +These are the main head-app–specific concepts. Details are in the sections below. + +### Middleware (Edge proxy) + +- **Where:** `src/proxy.ts`. Next.js runs middleware from `middleware.ts` at root or in `src/` — if the app only has `proxy.ts`, add `src/middleware.ts` that re-exports it. +- **What it does:** Runs on each request (respecting the `config.matcher`). Chain order is **fixed:** MultisiteProxy → RedirectsProxy → PersonalizeProxy. Multisite resolves site (e.g. hostname or cookie) and rewrites; redirects and personalization run after. +- **Config:** Uses `sitecore.config.ts` (multisite, redirects, personalize) and `.sitecore/sites.json`. **Do not change proxy order.** Use the `skip` callback and matcher to exclude `/api`, `/_next`, static files, and health checks so the proxy stays lightweight. + +### SitecoreClient + +- **Where:** Single shared instance in `src/lib/sitecore-client.ts` — `new SitecoreClient({ ...scConfig })` with config from `sitecore.config.ts`. +- **Use for:** `getPage`, `getDictionary`, `getComponentData`, `getPreview`, `getDesignLibraryData`, `getPagePaths`. All Sitecore data fetching in the app goes through this client (in `[[...path]].tsx` getStaticProps/getServerSideProps and in API routes). +- **Do not:** Create a second client or instantiate SitecoreClient elsewhere. Path comes from `extractPath(context)`; locale from `context.locale` (Next.js i18n). + +### Catch-all route + +- **Where:** `src/pages/[[...path]].tsx`. This is the **only** page component that renders Sitecore content; the optional `[[...path]]` segment captures the content path. +- **Flow:** Use `extractPath(context)` (from `@sitecore-content-sdk/nextjs/utils`) to get the path array; use `context.locale` for locale. In getStaticProps/getServerSideProps: `client.getPage(path, { locale: context.locale })`, then `client.getDictionary({ site: page.siteName, locale: page.locale })` and `client.getComponentData(page.layout, context, components)`. For SSG, paths from `client.getPagePaths(sites, context?.locales)` with `sites` from `.sitecore/sites.json`. For preview, use `context.preview` and `context.previewData` with `client.getPreview(context.previewData)` or `client.getDesignLibraryData(context.previewData)`. +- **Do not:** Add another page or catch-all for Sitecore content; keep this single entry point. + +### How locale works + +- **Config:** `next.config.js` → `i18n.locales` and `i18n.defaultLocale`. Match (or subset) Sitecore languages. There is no `[locale]` in the URL path; Next.js i18n handles locale via its built-in behavior (e.g. prefix or cookie). +- **In the app:** Per-request locale is `context.locale` in `getStaticProps` and `getServerSideProps`. Pass it to `client.getPage(path, { locale: context.locale })`. After fetching the page, use `page.siteName` and `page.locale` (or `context.locale`) for `client.getDictionary` and `client.getComponentData`. +- **Do not:** Assume locale from headers or a different source; always use `context.locale` and the page’s site/locale for Sitecore calls. + +### More (component map, editing, env) + +- **Component map:** `.sitecore/component-map.ts` — register every Sitecore component here; keep in sync with `src/components/`. Used by `getComponentData` and by the editing API routes. +- **Editing/preview:** Use `context.preview` and `context.previewData` in the catch-all page; when in preview, use `client.getPreview(context.previewData)` or `client.getDesignLibraryData(context.previewData)`. Editing API routes: `src/pages/api/editing/config.ts`, `render.ts`, `feaas/render.ts`. +- **Env:** All config via environment variables in `sitecore.config.ts`. Document vars in `.env.example` (or `.env.remote.example` / `.env.container.example`); never commit `.env` or `.env.local`. diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-overview.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-overview.md new file mode 100644 index 0000000000..de0521e1c4 --- /dev/null +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-overview.md @@ -0,0 +1,9 @@ +# Project overview (Pages Router) + +Optional, on-demand detail for this scaffolded head app. The compact guide is [AGENTS.md](../../AGENTS.md); open this file when you need scope and orientation beyond that file. + +## Project Overview + +This is a **Sitecore Content SDK** application built with **Next.js (Pages Router)** and **TypeScript**. AI agents work as developer assistants within this scaffolded head application. The app integrates with Sitecore XM Cloud for content, supports multisite and i18n, and uses Next.js API routes and Edge middleware for routing and SEO. + +**Scope:** This file applies to **this application only** (a scaffolded head app). Here we edit app code and config (pages, components, API routes, config); we do not modify SDK packages or CI. diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-router-specifics.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-router-specifics.md new file mode 100644 index 0000000000..790fbd1c63 --- /dev/null +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-router-specifics.md @@ -0,0 +1,49 @@ +# Next.js Pages Router specifics + +Optional, on-demand detail for this scaffolded head app. The compact guide is [AGENTS.md](../../AGENTS.md); open this file for routing, data fetching, API routes, component map, and layout depth. + +## Next.js Pages Router specifics + +### Routing and data fetching + +- **_app.tsx:** Wraps the app and receives the page/layout from the catch-all's getStaticProps/getServerSideProps. Do not fetch Sitecore data in _app; all data flows from `[[...path]].tsx`. +- **Single page for Sitecore content:** `src/pages/[[...path]].tsx` is the catch-all. Path comes from `extractPath(context)` (from `@sitecore-content-sdk/nextjs/utils`); locale from `context.locale` (Next.js i18n). +- **SSG:** Uses `getStaticPaths` and `getStaticProps`. Paths from `client.getPagePaths(sites, context?.locales)` with `sites` from `.sitecore/sites.json`. Use `revalidate` for ISR. +- **SSR:** Uses `getServerSideProps` only; no `getStaticPaths`. +- **Preview:** `context.preview` and `context.previewData`; use `client.getPreview(context.previewData)` or `client.getDesignLibraryData(context.previewData)` when applicable. +- **Page data:** `client.getPage(path, { locale: context.locale })`, then `client.getDictionary({ site: page.siteName, locale: page.locale })` and `client.getComponentData(page.layout, context, components)` for component props. + +### i18n (Pages Router) + +- **Config:** `next.config.js` → `i18n.locales` and `i18n.defaultLocale`. Match (or subset) Sitecore languages. +- **Per-request locale:** Provided by Next.js as `context.locale` in `getStaticProps` / `getServerSideProps`. No `[locale]` in the path; locale is from Next.js i18n. + +### Multisite and Edge middleware (proxy) + +- **Site list:** `.sitecore/sites.json` — typically generated by the Sitecore CLI or deployment. Used by middleware and API routes. Avoid hand-editing unless you know the format. +- **Edge middleware:** Implemented in **`src/proxy.ts`**. Next.js only runs middleware from a file named `middleware.ts` at root or in `src/`. If this app has only `proxy.ts`, add `src/middleware.ts` that re-exports it (e.g. `export { default } from './proxy';`) so the proxy runs. +- **Proxy chain (order matters):** `defineProxy(multisite, redirects, personalize).exec(req)`: + - **MultisiteProxy** — resolves site from request (e.g. hostname or cookie), rewrites to internal path; uses `scConfig.api.edge` and `scConfig.multisite` (e.g. `useCookieResolution`). + - **RedirectsProxy** — handles redirects; uses `scConfig.redirects`, `scConfig.api.edge`, `scConfig.api.local`. + - **PersonalizeProxy** — personalization; uses `scConfig.personalize`; often disabled in dev. +- **Skip function:** Each proxy has a `skip` callback. Use it to avoid running on certain paths (e.g. `/api`, `/_next`, static files) for performance. +- **Config:** `sitecore.config.ts` → `multisite.enabled`, `redirects.enabled`, `personalize`; never commit secrets. + +### API routes + +- **Sitemap:** `src/pages/api/sitemap.ts` — `SitemapMiddleware(scClient, sites).getHandler()`. Serves sitemap XML; uses `sites` from `.sitecore/sites.json`. +- **Robots:** `src/pages/api/robots.ts` — `RobotsMiddleware(scClient, sites).getHandler()`. Serves `robots.txt`; site can be resolved from request. +- **Editing:** `src/pages/api/editing/config.ts`, `render.ts`, `feaas/render.ts` — used by Sitecore Editor (XM Cloud); use SDK middleware/handlers and `.sitecore/component-map`, `.sitecore/metadata.json`. +- **Health:** `src/pages/api/healthz.ts` — health check. Rewrite in `next.config.js`: `/healthz` → `/api/healthz`. +- **Rewrites:** `next.config.js` → `rewrites()` for `/robots.txt`, `/sitemap*.xml`, `/feaas-render` to the corresponding API routes. + +### Sitecore client and config + +- **Client:** `src/lib/sitecore-client.ts` — `new SitecoreClient({ ...scConfig })`. Use this instance for `getPage`, `getDictionary`, `getComponentData`, `getPreview`, `getPagePaths`, etc. +- **Config:** `sitecore.config.ts` — `defineConfig({ api, defaultSite, defaultLanguage, editingSecret, redirects, multisite, personalize })`. Use env vars; no hardcoded secrets. + +### Component map and layout + +- **Component map:** `.sitecore/component-map.ts` — register all Sitecore components. Keep in sync with components under `src/components/`. +- **Layout:** `Layout.tsx` renders page layout and placeholders; `Providers` wrap component props and page context; `Bootstrap` handles site name and preview mode. +- **404 / 500 / _error:** When the catch-all returns `notFound: true` (no page), Next.js renders `404.tsx`. When the server returns 500, Next.js renders `500.tsx`. Both can optionally fetch and show Sitecore error content via `client.getErrorPage(ErrorPage.NotFound)` / `ErrorPage.InternalServerError` in their getStaticProps (when `scConfig.generateStaticPaths`); otherwise they show a simple fallback. `_error.tsx` is Next.js's error boundary for uncaught errors (client and server); it does not fetch from Sitecore. diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-workflows-and-boundaries.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-workflows-and-boundaries.md new file mode 100644 index 0000000000..31122fdab3 --- /dev/null +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/AGENTS-workflows-and-boundaries.md @@ -0,0 +1,20 @@ +# Example tasks and boundaries (Pages Router) + +Optional, on-demand detail for this scaffolded head app. The compact guide is [AGENTS.md](../../AGENTS.md); open this file for concrete task examples and edit boundaries. + +## Example agent tasks + +- **Add a new Sitecore component:** Create the component under `src/components/`, register it in `.sitecore/component-map.ts`, and ensure it is rendered in the layout/placeholder as in existing components. +- **Add an API route:** Create the route under `src/pages/api/`, add a rewrite in `next.config.js` if the route should be reached from a public URL (e.g. `/my-path` → `/api/my-handler`), and ensure the proxy `matcher` in `proxy.ts` still excludes it (or add the path to the matcher exclusions if needed). + +--- + +## Boundaries + +**Never edit:** `.next/`, `node_modules/`. + +**Environment variables:** You may add new env vars when needed. Do it carefully: add the variable to `.env.example` (or `.env.remote.example` / `.env.container.example` in this template) with a placeholder or comment; never put real secrets in example files. If editing `.env.local` for local dev, add only the variable name and tell the user to set the value. **Never commit** `.env` or `.env.local` — they are gitignored. + +**Edit with care:** `next.config.js` (rewrites, i18n), `sitecore.config.ts` (env only), `proxy.ts` (matcher and proxy order). When adding API routes or rewrites, keep middleware `matcher` and rewrite rules consistent. + +**Focus on:** `src/pages/`, `src/components/`, `src/lib/`, `Layout.tsx`, `Providers.tsx`, `sitecore.config.ts`, `next.config.js`, `proxy.ts`, `.sitecore/component-map.ts`. diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/README.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/README.md new file mode 100644 index 0000000000..dc8a1d7bdb --- /dev/null +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/docs/README.md @@ -0,0 +1,12 @@ +# Layered AI docs (Pages Router) + +Use [AGENTS.md](../../AGENTS.md) first (compact). Open **one** file below when you need depth. + +| File | Use when | +|------|----------| +| [AGENTS-overview.md](AGENTS-overview.md) | Project scope and what this head app is | +| [AGENTS-key-concepts.md](AGENTS-key-concepts.md) | Middleware, SitecoreClient, catch-all, locale, component map teaser | +| [AGENTS-router-specifics.md](AGENTS-router-specifics.md) | Pages Router routing, i18n, proxy, API routes, layout, component map detail | +| [AGENTS-workflows-and-boundaries.md](AGENTS-workflows-and-boundaries.md) | Example tasks (new component, API route) and edit boundaries | + +Skills: [.agents/skills/](../skills/) — load **one** [SKILL.md](https://agentskills.io) per task. See [Skills.md](../../Skills.md). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-data-strategy/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-data-strategy/SKILL.md index 05f96001c8..e97530db42 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-data-strategy/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-data-strategy/SKILL.md @@ -3,35 +3,24 @@ name: content-sdk-component-data-strategy description: Component data for Pages Router: after getPage use client.getComponentData(page.layout, context, components) to resolve component props; pass result to layout renderer. All Sitecore-driven component data goes through this flow. Use when wiring component data or BYOC. --- -# Content SDK Component Data Strategy (Pages Router) +# Component data (Pages Router) -This app **uses getComponentData**. After getPage, use **client.getComponentData(page.layout, context, components)** to resolve component props and pass the result to the layout renderer. All Sitecore-driven component data goes through this flow. +**Detail:** [AGENTS-key-concepts.md](../../docs/AGENTS-key-concepts.md#catch-all-route); **content-sdk-graphql-data-fetching**. -## When to Use +**Read code first:** `src/pages/[[...path]].tsx`, `.sitecore/component-map.ts`. -- User asks how to pass data to components, wire component props, or integrate custom/BYOC components. -- Task involves getComponentData, component props, or BYOC. -- User mentions "component data," "props," "BYOC," or "getComponentData." +## When -## How to perform +- Wiring props to layout/components, BYOC, or bypassing `getComponentData`. -- In [[...path]].tsx: getPage(path, { locale: context.locale }), then getDictionary, then getComponentData(page.layout, context, components). Return props to Layout; do not fetch in _app or in child components. Register BYOC in .sitecore/component-map.ts; getComponentData passes resolved props. +## Rules -## Hard Rules +- In the catch-all only: `getPage` → `getDictionary` → `getComponentData`; pass results to `Layout`/`Providers`. +- BYOC/custom components must be in `.sitecore/component-map.ts` and receive layout-driven props from `getComponentData`. +- No extra `getPage` calls inside leaf components. -- **Flow in catch-all page:** In getStaticProps/getServerSideProps: (1) `client.getPage(path, { locale: context.locale })`, (2) `client.getDictionary({ site: page.siteName, locale: page.locale })`, (3) `client.getComponentData(page.layout, context, components)` to resolve component props. Return `{ props: { page, dictionary, componentProps }, notFound: !page }`. Pass these props to Providers and Layout; do not fetch Sitecore data in _app. -- Do not fetch per-component data in parallel outside this flow unless the app pattern explicitly does so. All Sitecore-driven component data goes through getComponentData. -- Single client instance; do not create a new client inside components. The client is used in getStaticProps/getServerSideProps and in API routes. -- **BYOC or custom components:** Must be registered in `.sitecore/component-map.ts` and receive props in the shape the layout expects (e.g. fields, params). getComponentData will pass the resolved props. -- Do not fetch layout or page data inside a child component (e.g. another getPage call); fetch at the catch-all page level and pass props via getComponentData and layout. +## Stop -## Stop Conditions +- Reject moving Sitecore fetching into `_app` or arbitrary child components. -- Stop if the user wants to fetch page/layout data inside a child component; recommend fetching in [[...path]].tsx and passing via getComponentData and layout. -- Do not duplicate getComponentData or getPage logic across components; keep data fetching in the catch-all page only. -- Do not fetch Sitecore data in _app; all data flows from [[...path]].tsx. - -## References - -- content-sdk-graphql-data-fetching and [AGENTS.md](../../../AGENTS.md) for getPage, getComponentData, and data flow. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-registration/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-registration/SKILL.md index cc1b3d367c..5767cac81d 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-registration/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-registration/SKILL.md @@ -3,34 +3,24 @@ name: content-sdk-component-registration description: Registers Sitecore components in .sitecore/component-map.ts so layout and editing can resolve them. Pages Router uses a single map; used by getComponentData and editing API routes. Use when registering a new component or when layout/editor cannot find a component. --- -# Content SDK Component Registration (Pages Router) +# Component registration (Pages Router) -Register components in the Sitecore component map so the layout and editing pipeline can resolve and render them. This app has a **single** map: `.sitecore/component-map.ts`. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#component-map-and-layout), [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#api-routes). -## When to Use +**Read code first:** `.sitecore/component-map.ts`, `src/lib/component-props/index.ts`. -- After scaffolding or adding a new Sitecore component (must be registered). -- User reports a component not rendering, "component not found," or layout/placeholder showing raw component name. -- Task involves `.sitecore/component-map.ts`. -- User asks how to register a component or fix component resolution. +## When -## How to perform +- Component missing in editor/layout, or task touches `.sitecore/component-map.ts`. -- Open `.sitecore/component-map.ts` and add an entry mapping the layout component name to the React component import. The map is used by getComponentData and editing API routes; keep keys consistent with layout and existing entries. +## Rules -## Hard Rules +- Every layout component must have a map entry; keys must match layout names. +- Map is consumed by `getComponentData` and `src/pages/api/editing/*`; keep it aligned with `src/components/`. +- Do not rename/remove entries without updating layout and editing consumers. -- Every component rendered from Sitecore layout must be registered in `.sitecore/component-map.ts`. Keep the map in sync with `src/components/`. -- The map is used by `getComponentData(page.layout, context, components)` in the catch-all page and by editing API routes (`src/pages/api/editing/config.ts`, `render.ts`, `feaas/render.ts`). -- Use consistent component names (same key in map as used in layout). Follow existing naming in the map. -- Do not remove or rename registrations without updating all references (layout, getComponentData, editing routes). +## Stop -## Stop Conditions +- Escalate if changing the map would break published layout without a coordinated Sitecore change. -- Stop if modifying the component map would break existing layout or editing; suggest a safe change or ask for confirmation. -- Do not edit `.sitecore/metadata.json` or import-map unless the task explicitly requires it. - -## References - -- [AGENTS.md](../../../AGENTS.md) for component map and editing routes. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-scaffold/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-scaffold/SKILL.md index 96b1aed700..7bf5d0b304 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-scaffold/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-scaffold/SKILL.md @@ -3,32 +3,25 @@ name: content-sdk-component-scaffold description: Creates new Sitecore components with correct file structure, props interface, and placement under src/components/. Use when adding a new component from scratch or scaffolding a component. Pages Router: register in .sitecore/component-map.ts only. --- -# Content SDK Component Scaffold (Pages Router) +# Component scaffold (Pages Router) -Scaffold new Sitecore components so they integrate with the layout and editing pipeline. This app uses Pages Router with a single component map. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#component-map-and-layout), [AGENTS-workflows-and-boundaries.md](../../docs/AGENTS-workflows-and-boundaries.md#example-agent-tasks). -## When to Use +**Read code first:** `.sitecore/component-map.ts`, `src/lib/component-props/index.ts`, and one existing component under `src/components/` (e.g. `content-sdk`) before loading long prose. -- User asks to add a new Sitecore component, create a component from scratch, or scaffold a component. -- Task involves creating a new React component that will be rendered from Sitecore layout/placeholders. -- User mentions "new component," "add component," or "component file structure." +## When -## How to perform +- New Sitecore-driven React component or scaffold request. +- Component will render from layout/placeholders. -- Create a new file under `src/components/` (or existing feature folder). Define props (fields, params), export a single default component. Register in `.sitecore/component-map.ts` (content-sdk-component-registration). Run `npm run build` to verify. +## Rules -## Hard Rules +- Put files under `src/components/`; default export; typed props (`Field`, etc.). +- Register every new component in `.sitecore/component-map.ts` before considering the task done. +- Run `npm run build` to verify. -- Place components under `src/components/`. Use existing folder conventions. -- Define a props interface with the component's fields (e.g. `fields: { title: Field; ... }`) and any params. Use types from `@sitecore-content-sdk/react` or the app's types. -- Export a single default component; one component per file unless the app pattern differs. -- After creating the component file, register it in `.sitecore/component-map.ts` (see content-sdk-component-registration). Do not leave the component unregistered. Pages Router has a single map used by getComponentData and editing API routes. +## Stop -## Stop Conditions +- Do not add components under `.next/`, `node_modules/`, or build output. -- Do not create components in `.next/`, `node_modules/`, or build output. - -## References - -- [AGENTS.md](../../../AGENTS.md) for app structure and component map. -- [Skills.md](../../../Skills.md) for capability map. [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-variants/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-variants/SKILL.md index 94ae5309a7..b5d39ecf15 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-variants/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-component-variants/SKILL.md @@ -3,34 +3,21 @@ name: content-sdk-component-variants description: Implements component variants: different renderings or data-driven variants of the same component type. Pages Router: register in .sitecore/component-map.ts; getComponentData resolves props. Use when one component has multiple presentations. --- -# Content SDK Component Variants (Pages Router) +# Component variants (Pages Router) -One component definition can have multiple presentations or data-driven variants. Component props are resolved by **getComponentData(page.layout, context, components)**; keep registration and layout aligned. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#component-map-and-layout), [AGENTS-key-concepts.md](../../docs/AGENTS-key-concepts.md#more-component-map-editing-env). -## When to Use +## When -- User asks for different "variants," "versions," or "presentations" of a component. -- Task involves rendering the same component type with different layouts or props based on data (e.g. variant field or style). -- User mentions "component variants," "variations," or "multiple renderings." +- Multiple presentations of one component type (variant field, style param, etc.). -## How to perform +## Rules -- Prefer one component that accepts variant/style via props and branches internally; or multiple map entries if the app uses one key per variant. Use layout/fields/params for variant; register in `.sitecore/component-map.ts`. getComponentData resolves props; align with existing app convention. +- Prefer one component + variant props from layout over many map entries unless the app already uses separate keys. +- Variants must still flow through `getComponentData` and valid map registrations. -## Hard Rules +## Stop -- Prefer a single component registration that accepts variant/style data (e.g. params or fields) and branches internally, over multiple map entries for the same logical component unless the app pattern uses separate registrations per variant. -- Use props (fields, params) from layout to decide variant; do not rely on global state or URL for variant selection when data comes from Sitecore. getComponentData passes the layout-driven props to the component. -- Register in `.sitecore/component-map.ts` only. If the app uses one key per variant, register each; if one key with variant param, single registration. Follow existing app convention. -- Keep the component map in sync with src/components/. +- If layout does not expose variant data, fix content model/layout before hacking URLs or globals. -## Stop Conditions - -- Stop if the variant model (one registration vs many) is unclear; ask or follow the app's existing pattern. -- Do not add new component map entries without ensuring layout and editing can provide the corresponding data. -- Do not assume variant field names (e.g. "variant," "style") without checking the layout definition. - -## References - -- [AGENTS.md](../../../AGENTS.md) and content-sdk-component-registration for the map. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md index d9a83f6414..ee3fff344a 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md @@ -3,33 +3,21 @@ name: content-sdk-dictionary-and-i18n description: Dictionary and i18n for Pages Router: Next.js i18n in next.config.js (i18n.locales, defaultLocale). Per-request locale is context.locale in getStaticProps/getServerSideProps. Fetch dictionary with client.getDictionary({ site: page.siteName, locale: page.locale }) after getPage. Use when adding or changing translated content or locale behavior. --- -# Content SDK Dictionary and i18n (Pages Router) +# Dictionary & i18n (Pages Router) -This app uses **Next.js built-in i18n**. There is no [locale] in the URL path; locale is provided by Next.js as `context.locale` in getStaticProps/getServerSideProps. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#i18n-pages-router), [AGENTS-key-concepts.md](../../docs/AGENTS-key-concepts.md#sitecoreclient). -## When to Use +## When -- User asks to add or change translated content, locale, or dictionary. -- Task involves getDictionary, Next.js i18n, or context.locale. -- User mentions "dictionary," "i18n," "locale," or "translation." +- Locales, dictionary phrases, or `getDictionary`. -## How to perform +## Rules -- Locales: `next.config.js` → i18n.locales, defaultLocale. In getStaticProps/getServerSideProps use context.locale; after getPage use client.getDictionary({ site: page.siteName, locale: page.locale }). Use a single getDictionary per request. Do not assume locale from headers. +- Align `next.config.js` `i18n.locales` with Sitecore languages. +- Use `context.locale` for `getPage` and downstream `getDictionary` / `getComponentData` (no ad-hoc header locale). -## Hard Rules +## Stop -- **Config:** `next.config.js` → `i18n.locales` and `i18n.defaultLocale`. Match (or subset) Sitecore languages. -- **Per-request locale:** Use `context.locale` in getStaticProps and getServerSideProps. Pass it to `client.getPage(path, { locale: context.locale })`. After fetching the page, use `page.siteName` and `page.locale` (or `context.locale`) for `client.getDictionary({ site: page.siteName, locale: page.locale })` and for getComponentData. -- Align locales in next.config.js with Sitecore languages (e.g. from sitecore.config.ts defaultLanguage). Use a single client.getDictionary per request for the active site/locale. -- **Do not** assume locale from headers or a different source; always use `context.locale` and the page's site/locale for Sitecore calls. +- Do not add a locale that is not configured in both Next and Sitecore without explicit confirmation. -## Stop Conditions - -- Stop if adding a new locale without confirming it exists in Sitecore and in next.config.js i18n. -- Do not duplicate dictionary fetching without a clear need; prefer one fetch per request in the catch-all page. - -## References - -- [AGENTS.md](../../../AGENTS.md) for Next.js i18n and getDictionary usage. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-editing-safe-rendering/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-editing-safe-rendering/SKILL.md index d232e6bfd4..b64f61235c 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-editing-safe-rendering/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-editing-safe-rendering/SKILL.md @@ -3,35 +3,22 @@ name: content-sdk-editing-safe-rendering description: Ensures components render safely in XM Cloud editing and preview. Pages Router uses context.preview and context.previewData; use client.getPreview(context.previewData) or getDesignLibraryData(context.previewData) when in preview. Use when making components work in the Sitecore editor or fixing preview/editing behavior. --- -# Content SDK Editing-Safe Rendering (Pages Router) +# Editing / preview (Pages Router) -Ensure components behave correctly in XM Cloud editing, preview, and design library. This app uses **context.preview** and **context.previewData** in getStaticProps/getServerSideProps for editing data. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#routing-and-data-fetching), [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#api-routes). -## When to Use +## When -- User asks about editing, preview, design library, or "component not working in editor." -- Task involves draft mode, editing chromes, or design library integration. -- Fixing issues where components render differently or break in editor vs published. -- User mentions getPreview, getDesignLibraryData, or editing API routes. +- Editor, preview, design library, or chromes behave incorrectly. -## How to perform +## Rules -- In [[...path]].tsx getStaticProps/getServerSideProps: check context.preview; when true use isDesignLibraryPreviewData(context.previewData) to choose getDesignLibraryData vs getPreview; otherwise getPage + getDictionary + getComponentData. Editing routes: config uses EditingConfigMiddleware, render uses EditingRenderMiddleware, feaas/render uses FEAASRenderMiddleware; export handler as default. +- In `[[...path]].tsx` data fetching: if `context.preview`, use `isDesignLibraryPreviewData(context.previewData)` then `getDesignLibraryData` vs `getPreview`; else `getPage` + dictionary + `getComponentData`. +- Editing routes: `api/editing/config`, `render`, `feaas/render` use SDK middlewares and the same `.sitecore/component-map` as the app. +- Secrets only via env; document in `.env.example`. -## Hard Rules +## Stop -- In the catch-all page (`src/pages/[[...path]].tsx`), use `context.preview` and `context.previewData`. When in preview, use `isDesignLibraryPreviewData(context.previewData)` to distinguish: if true, use `client.getDesignLibraryData(context.previewData)`; otherwise use `client.getPreview(context.previewData)`. When not in preview, use `getPage(path, { locale: context.locale })` then getDictionary and getComponentData as usual. -- Do not assume editing/preview context in components that might run in static or non-editing contexts; guard on context.preview in getStaticProps/getServerSideProps. -- Editing API routes: `src/pages/api/editing/config.ts` uses `EditingConfigMiddleware({ components, metadata }).getHandler()` (import components from `.sitecore/component-map`, metadata from `.sitecore/metadata.json`). `src/pages/api/editing/render.ts` uses `EditingRenderMiddleware().getHandler()`. `src/pages/api/editing/feaas/render.ts` uses `FEAASRenderMiddleware().getHandler()`. Export the handler as default. Do not duplicate client creation; config uses the same component map as the app. -- Never commit editing secrets; use environment variables and document in .env.example only. +- Do not reorder Edge proxy to “fix” editing; do not disable secret checks without explicit user consent. -## Stop Conditions - -- Stop and clarify if the issue is preview vs design library vs published; behavior differs. -- Do not change proxy or middleware order to "fix" editing; editing is driven by API routes and context.previewData. -- Do not recommend disabling secret validation without explicit user request and warning. - -## References - -- [AGENTS.md](../../../AGENTS.md) for data fetching, preview flow, and editing routes. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md index 440d376c3c..efd663a2ed 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md @@ -3,34 +3,23 @@ name: content-sdk-field-usage-image-link-text description: Renders Sitecore fields using SDK field components (Text, RichText, Image, Link) with proper validation and fallbacks. Use when rendering content fields or when the user mentions Text, RichText, Image, Link, or field components. --- -# Content SDK Field Usage (Pages Router) +# Field components (Pages Router) -Use SDK field components to render Sitecore fields with proper validation and fallbacks. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#component-map-and-layout). -## When to Use +**Read code first:** an existing field-driven component under `src/components/`. -- User asks how to render a title, body, image, or link from Sitecore. -- Task involves displaying content fields, fixing empty/broken images or links, or using RichText/Text/Image/Link components. -- User mentions "field," "Image," "Link," "Text," "RichText," or "field value." +## When -## How to perform +- Rendering titles, rich text, images, links from Sitecore fields. -- Use SDK field components: ``, ``, ``, ``. Guard with `fields?.` when optional; use tag prop on Text when needed. Do not hardcode media or link URLs from Sitecore. +## Rules -## Hard Rules +- Prefer ``, ``, ``, `` with `field={fields?.…}`; optional chaining for optional fields. +- Do not hardcode media URLs when data comes from Sitecore field types that the SDK resolves. -- Prefer SDK field components over manual field value extraction: ``, ``, ``, ``. Use tag prop for Text when needed (e.g. tag="h1"). -- Validate or guard field existence before rendering when fields can be optional (e.g. `fields?.title`). Handle null/undefined and empty fields gracefully. -- Do not hardcode image or link URLs when the data comes from Sitecore; use the field components or helpers that resolve media/URLs. -- Follow the app's import pattern (e.g. from lib or components). +## Stop -## Stop Conditions +- If field names/types are unknown, confirm against layout/data before guessing. -- Stop if the field structure (name or type) is unknown; suggest checking the layout/data shape or asking the user. -- Do not assume field names (e.g. "title") without confirmation when the template might use different names. -- Do not commit or log raw field values that might contain PII or secrets. - -## References - -- [AGENTS.md](../../../AGENTS.md) for component and Sitecore patterns. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-graphql-data-fetching/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-graphql-data-fetching/SKILL.md index ba4f2afd73..aefbb099d8 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-graphql-data-fetching/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-graphql-data-fetching/SKILL.md @@ -3,36 +3,22 @@ name: content-sdk-graphql-data-fetching description: Fetches page, dictionary, and component data via the single Sitecore client. Pages Router: getPage(path, { locale: context.locale }), getDictionary({ site: page.siteName, locale: page.locale }), getComponentData(page.layout, context, components); for SSG use getPagePaths(sites, context?.locales). Use when fetching page or dictionary content. --- -# Content SDK GraphQL Data Fetching (Pages Router) +# Data fetching (Pages Router) -All Sitecore data fetching goes through the single client in `src/lib/sitecore-client.ts`. Use getPage, getDictionary, and **getComponentData** in the catch-all page. Path from **extractPath(context)**; locale from **context.locale**. +**Detail:** [AGENTS-key-concepts.md](../../docs/AGENTS-key-concepts.md#catch-all-route), [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#routing-and-data-fetching). -## When to Use +## When -- User asks how to fetch page data, layout, or dictionary phrases. -- Task involves getPage, getDictionary, getComponentData, getPreview, getDesignLibraryData, or getPagePaths. -- User mentions "sitecore client," "Layout Service," "page data," or "dictionary." +- `getPage`, `getDictionary`, `getComponentData`, `getPreview`, `getPagePaths`, or “how do I fetch…?” -## How to perform +## Rules -- Use the client from `src/lib/sitecore-client.ts` only. In [[...path]].tsx: use `extractPath(context)` and `context.locale`; call getPage(path, { locale: context.locale }), then getDictionary and getComponentData(page.layout, context, components). For SSG use getPagePaths in getStaticPaths. For preview use context.preview and getPreview/getDesignLibraryData(context.previewData). +- Use only `src/lib/sitecore-client.ts`. Path = `extractPath(context)`; locale = `context.locale`. +- Order: `getPage` → `getDictionary` → `getComponentData`; no Sitecore fetch in `_app`. +- SSG: `getPagePaths` from `.sitecore/sites.json` names; preview uses `context.preview` / `previewData`. -## Hard Rules +## Stop -- Use the single SitecoreClient instance in `src/lib/sitecore-client.ts`. Do not create a second client or instantiate SitecoreClient elsewhere. -- **Path and locale:** Use `extractPath(context)` (from `@sitecore-content-sdk/nextjs/utils`) to get the path array; use `context.locale` for locale. Do not assume path or locale from elsewhere. -- **Catch-all page flow:** In getStaticProps/getServerSideProps: `client.getPage(path, { locale: context.locale })`, then `client.getDictionary({ site: page.siteName, locale: page.locale })` and `client.getComponentData(page.layout, context, components)` for component props. Pass the result to the layout renderer. -- **SSG:** In getStaticPaths, use `client.getPagePaths(siteNames, context?.locales || [])` where site names come from `.sitecore/sites.json` (e.g. `sites.map((s) => s.name)`). Use `revalidate` in getStaticProps for ISR. -- **Preview:** Use `context.preview` and `context.previewData`; when in preview, use `client.getPreview(context.previewData)` or `client.getDesignLibraryData(context.previewData)`. -- Config for the client comes from `sitecore.config.ts`; use environment variables, never hardcode secrets. +- Do not add a second `SitecoreClient` or bypass the client with raw GraphQL unless explicitly required. -## Stop Conditions - -- Stop if the task requires moving the client to another folder without clear requirement; suggest keeping a single instance in lib. -- Do not add direct GraphQL or fetch to Layout Service bypassing the client unless the task explicitly requires it. -- Do not fetch in _app; all data flows from [[...path]].tsx. - -## References - -- [AGENTS.md](../../../AGENTS.md) for SitecoreClient, getPage, getDictionary, getComponentData, and SSG/SSR. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-multisite-management/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-multisite-management/SKILL.md index 534091c6cd..12aee130dd 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-multisite-management/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-multisite-management/SKILL.md @@ -3,35 +3,22 @@ name: content-sdk-multisite-management description: Handles multisite: site resolution, .sitecore/sites.json, and proxy in src/proxy.ts. Pages Router proxy order is fixed: MultisiteProxy → RedirectsProxy → PersonalizeProxy. Use when working with multiple sites or hostnames. --- -# Content SDK Multisite Management (Pages Router) +# Multisite / proxy (Pages Router) -Site resolution from request (e.g. hostname or cookie); proxy rewrites to internal path. No [locale] in URL; Next.js i18n handles locale separately. +**Detail:** [AGENTS-key-concepts.md](../../docs/AGENTS-key-concepts.md#middleware-edge-proxy), [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#multisite-and-edge-middleware-proxy). -## When to Use +## When -- User asks about multiple sites, hostnames, or site resolution. -- Task involves .sitecore/sites.json, multisite config, or proxy/middleware for site. -- User mentions "multisite," "site resolution," "hostname," or "sites.json." +- Multiple sites, hostnames, `sites.json`, or `src/proxy.ts` / matcher. -## How to perform +## Rules -- Site list: `.sitecore/sites.json`. Proxy in `src/proxy.ts`; ensure `src/middleware.ts` re-exports it if present. Keep chain order: MultisiteProxy → RedirectsProxy → PersonalizeProxy. Exclude /api, _next, static assets in matcher/skip. +- Sites list: `.sitecore/sites.json` (usually generated); avoid manual edits unless you know the format. +- Middleware must live in `middleware.ts` re-exporting `proxy.ts` if that is how the template ships. +- **Order:** MultisiteProxy → RedirectsProxy → PersonalizeProxy (do not reorder). Skip `/api`, `/_next`, static assets. -## Hard Rules +## Stop -- Site list is in `.sitecore/sites.json` (typically generated by Sitecore CLI or deployment). Avoid hand-editing unless the format is known. -- **Proxy:** Implemented in `src/proxy.ts`. Next.js runs middleware from `middleware.ts` at root or in `src/` — if the app only has `proxy.ts`, add `src/middleware.ts` that re-exports it. -- **Chain order is fixed:** MultisiteProxy → RedirectsProxy → PersonalizeProxy. **Do not change this order.** MultisiteProxy resolves site from request (hostname or cookie) and rewrites; redirects and personalization run after. -- **Skip / matcher:** Use the skip callback and matcher to exclude /api, /_next, static files, and health checks so the proxy stays lightweight. -- Config: sitecore.config.ts → multisite (e.g. enabled, useCookieResolution). Single SitecoreClient; pass resolved site (and locale from context.locale) into getPage, getDictionary, getComponentData. +- Do not add a parallel site-resolution mechanism. -## Stop Conditions - -- Stop if the user wants to reorder the proxy chain; explain that order is required. -- Stop if sites.json format is unknown and the change could break resolution; suggest checking SDK docs or CLI output. -- Do not add a second site resolution mechanism; use the existing proxy and config. - -## References - -- [AGENTS.md](../../../AGENTS.md) for proxy chain, skip, and multisite config. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-route-configuration/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-route-configuration/SKILL.md index 972b53e548..10679b9e07 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-route-configuration/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-route-configuration/SKILL.md @@ -3,36 +3,22 @@ name: content-sdk-route-configuration description: Configures routing and layout for Pages Router. Single catch-all at src/pages/[[...path]].tsx; path from extractPath(context), locale from context.locale. Data flows via getStaticProps/getServerSideProps to _app and Layout. Use when changing routing, placeholders, or Layout. --- -# Content SDK Route Configuration (Pages Router) +# Routing (Pages Router) -Single catch-all route; no [site] or [locale] in the URL path. Site is resolved by middleware; locale from Next.js i18n (context.locale). +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#routing-and-data-fetching). -## When to Use +## When -- User asks to change routing, add a route, or fix 404/500 behavior. -- Task involves catch-all route, placeholders, _app, or Layout.tsx. -- User mentions "[[...path]]," "placeholder," "layout," or "getStaticProps." +- Changing `[[...path]]`, placeholders, layout, or data-fetch contract for Sitecore pages. -## How to perform +## Rules -- Single Sitecore page: `src/pages/[[...path]].tsx`. Use `extractPath(context)` for path and `context.locale` for locale. Fetch all data in getStaticProps/getServerSideProps and pass to _app and Layout. Not-found/error: use getErrorPage in getStaticProps or 404.tsx / _error.tsx as appropriate. +- **Only** `src/pages/[[...path]].tsx` renders Sitecore pages; `extractPath` + `context.locale`; no duplicate catch-alls. +- All Sitecore data loads in that page’s `getStaticProps`/`getServerSideProps`, not `_app`. +- Do not change multisite proxy order (Multisite → Redirects → Personalize). -## Hard Rules +## Stop -- **Single Sitecore page:** `src/pages/[[...path]].tsx`. This is the **only** page that renders Sitecore content. Do not add another page or catch-all for Sitecore content. -- **Path:** Use `extractPath(context)` (from `@sitecore-content-sdk/nextjs/utils`) to get the path array. **Locale:** Use `context.locale` (Next.js i18n). Do not assume path or locale from headers or elsewhere. -- **Data flow:** All Sitecore data is fetched in getStaticProps/getServerSideProps in [[...path]].tsx and passed to _app and Layout. Do not fetch Sitecore data in _app.tsx. -- **Layout:** Layout.tsx renders page layout and placeholders; Providers wrap component props and page context; Bootstrap handles site name and preview mode. -- Placeholders are rendered by the layout; do not change placeholder names or structure without aligning with Sitecore layout definition. -- **404 / 500 / _error:** When the catch-all returns `notFound: true`, Next.js renders 404.tsx. For Sitecore-driven error content use `client.getErrorPage(ErrorPage.NotFound)` or `ErrorPage.InternalServerError` in getStaticProps when applicable. _error.tsx is the error boundary; it does not fetch from Sitecore. +- If the user wants a second Sitecore entry route, explain the single-entry constraint. -## Stop Conditions - -- Stop if the user wants to add a second catch-all or a different URL shape for Sitecore pages; explain single-entry-point constraint. -- Stop if changing proxy/middleware order; order is fixed (MultisiteProxy → RedirectsProxy → PersonalizeProxy). -- Do not move or rename the catch-all file without updating all references. - -## References - -- [AGENTS.md](../../../AGENTS.md) for exact paths, extractPath, and layout flow. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-site-setup-and-env/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-site-setup-and-env/SKILL.md index 2a469054a8..e2c36a6851 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-site-setup-and-env/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-site-setup-and-env/SKILL.md @@ -3,34 +3,21 @@ name: content-sdk-site-setup-and-env description: Configures site and environment: sitecore.config.ts, environment variables, default site and language. Use when configuring the app or adding env vars. Document in .env.example only; never commit .env or .env.local. --- -# Content SDK Site Setup and Environment (Pages Router) +# Config & env (Pages Router) -Central config in sitecore.config.ts; all secrets and environment-specific values via env vars. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#sitecore-client-and-config), [AGENTS-workflows-and-boundaries.md](../../docs/AGENTS-workflows-and-boundaries.md#boundaries). -## When to Use +## When -- User asks to configure site, default language, API host, or environment. -- Task involves sitecore.config.ts, .env, or defaultSite/defaultLanguage. -- User mentions "config," "environment variables," "API key," or "default site." +- `sitecore.config.ts`, API endpoints, default site/language, or new env vars. -## How to perform +## Rules -- Edit `sitecore.config.ts` with `defineConfig`; read all secrets and env-specific values from `process.env.*`. Add or change vars in `.env.example` (or `.env.remote.example` / `.env.container.example`) with placeholders; never commit `.env` or `.env.local`. +- `defineConfig` + `process.env` only for secrets and hosts; never hardcode production keys. +- Document every var in `.env.example` (or template-specific `*.example`); never commit `.env` / `.env.local`. -## Hard Rules +## Stop -- Use `sitecore.config.ts` with `defineConfig` from the SDK. Expose api (edge, local), defaultSite, defaultLanguage, editingSecret, multisite, redirects, personalize as needed. -- All sensitive or environment-specific values must come from environment variables (e.g. process.env.SITECORE_API_KEY). Never hardcode API keys, secrets, or production URLs in source. -- Document every new or changed env var in `.env.example` (or `.env.remote.example` / `.env.container.example`). Use placeholder or empty value and a short comment; never put real secrets in example files. -- Never commit `.env` or `.env.local`; they are gitignored. Example files are the source of truth for which vars exist. +- Refuse to commit real secrets; flag if deployment/CI must change to accept new vars. -## Stop Conditions - -- Stop if the user wants to commit real secrets or production values; insist on env vars and .env.example only. -- Stop if adding a new env var would require CI or deployment changes without explicit instruction; document the var and note that deployment must set it. -- Do not edit .next/, node_modules/, or lockfiles unless the task explicitly requires it. - -## References - -- [AGENTS.md](../../../AGENTS.md) for boundaries and env rules. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-sitemap-robots/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-sitemap-robots/SKILL.md index 7b46f421b0..b6dd646d2e 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-sitemap-robots/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-sitemap-robots/SKILL.md @@ -3,35 +3,21 @@ name: content-sdk-sitemap-robots description: Sitemap and robots.txt for Pages Router: src/pages/api/sitemap.ts and src/pages/api/robots.ts with SitemapMiddleware(scClient, sites).getHandler() and RobotsMiddleware(scClient, sites).getHandler(). Rewrites in next.config.js. Use when configuring sitemap, robots.txt, or SEO. --- -# Content SDK Sitemap and Robots (Pages Router) +# Sitemap & robots (Pages Router) -Sitemap and robots.txt are served via **API routes** and rewrites. Use the SDK middleware getHandler pattern and sites from .sitecore/sites.json. +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#api-routes). -## When to Use +## When -- User asks to add or change sitemap or robots.txt. -- Task involves SEO, sitemap.xml, or robots route. -- User mentions "sitemap," "robots," "SEO," or "rewrites." +- `sitemap.xml`, `robots.txt`, or SEO routing changes. -## How to perform +## Rules -- Sitemap: `src/pages/api/sitemap.ts` with `SitemapMiddleware(scClient, sites).getHandler()`; robots: `src/pages/api/robots.ts` with `RobotsMiddleware(scClient, sites).getHandler()`. Use sites from `.sitecore/sites.json`. Add rewrites in next.config.js for /sitemap*.xml and /robots.txt to these API routes. +- Use `SitemapMiddleware` / `RobotsMiddleware` handlers with the shared client and `sites` from `.sitecore/sites.json`. +- Keep `next.config.js` rewrites for `/sitemap*.xml` and `/robots.txt` in sync with API routes. -## Hard Rules +## Stop -- **Sitemap:** `src/pages/api/sitemap.ts` — use `new SitemapMiddleware(scClient, sites).getHandler()`. Export the handler. Use `sites` from `.sitecore/sites.json`. -- **Robots:** `src/pages/api/robots.ts` — use `new RobotsMiddleware(scClient, sites).getHandler()`. Same pattern. -- **Rewrites:** In `next.config.js`, add rewrites for `/robots.txt` and `/sitemap*.xml` to the corresponding API routes (e.g. `/sitemap.xml` → `/api/sitemap`). -- Use the same SitecoreClient instance (e.g. from `src/lib/sitecore-client.ts`) as the rest of the app; do not create a dedicated client for sitemap/robots. -- Avoid hardcoding the site list; use .sitecore/sites.json. +- Do not hardcode site lists if `sites.json` is the source of truth. -## Stop Conditions - -- Stop if the user wants to serve sitemap/robots from a different origin or with different auth; document and suggest proxy or edge config. -- Do not add new env vars for sitemap/robots without documenting them in .env.example. -- Do not change rewrite paths without updating docs and any references. - -## References - -- [AGENTS.md](../../../AGENTS.md) for API routes and rewrites. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-troubleshoot-editing/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-troubleshoot-editing/SKILL.md index 7b6cc96c2f..873d54dc36 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-troubleshoot-editing/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-troubleshoot-editing/SKILL.md @@ -3,37 +3,21 @@ name: content-sdk-troubleshoot-editing description: Troubleshoots XM Cloud editing, preview, and design library for Pages Router. Check context.preview, context.previewData, and editing API routes (config, render, feaas/render). Use when editing or preview does not behave as expected. --- -# Content SDK Troubleshoot Editing (Pages Router) +# Troubleshoot editing (Pages Router) -This skill focuses on **diagnosing** editing, preview, and design library issues. For implementing editing-safe rendering (context.preview, getPreview/getDesignLibraryData, API routes), use the **content-sdk-editing-safe-rendering** skill; the two are complementary (implementation vs. troubleshooting). +**Detail:** [AGENTS-router-specifics.md](../../docs/AGENTS-router-specifics.md#api-routes); implement fixes with **content-sdk-editing-safe-rendering**. -Diagnose and fix editing, preview, and design library issues without breaking the single client or proxy order. This app uses **context.preview** and **context.previewData** in getStaticProps/getServerSideProps. +## When -## When to Use +- Editor/preview/design library issues, missing chromes, wrong preview data. -- User reports that editing, preview, or design library is broken or inconsistent. -- Task involves debugging "not working in editor," missing chromes, or wrong data in preview. -- User mentions "editing broken," "preview not working," "design library," or "editor issues." +## Rules -## How to perform +- Verify `extractPath` / `context.locale`, `context.preview` / `previewData`, and that editing API routes match component map entries. +- Ensure matcher skips `/api` correctly and env (`editingSecret`, API) is set and documented. -- Confirm context.preview and context.previewData and correct path/locale (extractPath, context.locale). Verify editing API routes (config, render, feaas/render) are not rewritten (check proxy matcher) and component-map.ts includes the component. Check env (editingSecret, API config) and .env.example documentation. +## Stop -## Hard Rules +- If root cause is XM Cloud project/CI, stop after listing required external changes. -- **Preview flow:** In [[...path]].tsx getStaticProps/getServerSideProps, use `context.preview` and `context.previewData`. When in preview, use `client.getPreview(context.previewData)` or `client.getDesignLibraryData(context.previewData)`. Ensure path and locale come from extractPath(context) and context.locale when not in preview. -- Editing API routes: `src/pages/api/editing/config.ts` (EditingConfigMiddleware), `render.ts` (EditingRenderMiddleware), `feaas/render.ts` (FEAASRenderMiddleware) must be reachable and use the same component map (`.sitecore/component-map.ts`) and config as the app. Check proxy `config.matcher` so `/api` is excluded and not rewritten or blocked. -- Check that the component map includes all components used in the layout; missing registration causes "component not found" in editor. -- Environment: editingSecret and API config must be set (in env); document in .env.example only. Do not log or commit secrets. -- Common causes: wrong path/locale passed to getPreview/getDesignLibraryData, or component not registered in component-map.ts. - -## Stop Conditions - -- Stop if the fix would require changing CI, deployment, or XM Cloud project settings; suggest the user do that and document the required env or config. -- Stop if the issue might be in Sitecore (layout, template) rather than the app; suggest checking layout and content in XM Cloud. -- Do not recommend disabling security (e.g. skipping secret validation) without explicit user request and warning. - -## References - -- content-sdk-editing-safe-rendering skill and [AGENTS.md](../../../AGENTS.md) for preview and editing flow. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-upgrade-assistant/SKILL.md b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-upgrade-assistant/SKILL.md index 05618c04f1..3068b06e54 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-upgrade-assistant/SKILL.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/.agents/skills/content-sdk-upgrade-assistant/SKILL.md @@ -3,34 +3,21 @@ name: content-sdk-upgrade-assistant description: Guides upgrading @sitecore-content-sdk/* packages: version bumps, breaking changes, migration steps. Use when moving to a newer SDK or package version. Check Content SDK repo CHANGELOG and upgrade guides. --- -# Content SDK Upgrade Assistant (Pages Router) +# Upgrade SDK packages (Pages Router) -Upgrade @sitecore-content-sdk/* packages safely; follow the Content SDK repo changelog and migration guides. +**Detail:** [AGENTS-overview.md](../../docs/AGENTS-overview.md#project-overview); doc site migration docs; Content SDK repo CHANGELOG. -## When to Use +## When -- User asks to upgrade SDK packages, update to a new version, or apply a migration. -- Task involves version bumps, @sitecore-content-sdk/* dependencies, or breaking changes. -- User mentions "upgrade," "migration," "new version," or "breaking change." +- Bumping `@sitecore-content-sdk/*` or applying a migration. -## How to perform +## Rules -- Bump all @sitecore-content-sdk/* to consistent versions; read the Content SDK repo CHANGELOG (and MIGRATION/upgrade docs) for breaking changes and migration steps. Update package.json, run `npm install` and `npm run build`; test editing and preview after upgrade. +- Keep all `@sitecore-content-sdk/*` on compatible versions; run `npm install` + `npm run build`; re-test editing/preview. +- Apply breaking-change steps from the upstream CHANGELOG before shipping. -## Hard Rules +## Stop -- Prefer upgrading all @sitecore-content-sdk/* packages together to a consistent set of versions unless the user requests a partial upgrade. Check peer dependencies and compatibility. -- Update dependencies in package.json; run `npm install` and `npm run build`. Test editing and preview after upgrade. -- Read the **Content SDK repository** CHANGELOG (and any MIGRATION.md or upgrade guide) for breaking changes and required code/config updates. Apply migration steps before or with the version bump. -- Do not edit .next/, node_modules/, or lockfiles unless required for the upgrade. Do not change CI or root tooling unless the task explicitly includes it. +- If target version or required infra (new env vars) is unclear, ask before editing lockfiles or CI. -## Stop Conditions - -- Stop if the target version is not specified or unclear; ask or suggest checking the Content SDK CHANGELOG and supported versions. -- Stop if a breaking change requires product or deployment decisions (e.g. new env vars, config schema); list required changes and ask the user to confirm. - -## References - -- Content SDK repo [CHANGELOG](https://github.com/Sitecore/content-sdk/blob/dev/CHANGELOG.md) and upgrade docs. -- [AGENTS.md](../../../AGENTS.md) for build commands. -- [Official Content SDK docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +Docs: [Content SDK CHANGELOG](https://github.com/Sitecore/content-sdk/blob/dev/CHANGELOG.md) · [Product docs](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.cursor/rules/general.mdc b/packages/create-content-sdk-app/src/templates/nextjs/.cursor/rules/general.mdc index fb9c57659c..01f078ec79 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.cursor/rules/general.mdc +++ b/packages/create-content-sdk-app/src/templates/nextjs/.cursor/rules/general.mdc @@ -4,78 +4,10 @@ alwaysApply: true globs: [] --- -# General Coding Principles +# General principles -## Universal Standards - -DRY Principle: - -- Don't Repeat Yourself - extract common functionality -- Create reusable utilities and helper functions -- Use composition over inheritance -- Share types and interfaces across modules - -SOLID Principles: - -- Single Responsibility: each function/class has one purpose -- Open/Closed: extend functionality through composition -- Dependency Inversion: depend on abstractions, not implementations - -Code Clarity: - -- Write self-documenting code with clear intent -- Use meaningful names that express business concepts -- Prefer explicit over implicit behavior -- Make dependencies and requirements obvious - -## Architecture Patterns - -Modular Design: - -- Organize code into focused, cohesive modules -- Minimize coupling between modules -- Use clear interfaces between layers -- Follow established patterns consistently - -Data Flow: - -- Prefer unidirectional data flow -- Validate inputs at system boundaries -- Transform data at appropriate layers -- Handle errors close to their source - -Testing: - -- Write testable code with minimal dependencies -- Use dependency injection for better testability -- Mock external services and side effects -- Test behavior, not implementation details - -## Development Standards - -Version Control: - -- Write descriptive commit messages -- Keep commits focused and atomic -- Use branching strategies appropriate to team size -- Review code before merging - -Documentation: - -- Document public APIs and interfaces -- Include usage examples for complex functionality -- Keep documentation close to code -- Update documentation with code changes - -Performance: - -- Optimize for readability first, performance second -- Profile before optimizing -- Cache expensive operations appropriately -- Consider memory usage and cleanup - -Referenced: -@src/components/ -@src/lib/ -@package.json +- **DRY / clarity:** Reuse helpers and types; names reflect intent; prefer explicit behavior. +- **Structure:** Small focused modules; validate at boundaries; handle errors near the source. +- **Quality:** Test behavior; meaningful commits; document public APIs; profile before micro-optimizing. +Referenced: `@src/components/`, `@src/lib/`, `@package.json` diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.cursor/rules/project-setup.mdc b/packages/create-content-sdk-app/src/templates/nextjs/.cursor/rules/project-setup.mdc index cae2441411..20b2f1a44c 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.cursor/rules/project-setup.mdc +++ b/packages/create-content-sdk-app/src/templates/nextjs/.cursor/rules/project-setup.mdc @@ -4,97 +4,12 @@ alwaysApply: true globs: [] --- -# Sitecore Content SDK Next.js Project +# Sitecore Content SDK — Pages Router -## Project Overview +Next.js + TypeScript head app for XM Cloud. **Commands:** `npm install`, `npm run dev`, `npm run build`, `npm run lint`, `npm run type-check`. Copy `.env.example` → `.env.local` (never commit secrets). -This is a Sitecore Content SDK application built with Next.js. The project structure follows Sitecore best practices for XM Cloud development. +**Structure:** `src/pages/` (catch-all `[[...path]].tsx`, API routes), `src/components/`, `src/lib/sitecore-client.ts`, `src/proxy.ts`, `.sitecore/`, `sitecore.config.ts`, `next.config.js`. -Key Technologies: - -- Next.js (React framework) -- Sitecore Content SDK -- TypeScript -- Sitecore XM Cloud - -## Getting Started - -Development Workflow: - -1. Install dependencies: `npm install` -2. Configure environment variables (copy `.env.example` to `.env.local`) -3. Start development server: `npm run dev` -4. Build for production: `npm run build` - -Environment Configuration: - -- Copy `.env.example` to `.env.local` -- Add your Sitecore API endpoint and key -- Configure site name and other settings - -## Sitecore Integration - -Configuration: - -- Configure Sitecore connection in `sitecore.config.ts` -- Register components in the component map -- Use Sitecore field components for content rendering -- Follow Sitecore's layout service patterns - -Component Development: - -- Create components in `src/components/` -- Export from component files for registration -- Use TypeScript interfaces for component props -- Follow Sitecore field handling patterns - -## Project Structure - -``` -src/ - components/ # React-specific SDK - lib/ # Configuration and utilities - pages/ # Next.js pages - assets/ # Static assets and styles -``` - -## Best Practices - -Sitecore Components: - -- Use descriptive component names -- Handle field validation gracefully -- Implement proper error boundaries -- Cache content when appropriate - -Performance: - -- Optimize images using Next.js Image component -- Implement proper loading states -- Use React.memo for expensive components -- Consider server-side rendering implications - -## Development Commands - -```bash -npm run dev # Start development server -npm run build # Build for production -npm run start # Start production server -npm run lint # Run ESLint -npm run type-check # Run TypeScript compiler -``` - -## Next Steps - -1. Configure your Sitecore connection -2. Create your first component -3. Add content types and templates -4. Set up your development workflow -5. Deploy to your hosting platform - -Referenced: -@src/components/ -@sitecore.config.ts -@package.json -@.env.example +**Detail:** Guardrails and quick orientation stay in [`AGENTS.md`](../../AGENTS.md). For middleware, `getPage` / `getComponentData`, and i18n depth, see [`.agents/docs/`](../../.agents/docs/) (e.g. [`AGENTS-key-concepts.md`](../../.agents/docs/AGENTS-key-concepts.md), [`AGENTS-router-specifics.md`](../../.agents/docs/AGENTS-router-specifics.md)). +Referenced: `@sitecore.config.ts`, `@package.json`, `@.env.example` diff --git a/packages/create-content-sdk-app/src/templates/nextjs/.windsurfrules b/packages/create-content-sdk-app/src/templates/nextjs/.windsurfrules index faab8d6bfe..bf44015e97 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/.windsurfrules +++ b/packages/create-content-sdk-app/src/templates/nextjs/.windsurfrules @@ -1,186 +1,11 @@ -# Sitecore Content SDK Next.js Project - Windsurf AI Rules +# Sitecore Content SDK — Next.js (Pages Router) -## Project Purpose and Tech Stack +**Primary:** [AGENTS.md](AGENTS.md) — compact guide (commands, structure, best practices, guardrails). -This is a **Sitecore Content SDK** application built with **Next.js** and **TypeScript**. The project follows Sitecore best practices for XM Cloud development and provides a modern, performant web application framework. +**Depth:** [.agents/docs/](.agents/docs/) — one layer file when needed (routing, client, proxy, i18n, etc.). [README](.agents/docs/README.md) indexes layers. -### Key Technologies +**Optional:** [Skills.md](Skills.md) → one folder under [.agents/skills/](.agents/skills/) for the task. [CLAUDE.md](CLAUDE.md) — layered reading. [.cursor/rules/](.cursor/rules/) — same rules as Cursor. -- **Next.js** - React framework with SSR/SSG capabilities -- **Sitecore Content SDK** - Official SDK for Sitecore XM Cloud integration -- **TypeScript** - Type-safe JavaScript development -- **Sitecore XM Cloud** - Headless CMS platform -- **React** - Component-based UI library +**Commands:** `npm install`, `npm run dev`, `npm run build`, `npm run lint`, `npm run type-check`. Copy `.env.example` → `.env.local`; never commit secrets. -## Coding Standards - -### TypeScript Standards - -- Use **strict mode** in tsconfig.json -- Prefer type assertions over `any`: `value as ContentItem` -- Use discriminated unions for complex state management -- Enable strict null checks and strict function types - -### Naming Conventions - -- **Variables/Functions**: camelCase (`getUserData()`, `isLoading`, `currentUser`) -- **Components**: PascalCase (`SitecoreComponent`, `PageLayout`, `ContentBlock`) -- **Constants**: UPPER_SNAKE_CASE (`API_ENDPOINT`, `DEFAULT_TIMEOUT`) -- **Directories**: kebab-case (`src/components`, `src/api-clients`) -- **Types/Interfaces**: PascalCase (`ContentItem`, `LayoutProps`, `SitecoreConfig`) - -### Modular Layout - -``` -src/ - components/ # UI components (React) - lib/ # Configuration and utilities - pages/ # Next.js pages - assets/ # Static assets and styles - types/ # TypeScript type definitions - hooks/ # Custom React hooks -``` - -## Library Usage - -### @sitecore-content-sdk - -- Use `SitecoreClient` for content fetching -- Implement proper error handling with try/catch blocks -- Cache API responses using React Query or SWR -- Handle content preview vs. published content scenarios - -```typescript -import { SitecoreClient } from '@sitecore-content-sdk/nextjs/client'; -import scConfig from 'sitecore.config'; - -const client = new SitecoreClient({ - ...scConfig, -}); -``` - -### React Patterns - -- Use **Server Components** for data fetching and static content -- Use **Client Components** for interactivity (use 'use client') -- Implement proper error boundaries -- Use React.memo for expensive components -- Leverage useCallback and useMemo for performance optimization - -### Sitecore Field Components - -- Always use Sitecore field components: ``, ``, `` -- Validate field existence before rendering -- Handle empty/null fields gracefully -- Prefer Sitecore field components over manual rendering - -```typescript -// Good: Using Sitecore field components - - - - -// Avoid: Manual field value extraction unless necessary -``` - -## Example Patterns and Prompts - -### Component Development - -```typescript -// Component props interface -interface HeroProps { - fields: { - title: Field; - subtitle: Field; - backgroundImage: Field; - }; -} - -export default function Hero({ fields }: HeroProps) { - return ( -
- - - -
- ); -} -``` - -### Error Handling - -```typescript -async function fetchPageData(path: string): Promise { - if (!path) { - throw new Error('Page path is required'); - } - - try { - const pageData = await client.getPage(path); - return pageData; - } catch (error) { - throw new SitecoreFetchError(`Failed to fetch page data for ${path}`, error); - } -} -``` - -### Configuration - -```typescript -// sitecore.config.ts -import { defineConfig } from '@sitecore-content-sdk/nextjs/config'; - -export default defineConfig({ - api: { - edge: { - contextId: process.env.SITECORE_EDGE_CONTEXT_ID || '', - clientContextId: process.env.NEXT_PUBLIC_SITECORE_EDGE_CONTEXT_ID, - edgeUrl: - process.env.NEXT_PUBLIC_SITECORE_EDGE_PLATFORM_HOSTNAME || - process.env.SITECORE_EDGE_PLATFORM_HOSTNAME || - 'https://edge-platform.sitecorecloud.io', - }, - local: { - apiKey: process.env.SITECORE_API_KEY || '', - apiHost: process.env.SITECORE_API_HOST || '', - }, - }, - defaultSite: process.env.NEXT_PUBLIC_DEFAULT_SITE_NAME || 'default', - defaultLanguage: process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE || 'en', - editingSecret: process.env.SITECORE_EDITING_SECRET, -}); -``` - -## Development Workflow - -1. **Install dependencies**: `npm install` -2. **Configure environment**: Copy `.env.example` to `.env.local` -3. **Start development**: `npm run dev` -4. **Build for production**: `npm run build` - -## Best Practices - -### Performance - -- Optimize images using Next.js Image component -- Implement proper loading states -- Cache expensive operations appropriately -- Consider server-side rendering implications -- Lazy-load non-critical modules - -### Security - -- Sanitize user inputs before processing -- Validate data at application boundaries -- Use HTTPS for all Sitecore connections -- Never expose sensitive configuration in client-side code -- Escape content when rendering to prevent XSS - -### Code Quality - -- Follow DRY principle - extract common functionality -- Use SOLID principles for maintainable code -- Write self-documenting code with clear intent -- Implement proper error boundaries -- Test behavior, not implementation details +**Product docs:** [Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html) diff --git a/packages/create-content-sdk-app/src/templates/nextjs/AGENTS.md b/packages/create-content-sdk-app/src/templates/nextjs/AGENTS.md index 0f9190263d..d97d1bf57a 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/AGENTS.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/AGENTS.md @@ -1,196 +1,89 @@ -# AGENTS.md — AI Guidance for Sitecore Content SDK Next.js (Pages Router) App - -## Project Overview - -This is a **Sitecore Content SDK** application built with **Next.js (Pages Router)** and **TypeScript**. AI agents work as developer assistants within this scaffolded head application. The app integrates with Sitecore XM Cloud for content, supports multisite and i18n, and uses Next.js API routes and Edge middleware for routing and SEO. - -**Scope:** This file applies to **this application only** (a scaffolded head app). It is **not** the Content SDK monorepo — for SDK package development use that repo's `AGENTS.md`. Here we edit app code and config (pages, components, API routes, config); we do not modify SDK packages or CI. - ---- - -## Quick Commands - -```bash -npm install -npm run dev # Start development server -npm run build # Build for production -npm run start # Start production server -npm run lint # Run ESLint -npm run type-check # Run TypeScript compiler -``` - -**Environment:** Copy `.env.example` to `.env.local` and set Sitecore API endpoint, key, default site, and language. Never commit `.env` or `.env.local`. - ---- - -## Application Structure (Pages Router) - -``` -src/ - pages/ # Next.js Pages Router - [[...path]].tsx # Catch-all Sitecore page (SSG or SSR) - _app.tsx - 404.tsx, 500.tsx, _error.tsx - api/ # API routes (sitemap, robots, editing, healthz) - components/ # React components (Sitecore + app-specific) - lib/ # sitecore-client, component-props - Layout.tsx, Providers.tsx, Bootstrap.tsx, Scripts.tsx -proxy.ts # Edge middleware (multisite, redirects, personalize) -.sitecore/ # component-map.ts, import-map.ts, sites.json, metadata.json -sitecore.config.ts # Sitecore config (api, defaultSite, defaultLanguage, multisite, etc.) -next.config.js # i18n (locales, defaultLocale), rewrites, images -``` - ---- - -## Key concepts for this app - -These are the main head-app–specific concepts. Details are in the sections below. - -### Middleware (Edge proxy) - -- **Where:** `src/proxy.ts`. Next.js runs middleware from `middleware.ts` at root or in `src/` — if the app only has `proxy.ts`, add `src/middleware.ts` that re-exports it. -- **What it does:** Runs on each request (respecting the `config.matcher`). Chain order is **fixed:** MultisiteProxy → RedirectsProxy → PersonalizeProxy. Multisite resolves site (e.g. hostname or cookie) and rewrites; redirects and personalization run after. -- **Config:** Uses `sitecore.config.ts` (multisite, redirects, personalize) and `.sitecore/sites.json`. **Do not change proxy order.** Use the `skip` callback and matcher to exclude `/api`, `/_next`, static files, and health checks so the proxy stays lightweight. - -### SitecoreClient - -- **Where:** Single shared instance in `src/lib/sitecore-client.ts` — `new SitecoreClient({ ...scConfig })` with config from `sitecore.config.ts`. -- **Use for:** `getPage`, `getDictionary`, `getComponentData`, `getPreview`, `getDesignLibraryData`, `getPagePaths`. All Sitecore data fetching in the app goes through this client (in `[[...path]].tsx` getStaticProps/getServerSideProps and in API routes). -- **Do not:** Create a second client or instantiate SitecoreClient elsewhere. Path comes from `extractPath(context)`; locale from `context.locale` (Next.js i18n). - -### Catch-all route - -- **Where:** `src/pages/[[...path]].tsx`. This is the **only** page component that renders Sitecore content; the optional `[[...path]]` segment captures the content path. -- **Flow:** Use `extractPath(context)` (from `@sitecore-content-sdk/nextjs/utils`) to get the path array; use `context.locale` for locale. In getStaticProps/getServerSideProps: `client.getPage(path, { locale: context.locale })`, then `client.getDictionary({ site: page.siteName, locale: page.locale })` and `client.getComponentData(page.layout, context, components)`. For SSG, paths from `client.getPagePaths(sites, context?.locales)` with `sites` from `.sitecore/sites.json`. For preview, use `context.preview` and `context.previewData` with `client.getPreview(context.previewData)` or `client.getDesignLibraryData(context.previewData)`. -- **Do not:** Add another page or catch-all for Sitecore content; keep this single entry point. - -### How locale works - -- **Config:** `next.config.js` → `i18n.locales` and `i18n.defaultLocale`. Match (or subset) Sitecore languages. There is no `[locale]` in the URL path; Next.js i18n handles locale via its built-in behavior (e.g. prefix or cookie). -- **In the app:** Per-request locale is `context.locale` in `getStaticProps` and `getServerSideProps`. Pass it to `client.getPage(path, { locale: context.locale })`. After fetching the page, use `page.siteName` and `page.locale` (or `context.locale`) for `client.getDictionary` and `client.getComponentData`. -- **Do not:** Assume locale from headers or a different source; always use `context.locale` and the page’s site/locale for Sitecore calls. - -### More (component map, editing, env) - -- **Component map:** `.sitecore/component-map.ts` — register every Sitecore component here; keep in sync with `src/components/`. Used by `getComponentData` and by the editing API routes. -- **Editing/preview:** Use `context.preview` and `context.previewData` in the catch-all page; when in preview, use `client.getPreview(context.previewData)` or `client.getDesignLibraryData(context.previewData)`. Editing API routes: `src/pages/api/editing/config.ts`, `render.ts`, `feaas/render.ts`. -- **Env:** All config via environment variables in `sitecore.config.ts`. Document vars in `.env.example` (or `.env.remote.example` / `.env.container.example`); never commit `.env` or `.env.local`. - ---- - -## Next.js Pages Router specifics - -### Routing and data fetching - -- **_app.tsx:** Wraps the app and receives the page/layout from the catch-all's getStaticProps/getServerSideProps. Do not fetch Sitecore data in _app; all data flows from `[[...path]].tsx`. -- **Single page for Sitecore content:** `src/pages/[[...path]].tsx` is the catch-all. Path comes from `extractPath(context)` (from `@sitecore-content-sdk/nextjs/utils`); locale from `context.locale` (Next.js i18n). -- **SSG:** Uses `getStaticPaths` and `getStaticProps`. Paths from `client.getPagePaths(sites, context?.locales)` with `sites` from `.sitecore/sites.json`. Use `revalidate` for ISR. -- **SSR:** Uses `getServerSideProps` only; no `getStaticPaths`. -- **Preview:** `context.preview` and `context.previewData`; use `client.getPreview(context.previewData)` or `client.getDesignLibraryData(context.previewData)` when applicable. -- **Page data:** `client.getPage(path, { locale: context.locale })`, then `client.getDictionary({ site: page.siteName, locale: page.locale })` and `client.getComponentData(page.layout, context, components)` for component props. - -### i18n (Pages Router) - -- **Config:** `next.config.js` → `i18n.locales` and `i18n.defaultLocale`. Match (or subset) Sitecore languages. -- **Per-request locale:** Provided by Next.js as `context.locale` in `getStaticProps` / `getServerSideProps`. No `[locale]` in the path; locale is from Next.js i18n. - -### Multisite and Edge middleware (proxy) - -- **Site list:** `.sitecore/sites.json` — typically generated by the Sitecore CLI or deployment. Used by middleware and API routes. Avoid hand-editing unless you know the format. -- **Edge middleware:** Implemented in **`src/proxy.ts`**. Next.js only runs middleware from a file named `middleware.ts` at root or in `src/`. If this app has only `proxy.ts`, add `src/middleware.ts` that re-exports it (e.g. `export { default } from './proxy';`) so the proxy runs. -- **Proxy chain (order matters):** `defineProxy(multisite, redirects, personalize).exec(req)`: - - **MultisiteProxy** — resolves site from request (e.g. hostname or cookie), rewrites to internal path; uses `scConfig.api.edge` and `scConfig.multisite` (e.g. `useCookieResolution`). - - **RedirectsProxy** — handles redirects; uses `scConfig.redirects`, `scConfig.api.edge`, `scConfig.api.local`. - - **PersonalizeProxy** — personalization; uses `scConfig.personalize`; often disabled in dev. -- **Skip function:** Each proxy has a `skip` callback. Use it to avoid running on certain paths (e.g. `/api`, `/_next`, static files) for performance. -- **Config:** `sitecore.config.ts` → `multisite.enabled`, `redirects.enabled`, `personalize`; never commit secrets. - -### API routes - -- **Sitemap:** `src/pages/api/sitemap.ts` — `SitemapMiddleware(scClient, sites).getHandler()`. Serves sitemap XML; uses `sites` from `.sitecore/sites.json`. -- **Robots:** `src/pages/api/robots.ts` — `RobotsMiddleware(scClient, sites).getHandler()`. Serves `robots.txt`; site can be resolved from request. -- **Editing:** `src/pages/api/editing/config.ts`, `render.ts`, `feaas/render.ts` — used by Sitecore Editor (XM Cloud); use SDK middleware/handlers and `.sitecore/component-map`, `.sitecore/metadata.json`. -- **Health:** `src/pages/api/healthz.ts` — health check. Rewrite in `next.config.js`: `/healthz` → `/api/healthz`. -- **Rewrites:** `next.config.js` → `rewrites()` for `/robots.txt`, `/sitemap*.xml`, `/feaas-render` to the corresponding API routes. - -### Sitecore client and config - -- **Client:** `src/lib/sitecore-client.ts` — `new SitecoreClient({ ...scConfig })`. Use this instance for `getPage`, `getDictionary`, `getComponentData`, `getPreview`, `getPagePaths`, etc. -- **Config:** `sitecore.config.ts` — `defineConfig({ api, defaultSite, defaultLanguage, editingSecret, redirects, multisite, personalize })`. Use env vars; no hardcoded secrets. - -### Component map and layout - -- **Component map:** `.sitecore/component-map.ts` — register all Sitecore components. Keep in sync with components under `src/components/`. -- **Layout:** `Layout.tsx` renders page layout and placeholders; `Providers` wrap component props and page context; `Bootstrap` handles site name and preview mode. -- **404 / 500 / _error:** When the catch-all returns `notFound: true` (no page), Next.js renders `404.tsx`. When the server returns 500, Next.js renders `500.tsx`. Both can optionally fetch and show Sitecore error content via `client.getErrorPage(ErrorPage.NotFound)` / `ErrorPage.InternalServerError` in their getStaticProps (when `scConfig.generateStaticPaths`); otherwise they show a simple fallback. `_error.tsx` is Next.js's error boundary for uncaught errors (client and server); it does not fetch from Sitecore. - ---- - -## Best practices - -- **Quick checks:** If path or locale is wrong, ensure you use `extractPath(context)` and `context.locale` (from getStaticProps/getServerSideProps); do not assume path or locale from elsewhere. Keep the proxy chain order (Multisite → Redirects → Personalize). -- **Security:** Use only environment variables in `sitecore.config.ts`; never hardcode API keys, editing secret, or host URLs. Do not expose secrets in client-side code or in logs. Validate and sanitize user input at boundaries. -- **Performance:** Keep middleware lightweight; use the proxy `skip` callback and `matcher` so middleware does not run on `/api`, `_next`, static files, or health checks. Use `revalidate` in getStaticProps for ISR where appropriate. Prefer server-side data fetching for Sitecore content. -- **Sitecore patterns:** Use SDK field components (``, ``, ``) and validate field existence before render. Register new components in `.sitecore/component-map.ts`. Keep the single Sitecore client instance in `lib/sitecore-client.ts` and pass it (or use it) in API routes and getStaticProps/getServerSideProps. -- **Consistency:** Follow the existing patterns in `[[...path]].tsx`, `_app.tsx`, and API routes. When adding API routes, add the corresponding rewrite in `next.config.js` and keep the middleware matcher in sync. - ---- - -## DO & DON'T (app-level) - -| DO | DON'T | -|----|-------| -| Use `extractPath(context)` and `context.locale` for page data | Assume path or locale from elsewhere | -| Use `client.getPage`, `getDictionary`, `getComponentData` per existing patterns | Fetch in client components when SSR/SSG is intended | -| Keep `proxy.ts` / middleware matcher in sync with excluded paths | Add heavy logic to middleware without `skip` for `/api`, `_next`, etc. | -| Use `.sitecore/sites.json` for multisite list in API routes and middleware | Hardcode site list or commit `.env` | -| Follow existing SSG/SSR and preview patterns in `[[...path]].tsx` | Change getStaticPaths/getStaticProps contract without updating callers | -| Use Sitecore field components (``, ``, ``) and validate fields | Expose API keys or editing secret in client code | -| Document required env vars in `.env.example` only | Commit `.env` or `.env.local` | -| Run `npm run build` after changes to verify the app builds | Add npm dependencies without explicit user approval | - ---- - -## Guardrails for agentic AI - -- **Preserve behavior:** Do not change the contract of `getStaticPaths` / `getStaticProps` (or getServerSideProps), the proxy chain order, or the shape of page props/layout without updating all consumers. Preserve SSG/SSR and preview behavior. -- **Do not expand scope:** Limit edits to the app (pages, components, API routes, config). Do not modify SDK packages or monorepo tooling unless explicitly asked. Do not change CI, lockfiles, or root config. -- **Follow existing patterns:** When adding pages, API routes, or components, mirror the existing structure and naming. Use the same Sitecore client, component map, and env-based config. Do not introduce new patterns (e.g. a second client or a different way to resolve site/locale) without clear need. -- **Verify and stay safe:** After edits, the app should build with `npm run build`. Do not commit secrets or `.env`; only document variables in `.env.example`. Do not add npm dependencies without explicit approval. When in doubt, prefer the existing implementation and ask for clarification. -- **If the user asks for something that conflicts with these guardrails** (e.g. changing proxy order, committing `.env`, or skipping the component map), explain the constraint and suggest a safe alternative rather than complying. - ---- - -## Example agent tasks - -- **Add a new Sitecore component:** Create the component under `src/components/`, register it in `.sitecore/component-map.ts`, and ensure it is rendered in the layout/placeholder as in existing components. -- **Add an API route:** Create the route under `src/pages/api/`, add a rewrite in `next.config.js` if the route should be reached from a public URL (e.g. `/my-path` → `/api/my-handler`), and ensure the proxy `matcher` in `proxy.ts` still excludes it (or add the path to the matcher exclusions if needed). - ---- - -## Boundaries - -**Never edit:** `.next/`, `node_modules/`. - -**Environment variables:** You may add new env vars when needed. Do it carefully: add the variable to `.env.example` (or `.env.remote.example` / `.env.container.example` in this template) with a placeholder or comment; never put real secrets in example files. If editing `.env.local` for local dev, add only the variable name and tell the user to set the value. **Never commit** `.env` or `.env.local` — they are gitignored. - -**Edit with care:** `next.config.js` (rewrites, i18n), `sitecore.config.ts` (env only), `proxy.ts` (matcher and proxy order). When adding API routes or rewrites, keep middleware `matcher` and rewrite rules consistent. - -**Focus on:** `src/pages/`, `src/components/`, `src/lib/`, `Layout.tsx`, `Providers.tsx`, `sitecore.config.ts`, `next.config.js`, `proxy.ts`, `.sitecore/component-map.ts`. - ---- - -## References - -- **Skills.md** — Capability groupings for this app; [.agents/skills/](.agents/skills/) provides each capability as an Agent Skill (when-to-use, hard rules, stop conditions) for tools that support the [Agent Skills](https://agentskills.io) standard. -- **CLAUDE.md** — Full coding standards and Sitecore patterns for this template. -- **.cursor/rules/** — Project and Sitecore rules. -- [Sitecore Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html) — Official docs. -- [Next.js Pages Router](https://nextjs.org/docs/pages) — Data fetching, API routes, i18n. - -**For head applications / empty starters:** If you use this template for your head application (e.g. empty starter), keep this AGENTS.md as that head application's guide. Do not replace it with the Content SDK monorepo root AGENTS.md — that file describes the SDK source tree, not the head application. Adjust only what is specific to your project (e.g. custom layout or workflow). See the Content SDK README "AI Development Support" section for more on which AGENTS.md to use. - ---- - -**Remember:** When in doubt, follow existing patterns in this app and refer to `CLAUDE.md` and `.cursor/rules/` for Sitecore and code standards. +# AGENTS.md — AI Guidance for Sitecore Content SDK Next.js (Pages Router) App + +> **Context:** This file is the **compact** guide (commands, repo layout, best practices, guardrails, references). Deeper topics live under [.agents/docs/](.agents/docs/) — start with [README](.agents/docs/README.md) or open the layer you need: [AGENTS-overview.md](.agents/docs/AGENTS-overview.md), [AGENTS-key-concepts.md](.agents/docs/AGENTS-key-concepts.md), [AGENTS-router-specifics.md](.agents/docs/AGENTS-router-specifics.md), [AGENTS-workflows-and-boundaries.md](.agents/docs/AGENTS-workflows-and-boundaries.md). Use [Skills.md](Skills.md) to pick **one** [.agents/skills/](.agents/skills/) skill when needed; [CLAUDE.md](CLAUDE.md) explains layered reading. Cursor applies [.cursor/rules/](.cursor/rules/) by glob — you do not need every rule in chat context at once. + +--- + +## Quick Commands + +```bash +npm install +npm run dev # Start development server +npm run build # Build for production +npm run start # Start production server +npm run lint # Run ESLint +npm run type-check # Run TypeScript compiler +``` + +**Environment:** Copy `.env.example` to `.env.local` and set Sitecore API endpoint, key, default site, and language. Never commit `.env` or `.env.local`. + +--- + +## Application Structure (Pages Router) + +``` +src/ + pages/ # Next.js Pages Router + [[...path]].tsx # Catch-all Sitecore page (SSG or SSR) + _app.tsx + 404.tsx, 500.tsx, _error.tsx + api/ # API routes (sitemap, robots, editing, healthz) + components/ # React components (Sitecore + app-specific) + lib/ # sitecore-client, component-props + Layout.tsx, Providers.tsx, Bootstrap.tsx, Scripts.tsx +proxy.ts # Edge middleware (multisite, redirects, personalize) +.sitecore/ # component-map.ts, import-map.ts, sites.json, metadata.json +sitecore.config.ts # Sitecore config (api, defaultSite, defaultLanguage, multisite, etc.) +next.config.js # i18n (locales, defaultLocale), rewrites, images +``` + +--- + +## Best practices + +- **Quick checks:** If path or locale is wrong, ensure you use `extractPath(context)` and `context.locale` (from getStaticProps/getServerSideProps); do not assume path or locale from elsewhere. Keep the proxy chain order (Multisite → Redirects → Personalize). +- **Security:** Use only environment variables in `sitecore.config.ts`; never hardcode API keys, editing secret, or host URLs. Do not expose secrets in client-side code or in logs. Validate and sanitize user input at boundaries. +- **Performance:** Keep middleware lightweight; use the proxy `skip` callback and `matcher` so middleware does not run on `/api`, `_next`, static files, or health checks. Use `revalidate` in getStaticProps for ISR where appropriate. Prefer server-side data fetching for Sitecore content. +- **Sitecore patterns:** Use SDK field components (``, ``, ``) and validate field existence before render. Register new components in `.sitecore/component-map.ts`. Keep the single Sitecore client instance in `lib/sitecore-client.ts` and pass it (or use it) in API routes and getStaticProps/getServerSideProps. +- **Consistency:** Follow the existing patterns in `[[...path]].tsx`, `_app.tsx`, and API routes. When adding API routes, add the corresponding rewrite in `next.config.js` and keep the middleware matcher in sync. + +--- + +## DO & DON'T (app-level) + +| DO | DON'T | +|----|-------| +| Use `extractPath(context)` and `context.locale` for page data | Assume path or locale from elsewhere | +| Use `client.getPage`, `getDictionary`, `getComponentData` per existing patterns | Fetch in client components when SSR/SSG is intended | +| Keep `proxy.ts` / middleware matcher in sync with excluded paths | Add heavy logic to middleware without `skip` for `/api`, `_next`, etc. | +| Use `.sitecore/sites.json` for multisite list in API routes and middleware | Hardcode site list or commit `.env` | +| Follow existing SSG/SSR and preview patterns in `[[...path]].tsx` | Change getStaticPaths/getStaticProps contract without updating callers | +| Use Sitecore field components (``, ``, ``) and validate fields | Expose API keys or editing secret in client code | +| Document required env vars in `.env.example` only | Commit `.env` or `.env.local` | +| Run `npm run build` after changes to verify the app builds | Add npm dependencies without explicit user approval | + +--- + +## Guardrails for agentic AI + +- **Preserve behavior:** Do not change the contract of `getStaticPaths` / `getStaticProps` (or getServerSideProps), the proxy chain order, or the shape of page props/layout without updating all consumers. Preserve SSG/SSR and preview behavior. +- **Do not expand scope:** Limit edits to the app (pages, components, API routes, config). Do not modify SDK packages or monorepo tooling unless explicitly asked. Do not change CI, lockfiles, or root config. +- **Follow existing patterns:** When adding pages, API routes, or components, mirror the existing structure and naming. Use the same Sitecore client, component map, and env-based config. Do not introduce new patterns (e.g. a second client or a different way to resolve site/locale) without clear need. +- **Verify and stay safe:** After edits, the app should build with `npm run build`. Do not commit secrets or `.env`; only document variables in `.env.example`. Do not add npm dependencies without explicit approval. When in doubt, prefer the existing implementation and ask for clarification. +- **If the user asks for something that conflicts with these guardrails** (e.g. changing proxy order, committing `.env`, or skipping the component map), explain the constraint and suggest a safe alternative rather than complying. + +--- + +## References + +- **Skills.md** — Capability index; [.agents/skills/](.agents/skills/) — load **one** skill per task ([Agent Skills](https://agentskills.io)). +- **CLAUDE.md** — How to layer AI context for this template. +- **.cursor/rules/** — Editor rules (applied by glob / always-apply). +- [Sitecore Content SDK](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html) — Official docs. +- [Next.js Pages Router](https://nextjs.org/docs/pages) — Data fetching, API routes, i18n. + +**For head applications / empty starters:** If you use this template for your head application (e.g. empty starter), keep this AGENTS.md as that head application's guide. Do not replace it with the Content SDK monorepo root AGENTS.md — that file describes the SDK source tree, not the head application. Adjust only what is specific to your project (e.g. custom layout or workflow). See the Content SDK README "AI Development Support" section for more on which AGENTS.md to use. + +--- + +**Remember:** When in doubt, follow existing patterns in this app; open `.cursor/rules/` or a single skill when you need extra constraints beyond this file. diff --git a/packages/create-content-sdk-app/src/templates/nextjs/CLAUDE.md b/packages/create-content-sdk-app/src/templates/nextjs/CLAUDE.md index c772323e23..b65199e035 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/CLAUDE.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/CLAUDE.md @@ -1,9 +1,11 @@ # Claude Code — Sitecore Content SDK Next.js (Pages Router) App -At the start of every session, read these files for full project guidance: +**Start here:** [`AGENTS.md`](AGENTS.md) — compact guide (commands, structure, best practices, guardrails, references). -1. **`AGENTS.md`** — Canonical source of truth for this app: overview, commands, application structure, middleware, SitecoreClient, catch-all route, i18n, DO/DON'T, guardrails, boundaries -2. **`.cursor/rules/`** — Coding rules for this template: general, javascript, sitecore, project-setup -3. **`Skills.md`** and **`.agents/skills/`** — Capability-specific guidance (component registration, data fetching, editing, i18n, etc.) for tools that support the [Agent Skills](https://agentskills.io) standard. +**Add detail only when needed:** -This file applies to **this scaffolded head application only**. For the Content SDK monorepo (packages, CLI, templates source), use that repo's root `AGENTS.md` and `.cursor/rules/`. +- **Layered docs:** [`.agents/docs/`](.agents/docs/) — optional depth ([README](.agents/docs/README.md): overview, key concepts, router specifics, workflows/boundaries). Open **one** layer file for the topic you are working on; guardrails stay in `AGENTS.md`. +- **Cursor rules:** [`.cursor/rules/`](.cursor/rules/) — Cursor applies globs/`alwaysApply` automatically; otherwise open the rule that matches the file type or task. +- **Capabilities:** [`Skills.md`](Skills.md) maps tasks to skill folders. If your tool supports [Agent Skills](https://agentskills.io), read **only** [`.agents/skills//SKILL.md`](.agents/skills/) for the capability you need — not every skill at session start. + +This scaffolded head app only. For the Content SDK monorepo (packages, CLI), use that repo’s root `AGENTS.md`. diff --git a/packages/create-content-sdk-app/src/templates/nextjs/Skills.md b/packages/create-content-sdk-app/src/templates/nextjs/Skills.md index 019ceb48f9..5700400754 100644 --- a/packages/create-content-sdk-app/src/templates/nextjs/Skills.md +++ b/packages/create-content-sdk-app/src/templates/nextjs/Skills.md @@ -1,79 +1,69 @@ # Skills.md — Capability groupings for this app (Next.js Pages Router) -This file describes **this application** in terms of **capability-style groupings**: high-level areas that help AI tools and developers map tasks to the right part of the app. This is a Pages Router app with `pages/[[...path]].tsx`, Next.js i18n, and a single component map. For concrete steps and patterns, see [AGENTS.md](AGENTS.md) and the [official Content SDK documentation](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html). +This file maps tasks to **one** skill folder under [.agents/skills/](.agents/skills/). For essentials use compact [AGENTS.md](AGENTS.md); for depth open a layer under [.agents/docs/](.agents/docs/) (see [README](.agents/docs/README.md)). [CLAUDE.md](CLAUDE.md) explains layered reading. [Official Content SDK documentation](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html) covers APIs. -**Agent Skills:** Each grouping is also available as a skill in [.agents/skills/](.agents/skills/) in the standard [Agent Skills](https://agentskills.io) format (`SKILL.md` per capability). Tools that support this standard load skills from `.agents/skills/`; Cursor's built-in skills use `.cursor/skills/` unless it also supports the Agent Skills standard. The skills here are tailored for **Pages Router** (e.g. extractPath, context.locale, getComponentData, single component-map.ts). - ---- - -## Why capability grouping - -Grouping related capabilities makes it easier to know which area of the app applies to a given task and to point to the right docs and patterns. Map the task to one or more of the groupings below; use AGENTS.md and the official docs for concrete steps. - ---- +**Agent Skills:** [.agents/skills/](.agents/skills/) ([Agent Skills](https://agentskills.io)). **Load only the skill that matches the task.** ## Capability groupings ### content-sdk-component-scaffold -Creating new Sitecore components: file structure, props interface, and placement under `src/components/`. Use when adding a new component from scratch. Register in `.sitecore/component-map.ts`. +New component from scratch → [.agents/skills/content-sdk-component-scaffold/SKILL.md](.agents/skills/content-sdk-component-scaffold/SKILL.md) ### content-sdk-component-registration -Registering components in `.sitecore/component-map.ts` only. Required so layout and editing can resolve and render components. Used by getComponentData and editing API routes. Pages Router has a single map. +Register in `.sitecore/component-map.ts` → [.agents/skills/content-sdk-component-registration/SKILL.md](.agents/skills/content-sdk-component-registration/SKILL.md) ### content-sdk-editing-safe-rendering -Safe rendering in XM Cloud editing and preview: `context.preview` and `context.previewData`, editing chromes, and design library. Use when ensuring components work in the Sitecore editor and preview. Use `client.getPreview(context.previewData)` or `client.getDesignLibraryData(context.previewData)` when in preview. +XM Cloud editing / preview / design library → [.agents/skills/content-sdk-editing-safe-rendering/SKILL.md](.agents/skills/content-sdk-editing-safe-rendering/SKILL.md) ### content-sdk-field-usage-image-link-text -Using SDK field components: ``, ``, ``, ``, with proper validation and fallbacks. Use when rendering Sitecore fields. +``, ``, ``, `` → [.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md](.agents/skills/content-sdk-field-usage-image-link-text/SKILL.md) ### content-sdk-graphql-data-fetching -Page, dictionary, and component data via the single Sitecore client in `src/lib/sitecore-client.ts`. Use `getPage(path, { locale: context.locale })`, then `getDictionary({ site: page.siteName, locale: page.locale })` and `getComponentData(page.layout, context, components)`. For SSG use `getPagePaths(sites, context?.locales)`. +`getPage`, dictionary, SSG paths, preview → [.agents/skills/content-sdk-graphql-data-fetching/SKILL.md](.agents/skills/content-sdk-graphql-data-fetching/SKILL.md) ### content-sdk-route-configuration -Routing: single catch-all at `src/pages/[[...path]].tsx`. Path from `extractPath(context)`; locale from `context.locale`. Layout and page data flow via getStaticProps/getServerSideProps to _app and Layout.tsx. No [site]/[locale] in path; site resolved by middleware. +Catch-all `[[...path]].tsx`, `_app`, layout → [.agents/skills/content-sdk-route-configuration/SKILL.md](.agents/skills/content-sdk-route-configuration/SKILL.md) ### content-sdk-site-setup-and-env -Site and environment: `sitecore.config.ts`, environment variables, default site and language. Document vars in `.env.example` only; never commit `.env` or `.env.local`. +`sitecore.config.ts`, env vars, `.env.example` → [.agents/skills/content-sdk-site-setup-and-env/SKILL.md](.agents/skills/content-sdk-site-setup-and-env/SKILL.md) ### content-sdk-multisite-management -Multisite: `.sitecore/sites.json`, proxy in `src/proxy.ts`. Chain order is **fixed:** MultisiteProxy → RedirectsProxy → PersonalizeProxy. Do not change proxy order. +`sites.json`, proxy / multisite chain → [.agents/skills/content-sdk-multisite-management/SKILL.md](.agents/skills/content-sdk-multisite-management/SKILL.md) ### content-sdk-dictionary-and-i18n -Dictionary and i18n: Next.js i18n in `next.config.js` (i18n.locales, defaultLocale). Per-request locale is `context.locale` in getStaticProps/getServerSideProps. Fetch dictionary with `client.getDictionary({ site: page.siteName, locale: page.locale })` after getPage. +Next.js i18n, `context.locale`, dictionary → [.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md](.agents/skills/content-sdk-dictionary-and-i18n/SKILL.md) ### content-sdk-sitemap-robots -Sitemap and robots: `src/pages/api/sitemap.ts` and `src/pages/api/robots.ts` with `SitemapMiddleware(scClient, sites).getHandler()` and `RobotsMiddleware(scClient, sites).getHandler()`. Rewrites in next.config.js for /sitemap*.xml and /robots.txt. +Sitemap / robots API routes → [.agents/skills/content-sdk-sitemap-robots/SKILL.md](.agents/skills/content-sdk-sitemap-robots/SKILL.md) ### content-sdk-component-variants -Component variants: different renderings or data-driven variants of the same component type. Use when one component has multiple presentations. Register in `.sitecore/component-map.ts`; getComponentData resolves props. +Variants / multiple presentations → [.agents/skills/content-sdk-component-variants/SKILL.md](.agents/skills/content-sdk-component-variants/SKILL.md) ### content-sdk-troubleshoot-editing -Troubleshooting XM Cloud editing, preview, and design library. Use when editing or preview does not behave as expected. Check context.preview, context.previewData, and editing API routes (config, render, feaas/render). +Editing or preview misbehaves → [.agents/skills/content-sdk-troubleshoot-editing/SKILL.md](.agents/skills/content-sdk-troubleshoot-editing/SKILL.md) ### content-sdk-upgrade-assistant -Upgrading @sitecore-content-sdk/* packages: version bumps, breaking changes, migration steps. Use when moving to a newer SDK version. Check the Content SDK repo CHANGELOG and upgrade guides. +Bump `@sitecore-content-sdk/*` → [.agents/skills/content-sdk-upgrade-assistant/SKILL.md](.agents/skills/content-sdk-upgrade-assistant/SKILL.md) ### content-sdk-component-data-strategy -Component data: after getPage, use `client.getComponentData(page.layout, context, components)` to resolve component props; pass result to layout renderer. All Sitecore-driven component data goes through this flow. BYOC must be registered in `.sitecore/component-map.ts`. +`getComponentData`, layout props flow → [.agents/skills/content-sdk-component-data-strategy/SKILL.md](.agents/skills/content-sdk-component-data-strategy/SKILL.md) --- ## How to use this -Map the task to one or more groupings above. Use [AGENTS.md](AGENTS.md) for app-level instructions and the [official documentation](https://doc.sitecore.com/xmc/en/developers/content-sdk/sitecore-content-sdk-for-xm-cloud.html) for APIs. - -**If your tool supports Agent Skills:** Load skills from [.agents/skills/](.agents/skills/) (one folder per capability). They provide when-to-use, hard rules, and stop conditions tailored for this Pages Router app. +Pick **one** skill above. Use [AGENTS.md](AGENTS.md) for compact rules; use [.agents/docs/](.agents/docs/) when you need full patterns for a topic.