WORK-089
ID:WORK-089Status:in-progress

Create @refrakt-md/astro adapter package

Build the Astro framework adapter — the first non-SvelteKit target. Astro is MPA-first and SSG-focused, making it the simplest adapter to build and validate.

Priority:highComplexity:moderateMilestone:v1.0.0Source:ADR-001,SPEC-013,SPEC-030,SPEC-031
changeset-release/main View source

Criteria completion

No incremental history — criteria tracking started on Apr 19.

Branches 3
History 8
  1. f2b3512
    Content editedby Claude
    Add {ID}-{slug}.md filename convention + migrate filenames subcommand
  2. 59ded4a
    Content editedby Claude
    Implement SPEC-037 plan package hardening: all 7 work items
  3. f262d7b
    Content editedby Claude
    Backfill source attributes on all 123 work items
  4. e5a255f
    Content editedby Claude
    Implement SPEC-030 Phase 0 + Phase 1: shared utility extraction and Astr
  5. 11e81a8
    Content editedby Claude
    Add framework work items to v1.0.0 milestone
  6. 982a9db
    Content editedby Claude
    Add documentation ACs to adapter work items and create WORK-093
  7. cf1b816
    Content editedby Claude
    Update WORK-089 with islands-aware behavior loading and @astrojs/markdoc
  8. ead9531
    Created (in-progress)by Claude
    Add work items WORK-088 through WORK-092 for framework adapter system

Acceptance Criteria

  • packages/astro/ package exists with correct package.json (peer dep astro@^5.0.0)
  • Astro integration (integration.ts) reads refrakt.config.json, injects Lumina CSS, configures SSR noExternal list
  • BaseLayout.astro selects layout via matchRouteRule(), runs layoutTransform(), renders via renderToHtml() + set:html
  • SEO meta tags (Open Graph, JSON-LD) rendered in <head> from page SEO data
  • Behavior initialization script calls initRuneBehaviors(), initLayoutBehaviors(), registerElements() and sets RfContext
  • Behavior script conditionally included — only on pages that use interactive runes (tabs, accordion, datatable, etc.), shipping zero JS for static-only pages
  • Content loading works via getStaticPaths() using loadContent()
  • AstroTheme type interface exported for theme authors
  • Lumina Astro adapter exists (packages/lumina/astro/index.ts) exporting theme config + CSS entry point
  • Content HMR works in dev mode via Vite server.watcher
  • Example site renders core runes, layouts (docs + default), behaviors, and web components correctly
  • Adapter documentation page at site/content/docs/adapters/astro.md with installation, project structure, configuration, code examples (integration setup, page component, layout, content loading, behavior init, SEO injection), and getting-started guide matching the depth of existing SvelteKit adapter docs

Approach

Use renderToHtml() as the primary rendering strategy — no recursive Renderer.astro component needed while the component registry is empty. The integration hooks into Astro's astro:config:setup to inject CSS and configure Vite. Content is loaded at build time via getStaticPaths().

For View Transitions support, the behavior init script should listen to the astro:page-load event as an alternative to DOMContentLoaded.

@astrojs/markdoc coexistence: This adapter replaces @astrojs/markdoc, not supplements it — refrakt needs the full schema transform pipeline (rune models, content models, meta tag injection) which can't be expressed as simple Markdoc tag registrations. Users wanting a lighter integration that preserves Astro's content collections and @astrojs/markdoc should use @refrakt-md/vite (SPEC-031) instead.

Dependencies

  • WORK-088 (shared utility extraction)

References

  • SPEC-030 (Phase 1, including Compatibility Notes subsection)
  • SPEC-031 (Vite plugin — lighter Astro integration alternative)
  • ADR-001 (Astro readiness investigation)
  • SPEC-013 (layout transform architecture)