Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

astro-solid-next

Astro renderer integration for Solid 2.0 (solid-js@2.0.0-rc). The official @astrojs/solid-js targets Solid 1.x; this integration renders Astro islands with the 2.0 runtime (@solidjs/web) and the new compiler plugin (@solidjs/vite-plugin).

Usage

npm i astro-solid-next solid-js@next @solidjs/web@next --legacy-peer-deps
// astro.config.mjs
import { defineConfig } from 'astro/config'
import solidNext from 'astro-solid-next'

export default defineConfig({
  integrations: [solidNext()],
})
---
import Counter from '../components/Counter.tsx'
---
<Counter start={5} client:load>
  <p>slotted content</p>
</Counter>

Options: include / exclude (vite filter patterns) to scope which files the Solid compiler transforms — needed when combining multiple JSX frameworks.

How it maps onto Solid 2.0

  • Server islands render with await renderToStream(fn, { renderId, noScripts }) — awaiting the stream resolves the fully settled HTML, so async in the reactive graph (promises in createMemo under a Loading boundary) settles before the island serializes. Server-only islands render inside NoHydration with noScripts: true.
  • Hydration uses the same renderId on the client (hydrate(fn, el, { renderId })), scoping hydration keys per island. The hydration bootstrap is injected once per page via Astro's renderHydrationScriptgenerateHydrationScript().
  • Props updates (view transitions) patch a createStore with reconcile, same as the official 1.x renderer — stores are part of core solid-js in 2.0.
  • The compiler runs in legacy transform-only mode (ssr: true, no start): Astro owns the server and the document, the plugin only provides hydratable client output and string-mode SSR output per Vite environment.

Styling Solid islands

Keep Solid components unstyled and share one styling system with the rest of the site — the island boundary should separate interactivity, not design.

The mechanics: Astro's <style> in .astro files is scoped (hash selector), so it deliberately does not reach the HTML a Solid island renders. What both worlds share:

  • Global stylesheets — imported in a layout or via <style is:global>.
  • CSS imported from the component files — a Solid component can import './counter.css' or use CSS modules; Astro extracts it into the page's CSS bundle at build time (shipped as a <link> with the page, so no FOUC).

Recommended setups, in order:

  1. Tailwind (or another utility system) — one config, and .astro templates and .tsx islands write the same classes. For headless libraries like Kobalte, style state via the exposed data attributes: data-[expanded]:rotate-180, data-[highlighted]:bg-accent, etc.
  2. Global design tokens + component classes — custom properties (--color-accent, --radius) in one global file, plain classes written against them, used from both sides.

Avoid: inline style="" in components (can't see your tokens or theme), scoped Astro styles targeting island internals (they silently won't match), and runtime CSS-in-JS (payload and hydration cost).

Example

examples/basic — a static Astro build with a server-only island and a hydrated counter island with slotted content.

cd examples/basic && npm i --legacy-peer-deps && npm run build && npm run preview

Status

Experimental. Tracks the Solid 2.0 RC (peer ^2.0.0-rc.0) and Astro ≥ 5 (tested on Astro 7 / Vite 8). Expect churn until Solid 2.0 is stable.

About

Astro renderer integration for Solid 2.0 (solid-js@2 RC)

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages