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

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

References

History

  1. 59ded4a
    Content edited
  2. f262d7b
    source+ADR-001,SPEC-013,SPEC-030,SPEC-031
  3. e5a255f
    statusreadyin-progress
    • ☑ `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`
    • +8 more criteria
  4. 11e81a8
    milestone+v1.0.0
  5. 982a9db
    • + 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
  6. cf1b816
    • + Behavior script conditionally included — only on pages that use interactive runes (tabs, accordion, datatable, etc.), shipping zero JS for static-only pages
  7. ead9531
    Created (ready, high, moderate, frameworks, astro)