Add headless CMS reference and integration guides (#174)
* feat: add headless CMS reference and integration guides Add CMS selection guide, content modeling patterns, and editorial workflow reference for marketers. Add integration guides for Sanity (GROQ API), Contentful (CDA/CMA), and Strapi (v5 REST). Register all three in REGISTRY.md and link from content-strategy skill. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address review feedback on headless CMS guides - Use {curly_brace} placeholder convention for Strapi relation example - Add note that Contentful CMA create uses PUT with client-generated ID - Add URL-encoding note for Sanity GROQ query parameter - Switch Sanity mutation example from createOrReplace to create (no _id needed) - Add Content-Type header to Contentful update entry example - Fix outdated "Assembly" product name to "Studio" for Contentful Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -348,6 +348,12 @@ Visual or structured representation of how content interconnects.
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- **[Headless CMS Guide](references/headless-cms.md)**: CMS selection, content modeling for marketing, editorial workflows, platform comparison (Sanity, Contentful, Strapi)
|
||||
|
||||
---
|
||||
|
||||
## Related Skills
|
||||
|
||||
- **copywriting**: For writing individual content pieces
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
# Headless CMS Guide
|
||||
|
||||
Reference for choosing, modeling, and implementing a headless CMS for marketing content.
|
||||
|
||||
## When to Use This Reference
|
||||
|
||||
Use this when selecting a CMS for a new project, designing content models for marketing sites, setting up editorial workflows, or connecting CMS content to programmatic pages.
|
||||
|
||||
---
|
||||
|
||||
## Headless vs Traditional CMS
|
||||
|
||||
A headless CMS separates content management from presentation. Content is stored in a structured backend and delivered via API to any frontend.
|
||||
|
||||
### When Headless Makes Sense
|
||||
|
||||
- Multiple frontends consume the same content (web, mobile, email)
|
||||
- Developers want full control over the frontend stack
|
||||
- Content needs to be reused across channels
|
||||
- You're building with a modern framework (Next.js, Remix, Astro)
|
||||
- Marketing needs structured, reusable content blocks
|
||||
|
||||
### When Traditional Works Better
|
||||
|
||||
- Small team with no dedicated developers
|
||||
- Simple blog or brochure site
|
||||
- WYSIWYG editing is a hard requirement
|
||||
- Budget is tight and WordPress/Webflow does the job
|
||||
|
||||
### Decision Checklist
|
||||
|
||||
| Factor | Headless | Traditional |
|
||||
|--------|----------|-------------|
|
||||
| Multi-channel delivery | Yes | Limited |
|
||||
| Developer control | Full | Constrained |
|
||||
| Non-technical editing | Requires setup | Built-in |
|
||||
| Time to launch | Longer | Faster |
|
||||
| Content reuse | Native | Manual |
|
||||
| Hosting flexibility | Any frontend | Platform-dependent |
|
||||
|
||||
---
|
||||
|
||||
## Content Modeling for Marketing
|
||||
|
||||
### Core Principles
|
||||
|
||||
1. **Think in types, not pages.** A "Landing Page" is a content type with fields — not an HTML file. This lets you reuse components across pages.
|
||||
2. **Separate content from presentation.** Store the headline text, not the styled headline. Presentation belongs in the frontend.
|
||||
3. **Design for reuse.** If testimonials appear on 5 pages, create a Testimonial type and reference it — don't duplicate.
|
||||
4. **Keep models flat.** Deeply nested structures are hard to query and maintain. Prefer references over nesting.
|
||||
|
||||
### Common Marketing Content Types
|
||||
|
||||
| Type | Key Fields | Notes |
|
||||
|------|-----------|-------|
|
||||
| **Landing Page** | title, slug, hero, sections[], seo | Modular sections for flexibility |
|
||||
| **Blog Post** | title, slug, body, author, category, tags, publishedAt, seo | Rich text or Portable Text body |
|
||||
| **Case Study** | title, customer, challenge, solution, results, metrics[], logo | Link to related products/features |
|
||||
| **Testimonial** | quote, author, role, company, avatar, rating | Reference from landing pages |
|
||||
| **FAQ** | question, answer, category | Group by category for programmatic pages |
|
||||
| **Author** | name, bio, avatar, social links | Reference from blog posts |
|
||||
| **CTA Block** | heading, body, buttonText, buttonUrl, variant | Reusable across pages |
|
||||
|
||||
### SEO Fields Checklist
|
||||
|
||||
Every page-level content type needs:
|
||||
|
||||
- `metaTitle` — 50-60 characters
|
||||
- `metaDescription` — 150-160 characters
|
||||
- `ogImage` — 1200x630px social preview
|
||||
- `slug` — URL path segment
|
||||
- `canonicalUrl` — optional override
|
||||
- `noIndex` — boolean for excluding from search
|
||||
- `structuredData` — optional JSON-LD override
|
||||
|
||||
---
|
||||
|
||||
## Editorial Workflows
|
||||
|
||||
### Draft → Review → Publish Cycle
|
||||
|
||||
1. **Draft** — Author creates or edits content
|
||||
2. **Review** — Editor reviews for accuracy, brand voice, SEO
|
||||
3. **Approve** — Stakeholder signs off
|
||||
4. **Schedule** — Set publish date/time
|
||||
5. **Publish** — Content goes live via API
|
||||
|
||||
### Preview APIs
|
||||
|
||||
All major headless CMS platforms support draft previews:
|
||||
|
||||
- **Sanity**: Real-time preview with `useLiveQuery` or Presentation tool
|
||||
- **Contentful**: Preview API (`preview.contentful.com`) with separate access token
|
||||
- **Strapi**: Draft & Publish system with `status=draft` query parameter (v5; replaces v4's `publicationState`)
|
||||
|
||||
Set up a preview route in your frontend (e.g., `/api/preview`) that authenticates and renders draft content.
|
||||
|
||||
### Roles and Permissions
|
||||
|
||||
| Role | Can Create | Can Edit | Can Publish | Can Delete |
|
||||
|------|:----------:|:--------:|:-----------:|:----------:|
|
||||
| Author | Yes | Own | No | Own drafts |
|
||||
| Editor | Yes | All | Yes | Drafts |
|
||||
| Admin | Yes | All | Yes | All |
|
||||
|
||||
Exact permission models vary by platform. Sanity uses role-based access. Contentful has space-level roles. Strapi has granular RBAC.
|
||||
|
||||
---
|
||||
|
||||
## Platform Comparison
|
||||
|
||||
| Feature | Sanity | Contentful | Strapi |
|
||||
|---------|--------|------------|--------|
|
||||
| Hosting | Cloud (managed) | Cloud (managed) | Self-hosted or Cloud |
|
||||
| Query Language | GROQ | REST / GraphQL | REST / GraphQL |
|
||||
| Free Tier | Generous | Limited | Open source (free) |
|
||||
| Real-time Collab | Yes (built-in) | Limited | No |
|
||||
| Best For | Developer flexibility | Enterprise multi-locale | Budget / self-hosted |
|
||||
| Content Modeling | Schema-as-code | Web UI | Web UI or code |
|
||||
| Media Handling | Built-in DAM | Built-in | Plugin-based |
|
||||
|
||||
### Sanity
|
||||
|
||||
**Strengths**: GROQ query language is powerful and flexible. Schema defined in code (version-controlled). Real-time collaborative editing. Portable Text for rich content. Generous free tier.
|
||||
|
||||
**Considerations**: Steeper learning curve for non-developers. Studio customization requires React knowledge. Vendor lock-in on GROQ queries.
|
||||
|
||||
**Marketing fit**: Best when developers and marketers collaborate closely. Strong for content-heavy sites with complex models.
|
||||
|
||||
### Contentful
|
||||
|
||||
**Strengths**: Mature enterprise platform. Excellent multi-locale support. Strong ecosystem of integrations. Composable content with Studio. Well-documented APIs.
|
||||
|
||||
**Considerations**: Pricing scales with content types and locales. Two separate APIs (Delivery and Management). Rate limits can be tight on lower plans.
|
||||
|
||||
**Marketing fit**: Best for enterprises with multi-market content needs. Good when you need established vendor reliability.
|
||||
|
||||
### Strapi
|
||||
|
||||
**Strengths**: Open source, self-hosted option. Full control over data. No per-seat pricing. Customizable admin panel. Plugin ecosystem. REST by default, GraphQL via plugin.
|
||||
|
||||
**Considerations**: Self-hosting means you handle infrastructure. Smaller ecosystem than Sanity/Contentful. V5 migration can be significant from V4.
|
||||
|
||||
**Marketing fit**: Best for teams with DevOps capability who want full control and no vendor lock-in. Good for budget-conscious projects.
|
||||
|
||||
### Others Worth Knowing
|
||||
|
||||
- **Hygraph** — GraphQL-native, strong for federation and multi-source content
|
||||
- **Keystatic** — Git-based, good for developer-content hybrid workflows
|
||||
- **Payload** — TypeScript-first, self-hosted, code-configured like Sanity
|
||||
- **Builder.io** — Visual editor with headless backend, good for non-technical marketers
|
||||
- **Prismic** — Slice-based content modeling, strong Next.js integration
|
||||
|
||||
---
|
||||
|
||||
## Integration with Marketing Skills
|
||||
|
||||
### Programmatic SEO
|
||||
|
||||
Use CMS as the data source for programmatic pages. Store structured data (FAQs, comparisons, city pages) as content types and generate pages from queries. See **programmatic-seo** skill.
|
||||
|
||||
### Copywriting
|
||||
|
||||
CMS content models enforce consistent structure. Define fields that match your copy frameworks (headline, subheadline, social proof, CTA). See **copywriting** skill.
|
||||
|
||||
### Site Architecture
|
||||
|
||||
URL structure, navigation hierarchy, and internal linking all depend on how content is organized in the CMS. Plan your content model and site architecture together. See **site-architecture** skill.
|
||||
|
||||
### Email Sequences
|
||||
|
||||
Pull CMS content into email templates for consistent messaging across web and email. Case studies, testimonials, and blog posts can feed email nurture sequences. See **email-sequence** skill.
|
||||
|
||||
---
|
||||
|
||||
## Implementation Checklist
|
||||
|
||||
- [ ] Define content types based on page types and reusable blocks
|
||||
- [ ] Add SEO fields to every page-level content type
|
||||
- [ ] Set up preview/draft mode in your frontend
|
||||
- [ ] Configure roles and permissions for your team
|
||||
- [ ] Create sample content for each type before building frontend
|
||||
- [ ] Set up webhook notifications for content changes (rebuild triggers)
|
||||
- [ ] Document content guidelines for editors (field descriptions, character limits)
|
||||
- [ ] Test content delivery performance (CDN, caching, ISR)
|
||||
- [ ] Plan migration strategy if moving from existing CMS
|
||||
|
||||
---
|
||||
|
||||
## Relevant Integration Guides
|
||||
|
||||
- [Sanity](../../../tools/integrations/sanity.md) — GROQ queries, mutations, CLI
|
||||
- [Contentful](../../../tools/integrations/contentful.md) — Delivery/Management APIs, publishing
|
||||
- [Strapi](../../../tools/integrations/strapi.md) — REST CRUD, filters, document API
|
||||
+7
-1
@@ -82,6 +82,9 @@ Quick reference for AI agents to discover tool capabilities and integration meth
|
||||
| shopify | Commerce | ✓ | - | ✓ | ✓ | [shopify.md](integrations/shopify.md) |
|
||||
| wordpress | CMS | ✓ | - | ✓ | ✓ | [wordpress.md](integrations/wordpress.md) |
|
||||
| webflow | CMS | ✓ | - | ✓ | ✓ | [webflow.md](integrations/webflow.md) |
|
||||
| sanity | Headless CMS | ✓ | - | ✓ | ✓ | [sanity.md](integrations/sanity.md) |
|
||||
| contentful | Headless CMS | ✓ | - | ✓ | ✓ | [contentful.md](integrations/contentful.md) |
|
||||
| strapi | Headless CMS | ✓ | - | ✓ | ✓ | [strapi.md](integrations/strapi.md) |
|
||||
|
||||
---
|
||||
|
||||
@@ -386,8 +389,11 @@ E-commerce platforms and content management systems.
|
||||
| **shopify** | E-commerce, product sales | ✓ |
|
||||
| **wordpress** | Blogs, content sites | ✓ |
|
||||
| **webflow** | Design-focused marketing sites | ✓ |
|
||||
| **sanity** | Headless CMS, structured content | ✓ |
|
||||
| **contentful** | Enterprise headless CMS, multi-locale | ✓ |
|
||||
| **strapi** | Open-source headless CMS, self-hosted | ✓ |
|
||||
|
||||
**Agent recommendation**: Shopify for e-commerce. Webflow for marketing sites. WordPress for blogs.
|
||||
**Agent recommendation**: Shopify for e-commerce. Webflow for marketing sites. WordPress for blogs. For headless CMS: Sanity for developer-flexible content, Contentful for enterprise multi-locale, Strapi for self-hosted/budget-conscious. See [headless CMS guide](../skills/content-strategy/references/headless-cms.md) for selection criteria.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
# Contentful
|
||||
|
||||
Enterprise headless CMS with multi-locale support, two-API architecture, and composable content.
|
||||
|
||||
## Capabilities
|
||||
|
||||
| Integration | Available | Notes |
|
||||
|-------------|-----------|-------|
|
||||
| API | ✓ | Content Delivery API (read), Content Management API (write) |
|
||||
| MCP | - | No official MCP server |
|
||||
| CLI | ✓ | `contentful-cli` for spaces, content types, migrations |
|
||||
| SDK | ✓ | `contentful` (delivery), `contentful-management` (management) |
|
||||
|
||||
## Authentication
|
||||
|
||||
- **Delivery API (CDA)**: `Authorization: Bearer {delivery_token}`
|
||||
- Base URL: `https://cdn.contentful.com`
|
||||
- Read-only, CDN-cached
|
||||
- **Preview API (CPA)**: `Authorization: Bearer {preview_token}`
|
||||
- Base URL: `https://preview.contentful.com`
|
||||
- Read-only, returns draft content
|
||||
- **Management API (CMA)**: `Authorization: Bearer {management_token}`
|
||||
- Base URL: `https://api.contentful.com`
|
||||
- Read/write, not cached
|
||||
- **Tokens**: Create in Settings → API keys (delivery) or Settings → CMA tokens (management)
|
||||
|
||||
## Common Agent Operations
|
||||
|
||||
### Get entries (Delivery API)
|
||||
|
||||
```bash
|
||||
GET https://cdn.contentful.com/spaces/{space_id}/environments/{environment}/entries?content_type=blogPost&limit=10
|
||||
|
||||
Authorization: Bearer {delivery_token}
|
||||
```
|
||||
|
||||
### Get single entry
|
||||
|
||||
```bash
|
||||
GET https://cdn.contentful.com/spaces/{space_id}/environments/{environment}/entries/{entry_id}
|
||||
|
||||
Authorization: Bearer {delivery_token}
|
||||
```
|
||||
|
||||
### Search and filter
|
||||
|
||||
```bash
|
||||
# By field value
|
||||
GET https://cdn.contentful.com/spaces/{space_id}/environments/{environment}/entries?content_type=blogPost&fields.slug=my-post
|
||||
|
||||
# Full-text search
|
||||
GET https://cdn.contentful.com/spaces/{space_id}/environments/{environment}/entries?query=marketing+strategy
|
||||
|
||||
# By date range
|
||||
GET https://cdn.contentful.com/spaces/{space_id}/environments/{environment}/entries?content_type=blogPost&fields.publishDate[gte]=2024-01-01
|
||||
```
|
||||
|
||||
### Create entry (Management API)
|
||||
|
||||
CMA uses PUT with a client-generated `entry_id`. To auto-generate, use POST without an ID in the path.
|
||||
|
||||
```bash
|
||||
PUT https://api.contentful.com/spaces/{space_id}/environments/{environment}/entries/{entry_id}
|
||||
Content-Type: application/vnd.contentful.management.v1+json
|
||||
X-Contentful-Content-Type: blogPost
|
||||
Authorization: Bearer {management_token}
|
||||
|
||||
{
|
||||
"fields": {
|
||||
"title": {"en-US": "New Post"},
|
||||
"slug": {"en-US": "new-post"},
|
||||
"body": {"en-US": "Post content here"}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Update entry
|
||||
|
||||
```bash
|
||||
PUT https://api.contentful.com/spaces/{space_id}/environments/{environment}/entries/{entry_id}
|
||||
Content-Type: application/vnd.contentful.management.v1+json
|
||||
X-Contentful-Version: {current_version}
|
||||
Authorization: Bearer {management_token}
|
||||
|
||||
{
|
||||
"fields": {
|
||||
"title": {"en-US": "Updated Title"}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Publish entry
|
||||
|
||||
```bash
|
||||
PUT https://api.contentful.com/spaces/{space_id}/environments/{environment}/entries/{entry_id}/published
|
||||
X-Contentful-Version: {current_version}
|
||||
Authorization: Bearer {management_token}
|
||||
```
|
||||
|
||||
### Unpublish entry
|
||||
|
||||
```bash
|
||||
DELETE https://api.contentful.com/spaces/{space_id}/environments/{environment}/entries/{entry_id}/published
|
||||
X-Contentful-Version: {current_version}
|
||||
Authorization: Bearer {management_token}
|
||||
```
|
||||
|
||||
## CLI Commands
|
||||
|
||||
```bash
|
||||
# Login
|
||||
contentful login
|
||||
|
||||
# List spaces
|
||||
contentful space list
|
||||
|
||||
# Export space content
|
||||
contentful space export --space-id {space_id}
|
||||
|
||||
# Import content
|
||||
contentful space import --space-id {space_id} --content-file export.json
|
||||
|
||||
# Create migration
|
||||
contentful space migration --space-id {space_id} migration.js
|
||||
|
||||
# List content types
|
||||
contentful content-type list --space-id {space_id}
|
||||
```
|
||||
|
||||
## Key Objects
|
||||
|
||||
- **Space** — Top-level container for content (one per project)
|
||||
- **Environment** — Isolated content branch (`master`, `staging`, etc.)
|
||||
- **Content Type** — Schema definition with fields and validations
|
||||
- **Entry** — Content item of a specific content type
|
||||
- **Asset** — Media file (image, video, document)
|
||||
- **Locale** — Language/region variant (e.g., `en-US`, `de-DE`)
|
||||
|
||||
## When to Use
|
||||
|
||||
- Multi-locale marketing content (global sites)
|
||||
- Enterprise content operations with approval workflows
|
||||
- Composable content architecture
|
||||
- Teams needing established vendor support and SLAs
|
||||
- Content reuse across multiple channels
|
||||
|
||||
## Rate Limits
|
||||
|
||||
Rate limits are plan-dependent. Check `X-Contentful-RateLimit-Second-Limit` response header for your actual limits.
|
||||
|
||||
- Delivery API (CDA): Varies by plan (typically high throughput)
|
||||
- Preview API (CPA): Lower than CDA (varies by plan)
|
||||
- Management API (CMA): ~10 requests per second (default)
|
||||
- See [Contentful technical limits](https://www.contentful.com/developers/docs/technical-limits/) for current values
|
||||
|
||||
## Relevant Skills
|
||||
|
||||
- content-strategy (CMS selection, content modeling)
|
||||
- programmatic-seo (CMS as data source for generated pages)
|
||||
- site-architecture (multi-locale URL structure)
|
||||
@@ -0,0 +1,148 @@
|
||||
# Sanity
|
||||
|
||||
Headless CMS with real-time collaboration, GROQ query language, and schema-as-code.
|
||||
|
||||
## Capabilities
|
||||
|
||||
| Integration | Available | Notes |
|
||||
|-------------|-----------|-------|
|
||||
| API | ✓ | GROQ queries, Mutations API, Assets API |
|
||||
| MCP | - | No official MCP server |
|
||||
| CLI | ✓ | `sanity` CLI for studio, datasets, deployment |
|
||||
| SDK | ✓ | `@sanity/client`, `next-sanity`, `@sanity/image-url` |
|
||||
|
||||
## Authentication
|
||||
|
||||
- **Type**: API Token (Bearer)
|
||||
- **Header**: `Authorization: Bearer skXXXXXX`
|
||||
- **Tokens**: Create in Sanity Manage → API → Tokens
|
||||
- **Permissions**: Read-only or Read+Write per token
|
||||
|
||||
## Common Agent Operations
|
||||
|
||||
### Query documents (GROQ)
|
||||
|
||||
URL-encode the `query` parameter value in practice.
|
||||
|
||||
```bash
|
||||
GET https://{projectId}.api.sanity.io/v2024-01-01/data/query/{dataset}?query=*[_type == "post"]{title, slug, publishedAt}
|
||||
```
|
||||
|
||||
### Query with parameters
|
||||
|
||||
```bash
|
||||
GET https://{projectId}.api.sanity.io/v2024-01-01/data/query/{dataset}?query=*[_type == "post" && slug.current == $slug][0]&$slug="my-post"
|
||||
```
|
||||
|
||||
### Get document by ID
|
||||
|
||||
```bash
|
||||
GET https://{projectId}.api.sanity.io/v2024-01-01/data/doc/{dataset}/{documentId}
|
||||
```
|
||||
|
||||
### Create document (Mutations API)
|
||||
|
||||
```bash
|
||||
POST https://{projectId}.api.sanity.io/v2024-01-01/data/mutate/{dataset}
|
||||
|
||||
{
|
||||
"mutations": [
|
||||
{
|
||||
"create": {
|
||||
"_type": "post",
|
||||
"title": "New Post",
|
||||
"slug": {"_type": "slug", "current": "new-post"},
|
||||
"body": [{"_type": "block", "children": [{"_type": "span", "text": "Hello"}]}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Use `createOrReplace` instead if you want to upsert (requires `_id` field).
|
||||
|
||||
### Delete document
|
||||
|
||||
```bash
|
||||
POST https://{projectId}.api.sanity.io/v2024-01-01/data/mutate/{dataset}
|
||||
|
||||
{
|
||||
"mutations": [
|
||||
{"delete": {"id": "document-id"}}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Patch document
|
||||
|
||||
```bash
|
||||
POST https://{projectId}.api.sanity.io/v2024-01-01/data/mutate/{dataset}
|
||||
|
||||
{
|
||||
"mutations": [
|
||||
{
|
||||
"patch": {
|
||||
"id": "document-id",
|
||||
"set": {"title": "Updated Title"}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## CLI Commands
|
||||
|
||||
```bash
|
||||
# Create a new Sanity project
|
||||
sanity init
|
||||
|
||||
# Start the studio locally
|
||||
sanity dev
|
||||
|
||||
# Deploy studio to Sanity hosting
|
||||
sanity deploy
|
||||
|
||||
# Export dataset
|
||||
sanity dataset export production ./backup.tar.gz
|
||||
|
||||
# Import dataset
|
||||
sanity dataset import ./data.ndjson production
|
||||
|
||||
# List datasets
|
||||
sanity dataset list
|
||||
|
||||
# Run a GROQ query
|
||||
sanity documents query '*[_type == "post"][0..9]{title, slug}'
|
||||
```
|
||||
|
||||
## Key Objects
|
||||
|
||||
- **Document** — Top-level content item with `_id`, `_type`, `_rev`
|
||||
- **Asset** — Images and files stored in Sanity CDN
|
||||
- **Reference** — Link between documents (`{_type: "reference", _ref: "doc-id"}`)
|
||||
- **Portable Text** — Rich text as structured array of blocks
|
||||
- **Dataset** — Isolated content database (e.g., `production`, `staging`)
|
||||
- **Slug** — URL-friendly identifier (`{_type: "slug", current: "my-slug"}`)
|
||||
|
||||
## When to Use
|
||||
|
||||
- Structured content for marketing sites and blogs
|
||||
- Multi-channel content delivery (web, mobile, email)
|
||||
- Real-time collaborative editing workflows
|
||||
- Content-heavy sites with complex models
|
||||
- Next.js or React-based frontends
|
||||
|
||||
## Rate Limits
|
||||
|
||||
Rate limits vary by plan. Documented defaults:
|
||||
|
||||
- CDN API (queries): High throughput, globally distributed (no hard per-second cap published)
|
||||
- API (without CDN): Rate-limited per project (varies by plan)
|
||||
- Mutations: Rate-limited per project (varies by plan)
|
||||
- See [Sanity technical limits](https://www.sanity.io/docs/technical-limits) for current values
|
||||
|
||||
## Relevant Skills
|
||||
|
||||
- content-strategy (CMS selection, content modeling)
|
||||
- programmatic-seo (CMS as data source for generated pages)
|
||||
- site-architecture (URL structure from CMS slugs)
|
||||
@@ -0,0 +1,167 @@
|
||||
# Strapi
|
||||
|
||||
Open-source headless CMS with self-hosted option, REST and GraphQL APIs, and customizable admin panel. Targets Strapi 5.
|
||||
|
||||
## Capabilities
|
||||
|
||||
| Integration | Available | Notes |
|
||||
|-------------|-----------|-------|
|
||||
| API | ✓ | REST (default), GraphQL (plugin) |
|
||||
| MCP | - | No official MCP server |
|
||||
| CLI | ✓ | `strapi` CLI for project setup, content types, plugins |
|
||||
| SDK | ✓ | `@strapi/sdk-js`, `@strapi/blocks-react-renderer` |
|
||||
|
||||
## Authentication
|
||||
|
||||
- **Type**: API Token or Users & Permissions JWT
|
||||
- **Header**: `Authorization: Bearer {api_token}`
|
||||
- **Tokens**: Create in Settings → API Tokens (full access, read-only, or custom)
|
||||
- **JWT**: `POST /api/auth/local` with identifier + password returns JWT
|
||||
|
||||
## Common Agent Operations
|
||||
|
||||
### List documents
|
||||
|
||||
```bash
|
||||
GET http://localhost:1337/api/articles?populate=*
|
||||
|
||||
Authorization: Bearer {api_token}
|
||||
```
|
||||
|
||||
### Get single document
|
||||
|
||||
```bash
|
||||
GET http://localhost:1337/api/articles/{documentId}?populate=*
|
||||
|
||||
Authorization: Bearer {api_token}
|
||||
```
|
||||
|
||||
### Filter and sort
|
||||
|
||||
```bash
|
||||
# Filter by field
|
||||
GET http://localhost:1337/api/articles?filters[slug][$eq]=my-post
|
||||
|
||||
# Multiple filters
|
||||
GET http://localhost:1337/api/articles?filters[category][name][$eq]=Marketing&filters[publishedAt][$notNull]=true
|
||||
|
||||
# Sort
|
||||
GET http://localhost:1337/api/articles?sort=publishedAt:desc
|
||||
|
||||
# Pagination
|
||||
GET http://localhost:1337/api/articles?pagination[page]=1&pagination[pageSize]=10
|
||||
```
|
||||
|
||||
### Create document
|
||||
|
||||
```bash
|
||||
POST http://localhost:1337/api/articles
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer {api_token}
|
||||
|
||||
{
|
||||
"data": {
|
||||
"title": "New Article",
|
||||
"slug": "new-article",
|
||||
"body": "Article content here",
|
||||
"category": "{category_documentId}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Update document
|
||||
|
||||
```bash
|
||||
PUT http://localhost:1337/api/articles/{documentId}
|
||||
Content-Type: application/json
|
||||
Authorization: Bearer {api_token}
|
||||
|
||||
{
|
||||
"data": {
|
||||
"title": "Updated Title"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Delete document
|
||||
|
||||
```bash
|
||||
DELETE http://localhost:1337/api/articles/{documentId}
|
||||
|
||||
Authorization: Bearer {api_token}
|
||||
```
|
||||
|
||||
### Get draft content
|
||||
|
||||
```bash
|
||||
# Strapi 5 uses status parameter (replaces v4 publicationState)
|
||||
GET http://localhost:1337/api/articles?status=draft
|
||||
|
||||
Authorization: Bearer {api_token}
|
||||
```
|
||||
|
||||
Publishing and unpublishing are managed through the Strapi admin panel or Document Service API (server-side). The public REST API does not expose dedicated publish/unpublish endpoints.
|
||||
|
||||
### Populate relations and components
|
||||
|
||||
```bash
|
||||
# Populate all relations
|
||||
GET http://localhost:1337/api/articles?populate=*
|
||||
|
||||
# Populate specific relations
|
||||
GET http://localhost:1337/api/articles?populate[0]=author&populate[1]=category
|
||||
|
||||
# Deep populate
|
||||
GET http://localhost:1337/api/articles?populate[author][populate]=avatar
|
||||
```
|
||||
|
||||
## CLI Commands
|
||||
|
||||
```bash
|
||||
# Create new Strapi project
|
||||
npx create-strapi@latest my-project
|
||||
|
||||
# Start development server
|
||||
strapi develop
|
||||
|
||||
# Build admin panel
|
||||
strapi build
|
||||
|
||||
# Generate content type
|
||||
strapi generate content-type
|
||||
|
||||
# Generate controller
|
||||
strapi generate controller
|
||||
|
||||
# Add GraphQL plugin
|
||||
npm install @strapi/plugin-graphql
|
||||
```
|
||||
|
||||
## Key Objects
|
||||
|
||||
- **Content Type** — Schema definition (collection type or single type)
|
||||
- **Document** — Content item identified by `documentId` (Strapi 5 pattern)
|
||||
- **Component** — Reusable field group (e.g., SEO fields, CTA block)
|
||||
- **Dynamic Zone** — Flexible content area accepting multiple component types
|
||||
- **Media** — Files managed through the Media Library
|
||||
- **Locale** — i18n locale for content translation (plugin-based)
|
||||
|
||||
## When to Use
|
||||
|
||||
- Self-hosted CMS with full data ownership
|
||||
- Budget-conscious projects (no per-seat pricing)
|
||||
- Custom admin panel or plugin requirements
|
||||
- Teams with DevOps capability
|
||||
- Projects needing both REST and GraphQL access
|
||||
|
||||
## Rate Limits
|
||||
|
||||
- Self-hosted: No built-in rate limits (configure via middleware or reverse proxy)
|
||||
- Strapi Cloud: Varies by plan
|
||||
- Recommended: Add rate limiting middleware for production APIs
|
||||
|
||||
## Relevant Skills
|
||||
|
||||
- content-strategy (CMS selection, content modeling)
|
||||
- programmatic-seo (CMS as data source for generated pages)
|
||||
- site-architecture (URL structure from CMS slugs)
|
||||
Reference in New Issue
Block a user