Adds the Canvas Storybook AI website-to-components migration pipeline to a DDEV project.
website-to-components/— pipeline scripts that screenshot a live site, detect visual sections, and generate React components ready for Storybook and Drupal Canvasddev clone— command to kick off the migration pipeline against a URL- agent-browser — Chromium-based browser automation (installed standalone; safe to use alongside FreelyGive/DDEV-Canvas)
- Claude skills — migration-specific skills added to
.claude/skills/:website-to-components,website-to-components-multipagemigration-component-authoring,migration-create-component,migration-storiesacquia-source-setup,acquia-source-docs-explorertypography-audit,webpage-sections-splitter
- DDEV v1.23+
- Docker
- Claude Code authenticated (
ddev claudeonce, orclaudeon host)
ddev clone <url> --scope site discovers pages automatically — no external
dependency required:
- Reads
sitemap.xml(withsitemap_index.xmlandrobots.txtfallbacks). - Validates each URL over HTTP: keeps only URLs that return HTTP 200, did not
redirect, are not marked
noindex(viaX-Robots-Tagheader or<meta name="robots">tag), and whose<link rel="canonical">(if present) points to themselves. - Falls back to menu-reachable discovery if no sitemap is found.
Menus are always derived from on-page navigation, never from the sitemap. No claude-seo plugin or Python runtime required.
ddev add-on get FreelyGive/DDEV-migration-addon
ddev restartCan be used standalone or alongside the base Canvas addon:
ddev add-on get FreelyGive/DDEV-Canvas
ddev add-on get FreelyGive/DDEV-migration-addon
ddev restart# Screenshot a site and generate components
ddev clone https://your-site.com
# Multi-page migration
ddev exec node website-to-components/scripts/run-multipage.js https://your-site.com
# Then launch Claude to build the components
ddev claudeThe migration pipeline runs inside the DDEV web container. Results are written to website-to-components/output/.
Run ddev canvas-bootstrap once (from the host) before your first
ddev clone. It is a host command (it uses drush in the web container and
writes the host storybook/.env), idempotent, and safe to re-run. It:
- enables JSON:API read/write,
- ensures a usable OAuth consumer exists — reusing any consumer that already has the Client-Credentials grant and an assigned user, or creating one otherwise (without an assigned user the Canvas REST API returns 401),
- enables revisions on the
pagecontent type (so re-runs upsert safely), - writes
CANVAS_LOCAL_SITE_URL(the public.ddev.siteURL),CANVAS_LOCAL_CLIENT_ID,CANVAS_LOCAL_CLIENT_SECRET, andCANVAS_LOCAL_JSONAPI_PREFIXintostorybook/.env. On the reuse path the existing secret is preserved (a hashed consumer secret cannot be recovered).
The local OAuth scope is canvas:asset_library canvas:js_component (the member
scope is remote/Acquia-only and is invalid locally).
ddev clone reminds you to run it; because it cannot call a host command from
inside the nodejs container, it does not run bootstrap inline.