---
title: "contentful/skills"
description: "Skills for teaching agents how to build on Contentful."
source: https://github.com/contentful/skills
ref: main
license: MIT
licenseName: "MIT License"
canonical: https://skillsdocs.com/contentful/skills
base: https://github.com/contentful/skills/blob/main/
chapters: 9
inlined: 9
withheld: 0
words: 6981
updated: 2026-08-09T08:33:13Z
generator: "Skills Docs"
---

> **contentful/skills** — every Agent Skill in this repository, inlined verbatim.
>
> Canonical HTML: https://skillsdocs.com/contentful/skills
> Per-chapter Markdown: https://skillsdocs.com/contentful/skills/<skill>.md
> Machine manifest: https://skillsdocs.com/contentful/skills/.well-known/agent-skills/index.json
> JSON: https://skillsdocs.com/api/v1/books/contentful/skills
> Install: `npx skills add contentful/skills`
> Upstream: https://github.com/contentful/skills @ `main`
> Licence: MIT
>
> Content is mirrored from GitHub and © its authors, served unmodified. Takedown: https://github.com/DreambaseAI/skillsdocs/issues/new?labels=takedown&title=Takedown+request

# contentful/skills

Skills for teaching agents how to build on Contentful.

- **Chapters:** 9
- **Inlined:** 9 (licence detected)
- **Words:** 6,981
- **Reading time:** 33 min
- **Stars:** 37

## Table of contents

