Skip to content

Overview & Setup

@stratal/inertia is an Inertia.js v3 server-side adapter for Stratal. It lets you build server-driven single-page applications with React while keeping your routing, controllers, and data logic entirely on the server. There is no client-side router and no API layer to maintain — your Stratal controllers render React pages directly.

Install the adapter along with the Inertia.js client libraries and React:

Terminal window
yarn add @stratal/inertia @inertiajs/react @inertiajs/core react react-dom

The Quarry CLI can generate the recommended directory structure for you:

Terminal window
npx quarry inertia:install

This creates the client entry point, root HTML template, TypeScript declarations, and a sample page component so you can start building immediately.

Register InertiaModule in your application module using forRoot():

import { Module } from 'stratal/module'
import { InertiaModule } from '@stratal/inertia'
import rootView from './inertia/root.html'
import manifest from '../dist/.vite/manifest.json'
@Module({
imports: [
InertiaModule.forRoot({
rootView,
version: '1.0.0',
manifest,
entryClientPath: 'src/inertia/app.tsx',
flash: {
driver: 'kv',
binding: 'FLASH_KV',
},
routes: true,
sharedData: {
appName: 'My App',
},
i18n: {
lang: 'en',
},
}),
],
})
export class AppModule {}
OptionTypeDescription
rootViewstringRaw HTML template string containing placeholder tags
versionstringApp version string used for cache busting
ssrInertiaSsrOptionsSSR configuration for server-side rendering
flashInertiaFlashOptionsFlash message storage driver and binding
sharedDataRecord<string, unknown>Global props shared with every page
i18nInertiaI18nOptionsFrontend translation injection settings
routesbooleanInject serialized routes for client-side URL generation
manifestViteManifestVite build manifest for production asset resolution (omit for dev mode)
entryClientPathstringPath to the client entry file (default: 'src/inertia/app.tsx')

When your Inertia configuration depends on other providers (for example, a config service), use forRootAsync():

import { Module } from 'stratal/module'
import { InertiaModule } from '@stratal/inertia'
import { ConfigService } from './config.service'
@Module({
imports: [
InertiaModule.forRootAsync({
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
rootView: config.get('INERTIA_ROOT_VIEW'),
version: config.get('APP_VERSION'),
routes: true,
}),
}),
],
})
export class AppModule {}

The rootView option expects a raw HTML string with special placeholder tags. Create a file at src/inertia/root.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
@inertiaHead
@viteHead
</head>
<body>
@inertia
@viteScripts
</body>
</html>
PlaceholderDescription
@inertiaReplaced with the root <div> containing serialized page data
@inertiaHeadReplaced with any <Head> tags set by the current page component
@viteHeadReplaced with Vite CSS and preload links from the build manifest
@viteScriptsReplaced with Vite JavaScript <script> tags
  • Pages & Rendering — Learn how to render Inertia pages from your controllers.
  • Shared Data & Props — Share global data and use advanced prop loading strategies.
  • Quarry CLI — Explore all available CLI commands including Inertia scaffolding.