An adapter to bring SolidJS compatibility to systems using InertiaJS.
Important
This version of the adapter is compatible with Inertia.js v3.x. If you are using Inertia.js v2.x, please use an earlier version of this adapter.
# Using NPM
npm install -D solid-js vite-plugin-solid @solidjs/meta inertia-adapter-solid
# Using Yarn
yarn add -D solid-js vite-plugin-solid @solidjs/meta inertia-adapter-solid
# Using PNPM
pnpm add -D solid-js vite-plugin-solid @solidjs/meta inertia-adapter-solidIn your vite.config.js file, you will need to add the SolidJS plugin if not done already.
You will also need to register the Solid framework configuration with Inertia's Vite plugin.
import { defineConfig } from 'vite'
+ import solid from 'vite-plugin-solid'
+ import inertiaSolidFramework from 'inertia-adapter-solid/vite'
export default defineConfig({
plugins: [
laravel({
input: ['resources/js/app.jsx'],
refresh: true,
}),
+ solid({ ssr: true }),
+ inertia({
+ frameworks: inertiaSolidFramework,
+ })
// ...
]
})When adding the Solid Framework configuration for Inertia, the Inertia Vite plugin will automatically handle:
- Component resolution
- Server-Side rendering
Next, update your main JavaScript file to boot your Inertia app.
import { createInertiaApp } from 'inertia-adapter-solid'
createInertiaApp()Tip
You can also customize Inertia's configuration like other official adapters.
Learn more at the official Client-Side Setup documentation.
If you prefer not to use the Vite plugin,
you may provide the resolve and setup callbacks manually.
The resolve callback tells Inertia how to load a page
component and receives the component name and the full
page object.
The setup callback initializes the client-side framework.
import { createInertiaApp } from 'inertia-adapter-solid'
import { render } from 'solid-js/web'
createInertiaApp({
resolve(name) {
const pages = import.meta.glob('./Pages/**/*.jsx')
return pages[`./Pages/${name}.jsx`]()
},
setup({ el, App, props }) {
render(() => <App {...props} />, el)
},
})Inertia pages are simply SolidJS components, you will feel right at home.
import Layout from './Layout'
import { Title } from '@solidjs/meta'
export default function Welcome(props) {
return (
<Layout>
<Title>Welcome</Title>
<h1>Welcome</h1>
<p>Hello {props.user.name}, welcome to your first Inertia app!</p>
</Layout>
)
}Tip
Learn more at the official Pages documentation.
Important
Remember that destructuring props breaks SolidJS reactivity!
A layout is a standard component that accepts child content. There is nothing Inertia-specific about it.
import { Link } from 'inertia-adapter-solid'
export default function Layout(props) {
return (
<main>
<header>
<Link href="/">Home</Link>
<Link href="/about">About</Link>
<Link href="/contact">Contact</Link>
</header>
<article>{props.children}</article>
</main>
)
}You may use a layout by wrapping your page content with it directly. However, this approach forces the layout instance to be destroyed and recreated between visits.
import Layout from './Layout'
export default function Welcome(props) {
return (
<Layout>
<h1>Welcome</h1>
<p>Hello {props.user.name}, welcome to your first Inertia app!</p>
</Layout>
)
}Wrapping a page with a layout as a child component works, but it means the layout is destroyed and recreated on every visit. This prevents maintaining layout state across navigations, such as an audio player that should keep playing or a sidebar that should retain its scroll position. Persistent layouts solve this by telling Inertia which layout to use for a page. Inertia then manages the layout instance separately, keeping it alive between visits.
import Layout from './Layout'
import { Title } from '@solidjs/meta'
export default function Welcome(props) {
return (
<>
<Title>Welcome</Title>
<h1>Welcome</h1>
<p>Hello {props.user.name}, welcome to your first Inertia app!</p>
</>
)
}
Welcome.layout = LayoutAlternatively, you can also stack multiple layouts on top of each other.
import SiteLayout from './SiteLayout'
import NestedLayout from './NestedLayout'
import { Title } from '@solidjs/meta'
export default function Welcome(props) {
return (
<>
<Title>Welcome</Title>
<h1>Welcome</h1>
<p>Hello {props.user.name}, welcome to your first Inertia app!</p>
</>
)
}
Welcome.layout = [SiteLayout, NestedLayout]You can also create more complex layout arrangements using nested layouts.
import Layout from './Layout'
import { Title } from '@solidjs/meta'
export default function Welcome(props) {
return (
<Layout>
<Title>Welcome</Title>
<h1>Welcome</h1>
<p>Hello {props.user.name}, welcome to your first Inertia app!</p>
</Layout>
)
}
Welcome.layout = (props) => {
<SiteLayout title="Welcome">
<NestedLayout>
{props.children}
</NestedLayout>
</SiteLayout>
}Tip
Learn more at the official Layouts documentation.
This adapter brings compatibility to Meta-tags using @solidjs/meta
official package, working in both Client-side Rendering and Server-side Rendering.
import { Title, Meta } from '@solidjs/meta'
export default function Page() {
return (
<>
<Title>Your page title</Title>
<Meta name="description" content="Your page description" />
</>
)
}This package ships AI guidelines and an inertia-solid-development skill for
Laravel Boost, mirroring the official Inertia
adapters. When you run php artisan boost:install (or boost:update --discover)
in a Laravel project that has this package installed, Boost detects them
automatically and offers to install them — no extra setup required.
The guidelines teach AI coding agents how to use this adapter with SolidJS best
practices: pages and persistent layouts, <Link>, <Form>, useForm (including
Precognition), useHttp, deferred props, polling, prefetching, and the SolidJS
reactivity rules that apply to all of them.
While this library is Typescript-ready, your bundler may complain as it tries to compile TSX components with React in mind... But we're not using React, we're using SolidJS!
Actually, the fix is really simple. Add the following to your tsconfig.json file:
{
"compilerOptions": {
"jsx": "preserve",
"jsxImportSource": "solid-js"
}
}Tip
Learn more at the official Typescript documentation.
Server-side rendering pre-renders your JavaScript pages on the server, allowing your visitors to receive fully rendered HTML when they visit your application. Since fully rendered HTML is served by your application, it’s also easier for search engines to index your site.
Server-side rendering uses Node.js to render your pages in a background process; therefore, Node must be available on your server for server-side rendering to function properly. Inertia’s SSR server requires Node.js 22 or higher.
Update the build script in your package.json to build both bundles.
"scripts" {
"dev": "vite",
- "build": "vite build"
+ "build": "vite build && vite build --ssr"
}Tip
Learn more at the official Server-Side Rendering documentation.
The Vite plugin reuses your app.js entry point for SSR by default, so no separate file is needed.
For more control, such as providing a manual setup callback,
you may create a separate resources/js/ssr.jsx entry point and
update your app.jsx to use client-side hydration.
import { createInertiaApp } from 'inertia-adapter-solid'
import createServer from 'inertia-adapter-solid/server'
createServer((page) =>
createInertiaApp({
page,
resolve(name) {
const pages = import.meta.glob('./Pages/**/*.jsx')
return pages[`./Pages/${name}.jsx`]()
},
setup: ({ App, props }) => <App {...props} />,
}),
)Be sure to add anything that’s missing from your app.js file that
makes sense to run in SSR mode, such as plugins or custom mixins.
By default, we use the renderToString function for SSR,
but you may also pass a custom renderer to the render option:
import { createInertiaApp } from 'inertia-adapter-solid'
import createServer from 'inertia-adapter-solid/server'
import { renderToStringAsync } from 'solid-js/web'
createServer((page) =>
createInertiaApp({
// ...
render: renderToStringAsync
}),
)You should also update your app.js to use hydration instead of normal rendering. This allows React to pick up the server-rendered HTML and make it interactive without re-rendering it.
import { createInertiaApp } from 'inertia-adapter-solid'
- import { render } from 'solid-js/web'
+ import { hydrate } from 'solid-js/web'
createInertiaApp({
resolve(name) {
const pages = import.meta.glob('./Pages/**/*.jsx', { eager: true })
return pages[`./Pages/${name}.jsx`]
},
setup({ el, App, props }) {
- render(() => <App {...props} />, el)
+ hydrate(() => <App {...props} />, el)
},
})You can read the full documentation on Server-side Rendering on InertiaJS's Official Guide.