--- name: migrate-to-cloudcannon description: >- Migrate an existing SSG site to work with CloudCannon. Use when the user wants to onboard a site to CloudCannon, add CMS support, or make a template CloudCannon-compatible. --- # Migrating to CloudCannon This skill orchestrates a full migration of an existing SSG site to CloudCannon. It coordinates five phases, delegating domain-specific work to standalone skills that can also be used independently. > **Model recommendation:** Migrations involve multi-file architectural decisions across five phases. Use a high-reasoning model (not a fast/lightweight one) for best results. **MUST:** run the migration as its orchestrator. Read [orchestration.md](orchestration.md) before Phase 1, then dispatch each phase to a subagent and keep the user conversation yourself. On a host without subagents, run the phases yourself in order. ## When to use - An existing SSG site needs to work with CloudCannon end to end - A site template needs to be made CloudCannon-compatible - A site is being generated as part of the task (e.g. from WordPress) and should land CloudCannon-ready ## When not to use - **The site is already on CloudCannon and needs one piece added** — go straight to the capability skill: [`cloudcannon-configuration`](../cloudcannon-configuration/SKILL.md), [`cloudcannon-snippets`](../cloudcannon-snippets/SKILL.md), or [`cloudcannon-visual-editing`](../cloudcannon-visual-editing/SKILL.md) - **Only multilingual or translation work is wanted** — [`make-site-multilingual`](../make-site-multilingual/SKILL.md), then [`translate-site`](../translate-site/SKILL.md). Neither is part of the five phases. - **One CloudCannon feature is misbehaving on a working site** — the capability skill that owns it, not a full migration ## Contents | File | Covers | | -------------------------------------------------------- | ------------------------------------------------------------------------ | | **SKILL.md** (this file) | The five phases, handoff readiness, naming conventions, common mistakes | | [astro/overview.md](astro/overview.md) | **Start here for Astro** — the per-phase guides | | [hugo/overview.md](hugo/overview.md) | **Start here for Hugo** — the per-phase guides | | [eleventy/overview.md](eleventy/overview.md) | **Start here for Eleventy** — the per-phase guides | | [audit.md](audit.md) | Shared audit rules — classifying static pages | | [page-building.md](page-building.md) | Read when the census sends pages to a `pages` collection or page builder | | [cc-friendly-conventions.md](cc-friendly-conventions.md) | Shared-UI treatment table | | [orchestration.md](orchestration.md) | Running phases in subagents, questions, verification, sizing | | [handoff.md](handoff.md) | Closing with the user — who tests what, and what to ask back | | [reading-order.md](reading-order.md) | Which docs to read in which phase, and when to skip them | | [scripts/README.md](scripts/README.md) | Automation scripts for the deterministic steps | ## Supported SSGs | SSG | Guide | | -------- | -------------------------------------------- | | Astro | [astro/overview.md](astro/overview.md) | | Hugo | [hugo/overview.md](hugo/overview.md) | | Eleventy | [eleventy/overview.md](eleventy/overview.md) | ## Chaining with upstream skills If the site is being **generated** as part of this task (e.g. converting from WordPress), read the target SSG's scaffolding conventions before scaffolding — Astro: [astro/cc-friendly-conventions.md](astro/cc-friendly-conventions.md) — it covers the structural choices that make the migration smooth. Once scaffolded, return here and run the migration phases. ## Step 1: Detect the SSG Run from the project root: ```bash npx @cloudcannon/cli configure detect-ssg ``` Use the detected SSG to pick the correct guide above. ## Migration phases Each SSG guide walks through these in order. Phases that delegate to standalone skills are marked below. 1. **Audit** — Analyze content structure, components, routing, and build pipeline before changing anything. 2. **Configuration** — Generate and customize CloudCannon config files. - Read the `cloudcannon-configuration` skill. - If content uses components (MDX components, Hugo or Eleventy shortcodes) or inline HTML, also read the `cloudcannon-snippets` skill. 3. **Content** — Restructure content files if needed so they're CMS-friendly. 4. **Visual editing** — Add editable regions for CloudCannon's Visual Editor. - Read the `cloudcannon-visual-editing` skill. 5. **Build and test** — Validate the migration end-to-end. Not every site needs all phases. Small sites may skip Phase 3 if content is already well-structured. Phase 4 is optional but high-value. ### Per-phase workflow The phase subagent does steps 1–4; the orchestrator does step 5. See [orchestration.md](orchestration.md). 1. **Read** the phase doc end-to-end before touching any files. 2. **Track** one task per checklist item in that phase doc, using the host's task/todo tool. If there is none, keep the checklist in the phase's migration note and tick items off there. Set the task `in_progress` before starting it; mark `completed` only when the checklist item is satisfied. Do not batch-complete tasks at the end of the phase. 3. **Do the work** — small, mechanical cross-phase fixes (adding a missing field, normalizing a value) are fine in any phase; list each in the return. Structural changes (moving files, reorganizing collections, altering rendering) wait for their proper phase. 4. **Write** `.cloudcannon/migration/.md` with findings, plus two sections later phases rely on: - **Decisions and why** — each choice and the reason, so later phases follow it instead of re-deciding - **Open questions** — non-blocking questions for the user, each with the default taken 5. **Verify the handoff readiness row below**, by the orchestrator or a fresh verifier per [orchestration.md § Verification](orchestration.md#verification). Never by the subagent that did the phase. **Why:** checklists catch things agents otherwise skim past — data collections missing from `collections_config`, `data_config` entries missing for referenced data files, blog/detail page editables skipped while focusing on page-builder blocks, arrays not linked to structures. Per-item tracking makes the skim visible. ### Phase handoff readiness These rows define what must be true before the next phase's subagent starts. Cross-phase fixes (per step 3 above) are still fine. | After phase | Ready for handoff when… | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **1. Audit** | `.cloudcannon/migration/audit.md` exists, contains the census table, and lists every collection + every page route. Sizing thresholds ([orchestration.md § Sizing](orchestration.md#sizing)) have been evaluated; if tripped, `.cloudcannon/migration/plan.md` exists. | | **2. Configuration** | `cloudcannon.config.yml` validates against the published JSON schema (no IDE red squigglies). Every collection in the audit has a `collections_config` entry; every referenced data file has a `data_config` entry. `.cloudcannon/migration/configuration.md` written. | | **3. Content** | All structural content changes from Phase 2 are reflected in the files. `npm run build` (or project equivalent) succeeds. `.cloudcannon/migration/content.md` written. | | **4. Visual editing** | Every audit census row with a yes in **Needs editable region?** has been wired or has a documented justification for not being wired. Every component used inside a wrapped section can re-render — registered (Astro: `registerComponents.ts`) or resolvable (Hugo: a partial; Eleventy: a Liquid include — Nunjucks sections use primitive regions only). `.cloudcannon/migration/visual-editing.md` written. | | **5. Build and test** | Production build succeeds locally. User has run their CloudCannon-side verification (preview, inline edit, save-to-git). `.cloudcannon/migration/build.md` written. | ## Scripts Deterministic migration steps are automated as scripts in [scripts/](scripts/). Run these before or during the relevant phase. ## Migration notes All written to `.cloudcannon/migration/` (under `.cloudcannon/` so the CLI doesn't detect the folder as a collection): one file per phase (`audit.md`, `configuration.md`, `content.md`, `visual-editing.md`, `build.md`), plus `plan.md` if the migration is sectioned. See the per-phase workflow above for the gates that consume each file. ## Naming conventions Follow existing project conventions when present. Otherwise: - `kebab-case` for files - `camelCase` for JavaScript and JSON - Markdown frontmatter and YAML: match existing component prop names so frontmatter keys pass through without translation - New fields with no existing convention: prefer `snake_case` ## Cross-references for known pitfalls For specific architectural decisions and config-syntax mistakes, see: | Topic | Astro | Hugo | Eleventy | | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | Classifying static pages (source-editable vs page-builder vs collection) | [audit.md § Classifying static pages](audit.md#classifying-static-pages), then [astro/audit.md](astro/audit.md#classifying-static-pages-source-editables-vs-content-collection) | [hugo/audit.md § Classifying static pages](hugo/audit.md#classifying-static-pages) | [eleventy/audit.md § Classifying static pages](eleventy/audit.md#classifying-static-pages) | | Home page filename, collection-of-one | [page-building.md § Common mistakes](page-building.md#common-mistakes), then [astro/page-building.md § Pages collection cheatsheet](astro/page-building.md#pages-collection-cheatsheet) | [hugo/page-building.md § Common mistakes](hugo/page-building.md#common-mistakes) | [eleventy/page-building.md § Common mistakes](eleventy/page-building.md#common-mistakes) | | Shared UI (CTA banners, footers, share blocks) | [cc-friendly-conventions.md § Shared-UI treatment table](cc-friendly-conventions.md#shared-ui-treatment-table) | Same table | Same table | | Multi-schema collections | [../cloudcannon-configuration/astro/configuration.md § Schemas](../cloudcannon-configuration/astro/configuration.md#schemas) | [../cloudcannon-configuration/hugo/configuration.md § Schemas](../cloudcannon-configuration/hugo/configuration.md#schemas) | [../cloudcannon-configuration/schemas.md](../cloudcannon-configuration/schemas.md) | | Config-syntax hallucinations (wrong keys/types) | [`cloudcannon-configuration` § Invalid keys](../cloudcannon-configuration/SKILL.md#invalid-keys) | Same | Same | | Build verification | [build.md § Build verification checklist](build.md#build-verification-checklist), then [astro/build.md](astro/build.md#build-verification-checklist) | [build.md](build.md#build-verification-checklist), then [hugo/build.md](hugo/build.md#build-verification-checklist) | [build.md](build.md#build-verification-checklist), then [eleventy/build.md](eleventy/build.md#build-verification-checklist) | ## Common mistakes | Excuse | Reality | | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | "This site is simple enough to skip the audit" | The audit catches structural issues early. Skipping it means discovering problems mid-configuration. | | "I'll do the checklist at the end" | Read checklists BEFORE starting each phase. They tell you what to aim for. | | "Content restructuring can wait" | If a missing field blocks configuration, add it now. Phases are sequential, not siloed. | | "Visual editing is optional so I'll skip it" | It's the highest-value phase for editors. Only skip if the user explicitly says so. | | "The build passes so we're done" | A passing build doesn't mean the editor works. The user must verify in CloudCannon. | | "I'll call the homepage file `home.md` — it's more descriptive" | CloudCannon resolves the URL from the slug; `home.md` with `url: "/[slug]/"` → `/home/`. Use the SSG's index filename so the slug collapses to `/` — Astro: `index.md`; Hugo: `content/_index.md`; Eleventy: `index.md` in the input directory. | | "It's hardcoded, so it's developer-only" | If an editor can see it on the page, they must be able to edit it. The mechanism depends on the page: shared UI (CTA banners, footers, share blocks, author cards) → data file; pages whose sections editors add, remove or reorder → page-builder `pages` collection entry; long-form prose page → `default` schema in the `pages` collection; one-off page whose structure stays with the developer → `data-editable="source"`. See [cc-friendly-conventions.md § Shared-UI treatment table](cc-friendly-conventions.md#shared-ui-treatment-table) and [page-building.md § When to reach for a page builder](page-building.md#when-to-reach-for-a-page-builder). | | "This page is unique so it should be source-editable" | Uniqueness isn't the test. Page builder is the default; source editables need every condition in [page-building.md § When to reach for a page builder](page-building.md#when-to-reach-for-a-page-builder). | | "I'll make a single-entry `homepage` collection" | Use one `pages` collection with `index.md` as one entry. Add `our-team.md`, `about.md`, etc. as more entries. CloudCannon collections support multiple schemas per collection — via `schemas:` config, and in Astro also via Zod `z.union` in the content config. See [../cloudcannon-configuration/schemas.md](../cloudcannon-configuration/schemas.md). | | "Page builder is overkill for these few pages" | Page builder is the default when the project owns its layouts and has more than one unique-layout page. Pages a theme renders keep the theme's model — see [audit.md § Classifying static pages](audit.md#classifying-static-pages). The cost is a catch-all route plus a block dispatcher — Astro: `[...slug].astro` + `BlockRenderer`; Hugo: a `range` over `content_blocks` in the page layout; Eleventy: a `for` loop over `content_blocks` in the layout. All are mechanical. The benefit is editors can add new pages without engineering. |