← All playbooks · Raw API
articles
# Articles — SE Studio
## Routing
Public URLs use the **article type** as the first path segment (not a generic `/articles` prefix). Primary tag is **not** in the path.
| Type | Public URL pattern | Example |
|------|--------------------|---------|
| Case study (`work`) | `/work/{client}/{title-slug}/` | `https://www.se.studio/work/arcticdb/an-identity-with-scale/` |
| Blog (`blog`) | `/blog/{slug}/` | `https://www.se.studio/blog/ask-your-website-anything/` |
| Video (`video`) | `/video/{slug}/` | — |
**CMS slug** (Contentful) is without the type prefix:
- Case study: `{client}/{title-slug}` e.g. `arcticdb/an-identity-with-scale`
- Blog: single segment e.g. `ask-your-website-anything`
Read `cms-edit://customer/routing` and `production-site` before guessing markdown/preview URLs. Tag indexes and people indexes are **disabled**.
### Lab / test ports
When porting or experimenting with multi-block composition, create a **new** draft — never edit the live published entry:
| Field | Lab value |
|-------|-----------|
| `slug` | `lab/{original-slug}` e.g. `lab/arcticdb/an-identity-with-scale` |
| `hidden` | `true` |
| `indexed` | `false` |
| `cmsLabel` | prefix `LAB \| …` |
Do not publish lab articles.
## Article types (required)
Every article must link to an **articleType**. List types before creating:
```bash
cms-edit list --type articleType
```
| Type | Slug | Use for |
|------|------|---------|
| **Case study** | `work` | Client project stories — primary content type |
| **Blog** | `blog` | Studio thought leadership, product posts |
| **Video** | `video` | Video-led pieces |
Prefer `--article-type-slug work` (or `blog`, `video`) — marketers should not need Contentful entry IDs.
```bash
cms-edit list --type article --article-type-slug work
cms-edit list --type article --article-type-slug blog
```
## Template
Articles use **Article Template** (`18bSfHlEeNVisz9PWtOso0`). It provides **Article hero** (and related shell) in `preContent` and **Related articles** in `postContent` — do **not** duplicate hero or related collections in article `content`.
```bash
cms-edit peek --template-label "Article Template"
```
## Discoverability (SEO) — mandatory
Agents **must not** save a new or ported article without a strong meta description. Discoverability is a first-class requirement, not an afterthought.
| Field | Rule |
|-------|------|
| `title` | Full human headline for the piece (H1 in hero). **Not** the client name alone (bad: `OM1`). Include searchable terms (brand, website, campaign, industry). |
| `subtitle` | Case study: client or series name (hero client line). |
| `description` | **Required.** **120–160 characters.** Must include: **who** (client or topic) + **what SE delivered** + **outcome or differentiator**. No empty string, no “Learn more…”, no single clause under 100 chars. Draft from **existing source copy only** — do not invent claims. |
| `summary` | Rich-text hero summary when the template expects it — distinct from meta `description`. |
| `slug` | Stable kebab path; lab uses `lab/…`. |
### Good vs bad meta descriptions
**Good (case study, ~158 chars):**
> Brand identity for ArcticDB — built to signal technical credibility and bold innovation in fintech. Bold logomark, data-science typography, designed to scale.
**Good (blog, ~150 chars):**
> What if your marketing team could ask their website anything — and act on the answer instantly? SE Studio's AI content integration makes it a reality.
**Bad — refuse save until fixed:**
- `OM1 case study` (too short, no delivery detail)
- `Learn more about our work with healthcare brands.` (generic, no who/what)
- Missing `description` entirely
**Gate:** Before `create from-json` real run or final `save`, count `description` length. If < 100 or > 165, revise. Prefer 120–160.
Also see `task-seo-descriptions` and `task-create-article`.
## Source packages (Drive, Figma, docs)
Before building from an external package:
1. Run **`task-source-readiness-review`** (inventory → beat sheet → GO / GO-WITH-GAPS / NO-GO).
2. Post a **soft-proof** (numbered `content` order + gaps).
3. Get a light human **yes** / **go** / **proceed**.
4. **Do not rewrite source copy** — structure and place only.
5. Full package workflow: **`cms-edit://customer/case-study-from-package`**. Figma problems listed there are **NO-GO** and override a generic GO from `task-source-readiness-review`.
### Source hierarchy (when sources disagree)
1. **Sequence & layout** — Figma / approved comps
2. **Art files** — Drive / export
3. **Words** — approved copy (as written)
4. **CMS patterns** — production / this playbook (how to map, not what to invent)
## Reference articles
| CMS slug | Type | Notes |
|----------|------|-------|
| `arcticdb/an-identity-with-scale` | Case study | Client in `subtitle`; sibling text, images, and a quote |
| `microsoft/meet-the-makers` | Case study | Simpler image set — good multi-block lab source |
| `ask-your-website-anything` | Blog | Blog RTF layout; public path `/blog/…` |
```bash
cms-edit peek --article-slug /arcticdb/an-identity-with-scale
```
Production markdown (structure reference): append `.md` to the **public** path from `production-site` (e.g. `https://www.se.studio/work/arcticdb/an-identity-with-scale.md`).
## Article fields
| Field | Guidance |
|-------|----------|
| `title` | Full headline — discoverable (see SEO above) |
| `subtitle` | Client or series — hero client line |
| `description` | SEO meta — **required**, 120–160 chars (see SEO above) |
| `slug` | No leading slash; case study `client/title-slug`; lab `lab/…` |
| `date` | Publication date (ISO) |
| `articleType` | Required |
| `featuredImage` | OG/social — **landscape** preferred |
| `visuals` | Article-level hero/listing media only — **not** body image dumps |
| `summary` | Hero summary RTF |
| `tags` | Optional; public tag pages disabled |
| `hidden` / `indexed` | Lab: `hidden true`, `indexed false`. Production: `hidden false`, `indexed true` unless unlisted |
## Composition patterns
### Body component types (choose by article type)
| `componentType` | Use for |
|-----------------|---------|
| **Case study rich text** | **Preferred** for new / lab **work** multi-block bodies |
| **Blog rich text** | **Preferred** for new / lab **blog** multi-block bodies |
| **Article rich text** | **Legacy only** — existing production entries (layout still branches blog vs work by page type) |
Do not create new multi-block work articles with Article rich text when Case study rich text is available.
### A — Work articles (sibling blocks)
Work case studies use sibling blocks in `content`. The site spaces those siblings. A picture or quote inside a rich text body, or on Case study rich text `visual`, never receives the gap.
| Pair (either order) | Below 1024px | From 1024px |
|---------------------|--------------|-------------|
| Image and text | 48px | 48px |
| Text and quote | 128px | 96px |
| Image and quote | 96px | 96px |
| Image and image | 16px | 16px |
Text against text is not in that list. Adjacent prose blocks sit flush, so merge them.
- Copy in **Case study rich text** with `visual` empty.
- One image, or a row of three or more, is **Visuals**. Keep the Media `width` and `horizontalPosition`. Empty width stays empty (full column) and needs a visual check.
- A pair that is already **Separated visuals**, or a row that is already one **Visuals** entry, stays that entry. Do not invent a pair from two stacked images.
- A pull quote is **Centered quote**, **Wide quote**, or **Right aligned quote**.
- **Article rich text** with embedded pictures is the old shape. Split a work article in source order into the siblings above. Do not rewrite the words.
- Blog pages stay on **Blog rich text** or legacy **Article rich text**. Do not run this split on a blog.
- Article `featuredImage` and `visuals` stay the share image and the `-hero` / `-home` media. Do not move those into the body.
### B — Multi-block (preferred for new agent-built / lab work)
**Faithful sequence first.** Multiple siblings in article `content`, ordered like the design/source — not “CMS convenience.”
```
[template] Article hero …
Case study rich text (work, copy only) OR Blog rich text (blog, copy and optional visual)
Visuals — work: one image, or a row of 3+
Separated visuals — a designed pair
…
Centered quote — optional sibling when source has a pull quote
[template] Related articles …
```
**Mapping decision table:**
| Source signal | CMS mapping |
|---------------|-------------|
| Continuous prose (no art between) | **One** CSRT/BRT body — **merge** paragraphs; do not split body-only blocks |
| Work: one image | **Visuals** sibling. Set Media `width` and `horizontalPosition`. Empty width is full column |
| Work: image then prose | **Visuals**, then Case study rich text with `visual` empty |
| Blog: single feature image + prose | Blog rich text with field `visual` |
| True side-by-side pair in design | **Separated visuals** between body blocks |
| 3+ in one row | **Visuals** collection |
| Quote pull | Centered / wide / right quote as appropriate |
| Decorative loop demo | Media inside Visuals or Separated; **autoplay + loop** when decorative |
| Missing frame (GO-WITH-GAPS) | Keep the slot; **labeled placeholder** — do not renumber |
**Rules:**
1. Page title stays on the article entry / hero — block `heading` is a **section title** (section typography, not display 96–200px). Omit when the design has no section title.
2. Section titles may use **CMS `heading`** and/or **headings inside body RTF** (`##` / `###`) only when the **source** has them — do not invent.
3. **Separated visuals only for true pairs** — not the default for “two images nearby.” Stacked editorial images on a **work** article → one **Visuals** entry each.
4. **Grids (3+)** → top-level **Visuals** collection when the design is one row.
5. **Work single image** → **Visuals**, not Case study rich text `visual`. Set width from the frame. Empty width renders full column.
6. **Work media-before-copy:** a Visuals block, then a Case study rich text block with `visual` empty. Blog rich text may still put one image on its `visual` field.
7. Do **not** put the whole body image set only on article `visuals`. Article `visuals` is the `-hero` / `-home` role media.
8. Prefer incremental `open` → `add` / `set` / `rtf` over one giant `from-json`.
9. Labels: rename default cmsLabels; lab uses `LAB | …`.
10. **Spacing:** On a work article the gaps in section A come from the sibling stack. Merge continuous prose into one Case study rich text block. Do not invent empty paragraphs to make space. Do not leave a picture on `visual` or embedded in the body.
Read: `components/case-study-rich-text`, `components/blog-rich-text`, `components/article-rich-text` (legacy), `collections/separated-visuals`, `collections/visuals`, `case-study-from-package`.
## Featured images
Read `cms-edit://customer/defaults`.
1. **Custom** — set `featuredImage` / `featuredImageAssetFilename` when provided
2. **Article type default** — inherit if omitted
3. **Site default** — asset `5OU6quGThpQuSJFSbxHsHZ`
Landscape for OG. On a **case study**, a file ending `-hero` is Media on `article.visuals` (the page hero). A file ending `-home` is also Media on `article.visuals` (the work-grid preview). A file ending `-og` is `featuredImage` (the share image). Do not place the hero or work-grid asset in `content`.
## Creating articles
1. Read this playbook + `components-index` + `defaults` + `routing`
2. External package → **`task-source-readiness-review`** + soft-proof + light human yes
3. `index sync` if catalog may be stale
4. Resolve article type
5. **Write SEO fields** (`title`, `description` 120–160 from source claims only, `subtitle`) — refuse thin descriptions
6. Soft-proof the sibling structure in section A. A single Article rich text with embeds is not the work pattern.
7. Lab ports: `lab/…` + `hidden` + unindexed
8. `create from-json --dry-run --strict` or incremental create — **copy unchanged**
9. `diff` → `save`
10. `preview urls` + **`task-preview-verify`** multi-block checklist
### Case study from a package (preferred path)
1. `task-source-readiness-review` → see also **`case-study-from-package`**
2. Doc/Figma title → full `title`; client → `subtitle`; slug → `{client}/{kebab-title}` (or `lab/…`)
3. Soft-proof → copy in **Case study rich text** (no `visual`); one image or a 3+ row in **Visuals**; Separated **only** for true pairs. Figma NO-GO in `case-study-from-package` blocks create
4. Draft SEO description from the brief (120–160 chars) **before** create — no invented claims
5. `articleTypeSlug`: `work`
### Blog from a document
Same readiness + SEO gates; `articleTypeSlug`: `blog`; single-segment slug (or `lab/{slug}`); body blocks use **Blog rich text**.
## After save — preview
```
cms-edit preview urls <cms-slug>
```
Map CMS slug to public path: case study → `/work/{cms-slug}/`, blog → `/blog/{cms-slug}/`.
## Publish handoff
`save` creates **drafts only**. Publish in Contentful UI when ready. **Never publish lab articles** without explicit human request.