Convert HTML to Astro
Preserve observable output before improving architecture. Follow the checkpoints in order; skip only steps that are demonstrably inapplicable to the source.
Scale the workflow
- For one static page, keep the inventory and baseline concise, convert the single route, then verify build, assets, links, and responsive screenshots.
- For multiple pages or any interactivity, create route, dependency, and behavior matrices; prove one representative route before converting the rest.
- For an existing Astro project, inventory existing routes, integrations, aliases, styles, and commands before changing files. Never scaffold over it.
Load only the guidance the conversion needs
- Always read source inventory and baseline before inventory or baseline capture.
- Read Astro migration decisions before creating a target, changing routes, or modifying an existing Astro project.
- Read CSS and assets when the source has authored CSS, fonts, images, media, or URL-sensitive assets. Do not load it for a markup-only source with no asset migration.
- Read interactivity when the source contains scripts, inline handlers, forms, widgets, dialogs, or stateful behavior. Do not load it for a demonstrably static page.
- Always read verification before declaring parity or handing off the conversion.
Do not load every reference by default. Re-evaluate these triggers when later inventory reveals additional CSS, assets, routes, or behavior.
1. Establish the conversion contract
- Identify the source root and whether the target is new or existing.
- Record package manager, Astro version, deployment/output constraints, URL mapping, allowed integrations, and required browser support.
- State non-goals and decide whether fidelity or modernization wins when they conflict.
- Stop only for questions that materially change URLs, output mode, dependencies, or fidelity requirements.
2. Inventory every source page and dependency
- Enumerate HTML entry points and map each to its intended route.
- Record CSS source order, inline styles, scripts, handlers, forms, widgets, fonts, images, favicons, data files, and internal/external links.
- Classify interactions and their urgency without selecting a framework.
- Resolve
SKILL_DIR to this activated skill's directory (the directory containing this SKILL.md), then run the helper by absolute path so the command does not depend on the target project's working directory:
SKILL_DIR="<absolute-path-to-this-skill>"
node "${SKILL_DIR}/scripts/analyze-html.js" <html-file-or-source-directory> > inventory.json
For a multi-route conversion, write the intended mappings as a JSON array of { "source": "...", "route": "/.../" } objects and reject ambiguous output before creating pages:
node "${SKILL_DIR}/scripts/validate-route-map.js" route-map.json
Treat the report as evidence, not semantic HTML/CSS analysis. Do not infer shared components, route intent, CSS ownership, or framework choice from it. See source inventory and baseline.
Checkpoint: Account for every page, local asset, stylesheet, script, and external dependency.
3. Capture the source baseline
- Serve the unmodified source.
- Capture desktop/mobile screenshots and every breakpoint that changes layout.
- Record interactions, focus/keyboard behavior, form outcomes, metadata, links, console errors, and failed requests.
- Hash or otherwise protect source inputs from mutation.
Checkpoint: Reproduce the baseline before conversion.
4. Create or validate the minimal Astro foundation
- For a new target, use the current official
create astro flow with strict TypeScript and no UI integration by default.
- Build the untouched project before migrating source files.
- For an existing target, preserve its config, integrations, routes, aliases, styles, and commands.
- Keep opaque/unprocessed assets in
public/; place authored code and processed assets under src/.
Do not install React, Alpine, or another framework until source evidence requires it. See Astro migration decisions.
Checkpoint: Build the minimal or pre-existing target without overwriting project behavior.
5. Migrate one representative route's static surface
- Choose the route exercising the shared shell and representative styling or behavior.
- Create the matching
src/pages/ route.
- Preserve markup order, class names, CSS order, metadata, body attributes, and asset URLs with minimal transformation.
- Add only a thin layout for the document shell or already-proven shared metadata.
- List remaining interactive states explicitly.
Checkpoint: Build the route and reach structural/static parity before abstraction.
6. Stabilize CSS, fonts, and asset paths
- Preserve cascade order, specificity, custom properties, layers, keyframes, and media queries.
- Import authored CSS from
src/ when Astro should bundle it. Use scoped .astro <style> blocks only after selectors can safely change; use is:global deliberately.
- Keep opaque assets in
public/ initially. Move images to src/ and adopt astro:assets only after URL and dimension behavior is stable.
- Never split or rewrite CSS with regex-based semantic extraction.
See CSS and assets.
Checkpoint: Meet the agreed screenshot tolerance with JavaScript disabled where applicable.
7. Restore representative-route behavior
- Prefer processed Astro
<script> tags or imported local scripts for DOM events, progressive enhancement, analytics, and simple state.
- Use a custom element when reusable instance-local browser behavior benefits from lifecycle encapsulation.
- Add a UI framework only for justified source reuse, complex state, ecosystem constraints, or an explicit requirement.
- Apply
client:* only to supported framework components and select hydration from actual rendering and interaction priority.
- Preserve an unprocessed or inline legacy script only deliberately and document the tradeoff.
See interactivity.
Checkpoint: Match recorded visual, pointer, keyboard, focus, form, console, and network behavior.
8. Convert the remaining route matrix
- Convert each remaining entry point to its mapped
src/pages/ route.
- Preserve internal URLs, queries, hashes, canonical metadata, and page-specific body attributes.
- Verify each route immediately rather than deferring behavior checks.
- Record repeated structures as evidence for later extraction.
Checkpoint: Load every route without missing assets and pass its baseline comparisons.
9. Extract evidenced layouts and components
- Consolidate a shared shell only after multiple routes prove it is shared.
- Extract a component for verified reuse, isolated behavior, a meaningful semantic boundary, or testability.
- Keep page-specific markup local when abstraction only adds indirection.
- Re-run visual, link, and behavior checks after each extraction batch.
Checkpoint: Improve reuse without changing output or behavior.
10. Optimize and hand off
- Remove dead legacy files and dependencies only after equivalence is proven.
- Improve images, script loading, caching, metadata, semantics, accessibility, and performance in isolated changes.
- Run available format, lint, typecheck, test, build, and production-preview checks.
- Verify routes, assets, links, breakpoints, interactions, metadata, console/network cleanliness, and accessibility smoke checks.
- Report intentional differences, deferred cleanup, installed integrations, and deployment assumptions.
Use verification for proportional evidence and final reporting.
Checkpoint: Provide reproducible evidence for parity and every intentional difference.
Failure branches
- Duplicate or invalid routes: Stop page creation, run the route-map validator, and resolve every collision explicitly. Never let filesystem overwrite order choose the winner.
- Non-empty target: Inventory the target as an existing Astro project or choose a separate empty destination. Never scaffold into it merely because expected Astro files are absent.
- Malformed HTML: Keep the lexical inventory, but use a standards-aware HTML parser or browser DOM to establish intended structure. Record browser repairs instead of silently treating repaired markup as source markup.
- Unreadable input or asset: Report the exact path and preserve the failure. Do not replace it with an empty placeholder or omit it from the inventory.
- Unavailable browser tooling: Build and perform static checks, but report visual and behavioral parity as unverified. Do not substitute DOM inspection for screenshot or interaction evidence.
- Non-deterministic third-party content: Capture the dependency and expected contract, then use a deterministic local stub or explicitly exclude it from pixel comparison. Never claim parity from a changing live response.
- Build or preview mismatch: Treat production preview as authoritative for deployment behavior; isolate config, base-path, adapter, and asset-URL differences before optimizing.
Never cross these fidelity boundaries
- Never mutate source inputs; doing so destroys the baseline needed to distinguish migration defects from source changes.
- Never componentize or optimize before parity; combined structural and behavioral changes make regressions difficult to attribute.
- Never install a UI framework by default; unnecessary hydration changes runtime, dependency, and failure surfaces without source evidence.
- Never perform semantic CSS extraction without a standards-aware parser and dedicated tests; regex cannot safely model nested rules, keyframes, comments, strings, or data URLs.
- Never claim visual or behavioral parity from a successful build alone; build success does not exercise rendering, assets, focus, forms, or client-side behavior.
- Resolve bundled resources relative to this skill directory; do not assume a fixed installation path.
- Prefer current official Astro documentation when version-sensitive behavior differs from these instructions.