1. [optimization-sdk-sync](https://skillsdocs.com/contentful/skills/optimization-sdk-sync.md) — Synchronize the Contentful Optimization SDK's public API, behavior, and implementation guidance into concise, runtime-specific references for the contentful-pe…
2. [skill-authoring](https://skillsdocs.com/contentful/skills/skill-authoring.md) — Create, modify, review, and fix Agent Skills in the contentful/skills repository. Use when creating a new skill from scratch, editing an existing SKILL.md or p…
3. [contentful-api](https://skillsdocs.com/contentful/skills/contentful-api.md) — Comprehensive Contentful REST API guide. Covers Content Management API (CMA) for creating/updating content, Content Delivery API (CDA) for fetching published c…
4. [contentful-custom-app-enhancement](https://skillsdocs.com/contentful/skills/contentful-custom-app-enhancement.md) — Improve, debug, and extend an existing Contentful App Framework custom app in a customer's own repository. Use when users provide a bug report, feature request…
5. [contentful-custom-app-from-scratch](https://skillsdocs.com/contentful/skills/contentful-custom-app-from-scratch.md) — Design, scaffold, build, and validate a new Contentful App Framework custom app for a customer's own repository or workspace. Use when users want to create a c…
6. [contentful-guide](https://skillsdocs.com/contentful/skills/contentful-guide.md) — Explain core Contentful concepts and route users to the right implementation skill or documentation. Use when users ask conceptual questions, need terminology…
7. [contentful-migration](https://skillsdocs.com/contentful/skills/contentful-migration.md) — Write and run Contentful content model migration scripts using the contentful-migration library and the Contentful CLI. Covers creating, editing, and deleting…
8. [contentful-nextjs](https://skillsdocs.com/contentful/skills/contentful-nextjs.md) — Add and configure Contentful in an existing Next.js project. Covers installing the JavaScript SDK, configuring environment variables, creating production and p…
9. [contentful-personalization](https://skillsdocs.com/contentful/skills/contentful-personalization.md) — Implement, extend, and debug Contentful personalization. Use onboarding for new, project-wide, or unknown setups; use extend-existing only for scoped work on a…


## Front matter

_The repository README, verbatim except that relative links are resolved against https://github.com/contentful/skills/blob/main/._

<div align="center">

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="contentful-logo.svg" />
  <img src="contentful-logo.svg" alt="Contentful" height="40" />
</picture>

<br /><br />

**Your AI agent knows how to code. These skills teach it Contentful.**

<br />

[![version](https://img.shields.io/badge/v1.5.1-0286FF?style=flat&label=version)](https://github.com/contentful/skills/releases)
[![license](https://img.shields.io/badge/MIT-grey?style=flat&label=license)](LICENSE)
[![skills](https://img.shields.io/badge/7_skills-0286FF?style=flat&label=)](skills/)
[![platforms](https://img.shields.io/badge/35%2B_platforms-0286FF?style=flat&label=)](https://agentskills.io)

</div>

<br />

AI coding agents write great code but know nothing about your content model, your SDK patterns, or which of Contentful's five APIs to reach for. **Contentful Skills** fixes that — curated instructions, reference docs, and structured workflows that produce correct Contentful integrations on the first try.

## Quickstart — Claude Code

Two commands. You get seven skills plus live MCP connections to your Contentful spaces.

```
/plugin marketplace add contentful/skills
/plugin install contentful@contentful
```

Run `/reload-plugins` to activate. This registers two MCP servers:
- **contentful-mcp** — connection to `mcp.contentful.com` for CMS operations
- **contentful-personalization** — local MCP for structured personalization workflows

---

## What's inside

| Skill | What it does |
|:------|:-------------|
| **[contentful-guide](#contentful-guide)** | Explains core concepts and routes you to the right skill, API, or doc. Start here. |
| **[contentful-api](#contentful-api)** | Language-agnostic REST and GraphQL API reference — curl examples for CMA, CDA, CPA, Images, and GraphQL. |
| **[contentful-nextjs](#contentful-nextjs)** | Integrates Contentful into a Next.js project — SDK setup, content fetching, Draft Mode previews. |
| **[contentful-migration](#contentful-migration)** | Writes and runs content model migration scripts — fields, validations, transforms, editor interfaces. |
| **[contentful-custom-app-from-scratch](#contentful-custom-app-from-scratch)** | Designs, scaffolds, builds, and validates new App Framework custom apps. |
| **[contentful-custom-app-enhancement](#contentful-custom-app-enhancement)** | Improves and debugs existing Contentful custom apps in customer-owned repos. |
| **[contentful-personalization](#contentful-personalization)** | Sets up, debugs, and develops personalization and A/B testing with the Experiences SDK. |

The custom app skills are packaged together under `skills/contentful-apps/`.

---

## Other platforms

Skills also work without the plugin on any platform that supports the [agentskills.io](https://agentskills.io) spec.

### Cursor

Install the [Contentful Cursor plugin](https://cursor.directory/plugins/contentful-1) from Cursor Directory.

Alternatively, add the skills manually:

1. Open **Settings** → **Rules**
2. Click **Add Rule** → **Remote Rule (GitHub)**
3. Enter `contentful/skills`

### Universal CLI

```bash
npx skills add contentful/skills
```

Works with GitHub Copilot, VS Code, OpenAI Codex, Gemini CLI, and [35+ other platforms](https://agentskills.io).

<details>
<summary><strong>More options</strong></summary>

<br />

**Gemini CLI:**

```bash
gemini skills install contentful/skills
```

**GitHub Copilot / VS Code:**

Skills auto-discover from `.agents/skills/` when added to your project. Use `/skills` in Copilot Chat to confirm they're loaded.

**Install a single skill:**

```bash
npx skills add contentful/skills --skill contentful-personalization
```

Available: `contentful-guide`, `contentful-api`, `contentful-nextjs`, `contentful-migration`, `contentful-custom-app-from-scratch`, `contentful-custom-app-enhancement`, `contentful-personalization`

</details>

---

## Skills

### contentful-guide

Explains core Contentful concepts and routes you to the right skill or documentation. Start here if you're new to Contentful or unsure which API to use.

<details>
<summary>Triggers and details</summary>

<br />

**Activates on:** "Contentful 101", "which API should I use", "how do I get started", "what does X mean in Contentful"

**Covers:**
- Core vocabulary — spaces, environments, content types, entries, assets, locales
- API selection — CDA vs CPA vs CMA vs GraphQL vs Images API
- Routing to the right implementation skill
- Contentful MCP server orientation

</details>

### contentful-api

Language-agnostic reference for Contentful's REST and GraphQL APIs. Pair this with any framework or language — examples are curl-based.

<details>
<summary>Triggers and details</summary>

<br />

**Activates on:** "curl Contentful", "CMA request", "CDA query parameters", "publish entry HTTP", "Images API URL", "Contentful GraphQL query"

**Covers:**
- Authentication — token types, headers, US/EU base URLs
- HTTP conventions — version locking, rate limits, pagination, error payloads, locale structure
- Content Management API — entries, content types, assets, environments, bulk actions
- Content Delivery API — querying, includes/link resolution, localization, sync
- Content Preview API — draft + published content via CDA endpoints
- Images API — on-the-fly transformations via URL parameters
- GraphQL Content API — querying with CDA tokens

</details>

### contentful-nextjs

Add and configure Contentful in a Next.js project. Covers SDK setup, environment variables, content fetching, and Draft Mode preview flows for both App Router and Pages Router.

<details>
<summary>Triggers and details</summary>

<br />

**Activates on:** "add Contentful to Next.js", "Contentful SDK setup", "Draft Mode", "preview mode", "Server Components Contentful"

**Covers:**
- SDK installation and client configuration
- Environment variables and environment aliases
- Content fetching patterns (App Router and Pages Router)
- Draft Mode preview flows with CPA
- ISR (Incremental Static Regeneration) setup
- Troubleshooting common integration issues

</details>

### contentful-migration

Write and run content model migration scripts using the Contentful migration library. Covers field operations, validations, entry transforms, and editor interface configuration.

<details>
<summary>Triggers and details</summary>

<br />

**Activates on:** "write a migration", "create content type", "schema migration", "field validation", "editor interface", "changeFieldId"

**Covers:**
- Content type creation, editing, and deletion
- Field operations — add, rename, move, change type
- Validations — range, regex, linked content types, asset file constraints
- Entry transforms — in-place edits, deriving linked entries, moving entries between types
- Editor interface wiring — widgets, field layout, sidebar controls
- Best practices — sandbox testing, sequential file naming, separating schema from data changes

</details>

### contentful-custom-app-from-scratch

Design, scaffold, build, and validate a new Contentful App Framework custom app for your own repository or workspace.

<details>
<summary>Triggers and details</summary>

<br />

**Activates on:** "build a Contentful app", "custom app from scratch", "App Framework app", "sidebar app", "field editor app", "page app", "app action", "app function"

**Covers:**
- Idea shaping and v1 scoping for internal custom apps
- App location selection — app config, page, home, dialog, entry editor, entry field, entry sidebar
- Scaffolding with `create-contentful-app`
- App SDK, React Apps Toolkit, Forma 36, installation parameters, App Actions, and Functions guidance
- Local Contentful setup, sandbox testing, validation, and handoff

</details>

### contentful-custom-app-enhancement

Improve, debug, and extend an existing Contentful App Framework custom app in a customer-owned repository.

<details>
<summary>Triggers and details</summary>

<br />

**Activates on:** "fix my Contentful app", "improve a custom app", "enhance App Framework app", "debug custom app", "update sidebar app", "custom app feature request"

**Covers:**
- Triage from bug reports, support notes, screenshots, and feature requests
- Existing app inspection across locations, SDK usage, parameters, App Actions, Functions, and backend code
- Small, reviewable implementation plans
- App-native UI and security guardrails
- Targeted tests, local smoke checks, sandbox verification, and PR handoff

</details>

### contentful-personalization

Set up, debug, and develop with Contentful personalization and A/B testing. A structured, multi-step skill with three workflows and a reference library of 19+ documents.

<details>
<summary>Workflows and details</summary>

<br />

**Activates on:** "set up personalization", "A/B test", "personalization not working", "Experiences SDK", "run an experiment", "audience targeting"

**Workflows:**
- **Onboard** — Assess readiness, select SDK, guided installation, content type setup
- **Doctor** — Diagnose broken setups: checks packages, env vars, API connectivity, content state
- **Develop** — Day-to-day companion for personalizing components, running experiments, wiring analytics

**Reference library:** SDK guides, component patterns, SSR/middleware patterns, provider patterns, analytics setup, environment variables, error resolution, and more.

Built with [@contentful/skill-kit](https://github.com/contentful/skill-kit) — a structured state machine with MCP server integration.

</details>

---

## MCP Server Setup

Plugin installs configure MCP connections automatically. If you installed via `npx skills add` or another non-plugin path, set up the MCP servers manually to get the full experience.

### Contentful MCP (CMS operations)

Connects your agent to your Contentful spaces for reading and writing content, content types, and assets.

**Claude Code:**

```
/mcp add-http contentful-mcp https://mcp.contentful.com/mcp
```

**Other platforms** — add to your MCP config:

```json
{
  "mcpServers": {
    "contentful-mcp": {
      "type": "http",
      "url": "https://mcp.contentful.com/mcp"
    }
  }
}
```

- **Documentation:** [contentful.com/developers/docs/tools/mcp-server](https://www.contentful.com/developers/docs/tools/mcp-server/)

### Personalization MCP (structured workflows)

The `contentful-personalization` skill includes a local MCP server that powers its interactive workflows. Point your agent at the skill's run script:

**Claude Code:**

```
/mcp add -- /path/to/skills/contentful-personalization/scripts/run mcp --host claude-code
```

**Other platforms** — add to your MCP config:

```json
{
  "mcpServers": {
    "contentful-personalization": {
      "command": "/path/to/skills/contentful-personalization/scripts/run",
      "args": ["mcp", "--host", "claude-code"]
    }
  }
}
```

> [!NOTE]
> Replace `/path/to/skills/` with the actual path where skills were installed (typically `.agents/skills/` in your project).

---

## Local Plugin Testing (Claude Code)

To test the full plugin locally — including skills, MCP servers, and hooks — without publishing:

```bash
claude --plugin-dir /path/to/contentful/skills
```

This loads everything defined in `.claude-plugin/plugin.json` for that session: skills, the Contentful MCP server, and the personalization MCP server. Use `/reload-plugins` inside the session to pick up changes without restarting.

You can also combine multiple plugin directories:

```bash
claude --plugin-dir ./skills --plugin-dir ./other-plugin
```

## Contributing

See [CONTRIBUTING.md](https://github.com/contentful/skills/blob/main/CONTRIBUTING.md) for development setup and guidelines. We welcome bug reports, feature requests, and pull requests.

## Help and Support

- Open a [GitHub issue](https://github.com/contentful/skills/issues) for bugs and feature requests
- For security issues, see [SECURITY.md](https://github.com/contentful/skills/blob/main/SECURITY.md)
- Contentful support: [contentful.com/help](https://www.contentful.com/help/getting-started/how-to-get-help/)

## Contributors

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
  <tbody>
    <tr>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/Lp-Francois"><img src="https://avatars.githubusercontent.com/u/32224751?v=4?s=100" width="100px;" alt="François"/><br /><sub><b>François</b></sub></a><br /><a href="https://github.com/contentful/skills/commits?author=Lp-Francois" title="Code">💻</a></td>
      <td align="center" valign="top" width="14.28%"><a href="https://github.com/TimBeyer"><img src="https://avatars.githubusercontent.com/u/2362075?v=4?s=100" width="100px;" alt="Tim Beyer"/><br /><sub><b>Tim Beyer</b></sub></a><br /><a href="https://github.com/contentful/skills/commits?author=TimBeyer" title="Code">💻</a></td>
    </tr>
  </tbody>
</table>

<!-- markdownlint-restore -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

## License

MIT — see [LICENSE](https://github.com/contentful/skills/blob/main/LICENSE) for details.

---

<!-- chapter:begin slug=optimization-sdk-sync position=1 -->

## 1. optimization-sdk-sync

- **Source:** https://github.com/contentful/skills/blob/main/local-skills/skills/optimization-sdk-sync/SKILL.md
- **Raw:** https://raw.githubusercontent.com/contentful/skills/main/local-skills/skills/optimization-sdk-sync/SKILL.md
- **Markdown:** https://skillsdocs.com/contentful/skills/optimization-sdk-sync.md
- **Licence:** MIT — https://spdx.org/licenses/MIT.html

Bundled files (1), referenced from this skill's directory:
  - `package.json` — https://raw.githubusercontent.com/contentful/skills/main/local-skills/skills/optimization-sdk-sync/package.json

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: optimization-sdk-sync
description: Synchronize the Contentful Optimization SDK's public API, behavior, and implementation guidance into concise, runtime-specific references for the contentful-personalization skill. Use when the optimization repository or SDK documentation changes, when modern SDK guidance appears stale, or when validating that the skill matches an immutable upstream revision.
---

# Optimization SDK Sync

Update the modern Optimization SDK knowledge in `contentful-personalization` from a verified upstream revision. Optimize the result for an agent solving implementation tasks: concise, explicit, runtime-specific, and grounded in public API and maintained examples.

Do not copy upstream guides wholesale. Treat this as a knowledge compilation workflow.

## Scope

This skill owns modern `@contentful/optimization*` guidance. Preserve legacy `@ninetailed/*` guidance unless upstream evidence requires a compatibility correction.

Supported runtime references:

- shared concepts and behavior
- React Web
- Next.js App Router
- Next.js Pages Router
- browser Web
- Node.js
- React Native

Do not synthesize iOS or Android guidance until upstream provides equivalent knowledge-base facts, public API declarations, and guide blueprints.

## Source resolution

Use the public repository by default:

```text
https://github.com/contentful/optimization.git
```

Resolve sources in this order:

1. An explicit local path supplied by the user.
2. An existing reusable clone at `.docs/optimization-sdk-sync/repository`.
3. A fresh clone of the official HTTPS repository into that cache.

The cache is repo-local working state for the sync process. It is not committed or distributed.
Reusing it avoids cloning the public repository on every run while still allowing the skill to
fetch and inspect an exact upstream commit.

For the default remote flow:

1. Inspect the managed cache's origin and worktree status before checkout.
2. Verify `origin` is exactly the official HTTPS repository before fetching.
3. If the origin differs or the cache has local changes, do not repoint, reset, delete, or clean it.
   Stop and report the conflict, or use a separately approved clean cache.
4. Fetch the requested ref, defaulting to `main`.
5. Resolve it to a full immutable commit SHA.
6. Inspect a detached checkout of that SHA. Do not use `git pull` or merge upstream history.

For an explicit local path:

1. Resolve and record `HEAD`.
2. Record the origin URL when present.
3. If tracked or untracked files are present, treat the run as preview-only unless the user explicitly asks to use dirty state.
4. Never edit, clean, stash, reset, or otherwise mutate the source repository.

## Read repository policy first

Before interpreting upstream files, read every applicable `AGENTS.md` from the repository root down to each source directory. Follow upstream-generated-file and validation rules.

## Evidence hierarchy

Use all four evidence layers. Knowledge-base facts and types alone are not sufficient for complete agent guidance.

1. **Knowledge base** — behavioral contracts, caveats, lifecycle, architecture, platform differences, and source pointers under `documentation/internal/sdk-knowledge/`.
2. **Public exports and types** — exact import paths, names, signatures, option shapes, return values, and deprecations under `packages/`.
3. **Guide blueprints** — task coverage, prerequisite ordering, validation expectations, and troubleshooting branches under `documentation/authoring/blueprints/`.
4. **Maintained implementations and public docs** — canonical composition, file boundaries, realistic usage, edge cases, and completeness checks.

Resolve conflicts using the most authoritative source for the claim:

- exact API shape: public exports and types
- behavioral semantics: knowledge-base fact backed by its source pointer
- implementation topology: maintained first-party implementation
- task completeness: blueprint
- public wording: public docs, only after checking the layers above

Never infer an API from prose when an exported type or implementation is available.

Treat repository knowledge and guide validators as structural integrity gates. They verify pointers,
templates, links, and planned structure; they do not prove that two valid sources agree semantically.
When a knowledge fact conflicts with an exported public type, record the discrepancy and follow the
public type for downstream API guidance.

## Validate upstream inputs

From the resolved checkout, run the repository's documented dependency setup if required, then:

```bash
pnpm knowledge:check
pnpm guides:check
```

Record each result as `passed`, `failed`, or `blocked`. A sandbox, dependency, or runtime restriction
is `blocked`, not `failed`, but both are non-passing. Stop authoritative downstream writes unless
both checks pass; report the immutable SHA, command, status, and concrete failure or blocking reason.

## Determine the delta

Read `src/skills/contentful-personalization/optimization-sdk-sync.json` when it exists. Compare its previous upstream SHA with the newly resolved SHA.

Use the changed-file set to prioritize inspection, but always revalidate:

- public entry points and declarations for affected packages
- fact files that point to changed code
- affected blueprints
- maintained examples referenced by those facts or blueprints

A file delta narrows review; it never replaces the evidence hierarchy.

## Parallel execution

When sub-agents are available, use isolated ownership:

1. The coordinator resolves and validates the upstream SHA, computes the delta, and owns the
   overview, shared reference, provenance manifest, and consumer wiring.
2. Give each runtime worker only its matching knowledge file, blueprint, public entry points and
   types, linked maintained implementation, and public guide. Each worker writes one runtime file.
3. No two workers edit the same file.
4. After integration, run an independent read-only worker that source-verifies the complete pack and
   searches consumers for stale or contradictory modern guidance.

Workers must follow the same immutable SHA and evidence hierarchy. A worker's report is review
input, not a substitute for coordinator validation.

## Compile the reference pack

Write source references under `src/skills/contentful-personalization/references/`:

```text
optimization-overview.md
optimization-shared.md
optimization-react-web.md
optimization-nextjs-app-router.md
optimization-nextjs-pages-router.md
optimization-web.md
optimization-node.md
optimization-react-native.md
```

Each runtime reference should stand alone after `optimization-shared.md` is loaded. Include only what materially helps an agent implement, review, or debug that runtime:

- correct package and public import paths
- initialization and provider or factory boundaries
- minimal canonical setup
- user, consent, page or screen, event, and reset lifecycle where supported
- content fetching or prefetch behavior where supported
- server/client boundaries and request handling where relevant
- runtime-specific validation and common failure modes

The overview should route an agent to the right runtime and summarize package selection. Shared concepts belong in `optimization-shared.md`; do not repeat them in every runtime file.

Writing rules:

- Aim for at most 120 lines in the overview, 200 in shared concepts, and 300 per runtime. Exceed a
  target only when removing material would hide a public API boundary or production failure mode.
- Prefer short declarative sections and small canonical snippets.
- Use current exported names exactly.
- State unsupported behavior explicitly rather than implying parity.
- Distinguish required setup from optional integration.
- Remove historical narrative unless it prevents a migration mistake.
- Do not expose internal source-pointer syntax in distributed references.
- Do not create a second downstream blueprint system.
- Do not add repo-specific editorial overrides unless required by the consuming workflow.

## Update consumers

After compiling the pack:

1. Route modern SDK topics to the overview or a runtime-specific reference.
2. Make onboarding and development workflows load `optimization-shared.md` plus only the detected
   runtime reference or references.
3. Keep legacy SDK paths on legacy references.
4. Remove or rewrite stale modern claims in shared references so they cannot override the generated pack.
5. Keep modern product policy owned by downstream workflows; synchronize only SDK facts and implementation guidance.

## Record provenance

Update `src/skills/contentful-personalization/optimization-sdk-sync.json` with:

- schema version
- official repository URL
- resolved ref and full commit SHA
- generation timestamp in UTC
- source mode (`remote` or `local`)
- whether the source tree was dirty
- validation commands and `passed` / `failed` / `blocked` results
- generated reference paths
- upstream source paths consulted for each generated reference

Do not put machine-specific local paths in the manifest.

## Build and verify

The source tree is authoritative. Generate distribution output only after source references and workflow code are updated:

```bash
pnpm run build
pnpm run lint
pnpm run typecheck
pnpm run test
python3 local-skills/skills/skill-authoring/scripts/quick_validate.py local-skills/skills/optimization-sdk-sync
python3 local-skills/skills/skill-authoring/scripts/quick_validate.py skills/contentful-personalization
npx skills add . --list --full-depth
```

Also search the distributed skill for removed API names and obsolete import paths discovered during the sync. Review the generated diff for accidental duplication and machine-specific provenance.

Do not commit, push, or open a pull request unless the user asks.

## Completion report

Report:

- upstream repository, resolved ref, and immutable SHA
- upstream validation results
- runtimes updated or deliberately excluded
- material API or behavioral corrections
- downstream validation results
- any unresolved ambiguity, with the competing evidence named

<!-- chapter:end slug=optimization-sdk-sync -->

---

<!-- chapter:begin slug=skill-authoring position=2 -->

## 2. skill-authoring

- **Source:** https://github.com/contentful/skills/blob/main/local-skills/skills/skill-authoring/SKILL.md
- **Raw:** https://raw.githubusercontent.com/contentful/skills/main/local-skills/skills/skill-authoring/SKILL.md
- **Markdown:** https://skillsdocs.com/contentful/skills/skill-authoring.md
- **Licence:** MIT — https://spdx.org/licenses/MIT.html

Bundled files (4), referenced from this skill's directory:
  - `package.json` — https://raw.githubusercontent.com/contentful/skills/main/local-skills/skills/skill-authoring/package.json
  - `references/conventions.md` — https://raw.githubusercontent.com/contentful/skills/main/local-skills/skills/skill-authoring/references/conventions.md
  - `references/typescript-scripts.md` — https://raw.githubusercontent.com/contentful/skills/main/local-skills/skills/skill-authoring/references/typescript-scripts.md
  - `scripts/quick_validate.py` — https://raw.githubusercontent.com/contentful/skills/main/local-skills/skills/skill-authoring/scripts/quick_validate.py

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: skill-authoring
description: >-
  Create, modify, review, and fix Agent Skills in the contentful/skills repository.
  Use when creating a new skill from scratch, editing an existing SKILL.md or
  package.json, reviewing skill structure for correctness, fixing skill formatting
  or naming issues, or looking up skill conventions. Also triggers on "create a
  skill", "add a skill", "skill template", "review this skill", "fix skill
  structure", "SKILL.md format", "naming convention", "how do I make a skill",
  "how do skills work", "what is an Agent Skill", "skill description", "write a
  description", "improve description", "skill frontmatter", "skill-kit",
  "build a skill", "validate skill", "check my skill". Not for general
  development or non-skill work.
argument-hint: "[create | review | fix]"
---

# Skill Authoring

How to create, modify, and review [Agent Skills](https://agentskills.io) for the
`contentful/skills` repository.

For the full conventions document with templates, detailed rules, and examples, see
[references/conventions.md](references/conventions.md).

## What is an Agent Skill?

An Agent Skill is a directory containing a `SKILL.md` file with YAML frontmatter
and markdown instructions. It can optionally include scripts, reference documents,
and assets. The format is portable across Claude Code, Cursor, GitHub Copilot,
OpenAI Codex, Gemini CLI, and other agent platforms.

Skills use **progressive disclosure** — three tiers of context loading:

1. **Metadata** (~100 tokens): `name` and `description` fields loaded at startup
   for all installed skills. This is how the agent decides which skills are relevant.
2. **Instructions** (< 5000 tokens recommended): The full `SKILL.md` body loaded
   when the agent activates the skill.
3. **Resources** (on demand): Files in `scripts/`, `references/`, and `assets/`
   loaded only when the instructions reference them.

The `description` field is the most important piece — it's always in context and
determines whether the skill activates. Keep the `SKILL.md` body concise (under
500 lines). Heavy reference material goes in separate files.

## Repository Layout

```
skills/                         Distributed to customers (distribution boundary)
  contentful-personalization/   A skill — name field is "contentful-personalization"
    SKILL.md
    package.json
    references/
    scripts/
    bin/
.agents/skills/                 Internal contributor skills (never distributed)
  skill-authoring/
    SKILL.md
    package.json
    references/
```

`skills/` is the distribution boundary. Only its contents are installed via
`npx skills add contentful/skills`. Internal skills in `.agents/skills/` stay
in the repo. `.claude/skills` is a symlink to `.agents/skills/` for Claude Code
discovery.

## SKILL.md Format

### Required Frontmatter

| Field | Constraints |
|-------|-------------|
| `name` | 1-64 chars. Lowercase letters, numbers, hyphens only. No leading/trailing/consecutive hyphens. **Must match parent directory name.** |
| `description` | 1-1024 chars. What the skill does AND when to use it. This is the sole activation trigger — make it count. |

### Optional Frontmatter

| Field | Purpose |
|-------|---------|
| `license` | License name or reference to bundled file |
| `compatibility` | 1-500 chars. Environment requirements (e.g., "Requires Node.js 18+") |
| `metadata` | Arbitrary key-value map. Use `metadata.author` and `metadata.version`. |
| `allowed-tools` | Space-delimited pre-approved tools (experimental) |

### Claude Code Extensions

These fields are beyond the base agentskills.io spec — use for skills in this repo:

| Field | Description |
|-------|-------------|
| `disable-model-invocation` | `true` prevents auto-loading; user invokes via `/<name>` |
| `user-invocable` | `false` hides from `/` menu; Claude can still auto-load |
| `context` | `fork` runs in an isolated subagent |
| `agent` | Subagent type when `context: fork` |
| `model` | Model override when skill is active |
| `effort` | Effort level override (`low`, `medium`, `high`, `max`) |

### Body Content

Markdown after the frontmatter. No format restrictions, but recommended sections:

- Step-by-step instructions
- Examples of inputs and outputs
- Common edge cases and gotchas
- Pointers to reference files (loaded on demand)

Reference scripts and docs with relative paths from the skill root:

```markdown
Run the diagnostic:
    ${CLAUDE_SKILL_DIR}/scripts/check.sh --env production

For API details, see [references/api.md](references/api.md).
```

## Writing Effective Descriptions

The description is the **sole activation trigger**. The agent scans all installed
skills at startup and loads only `name` + `description` (~100 tokens each). The
full SKILL.md body loads only when the agent judges the skill relevant.

Write descriptions that are slightly "pushy" — it's better to activate too often
than to miss a relevant trigger.

**Best pattern:**
```
Use this skill when [explicit scenarios]. Triggers on [keyword list].
Does NOT apply to [boundary conditions].
```

**Good:**
```yaml
description: >-
  Diagnose and fix Contentful optimization and personalization issues.
  Validates configuration, SDK versions, API connectivity. Use when
  troubleshooting optimization problems, debugging personalization behavior,
  or checking why experiments aren't running. Also triggers on "why isn't
  personalization working" or "check my config". Not for initial end-to-end
  setup from scratch — that is covered by the onboard flow in the same
  `contentful-personalization` skill.
```

**Bad:**
```yaml
description: Helps with optimization issues.
```

Include:
- Imperative phrasing ("Diagnose and fix", not "A skill for diagnosing")
- Direct trigger keywords the user would naturally say
- Indirect keywords (e.g., for a deploy skill, also mention "ship", "release")
- Negative scope to prevent false activations
- Cross-references to related skills with explicit phrasing (for example, `the contentful-guide skill` for general CMS help)

## Directory Structure

### Documentation-only skill (minimum)

```
my-skill/
  SKILL.md              Required
  package.json          Required (even for docs-only)
```

### Skill with references

```
my-skill/
  SKILL.md              Required
  package.json          Required
  references/           On-demand documentation
    api.md
    patterns.md
  assets/               Templates, data files, static resources
```

### Skill with scripts

```
my-skill/
  SKILL.md              Required
  package.json          Required
  scripts/              Stable public interface (SKILL.md references these)
    check               Executable (chmod +x)
    fix                 Executable (chmod +x)
  src/                  Optional — implementation behind scripts/
    ...
  references/           On-demand documentation
```

## package.json

Required for every skill, even documentation-only. Provides versioning and
npm-compatible metadata.

**Distributed skills** (in `skills/`):
```json
{
  "name": "@contentful/skill-<domain>-<skill-name>",
  "version": "1.0.0",
  "description": "Same as SKILL.md description (short form)",
  "license": "MIT",
  "files": ["SKILL.md", "references/**", "scripts/**", "assets/**"]
}
```

**Internal skills** (in `.agents/skills/`):
```json
{
  "name": "skill-name",
  "version": "1.0.0"
}
```

Versioning happens at the package level — `metadata.version` in SKILL.md
frontmatter should mirror `package.json` version.

## Naming Conventions

| Context | Pattern | Example |
|---------|---------|---------|
| Directory name | `<domain>-<product-or-topic>`, lowercase-hyphen | `contentful-personalization` |
| `name` field | must match directory | `contentful-personalization` |
| npm package | `@contentful/skill-<skill-name>` | `@contentful/skill-contentful-personalization` |

Name validation rules: 1-64 chars, `[a-z0-9-]` only, no leading/trailing/consecutive
hyphens, must match parent directory name exactly.

Skills live in a flat structure directly under `skills/`. The name must be globally
unambiguous (not just `readiness`) — the domain prefix makes this possible while
remaining compatible with the agentskills.io spec.

## Script Conventions

### The key pattern

`scripts/` is the skill's **stable public interface**. SKILL.md references
only `scripts/<name>`, never internal paths.

Scripts can be anything executable: bash, Python, compiled binaries, Node.js,
etc. The only requirement is that they are executable (`chmod +x`) and follow
the design rules below.

**Simple skills** — executables directly in `scripts/`:

```
contentful-personalization/
  scripts/
    run                 Entry script (chmod +x) or thin wrapper
```

**Complex skills** — wrappers in `scripts/` delegate to an implementation
directory (e.g., `src/`, `bin/`):

```
my-code-skill/
  scripts/
    check                 Thin wrapper → delegates to src/ or bin/
  src/                    Optional — TypeScript source for skill-kit builds
    ...
  bin/                    Optional — compiled output
```

The wrapper decouples the skill's contract from its implementation. You can
refactor `src/` freely without updating SKILL.md. SKILL.md never references
`src/` paths — only `scripts/<name>`.

### Wrapper example

A wrapper is a thin executable that delegates to the real implementation:

```bash
#!/usr/bin/env bash
exec node "$(dirname "$0")/../src/check.js" "$@"
```

Make wrappers executable: `chmod +x scripts/check`

For a complete TypeScript project setup (tsconfig, src/ layout, dependencies,
testing), see [references/typescript-scripts.md](references/typescript-scripts.md).

### Script design rules

Scripts are invoked by agents in non-interactive shells. Design them so the
agent can read stdout/stderr and decide what to do next.

**Hard requirements:**
- **Non-interactive**: no TTY prompts, password dialogs, or confirmation menus.
  All input via flags, env vars, or stdin.
- **`--help` / `-h`**: print usage to stderr, exit 0. This is the primary way
  an agent learns the script's interface.
- **JSON to stdout**: this is what the agent consumes. Never mix data and
  diagnostics on the same stream.
- **Non-zero exit on failure** with a descriptive error message to stderr.
  Say what went wrong, what was expected, and what to try.

**Best practices:**
- **Idempotent** where possible — agents may retry
- **`--dry-run`** for destructive operations
- **`--long-name`** flags (no single-letter flags except `-h`)
- **Predictable output size**: many agent harnesses truncate beyond 10-30K chars.
  Default to summaries; support `--limit`/`--offset` for pagination.
- **Safe defaults**: destructive operations require explicit `--confirm` or `--force`

For output patterns, exit code conventions, and `--help` templates, see
[references/conventions.md](references/conventions.md).

## Cross-Skill References

Use explicit phrasing in SKILL.md body to reference related skills:

```markdown
For personalization, use the contentful-personalization skill. Its onboard
flow covers readiness and SDK install; the doctor flow covers troubleshooting.
For "which API should I use", use the contentful-guide skill.
```

This is a documentation convention for the agent — no runtime enforcement.

## Independence Rule

- No cross-skill imports — each skill is independently packageable
- The `skills/` directory is the distribution boundary
- Shared code becomes a separate npm package
- Each skill directory must be fully self-contained

## Creating a New Skill

### Checklist

1. Choose the right location:
   - Customer-facing skill → `skills/<skill-name>/` (flat, one directory per skill)
   - Internal contributor skill → `.agents/skills/<skill-name>/`

2. Create the directory with the skill name as directory name

3. Write `SKILL.md`:
   - Add frontmatter with `name` (matching directory) and `description`
   - Write the body with clear instructions, examples, edge cases
   - Keep under 500 lines — move heavy content to `references/`

4. Write `package.json`:
   - Distributed: `@contentful/skill-<domain>-<name>`, version, files array
   - Internal: just name and version

5. Add supporting files as needed:
   - `references/` for on-demand documentation
   - `scripts/` for executable code
   - `assets/` for templates and static resources

6. Verify discovery: `npx skills add . --list --full-depth`

7. Update `README.md` if it's a distributed skill

## Reviewing an Existing Skill

### Checklist

- [ ] `name` field matches parent directory name exactly
- [ ] `description` is 1-1024 chars, specific about triggers and scope
- [ ] `description` includes negative scope ("Not for X")
- [ ] SKILL.md body is under 500 lines
- [ ] Heavy content is in `references/`, not inline
- [ ] `package.json` exists with name and version
- [ ] For distributed skills: package name follows `@contentful/skill-<domain>-<name>`
- [ ] Scripts are non-interactive with `--help` support
- [ ] No cross-skill imports — skill is self-contained
- [ ] Reference file paths are relative from skill root

## Improving a Description

If a skill isn't triggering when it should (or triggers when it shouldn't):

1. Check that the description includes the keywords users actually say
2. Add indirect triggers (synonyms, related phrases)
3. Add negative scope to prevent false activations
4. Make the description slightly "pushy" — better to over-trigger
5. Test by asking the agent varied prompts and checking if the skill activates

For automated description optimization with evals, see
[Anthropic's skill-creator](https://github.com/anthropics/skills/tree/main/skills/skill-creator).

<!-- chapter:end slug=skill-authoring -->

---

<!-- chapter:begin slug=contentful-api position=3 -->

## 3. contentful-api

- **Source:** https://github.com/contentful/skills/blob/main/skills/contentful-api/SKILL.md
- **Raw:** https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/SKILL.md
- **Markdown:** https://skillsdocs.com/contentful/skills/contentful-api.md
- **Licence:** MIT — https://spdx.org/licenses/MIT.html

Bundled files (17), referenced from this skill's directory:
  - `package.json` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/package.json
  - `references/authentication.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/authentication.md
  - `references/content-delivery/includes-links.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-delivery/includes-links.md
  - `references/content-delivery/localization.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-delivery/localization.md
  - `references/content-delivery/overview.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-delivery/overview.md
  - `references/content-delivery/querying.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-delivery/querying.md
  - `references/content-delivery/sync.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-delivery/sync.md
  - `references/content-management/assets.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-management/assets.md
  - `references/content-management/bulk-actions.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-management/bulk-actions.md
  - `references/content-management/content-types.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-management/content-types.md
  - `references/content-management/entries.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-management/entries.md
  - `references/content-management/environments.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-management/environments.md
  - `references/content-management/overview.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-management/overview.md
  - `references/content-preview/overview.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/content-preview/overview.md
  - `references/graphql/overview.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/graphql/overview.md
  - `references/http-conventions.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/http-conventions.md
  - `references/images/overview.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-api/references/images/overview.md

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: contentful-api
description: Comprehensive Contentful REST API guide. Covers Content Management API (CMA) for creating/updating content, Content Delivery API (CDA) for fetching published content, Preview API, Images API, and GraphQL API. All examples use curl/HTTP — language-agnostic.
---

# Contentful REST API Guide

Language-agnostic guide for Contentful APIs using HTTP/curl.

## Shared References

- **[Authentication](references/authentication.md)** — Token types, auth headers, API base URLs (US/EU)
- **[HTTP Conventions](references/http-conventions.md)** — Version locking, rate limits, pagination, errors, locale structure

## Content Management API (CMA)

Read/write API for managing content, content types, assets, and environments.

**Start here**: [references/content-management/overview.md](references/content-management/overview.md)

- [**entries.md**](references/content-management/entries.md) — CRUD, publish/unpublish, versioning, query parameters
- [**content-types.md**](references/content-management/content-types.md) — Define/update content models, field types, validations
- [**assets.md**](references/content-management/assets.md) — Upload, process, publish media files
- [**environments.md**](references/content-management/environments.md) — Create, clone, manage environments and aliases

## Content Delivery API (CDA)

Read-only API for fetching published content.

**Start here**: [references/content-delivery/overview.md](references/content-delivery/overview.md)

- [**querying.md**](references/content-delivery/querying.md) — Filters, search operators, pagination, ordering
- [**includes-links.md**](references/content-delivery/includes-links.md) — Include parameter, link resolution
- [**localization.md**](references/content-delivery/localization.md) — Locale parameter, fallback chains
- [**sync.md**](references/content-delivery/sync.md) — Incremental content synchronization

## Content Preview API

Draft + published content via same CDA endpoints, different host/token.

**Reference**: [references/content-preview/overview.md](references/content-preview/overview.md)

## Images API

On-the-fly image transformations via URL parameters. No authentication needed.

**Reference**: [references/images/overview.md](references/images/overview.md)

## GraphQL API

Query content via GraphQL with CDA tokens.

**Reference**: [references/graphql/overview.md](references/graphql/overview.md)

## Quick Reference

```bash
# CMA: Create a draft entry
curl -X POST https://api.contentful.com/spaces/{space_id}/environments/{env_id}/entries \
  -H "Authorization: Bearer {cma_token}" \
  -H "Content-Type: application/vnd.contentful.management.v1+json" \
  -H "X-Contentful-Content-Type: blogPost" \
  -d '{"fields":{"title":{"en-US":"Hello"}}}'
# Then publish: PUT .../entries/{id}/published with X-Contentful-Version header

# CDA: Fetch entries
curl "https://cdn.contentful.com/spaces/{space_id}/environments/{env_id}/entries?content_type=blogPost" \
  -H "Authorization: Bearer {cda_token}"
```

<!-- chapter:end slug=contentful-api -->

---

<!-- chapter:begin slug=contentful-custom-app-enhancement position=4 -->

## 4. contentful-custom-app-enhancement

- **Source:** https://github.com/contentful/skills/blob/main/skills/contentful-apps/contentful-custom-app-enhancement/SKILL.md
- **Raw:** https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-apps/contentful-custom-app-enhancement/SKILL.md
- **Markdown:** https://skillsdocs.com/contentful/skills/contentful-custom-app-enhancement.md
- **Licence:** MIT — https://spdx.org/licenses/MIT.html

Bundled files (2), referenced from this skill's directory:
  - `package.json` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-apps/contentful-custom-app-enhancement/package.json
  - `references/enhancement-checklist.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-apps/contentful-custom-app-enhancement/references/enhancement-checklist.md

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: contentful-custom-app-enhancement
description: >-
  Improve, debug, and extend an existing Contentful App Framework custom app in
  a customer's own repository. Use when users provide a bug report, feature
  request, support note, customer feedback, or direct change request for an
  existing custom app, including app configuration, sidebar, field editor,
  dialog, page, home, App Action, Function, installation parameters, local
  validation, or PR preparation. Also triggers on "fix my Contentful app",
  "improve a custom app", "enhance App Framework app", "debug custom app",
  "update sidebar app", and "custom app feature request". Not for creating a
  brand new app from scratch (contentful-custom-app-from-scratch), generic API
  examples (contentful-api), migrations (contentful-migration), or website
  integration (contentful-nextjs).
license: MIT
metadata:
  author: contentful
  version: "2.0.0"
allowed-tools: mcp__contentful-mcp__* mcp__plugin_contentful_contentful-mcp__*
---

# Contentful Custom App Enhancement

Use this skill to turn a bug report, support note, or feature request into a
small, reviewable improvement for an existing Contentful custom app.

Default to the user's app repository and workflow. Do not assume a specific
repository convention, publication process, or review policy unless the user
provides one.

When a comparable public Contentful Marketplace app or example in Contentful's
public apps repository (`https://github.com/contentful/apps`) exists, use it as
a best practice reference for App Framework patterns and UX polish without
inheriting its release or distribution workflow.

## Inputs

Accept:

- bug reports,
- customer or editor feedback,
- support tickets or issue links,
- screenshots or screen recordings,
- direct requests to change a known custom app,
- partial notes about an App Framework behavior.

If the source material is incomplete, continue with local code and provided
context when the risk is low. Ask a targeted question when the missing answer
could change the user-facing behavior, data writes, authentication, or
deployment path.

## Workflow

### 1. Build the Request Context

Identify:

- original request and affected users,
- current app behavior versus expected behavior,
- Contentful location and workflow affected,
- space, environment, content type, field, locale, and role assumptions,
- external service or credential dependencies,
- evidence available locally and evidence still missing.

Separate confirmed facts from assumptions.

### 2. Inspect the Existing App

Before editing:

- check repository status and avoid overwriting user changes,
- inspect `package.json`, scripts, lockfile, and framework conventions,
- locate the relevant app locations and SDK usage,
- review existing tests and nearby components,
- identify app definition, installation parameters, and deployment notes if they
  exist,
- confirm whether the app uses App SDK, React Apps Toolkit, Forma 36,
  contentful-management, App Actions, Functions, or an external backend.

For a reusable checklist, use
[Enhancement checklist](references/enhancement-checklist.md).

### 3. Decide Whether the Change Is Small Enough

Proceed with implementation when the change can plausibly be:

- scoped to one app,
- explained in one short PR,
- validated locally or in a sandbox,
- reviewed without broad product redesign,
- implemented without risky migrations or secret-handling changes.

Pause and clarify when the request requires:

- production data changes,
- a new external auth model,
- major content model redesign,
- multi-app coordination,
- new backend infrastructure,
- unavailable Function or plan capabilities,
- ambiguous editor behavior.

### 4. Plan the Smallest Useful Change

Write a short plan before editing:

- files or app locations likely to change,
- data read/write behavior,
- UI and validation updates,
- tests or manual verification to run,
- risks and rollback path.

Prefer improving the existing flow over replacing it.

### 5. Implement in the App's Existing Style

- Reuse current framework, routing, hooks, components, and package manager.
- Keep TypeScript precise and avoid broad `any` types.
- Use Forma 36 for Contentful web app UI unless the app already uses another
  deliberate design system.
- Preserve editor trust: show loading, empty, error, permission, and destructive
  action states when relevant.
- Keep configuration UI explicit about what values are stored at installation
  versus instance scope.
- Treat non-secret parameters as readable by space members.
- When runtime locations need installation parameters, prefer
  `sdk.parameters.installation`. Do not add or preserve CMA app-installation
  reads in sidebar, field editor, entry editor, page, dialog, home, mount
  effects, render paths, or click handlers just to retrieve app configuration.
- Do not expose tokens or private credentials in client code.
- Keep changes narrow; avoid unrelated formatting, dependency churn, or
  refactors.

### 6. Validate the Improvement

Run the closest available validation:

- targeted unit or component tests,
- typecheck,
- lint or formatter check,
- production build,
- local dev server smoke test,
- Contentful web app manual flow in a non-production space,
- grep or ripgrep for `appInstallation.getForOrganization`,
  `appInstallation.get`, and `getForOrganization` when installation-parameter
  access is touched, confirming runtime config reads use
  `sdk.parameters.installation` or documenting why a CMA app-installation call
  remains,
- App Action, Function, or backend endpoint test when the change touches
  server-side behavior.

When validation requires credentials or access the agent does not have, explain
exactly what remains for the user to verify.

### 7. Prepare Reviewable Output

If the user wants a commit or PR:

- create a focused branch using the user's repo convention when known,
- keep commits small and conventional,
- do not stage unrelated local files,
- include request context, implementation summary, validation, and open
  questions in the PR draft.

If the user only asked for the fix, end with:

- context,
- assessment,
- implementation summary,
- validation,
- remaining risks or follow-up.

## Guardrails

- Do not force a code change when the better answer is product clarification.
- Do not overfit one vague report without saying what is uncertain.
- Do not widen the scope into a rewrite unless the user asks.
- Do not assume app users have publication or distribution requirements unless
  they say so.
- Do not claim Contentful plan features, SDK behavior, or API limits from memory
  when current official docs should be checked.

## Related Skills

- `contentful-custom-app-from-scratch` - design and build a new custom app.
- `contentful-api` - concrete REST and GraphQL API examples.
- `contentful-migration` - content model migration scripts.
- `contentful-guide` - Contentful concepts and API routing.

<!-- chapter:end slug=contentful-custom-app-enhancement -->

---

<!-- chapter:begin slug=contentful-custom-app-from-scratch position=5 -->

## 5. contentful-custom-app-from-scratch

- **Source:** https://github.com/contentful/skills/blob/main/skills/contentful-apps/contentful-custom-app-from-scratch/SKILL.md
- **Raw:** https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-apps/contentful-custom-app-from-scratch/SKILL.md
- **Markdown:** https://skillsdocs.com/contentful/skills/contentful-custom-app-from-scratch.md
- **Licence:** MIT — https://spdx.org/licenses/MIT.html

Bundled files (3), referenced from this skill's directory:
  - `package.json` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-apps/contentful-custom-app-from-scratch/package.json
  - `references/app-planning.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-apps/contentful-custom-app-from-scratch/references/app-planning.md
  - `references/repo-and-validation.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-apps/contentful-custom-app-from-scratch/references/repo-and-validation.md

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: contentful-custom-app-from-scratch
description: >-
  Design, scaffold, build, and validate a new Contentful App Framework custom
  app for a customer's own repository or workspace. Use when users want to
  create a custom app from an idea, choose App Framework locations, build a
  sidebar app, field editor app, page app, dialog, configuration screen, App
  Action, or Function-backed app, scaffold with create-contentful-app, or make a
  locally testable app for an organization-specific Contentful workflow. Also
  triggers on "build a Contentful app", "custom app from scratch", "App
  Framework app", "sidebar app", "field editor app", "page app", "app action",
  and "app function". Not for generic Contentful API examples (contentful-api),
  content model migrations (contentful-migration), or website integration
  (contentful-nextjs).
license: MIT
metadata:
  author: contentful
  version: "2.0.0"
allowed-tools: mcp__contentful-mcp__* mcp__plugin_contentful_contentful-mcp__*
---

# Contentful Custom App From Scratch

Use this skill to turn a customer app idea into a small, locally testable
Contentful App Framework implementation.

Default to the user's own repository, Contentful organization, and app delivery
workflow unless they explicitly choose another destination.

Public Contentful Marketplace apps and Contentful's public apps repository
(`https://github.com/contentful/apps`) can be useful references for mature App
Framework patterns, UX conventions, and configuration flows. Use them as
examples to adapt, not as required repo structure or publication process.

## Working Style

- Start with the app's job, primary users, affected content model, and target
  Contentful surface before writing code.
- Ask only for information that changes the architecture or prevents a wrong
  build.
- Prefer the smallest version that proves the value in a non-production space.
- Ground capability decisions in official App Framework docs and the current
  project structure.
- Keep user-owned secrets, tokens, and production content out of generated code,
  logs, and examples.

## Workflow

### 1. Create the Implementation Brief

Capture a short brief before scaffolding:

- app concept in one sentence,
- target users and the workflow they need to improve,
- Contentful locations needed for v1,
- content types, fields, locales, and environments involved,
- external systems, authentication, or APIs involved,
- expected installation and configuration model,
- must-have v1 behavior,
- assumptions and non-goals,
- validation plan for local and sandbox testing.

If the idea is still broad, propose 2-3 feasible v1 options and recommend the
smallest useful one.

For planning details, use [App planning](references/app-planning.md).

### 2. Choose the App Shape

Choose locations by user workflow:

- Use `app-config` when the app needs installation-time setup.
- Use `entry-sidebar` for entry-level context, status, helper actions, and
  lightweight insights.
- Use `entry-field` to replace or enhance a field's editing experience.
- Use `dialog` for focused picker, confirmation, or multi-step flows launched
  from another location.
- Use `page` or `home` for dashboards, bulk tools, onboarding, or full-screen
  operational workflows.
- Use `entry-editor` only when replacing or heavily extending the full entry
  editing experience is worth the maintenance cost.
- Use App Actions or Functions only when the app needs asynchronous behavior,
  server-side execution, verified inbound requests, event handling, or access to
  secret values outside the browser.

If sensitive credentials are required, model them as secret installation
parameters and consume raw values only in a backend or Function-backed path.

### 3. Inspect or Scaffold the Project

If the user already has a repo:

1. Inspect `package.json`, app-related docs, existing app locations, build
   scripts, tests, and style conventions.
2. Reuse the repo's framework, package manager, lint/test setup, and component
   patterns.
3. Identify whether the app already uses `@contentful/app-sdk`,
   `@contentful/react-apps-toolkit`, `@contentful/f36-components`, or
   `contentful-management`.

If the user does not have a repo:

1. Scaffold with `npx create-contentful-app@latest <app-name>`.
2. Prefer TypeScript unless the user requests JavaScript.
3. Keep the first scaffold close to the generated project until the local app is
   wired into Contentful and verified.

### 4. Build in Contentful-Native Style

- Use the App SDK or React Apps Toolkit to access the current location SDK.
- Use Forma 36 components for Contentful web app UI. Always check if Forma 36 has a similar component before attempting to build something custom.
- Keep UI dense, clear, and editor-friendly; avoid marketing layouts inside the
  Contentful web app.
- Include loading, empty, permission, and error states when they affect the main
  workflow.
- Keep field and entry writes explicit, reversible where possible, and easy for
  editors to understand.
- When runtime locations need app configuration, read installation parameters
  from `sdk.parameters.installation`. Do not fetch app installation records
  through CMA from mount effects, render paths, hooks, or user interactions just
  to retrieve configured parameters.
- Avoid broad abstractions until the app has more than one real usage path.
- Do not expose management tokens, API keys, or third-party credentials in
  browser code.

### 5. Wire the Local App into Contentful

Create or update the app definition in a development organization or sandbox:

- set the frontend URL to the local dev server, commonly
  `http://localhost:3000`,
- select only the locations implemented in v1,
- define required installation or instance parameters,
- install the app into a non-production space or environment,
- assign the app to the relevant content types, fields, sidebar, home page, or
  page location,
- seed minimal test content when needed.

For local test and handoff steps, use
[Repository and validation](references/repo-and-validation.md).

### 6. Verify Before Handoff

Run the closest meaningful checks available in the user's project:

- package install check when dependencies changed,
- typecheck and lint,
- unit or component tests,
- production build,
- local dev server smoke test,
- manual Contentful web app flow in a non-production space.
- `rg -n "appInstallation\\.(getForOrganization|get)\\(|getForOrganization"`
  over the app source when runtime code reads installation parameters, with any
  remaining CMA app-installation call explained.

Do not claim the app works unless you ran the relevant validation or clearly
state what could not be run.

### 7. Hand Off the Result

End with:

- what was built,
- how to run it locally,
- how to install or assign it in Contentful,
- validation performed,
- remaining assumptions, limitations, or credentials needed,
- suggested next iteration.

## Related Skills

- `contentful-custom-app-enhancement` - improve or debug an existing custom app.
- `contentful-api` - concrete CMA, CDA, CPA, Images API, and GraphQL examples.
- `contentful-migration` - content model migration scripts.
- `contentful-guide` - Contentful concepts and API routing.

<!-- chapter:end slug=contentful-custom-app-from-scratch -->

---

<!-- chapter:begin slug=contentful-guide position=6 -->

## 6. contentful-guide

- **Source:** https://github.com/contentful/skills/blob/main/skills/contentful-guide/SKILL.md
- **Raw:** https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-guide/SKILL.md
- **Markdown:** https://skillsdocs.com/contentful/skills/contentful-guide.md
- **Licence:** MIT — https://spdx.org/licenses/MIT.html

Bundled files (4), referenced from this skill's directory:
  - `package.json` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-guide/package.json
  - `references/docs-map.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-guide/references/docs-map.md
  - `references/lexicon.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-guide/references/lexicon.md
  - `references/skill-routing.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-guide/references/skill-routing.md

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: contentful-guide
description: >-
  Explain core Contentful concepts and route users to the right implementation
  skill or documentation. Use when users ask conceptual questions, need
  terminology clarified, want help choosing between APIs (CDA/CMA/CPA/GraphQL),
  or need guidance on the Contentful MCP server. Also triggers on "Contentful
  101", "which Contentful API", "how do I get started", "which skill should I
  use", "what does X mean in Contentful", "Contentful glossary", "CDA vs CPA",
  "CDA vs GraphQL", "how does Contentful work", "Contentful architecture",
  "explain environments", "what are aliases", "content model design",
  "headless CMS", "Contentful MCP", "MCP server", "set up MCP",
  "Remix Contentful", "Astro Contentful", "Gatsby Contentful",
  "SvelteKit Contentful", "Nuxt Contentful". Not for framework-specific
  implementation (contentful-nextjs), migrations (contentful-migration),
  personalization (contentful-personalization), or hands-on REST/GraphQL
  request examples (contentful-api).
argument-hint: "[concept or API name]"
allowed-tools: mcp__contentful-mcp__* mcp__plugin_contentful_contentful-mcp__*
---

# Contentful Guide

Use this skill as the routing and vocabulary layer for Contentful tasks.

Contentful is a headless, API-first CMS (composable content platform) where teams model content once and deliver it to many channels.

## What this skill does

1. Clarifies core terms (space, environment, environment alias, content model, content type, entry, asset, locale).
2. Maps user intent to the right API (CDA, CPA, CMA, GraphQL, Images API).
3. Routes implementation requests to the right skill and docs.
4. Prevents incorrect setup by identifying when a request is not in this skill's scope.

## Routing rules

- If the user asks to add Contentful to a Next.js project, use the contentful-nextjs skill.
- If the user asks about optimization/personalization/analytics setup or debugging, route to the `contentful-personalization` skill.
- If the user asks to write content type migrations or schema changes, route to the `contentful-migration` skill.
- If the user asks for concrete REST/GraphQL requests (curl examples, headers, query parameters, payload shapes for CMA/CDA/CPA/Images/GraphQL), route to the `contentful-api` skill.
- If the user asks for conceptual guidance, architecture tradeoffs, or where to read docs, stay in this skill.
- If the user asks about environment aliases and deployment workflows, stay in this skill unless they also ask for framework implementation.

## API chooser

- Use **CDA** for published delivery content in websites/apps.
- Use **CPA** for unpublished preview content.
- Use **CMA** for write operations (create/update/manage content and models).
- Use **GraphQL Content API** when query shape control is preferred over REST payloads.
- Use **Images API** for image transformations.

## Contentful MCP note

- The Contentful MCP server is often the easiest way to let an agent interact with Contentful.
- Use it when the user wants conversational access to spaces, entries, and content model context without wiring SDK code first.
- Canonical docs: `https://www.contentful.com/developers/docs/tools/mcp-server/`

## Operating pattern

When answering with this skill:

1. Define terms using shared vocabulary from `references/lexicon.md`.
2. Pick the right docs path from `references/docs-map.md`.
3. If implementation is requested, hand off using `references/skill-routing.md`.
4. Keep answers concise and cite canonical docs paths.

## Guardrails

- Do not invent product capabilities, API behavior, or limits.
- Do not provide framework code unless routing to the specialized implementation skill.
- Prefer official docs over memory when details may be version-sensitive.

## References

- [Lexicon](references/lexicon.md)
- [Docs map](references/docs-map.md)
- [Skill routing](references/skill-routing.md)

<!-- chapter:end slug=contentful-guide -->

---

<!-- chapter:begin slug=contentful-migration position=7 -->

## 7. contentful-migration

- **Source:** https://github.com/contentful/skills/blob/main/skills/contentful-migration/SKILL.md
- **Raw:** https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-migration/SKILL.md
- **Markdown:** https://skillsdocs.com/contentful/skills/contentful-migration.md
- **Licence:** MIT — https://spdx.org/licenses/MIT.html

Bundled files (4), referenced from this skill's directory:
  - `package.json` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-migration/package.json
  - `references/api-reference.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-migration/references/api-reference.md
  - `references/patterns.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-migration/references/patterns.md
  - `references/running-migrations.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-migration/references/running-migrations.md

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: contentful-migration
description: >-
  Write and run Contentful content model migration scripts using the
  contentful-migration library and the Contentful CLI. Covers creating,
  editing, and deleting content types and fields, validations, editor interface
  configuration, editor layouts, sidebar widgets, entry transformations, tags,
  annotations, and the migration context object. Use when asked to write a
  migration, create or add a content type, add, rename, or delete fields,
  change or update a content model, transform entries, derive linked entries,
  configure editor controls, or run a migration script. Also triggers on
  "migration script", "contentful-migration", "schema migration",
  "content model migration", "field validation", "editor interface",
  "editor layout", "sidebar widget", "moveField", "changeFieldId",
  "rich text field", "reference field", "link field". Not for SDK client
  setup or Next.js integration (contentful-nextjs). Not for Contentful
  terminology or API routing (contentful-guide).
license: MIT
argument-hint: "[task description]"
allowed-tools: Bash(npx contentful-migration *) Bash(npx contentful space migration *) mcp__contentful-mcp__* mcp__plugin_contentful_contentful-mcp__*
paths: "migrations/**"
---

# Contentful Migration

The `contentful-migration` tool lets you describe and execute content model changes as code. Migrations are TypeScript scripts that create, edit, or delete content types, fields, editor interfaces, and entries.

**Install:**

```bash
npm install contentful-migration
```

GitHub: https://github.com/contentful/contentful-migration

## Scope

This skill covers:
- Content type and field CRUD operations
- Field types, validations, and editor interface configuration
- Entry transformations (in-place transforms, deriving linked entries, cross-type transforms)
- Tags, annotations, taxonomy validations
- Editor layouts, sidebar widgets
- Running migrations via `npx contentful space migration` (Contentful CLI) and programmatic API

Do not run migrations with `npx contentful-migration`. Use `contentful-cli` for CLI execution, install it as a dev dependency when needed, and run via `npx contentful ...`.

Not covered: SDK client setup (the contentful-nextjs skill), Contentful concepts and API routing (the contentful-guide skill).

## Contentful MCP note

- For users who want easier agent interaction with Contentful while planning or reviewing migrations, point them to the Contentful MCP server docs: `https://www.contentful.com/developers/docs/tools/mcp-server/`.
- Continue to use `contentful-migration` scripts and `contentful-cli` for actual migration execution.

## Migration Script Format

Every migration file exports a function that receives a `migration` object:

```typescript
import type { MigrationFunction } from 'contentful-migration'

const migration: MigrationFunction = (migration) => {
  const blogPost = migration.createContentType('blogPost', {
    name: 'Blog Post',
    description: 'A blog post entry',
    displayField: 'title',
  })

  blogPost.createField('title')
    .name('Title')
    .type('Symbol')
    .required(true)
}

export = migration
```

The function also receives a `context` object as its second parameter, providing `makeRequest` (direct CMA access), `spaceId`, and `accessToken`. Use `makeRequest` when you need data not available through the migration API.

## Project state

```!
echo "=== Existing migrations ===" && ls migrations/ 2>/dev/null || echo "(no migrations/ directory found)"
echo ""
echo "=== Contentful env vars ===" && grep -h CONTENTFUL .env .env.local 2>/dev/null | sed 's/=.*/=<set>/' || echo "(no Contentful env vars found in .env or .env.local)"
```

## Workflow

When writing a migration:

1. **Confirm required env vars first.** If values are missing, ask the user to add them to a local `.env` file before proceeding.
2. **Assess the change.** Identify which content types and fields need to change. Check the current content model in the Contentful web app or via CMA.
3. **Write the migration script.** Use the operations below. Prefer chaining over object notation — it gives better error messages with line numbers.
4. **Test in a sandbox environment.** Never run untested migrations against production. Create a sandbox environment first: `contentful environment create --name sandbox --source master`.
5. **Run the migration.** See [Running Migrations](references/running-migrations.md) for CLI and programmatic options.
6. **Verify.** Check the content model in the web app. Confirm entries are intact.

## Required environment variables

- `CONTENTFUL_SPACE_ID` - Space ID. Find it in the Contentful web app URL (`/spaces/<SPACE_ID>/...`) or in **Space settings -> API keys**.
- `CONTENTFUL_MANAGEMENT_ACCESS_TOKEN` - CMA token used for migrations. Create it in **Account settings -> CMA tokens** (`https://app.contentful.com/account/profile/cma_tokens`) or from a space-scoped CMA tokens page (`https://app.contentful.com/spaces/<SPACE_ID>/api/cma_tokens`).
- `CONTENTFUL_ENVIRONMENT_ID` (optional) - Target environment ID (for example `master` or `sandbox`) when you want to avoid passing `--environment-id`.

If any required value is missing, explicitly ask the user for the missing values and tell them where to find each one.

## Content Type Operations

**Create a content type:**

```typescript
const page = migration.createContentType('page', {
  name: 'Page',
  description: 'A generic page',
  displayField: 'title',
})
```

**Edit an existing content type:**

```typescript
const page = migration.editContentType('page')
page.description('Updated description')
page.displayField('internalName')
```

**Delete a content type:**

```typescript
migration.deleteContentType('page')
```

Content type must have zero entries before deletion. Delete all entries first, or use `transformEntriesToType` to move them.

## Field Operations

**Create a field:**

```typescript
page.createField('title')
  .name('Title')
  .type('Symbol')
  .required(true)
  .localized(true)
```

**Edit an existing field:**

```typescript
page.editField('title')
  .name('Page Title')
  .required(false)
```

**Delete a field:**

```typescript
page.deleteField('legacyField')
```

Deleting a field permanently removes its content from all entries.

**Change a field ID:**

```typescript
page.changeFieldId('oldName', 'newName')
```

Existing content is preserved — only the ID changes.

**Move a field:**

```typescript
page.moveField('slug').afterField('title')
page.moveField('featured').toTheTop()
page.moveField('metadata').toTheBottom()
page.moveField('author').beforeField('publishDate')
```

## Field Types Quick Reference

| Type | Description | Extra config |
|------|-------------|--------------|
| `Symbol` | Short text (max 256 chars) | — |
| `Text` | Long text (max 50,000 chars) | — |
| `Integer` | Whole number | — |
| `Number` | Decimal number | — |
| `Date` | ISO 8601 date/time | — |
| `Boolean` | True/false | — |
| `Object` | Arbitrary JSON | — |
| `Location` | Lat/lon coordinates | — |
| `RichText` | Structured rich text | `enabledNodeTypes`, `enabledMarks` validations |
| `Array` | List of values or references | Requires `items`: `{ type, linkType?, validations? }` |
| `Link` | Single reference | Requires `linkType`: `'Asset'` or `'Entry'` |
| `ResourceLink` | Cross-space reference | Requires `allowedResources` |

See [API Reference — Field Types](references/api-reference.md#field-types) for full configuration details.

## Validations Quick Reference

| Validation | Applies to | Example |
|------------|-----------|---------|
| `in` | Symbol, Integer, Number | `{ in: ['draft', 'published', 'archived'] }` |
| `unique` | Symbol, Integer, Number | `{ unique: true }` |
| `size` | Array, Text, Symbol | `{ size: { min: 1, max: 5 } }` |
| `range` | Integer, Number | `{ range: { min: 0, max: 100 } }` |
| `regexp` | Symbol, Text | `{ regexp: { pattern: '^[a-z0-9-]+$' } }` |
| `dateRange` | Date | `{ dateRange: { min: '2020-01-01', max: '2030-12-31' } }` |
| `linkContentType` | Link, Array of Links | `{ linkContentType: ['author', 'organization'] }` |
| `linkMimetypeGroup` | Link (Asset) | `{ linkMimetypeGroup: ['image', 'video'] }` |
| `assetFileSize` | Link (Asset) | `{ assetFileSize: { min: 0, max: 5242880 } }` |
| `assetImageDimensions` | Link (Asset) | `{ assetImageDimensions: { width: { min: 100, max: 2000 } } }` |

Apply validations via `.validations([...])` on a field. See [API Reference — Validations](references/api-reference.md#validations) for all options.

## Entry Transformations

**Transform entries in place:**

```typescript
migration.transformEntries({
  contentType: 'blogPost',
  from: ['firstName', 'lastName'],
  to: ['fullName'],
  transformEntryForLocale: (fields, locale) => {
    const first = fields.firstName[locale]
    const last = fields.lastName[locale]
    if (!first && !last) return
    return { fullName: `${first || ''} ${last || ''}`.trim() }
  },
})
```

Options: `shouldPublish` (`true`, `false`, or `'preserve'` — default `'preserve'`).

**Derive linked entries:**

```typescript
migration.deriveLinkedEntries({
  contentType: 'blogPost',
  derivedContentType: 'author',
  from: ['authorName'],
  toReferenceField: 'authorRef',
  derivedFields: ['name'],
  identityKey: (fields) =>
    fields.authorName['en-US'].toLowerCase().replace(/\s+/g, '-'),
  deriveEntryForLocale: (fields, locale) => {
    if (locale !== 'en-US') return
    return { name: fields.authorName[locale] }
  },
})
```

This creates new `author` entries from existing `blogPost.authorName` data and links them via `authorRef`.

See [Patterns — Transform Entries](references/patterns.md#transform-entries) and [Patterns — Derive Linked Entries](references/patterns.md#derive-linked-entries) for more examples.

## Editor Interface

**Change the widget for a field:**

```typescript
const page = migration.editContentType('page')

page.changeFieldControl('slug', 'builtin', 'slugEditor', {
  helpText: 'URL-friendly identifier',
  trackingFieldId: 'title',
})

page.changeFieldControl('category', 'builtin', 'dropdown')
page.changeFieldControl('publishDate', 'builtin', 'datePicker', { format: 'dateonly' })
```

Widget namespaces: `builtin`, `extension` (UI extensions), `app` (custom apps).

See [API Reference — Editor Interface](references/api-reference.md#editor-interface) for all built-in widgets and their settings.

## Best Practices

1. **Number migration files sequentially:** `001-create-blog-post.ts`, `002-add-author-field.ts`, `003-transform-categories.ts`.
2. **One logical change per migration.** Easier to debug, revert, and review.
3. **Always test in a sandbox environment** before running against production.
4. **Use `shouldPublish: 'preserve'`** (the default) to maintain existing publish states during transforms.
5. **Prefer chaining over object notation** — chaining gives line-level error messages.
6. **Split data transforms from schema changes.** First migration changes the schema, second transforms data. This makes each step independently verifiable.
7. **Use `context.makeRequest`** sparingly — only when the migration API doesn't cover your use case.

## Common Mistakes

- **Forgetting `items` on Array fields.** `type: 'Array'` requires an `items` property specifying the element type.
- **Deleting a content type with entries.** You must delete all entries first, or move them with `transformEntriesToType`.
- **Missing `linkType` on Link fields.** `type: 'Link'` requires `linkType: 'Asset'` or `linkType: 'Entry'`.
- **Running against master.** Always test in a sandbox environment. Use `--environment-id sandbox` on the CLI.
- **Not handling missing locales in transforms.** `transformEntryForLocale` is called for every locale — return `undefined` to skip.
- **Setting `displayField` to a non-Symbol field.** The display field must be of type `Symbol`.

## References

- [API Reference](references/api-reference.md) — complete migration API surface
- [Patterns](references/patterns.md) — common migration examples
- [Running Migrations](references/running-migrations.md) — CLI, programmatic API, CI/CD

## Related Skills

- the contentful-guide skill — Contentful concepts, terminology, API routing
- the contentful-nextjs skill — Next.js integration with Contentful

<!-- chapter:end slug=contentful-migration -->

---

<!-- chapter:begin slug=contentful-nextjs position=8 -->

## 8. contentful-nextjs

- **Source:** https://github.com/contentful/skills/blob/main/skills/contentful-nextjs/SKILL.md
- **Raw:** https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-nextjs/SKILL.md
- **Markdown:** https://skillsdocs.com/contentful/skills/contentful-nextjs.md
- **Licence:** MIT — https://spdx.org/licenses/MIT.html

Bundled files (4), referenced from this skill's directory:
  - `package.json` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-nextjs/package.json
  - `references/nextjs-setup.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-nextjs/references/nextjs-setup.md
  - `references/preview-and-draft-mode.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-nextjs/references/preview-and-draft-mode.md
  - `references/troubleshooting.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-nextjs/references/troubleshooting.md

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: contentful-nextjs
description: >-
  Add and configure Contentful in an existing Next.js project. Covers installing
  the JavaScript SDK, configuring environment variables, creating production and
  preview-aware clients, fetching content in App Router or Pages Router, and
  wiring Draft Mode preview flows. Use when users ask to integrate Contentful
  with Next.js, fetch entries, set up preview or draft content, or configure
  the Contentful client. Also triggers on "Contentful SDK Next.js",
  "contentful.js", "fetch Contentful entries", "get content from Contentful",
  "Contentful preview", "preview mode", "Contentful environment variables",
  "Contentful client setup", "create Contentful client", "Pages Router
  Contentful", "getStaticProps Contentful", "Server Components Contentful",
  "revalidate Contentful", "ISR Contentful". Not for personalization or
  Experiences SDK setup (contentful-personalization). Not for non-Next.js
  frameworks (contentful-guide can route to platform docs).
argument-hint: "[what to set up]"
allowed-tools: Bash(npm install contentful) Bash(npm install @contentful/rich-text-*) mcp__contentful-mcp__* mcp__plugin_contentful_contentful-mcp__*
---

# Contentful Next.js

Use this skill to integrate Contentful into an existing Next.js application.

Contentful is a headless, API-first CMS (composable content platform) that lets Next.js apps fetch structured content through delivery and preview APIs.

## Scope

- Next.js App Router and Pages Router.
- Published content delivery (CDA).
- Preview content delivery with Draft Mode (CPA).
- Environment variable and client setup patterns.
- Environment alias-aware setup for stable deployment paths.

## Not in scope

- Personalization/optimization implementations.
- Studio Experiences SDK setup.
- Full content-model strategy design.

## Contentful MCP note

- If the user wants easier agent-driven interaction with Contentful during setup, suggest the Contentful MCP server docs: `https://www.contentful.com/developers/docs/tools/mcp-server/`.
- Keep this skill focused on Next.js implementation. MCP guidance complements setup but does not replace app-side client wiring.

## Project state

```!
echo "=== Contentful packages ===" && node -e "try{const p=require('./package.json');const d={...p.dependencies,...p.devDependencies};const c=Object.entries(d).filter(([k])=>k.includes('contentful'));console.log(c.length?c.map(([k,v])=>k+'@'+v).join('\n'):'(Contentful SDK not installed)')}catch{console.log('(no package.json)')}" 2>/dev/null
echo ""
echo "=== Contentful env vars ===" && grep -h CONTENTFUL .env.local .env 2>/dev/null | sed 's/=.*/=<set>/' || echo "(no Contentful env vars found in .env.local or .env)"
echo ""
echo "=== Router type ===" && ([ -d "app" ] && echo "App Router detected (app/ directory exists)" || ([ -d "pages" ] && echo "Pages Router detected (pages/ directory exists)" || echo "(could not detect router type)"))
```

## Workflow

1. Check the latest stable Next.js release online at `https://github.com/vercel/next.js/releases` when version-specific guidance is needed.
2. Confirm Next.js project structure (App Router vs Pages Router).
3. Configure required env vars. If they are missing, ask the user to add them to `.env.local` before continuing, and explain where to find each value.
4. Install and initialize `contentful` SDK.
5. Implement published-content fetching.
6. Add preview-aware behavior for Draft Mode.
7. Validate with a minimal test route/page and troubleshooting checklist.

## Version-check policy

- Do not rely on memory for "latest Next.js version" claims.
- Verify against `https://github.com/vercel/next.js/releases` before recommending upgrades, compatibility workarounds, or version-specific fixes.
- Treat the latest non-prerelease tag as default unless the user explicitly asks for canary/RC guidance.

## Required environment variables

- `CONTENTFUL_SPACE_ID` - Find it in the Contentful URL (`/spaces/<SPACE_ID>/...`) or in **Space settings -> API keys**.
- `CONTENTFUL_ACCESS_TOKEN` - CDA token from **Space settings -> API keys**.
- `CONTENTFUL_PREVIEW_ACCESS_TOKEN` (for preview workflows) - CPA token from **Space settings -> API keys**.

Creating an API key in Contentful provides both tokens needed here:
- CDA token -> `CONTENTFUL_ACCESS_TOKEN`
- CPA token -> `CONTENTFUL_PREVIEW_ACCESS_TOKEN`

## Defaults

- If the user does not specify router type, default to Next.js App Router guidance.
- Use CDA host for normal delivery.
- Use `preview.contentful.com` and preview token when Draft Mode is enabled.
- Prefer an environment alias (for example `master`) as the client `environment` value to decouple runtime clients from release environment IDs.
- Keep Contentful client creation in a shared utility module.

## References

- [Next.js setup](references/nextjs-setup.md)
- [Preview and Draft Mode](references/preview-and-draft-mode.md)
- [Troubleshooting](references/troubleshooting.md)

<!-- chapter:end slug=contentful-nextjs -->

---

<!-- chapter:begin slug=contentful-personalization position=9 -->

## 9. contentful-personalization

- **Source:** https://github.com/contentful/skills/blob/main/skills/contentful-personalization/SKILL.md
- **Raw:** https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/SKILL.md
- **Markdown:** https://skillsdocs.com/contentful/skills/contentful-personalization.md
- **Licence:** MIT — https://spdx.org/licenses/MIT.html

Bundled files (29), referenced from this skill's directory:
  - `bin/contentful-personalization.mjs` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/bin/contentful-personalization.mjs
  - `package.json` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/package.json
  - `references/analytics-and-preview.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/analytics-and-preview.md
  - `references/analytics-patterns.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/analytics-patterns.md
  - `references/common-errors.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/common-errors.md
  - `references/component-patterns.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/component-patterns.md
  - `references/contentful-app-setup.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/contentful-app-setup.md
  - `references/contentful-integration-guide.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/contentful-integration-guide.md
  - `references/env-var-spec.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/env-var-spec.md
  - `references/framework-notes.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/framework-notes.md
  - `references/how-personalization-works.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/how-personalization-works.md
  - `references/implementation-examples.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/implementation-examples.md
  - `references/middleware-patterns.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/middleware-patterns.md
  - `references/optimization-nextjs-app-router.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/optimization-nextjs-app-router.md
  - `references/optimization-nextjs-pages-router.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/optimization-nextjs-pages-router.md
  - `references/optimization-node.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/optimization-node.md
  - `references/optimization-overview.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/optimization-overview.md
  - `references/optimization-react-native.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/optimization-react-native.md
  - `references/optimization-react-web.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/optimization-react-web.md
  - `references/optimization-shared.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/optimization-shared.md
  - `references/optimization-web.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/optimization-web.md
  - `references/package-versions.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/package-versions.md
  - `references/provider-patterns.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/provider-patterns.md
  - `references/readiness-criteria.md` — https://raw.githubusercontent.com/contentful/skills/main/skills/contentful-personalization/references/readiness-criteria.md
  - …and 5 more, listed in https://skillsdocs.com/api/v1/books/contentful/skills/skills/contentful-personalization

<!-- Verbatim upstream SKILL.md follows, YAML frontmatter included. -->

---
name: contentful-personalization
description: "Implement, extend, and debug Contentful personalization. Use onboarding for new, project-wide, or unknown setups; use extend-existing only for scoped work on an explicitly working integration. Trigger keywords: personalization, optimization, ninetailed, A/B test, experiment, multivariate test, targeting, audience targeting, segments, variants, content variants, set up personalization, implement personalization, enable personalization, personalization not working, personalization broken, personalize this component, am I ready for personalization, experience API, Contentful Experiences, Experiences SDK, Studio Experiences, personalization in Next.js, @contentful/optimization, @ninetailed/experience.js, run an experiment, check this URL, debug this live page, inspect network requests, check console errors, experience.ninetailed.co"
metadata:
  version: "2.4.22"
argument-hint: "[question or topic]"
allowed-tools: "Bash(scripts/run *) Read mcp__contentful-personalization__start mcp__contentful-personalization__advance mcp__contentful-personalization__topic mcp__contentful-personalization__topics mcp__contentful-mcp__* mcp__chrome-devtools__* mcp__plugin_*chrome-devtools*__* mcp__plugin_contentful_contentful-mcp__* mcp__plugin_contentful_contentful-personalization__*"
license: "MIT"
---

# contentful-personalization

This skill is a structured workflow driven by a compiled CLI binary. You interact with it
by calling the binary, reading its JSON output, following the instructions in the `prompt`
field, and passing your response back. **Do not show the raw JSON or Bash commands to the user.**

## How this skill works

This skill was built with skill-kit, a structured workflow engine. Each step provides
a prompt containing XML-tagged sections:

- **`<system>`** — Behavioral directives: persona, tone, or constraints. Follow as
  guidelines for how to behave, not as tasks to relay to the user.
- **`<prompt>`** — Task instructions: what to do, what context to consider, what to produce.
- **`<ask-user>`** — Ask the user a question. Contains `<option>` children for structured
  choices, or `type="open"` for free-form conversation.
- **`<confirm>`** — Binary yes/no confirmation. Attributes: `default`, `destructive`.
- **`<plan>`** — Present a plan for approval. Contains `<step>` children.
- **`<checklist>`** — Create tracked work items. Contains `<item>` children with status.
- **`<subagent>`** — Delegate work to an isolated sub-agent. If `no-recurse` is set,
  the subagent must not invoke the skill named in the attribute.
- **`<rendered>`** — Pre-rendered output. Emit verbatim — no edits, no added commentary.

A step may contain one or more of these sections in sequence. Follow them in order.

The skill author composed these sections to guide your behavior. The tags and tool
mappings are generated by the SDK based on the author's intent and your host's
capabilities. A skill-level system directive may appear in the preamble — it applies
to all steps unless a step includes its own `<system>` override.

The **preamble** (sent on the first step) contains a table mapping each tag to the
specific tool available in your environment. Refer to it throughout the workflow.

## How to run this skill

### MCP mode (preferred)

If you have MCP tools for this skill (e.g., `mcp__contentful-personalization__start` and
`mcp__contentful-personalization__advance`), use them instead of the CLI:

1. Call the `start` tool (with `params` if the skill requires them).
2. Read the `preamble` field (first call only). It maps XML tags to your available tools.
3. Follow the `prompt` instructions. Produce a JSON object matching the `schema`.
4. Call the `advance` tool with the `session`, `step`, and `output`.
5. Repeat steps 3-4 until `status` is `"done"`.

If you get `status: "error"` with `retry: true`, fix your output and resubmit.
**Do not show raw JSON, session IDs, or MCP tool calls to the user.**

Skip the rest of this section — the CLI instructions below are only needed when
MCP tools are not available.

### CLI mode (fallback)

This SKILL.md file is inside the skill directory. Resolve the **absolute path** to `scripts/run`
from this file's location (e.g., `/path/to/skill/scripts/run`). Use the absolute path in all
Bash commands — do not `cd` into the skill directory.

In the examples below, `<skill>/scripts/run` is a placeholder for this absolute path.

### Detect your host

Determine which agent host you are running in, and pass it as `--host`:
- Claude Code: `--host claude-code`
- Codex: `--host codex`
- OpenCode: `--host opencode`
- Gemini CLI: `--host gemini-cli`
- Cline: `--host cline`
- Roo Code: `--host roo-code`
- Kilo Code: `--host kilo-code`
- Cursor: `--host cursor`
- Amp: `--host amp`
- Unknown/other: omit the flag (defaults to generic)

### Report your tools

Pass the tools you have available as a comma-separated `--tools` flag on the **start**
command. The session remembers them — you don't need to pass `--tools` on advance.

When `--host` is provided, `--tools` is merged with the host's known tool registry.
This means partial reporting is handled gracefully — the registry fills in any tools
you omit. If `--tools` is omitted entirely, the skill infers tools from `--host`.
If both are omitted, all interactions use generic fallbacks.

### Subagent invocations

If you are a **subagent** (spawned by another agent, not the top-level agent the user
is talking to), add `--subagent` to the start command. This tells the skill that your
reported tools are a genuine subset — the skill will not merge them with the host registry.

Without `--subagent`, the skill assumes you are a top-level agent and merges your tools
with the registry (since top-level agents often under-report their tools).

## Parameters

This skill takes no parameters. Pass `--params '{}'`.

### Step 1: Start with a session

```bash
<skill>/scripts/run --params '{}' --host claude-code --tools <your-tools> --session new 2>/dev/null
```

This returns a JSON pointer with `sessionId`, `file`, and `line`. The `line` field tells you
which line to read — it will be `2`, not `1` (line 1 is an internal header, never read it).

Read **only** line `line` from `file`. It contains the step prompt, schema, and preamble.

**Read the `preamble` first.** It contains a table mapping XML tags to the tools
available in your environment. Refer to it throughout the workflow.

### Step 2: Follow the prompt

Read the `prompt` field. It contains XML-tagged sections (described in "How this skill
works" above): `<system>` directives to follow, `<prompt>` instructions to act on, and
interaction tags (`<ask-user>`, `<confirm>`, `<plan>`, `<checklist>`, `<subagent>`)
to execute using the tools mapped in the preamble. If a `<rendered>` block appears,
emit its content verbatim.

Produce a JSON object matching the `schema`.

### Step 3: Advance

Pass your output back with the step name:

```bash
<skill>/scripts/run advance --step <step-name> --output '<your-json>' --session abc123 2>/dev/null
```

This returns a single line number (e.g., `4`). Read **exactly and only that line** from the session file — it contains the next prompt. Do not read any other lines.

### Step 4: Repeat until done

Keep advancing until the line you read contains `"type":"done"`. The `finalOutput` field
contains the skill's result. Present it to the user.

### Important

- **Never show raw JSON output or Bash commands to the user.** The user sees your natural
  language responses, not the protocol.
- **If you get a validation error** (the response has `"error": "validation"` or `"type":"error"`),
  read the `message` field, fix your output, and retry the same step.

## Steps in this skill

- **classify**: Classify the user's request into one of the categories below.
Read only the user's message — do N...
- **gather-context**: You were not confident enough to classify the user's request.
Silently explore the project to gat...
- **pick-topic**: (dynamic)


## Sub-skills

This skill contains sub-skills that the workflow routes to automatically.
Start the skill normally — the dispatcher will determine which sub-skill to use.
Only use direct sub-skill access if the user explicitly requests a specific sub-skill by name.

Sub-skill step names are prefixed: `<subskill>/<step>` (e.g., `doctor/diagnose`).

### Direct sub-skill access

```bash
<skill>/scripts/run <subskill> --params '<json>' --session new
<skill>/scripts/run <subskill> advance --session <id>
```

### Available sub-skills

- **onboard**: Default workflow for implementing, setting up, or enabling Contentful personalization project-wide, including when the existing setup state is unknown. Explores the codebase, checks readiness, chooses SDK and architecture, installs packages, implements, and validates. Use extend-existing only for a scoped change to an explicitly working integration. — params: `readinessOnly` (boolean), `userQuery` (string)
- **live-debug**: Inspect a live URL with Chrome DevTools MCP for runtime personalization issues. Checks console problems, observes ninetailed.co requests, and reports whether the next step should be static doctor diagnosis. — params: `requestedUrl` (string)
- **doctor**: Diagnose and fix Contentful personalization issues. Runs programmatic checks first (credentials, API connectivity, content state), fixes infrastructure problems, and only then explores the codebase. — params: `userQuery` (string)
- **extend-existing**: Extend an explicitly existing, working Contentful personalization integration. Use only for scoped changes such as personalizing another component, adding an experiment, or wiring analytics into the installed SDK. Not for first-time, project-wide, or unknown-state implementation requests; use onboard for those. — params: `userQuery` (string)

## Reference topics

Quick-reference topics accessible without running the full workflow:

```bash
<skill>/scripts/run topics              # list all topics
<skill>/scripts/run topic <name>         # load a specific topic
```

- **how-personalization-works**: Core concepts: content model, rendering flow, and how personalization works
- **sdk-selection**: SDK decision framework: Optimization default vs legacy deployment maintenance
- **provider-patterns**: Provider placement patterns for Pages Router, App Router, and both SDKs
- **middleware-patterns**: Middleware and SSR/edge patterns: preflight, cookies, matcher config
- **component-patterns**: Component architecture patterns: ContentTypeMap, BlockRenderer, isolation
- **rendering-pipeline**: Rendering pipeline: Contentful client setup, include depth, component mapper
- **environment-variables**: Environment variables: names, runtime matrix, framework prefixes
- **analytics-and-preview**: Analytics plugins (Insights, GTM, Segment) and preview configuration
- **common-errors**: Common failure modes with root causes and fixes
- **ssr-guide**: SSR and edge-side personalization: patterns, anti-patterns, troubleshooting
- **sdk-legacy-guide**: @ninetailed/experience.js reference for debugging or extending existing deployments
- **sdk-next-guide**: @contentful/optimization SDK runtime chooser
- **optimization-overview**: @contentful/optimization runtime and package chooser
- **optimization-react-web**: @contentful/optimization React Web provider, hooks, entries, and routing
- **optimization-nextjs-app-router**: @contentful/optimization Next.js App Router integration
- **optimization-nextjs-pages-router**: @contentful/optimization Next.js Pages Router integration
- **optimization-web**: @contentful/optimization imperative browser and Web Components integration
- **optimization-node**: @contentful/optimization stateless Node request integration
- **optimization-react-native**: @contentful/optimization React Native integration
- **contentful-integration-guide**: Contentful CMS integration: content types, ExperienceMapper, publishing workflow
- **implementation-examples**: Real code examples: providers, BlockRenderer, Experience component patterns

<!-- chapter:end slug=contentful-personalization -->
