Content Manager (CMS)
When to use this skill
- When the user needs a "Blog", "Portfolio", "E-commerce Product List", or "Team Page".
- When the user asks to "connect Sanity/Strapi".
- When content needs to be editable by non-developers.
Workflow
- Selection: Choose the CMS logic.
- Sanity.io: (Cloud) Real-time, multi-user, hosted. Best for teams/rich-text heavy sites.
- Keystatic: (Local) Git-based. Free, simple, no-hosting. Best for solo devs.
- Custom Firebase: (DIY) Build your own Admin Panel on Firestore. Best if you want 100% UI control and already use Firebase Auth.
- Modeling: Define the content structure.
- Keystatic:
keystatic.config.ts.
- Sanity:
sanity/schemaTypes.
- Firebase: Define TypeScript Interfaces models (e.g.,
interface Post { ... }).
- Integration:
- Firebase: Use
getDocs(collection(db, "posts")).
Instructions
1. The Local Route (Keystatic)
Perfect for "Hardcoded but Editable".
- Setup: Install
@keystatic/core and @keystatic/next.
- Config: Create
keystatic.config.ts.export default config({
storage: { kind: 'local' },
collections: {
posts: collection({
label: 'Posts',
slugField: 'title',
schema: {
title: fields.slug({ name: { label: 'Title' } }),
content: fields.document({ label: 'Content' }),
},
path: 'content/posts/*',
}),
},
});
2. The Cloud Route (Sanity)
Always separate schemas into small files in sanity/schemaTypes/.
3. The DIY Route (Firebase)
Use the managing-databases skill to build the Admin Dashboard.
- Auth: Restrict
/admin to your uid.
- Storage: Use Firebase Storage for image uploads.
- Rich Text: You must install a library like Tiptap or Quill manually.
// post.ts
export default {
name: 'post',
type: 'document',
fields: [
{ name: 'title', type: 'string' },
{ name: 'image', type: 'image' }
]
}
2. The Fetching Layer
Create a lib/sanity.ts or services/cms.ts.
- Type Safety: Use tools like
sanity-typegen to ensure TypeScript knows your schema.
- Caching: Use
fetch(url, { next: { revalidate: 60 } }) for ISR.
3. Rich Text Rendering
Never dump raw HTML. Use PortableText (Sanity) or ReactMarkdown to render safe, styled content.
Self-Correction Checklist
- "Did I add the API keys to
.env?" -> Never hardcode tokens.
- "Is the dataset public or private?" -> specific read settings.
1---2name: managing-content3description: Integrates Headless CMS (Sanity, Strapi, Contentful) to manage dynamic content. Generates schemas, connects APIs, and builds type-safe frontend fetchers.4---5
6# Content Manager (CMS)
7
8## When to use this skill
9- When the user needs a "Blog", "Portfolio", "E-commerce Product List", or "Team Page".
10- When the user asks to "connect Sanity/Strapi".
11- When content needs to be editable by non-developers.
12
13## Workflow
141. **Selection**: Choose the CMS logic.
15 - **Sanity.io**: (Cloud) Real-time, multi-user, hosted. Best for teams/rich-text heavy sites.
16 - **Keystatic**: (Local) Git-based. Free, simple, no-hosting. Best for solo devs.
17 - **Custom Firebase**: (DIY) Build your own Admin Panel on Firestore. Best if you want 100% UI control and already use Firebase Auth.
182. **Modeling**: Define the content structure.
19 - *Keystatic*: `keystatic.config.ts`.
20 - *Sanity*: `sanity/schemaTypes`.
21 - *Firebase*: Define TypeScript Interfaces models (e.g., `interface Post { ... }`).
223. **Integration**:
23 - *Firebase*: Use `getDocs(collection(db, "posts"))`.
24
25## Instructions
26
27### 1. The Local Route (Keystatic)
28Perfect for "Hardcoded but Editable".
291. **Setup**: Install `@keystatic/core` and `@keystatic/next`.
302. **Config**: Create `keystatic.config.ts`.
31 ```typescript
32 export default config({
33 storage: { kind: 'local' },
34 collections: {
35 posts: collection({
36 label: 'Posts',
37 slugField: 'title',
38 schema: {
39 title: fields.slug({ name: { label: 'Title' } }),
40 content: fields.document({ label: 'Content' }),
41 },
42 path: 'content/posts/*',
43 }),
44 },
45 });
46 ```
47
48### 2. The Cloud Route (Sanity)
49Always separate schemas into small files in `sanity/schemaTypes/`.
50
51### 3. The DIY Route (Firebase)
52Use the `managing-databases` skill to build the Admin Dashboard.
53- **Auth**: Restrict `/admin` to your `uid`.
54- **Storage**: Use Firebase Storage for image uploads.
55- **Rich Text**: You must install a library like Tiptap or Quill manually.
56```javascript
57// post.ts
58export default {
59 name: 'post',
60 type: 'document',
61 fields: [
62 { name: 'title', type: 'string' },
63 { name: 'image', type: 'image' }
64 ]
65}
66```
67
68### 2. The Fetching Layer
69Create a `lib/sanity.ts` or `services/cms.ts`.
70- **Type Safety**: Use tools like `sanity-typegen` to ensure TypeScript knows your schema.
71- **Caching**: Use `fetch(url, { next: { revalidate: 60 } })` for ISR.
72
73### 3. Rich Text Rendering
74Never dump raw HTML. Use `PortableText` (Sanity) or `ReactMarkdown` to render safe, styled content.
75
76## Self-Correction Checklist
77- "Did I add the API keys to `.env`?" -> Never hardcode tokens.
78- "Is the dataset public or private?" -> specific read settings.