|
| 1 | +--- |
| 2 | +name: blog-to-docs |
| 3 | +description: > |
| 4 | + Convert ClickHouse blog content into docs pages. Use when porting a feature |
| 5 | + announcement, tutorial, or deep-dive from the blog into the docs site. |
| 6 | + Covers content extraction, asset handling, structural transformation, and |
| 7 | + voice conversion. |
| 8 | +--- |
| 9 | + |
| 10 | +# Blog-to-Docs Skill |
| 11 | + |
| 12 | +Convert blog posts (or blog sections) into docs pages. Blog content is |
| 13 | +marketing-adjacent and narrative; docs content is task-oriented and |
| 14 | +scannable. This skill covers the transformation process. |
| 15 | + |
| 16 | +## When to use |
| 17 | + |
| 18 | +- A Linear issue or request asks you to port blog content into docs |
| 19 | +- A new feature was announced in a blog post and needs a docs page |
| 20 | +- A blog post contains technical depth that belongs in the docs |
| 21 | + |
| 22 | +## Process |
| 23 | + |
| 24 | +### 1. Extract content from the blog |
| 25 | + |
| 26 | +Fetch the blog URL and extract **all** content from the relevant section. |
| 27 | +Request verbatim content, not a summary — you need every detail to avoid |
| 28 | +losing information during the conversion. |
| 29 | + |
| 30 | +After extraction, build an **exhaustive numbered checklist** of every |
| 31 | +distinct technical claim, fact, setting, default value, behavioral detail, |
| 32 | +caveat, and recommendation in the blog. This is the source-of-truth |
| 33 | +inventory — you will check every item against the docs later in step 8. |
| 34 | +Don't summarize; enumerate. |
| 35 | + |
| 36 | +### 2. Download assets |
| 37 | + |
| 38 | +Download all images and videos from the blog to |
| 39 | +`static/images/clickstack/<feature-name>/` (or the appropriate path). |
| 40 | + |
| 41 | +**Images:** Download as `.png` or `.jpg`. Name descriptively |
| 42 | +(`service-map-overview.png`, not `screenshot-1.png`). |
| 43 | + |
| 44 | +**Videos:** Download `.mp4` files. Keep them — MP4 at ~1MB is far better |
| 45 | +than converting to GIF (which would be 5-15x larger and lower quality). |
| 46 | + |
| 47 | +**Import pattern:** Import assets as webpack modules, not static paths. |
| 48 | +Static paths (`/images/...`) don't work reliably with the dev server. |
| 49 | + |
| 50 | +```jsx |
| 51 | +// Images — use IdealImage |
| 52 | +import Image from '@theme/IdealImage'; |
| 53 | +import overview from '@site/static/images/clickstack/feature/overview.png'; |
| 54 | +<Image img={overview} alt="Description" size="lg"/> |
| 55 | + |
| 56 | +// Videos — import as module, self-closing tag |
| 57 | +import demo from '@site/static/images/clickstack/feature/demo.mp4'; |
| 58 | +<video src={demo} autoPlay loop muted playsInline width="100%" /> |
| 59 | +``` |
| 60 | + |
| 61 | +**Do NOT use:** |
| 62 | +```html |
| 63 | +<!-- Static path — won't work in dev server --> |
| 64 | +<video src="/images/clickstack/feature/demo.mp4" ... /> |
| 65 | + |
| 66 | +<!-- Nested source tag — doesn't render in MDX --> |
| 67 | +<video> |
| 68 | + <source src={demo} type="video/mp4" /> |
| 69 | +</video> |
| 70 | +``` |
| 71 | + |
| 72 | +### 3. Read sibling pages |
| 73 | + |
| 74 | +Before writing, read 2-3 sibling pages in the target directory. Match: |
| 75 | +- Frontmatter fields and conventions |
| 76 | +- Section ordering patterns |
| 77 | +- H2 header style (task-oriented, not explainer-style) |
| 78 | +- Component usage (BetaBadge, VerticalStepper, Tabs, etc.) |
| 79 | + |
| 80 | +### 4. Restructure: blog framing to docs framing |
| 81 | + |
| 82 | +This is the critical transformation. Blog posts explain and narrate; docs |
| 83 | +pages orient and instruct. |
| 84 | + |
| 85 | +**Blog patterns to eliminate:** |
| 86 | +- "How it works" explainer sections — fold technical detail into the intro |
| 87 | + or the section where it's actionable |
| 88 | +- "Reading the map" / "Understanding X" headers — reframe as |
| 89 | + "Exploring X" or "Using X" (task-oriented) |
| 90 | +- "Controls" as a standalone section — merge with the section that uses them |
| 91 | +- Narrative buildup before the feature — lead with what it does, not the |
| 92 | + story of why it was built |
| 93 | +- Inline numbered lists like "(1) ... (2) ... (3) ..." — convert to |
| 94 | + markdown bullet or numbered lists |
| 95 | + |
| 96 | +**Docs patterns to apply:** |
| 97 | +- Intro paragraph: what it is + where to find it + prerequisites |
| 98 | +- H2s named after what you **do**, not what you **learn** |
| 99 | +- Fewer H2s (2-3 for a feature page, not 5) |
| 100 | +- Technical detail woven into context, not siloed in its own section |
| 101 | + |
| 102 | +**Example transformation:** |
| 103 | + |
| 104 | +Blog structure (5 sections): |
| 105 | +``` |
| 106 | +- Intro |
| 107 | +- Accessing service maps |
| 108 | +- Reading the map |
| 109 | +- Controls |
| 110 | +- How it works |
| 111 | +``` |
| 112 | + |
| 113 | +Docs structure (2 sections): |
| 114 | +``` |
| 115 | +- Intro (what it is + how it works + where to find it + prereqs) |
| 116 | +- Exploring the service map (nodes, edges, controls — all in one) |
| 117 | +- Trace-level service maps (the contextual variant) |
| 118 | +``` |
| 119 | + |
| 120 | +### 5. Convert voice |
| 121 | + |
| 122 | +Blog posts often use third person, marketing language, and narrative |
| 123 | +framing. Convert to docs voice per the **docs-drafting** skill: |
| 124 | + |
| 125 | +- "Teams can visualize..." → "Service maps visualize..." |
| 126 | +- "This highly requested feature..." → cut entirely |
| 127 | +- "We're excited to announce..." → cut entirely |
| 128 | +- "Users can explore..." → "Click **Service Map** to open..." |
| 129 | + |
| 130 | +The blog is the **source of truth** for technical claims. Don't weaken |
| 131 | +or second-guess what the blog says about how the feature works — but do |
| 132 | +strip the marketing wrapper. |
| 133 | + |
| 134 | +### 6. Handle beta/experimental status |
| 135 | + |
| 136 | +Check sibling pages for how they mark beta features. Don't use `:::note` |
| 137 | +admonitions for beta status — use the `<BetaBadge/>` component if that's |
| 138 | +what siblings use. |
| 139 | + |
| 140 | +```jsx |
| 141 | +import BetaBadge from '@theme/badges/BetaBadge'; |
| 142 | +<BetaBadge/> |
| 143 | +``` |
| 144 | + |
| 145 | +### 7. Add to sidebar |
| 146 | + |
| 147 | +Add the page to `sidebars.js` in the appropriate position. Check the |
| 148 | +logical ordering relative to sibling pages. |
| 149 | + |
| 150 | +### 8. Verify coverage |
| 151 | + |
| 152 | +After drafting, go back to the numbered checklist you built in step 1. |
| 153 | +Check **every item** against the current state of the docs — not just your |
| 154 | +draft, but also existing pages that may already cover it. For each item, |
| 155 | +mark one of: |
| 156 | + |
| 157 | +- **Covered** — already in docs (note where) |
| 158 | +- **Added** — you added it in this pass |
| 159 | +- **Blog-only** — intentionally left in blog (customer-specific, benchmark, narrative) |
| 160 | +- **Gap** — generalizable content not yet in docs → fix it now |
| 161 | + |
| 162 | +Present the results as a coverage table. Every item must be accounted for. |
| 163 | +Don't move on until there are zero gaps. |
| 164 | + |
| 165 | +**Generalizable technical content must be moved.** Every piece of |
| 166 | +technical guidance in the blog — commands, configuration, process steps, |
| 167 | +caveats, edge cases — belongs in the docs unless it is customer-specific. |
| 168 | + |
| 169 | +**Do not move customer-specific benchmarks or metrics.** Performance |
| 170 | +numbers, resource comparisons, and before/after metrics from a specific |
| 171 | +customer deployment read as marketing in technical reference docs, imply |
| 172 | +universal applicability they don't have, and belong in the blog only. |
| 173 | +The test: would this number be true for a different customer on different |
| 174 | +hardware? If not, leave it in the blog. |
| 175 | + |
| 176 | +### 9. Run drafting skill and pre-ship review |
| 177 | + |
| 178 | +Apply the **docs-drafting** skill for voice/style, then the |
| 179 | +**docs-pre-ship-review** skill before shipping. These are separate passes. |
| 180 | + |
| 181 | +## Link text should match the destination |
| 182 | + |
| 183 | +When linking to another docs page, the link text should describe what the |
| 184 | +reader will find at that destination — not the concept you're discussing. |
| 185 | + |
| 186 | +- "you need [ingesting trace data](/path/to/ingesting-data)" — link text |
| 187 | + matches the destination (the ingestion guide) |
| 188 | +- "you need [distributed tracing](/path/to/ingesting-data)" — link text |
| 189 | + describes a concept, but the destination is about ingestion. Misleading. |
| 190 | + |
| 191 | +## Screenshots over hollow tables |
| 192 | + |
| 193 | +If you have UI screenshots for controls or settings, use them instead of |
| 194 | +(or alongside) a description table. A table of control names and |
| 195 | +descriptions without visuals feels hollow. Individual screenshots with |
| 196 | +a one-line description are more useful: |
| 197 | + |
| 198 | +```markdown |
| 199 | +**Source selector** — filter the map to a specific trace source. |
| 200 | + |
| 201 | +<Image img={source_selector} alt="Source selector in toolbar" size="lg"/> |
| 202 | +``` |
| 203 | + |
| 204 | +## Unused assets |
| 205 | + |
| 206 | +Before committing, check the asset directory for unused files (screenshots |
| 207 | +with default names, duplicates, `.DS_Store`). Clean them up. |
0 commit comments