SSR, TypeScript & Upgrade Guide¶
This guide covers Server-Side Rendering (InertiaSSRConfig), client helpers (resolvePageComponent, unwrapPageProps), end-to-end PageProps TypeScript generation, and Inertia v3 compatibility.
Server-Side Rendering¶
Enabling InertiaConfig(ssr=True) (or ssr=InertiaSSRConfig(...)) pre-renders initial full-page Inertia visits on the server before returning HTML to the browser:
- Development (
dev_mode=True): Litestar sends thePagePropspayload overTCPStreamIPCTransportto Vite's/__litestar_ssr__endpoint, which executes yourresources/ssr.tsx(orresources/ssr.ts) entrypoint through Vite'sModuleRunnerwith full HMR invalidation. - Production (
dev_mode=False): Litestar streams NDJSON requests overStdioIPCTransportto your compiledssr.jsworker (startSsrWorker({ render })).
import { createInertiaApp } from "@inertiajs/react";
import ReactDOMServer from "react-dom/server";
import { resolvePageComponent } from "litestar-vite-plugin/inertia-helpers";
import { startSsrWorker } from "litestar-vite-plugin/ssr-worker";
export default function render(page: unknown) {
return createInertiaApp({
page: page as never,
render: ReactDOMServer.renderToString,
defaults: {
future: {
useScriptElementForInitialPage: true,
},
},
resolve: (name: string) =>
resolvePageComponent(
`./pages/${name}.tsx`,
import.meta.glob("./pages/**/*.tsx", { eager: true }),
),
setup: ({ App, props }: { App: any; props: any }) => <App {...props} />,
});
}
startSsrWorker({ render });
Bootstrap Interaction¶
When SSR returns { head, body }, inject_inertia_ssr_tags splices head into <!--inertia-head--> (or <head>) and replaces <div id="app"> (your configured app_selector) with the pre-rendered body while preserving <script type="application/json" id="app_page" data-page="app"> when use_script_element=True (or the data-page attribute when use_script_element=False).
Page Resolution & Prop Unwrapping Helpers¶
litestar-vite-plugin/inertia-helpers exports two zero-dependency utilities:
| Function | Signature | Purpose |
|---|---|---|
resolvePageComponent |
resolvePageComponent(path, pages, options?): Promise<T> |
Resolves a page module from import.meta.glob(...) (eager or lazy), supporting fallback path arrays and descriptive errors when a component is missing. |
unwrapPageProps |
unwrapPageProps<T>(props: T): UnwrappedPageProps<T> |
Unwraps nested { content: ... } envelopes when handlers wrap structured responses. |
Automatic PageProps Type Generation¶
When TypeGenConfig(generate_page_props=True) is active, Litestar Vite inspects every route handler with a component="..." option (extract_inertia_pages), writes .litestar/inertia-pages.json, and generates src/generated/page-props.ts:
import type { InvoiceSummary } from "./api/types.gen";
export interface InvoicesIndexProps {
invoices: InvoiceSummary[];
}
export interface PageProps {
"Invoices/Index": InvoicesIndexProps;
"Invoices/Show": InvoiceSummary;
}
export type InertiaPageProps<C extends keyof PageProps = keyof PageProps> =
PageProps[C] & SharedPageProps;
export type PagePropsFor<C extends keyof PageProps> = InertiaPageProps<C>;
Customizing User and SharedProps Types¶
Customize default AuthData or SharedProps in src/types/inertia.d.ts (or disable default auth generation with InertiaTypeGenConfig(include_default_auth=False)):
import "litestar-vite-plugin/inertia";
declare module "litestar-vite-plugin/inertia" {
interface User {
id: string;
email: string;
roles: ("admin" | "member")[];
}
interface SharedProps {
tenantId: string;
}
}
Inertia v3 Compatibility¶
| Feature | Standard Inertia.js | Inertia v3 (@inertiajs/* v3) |
|---|---|---|
| Script-Element Bootstrap | Opt-in on client via defaults: { future: { useScriptElementForInitialPage: true } } |
Default behavior when InertiaConfig(use_script_element=True) is active (defaults: {}). |
Document <title> Tag |
<title inertia> or <title data-inertia> |
Plain <title>App</title> (v3 replaces the single <title> element automatically without marker attributes). |
| HTTP Client | Axios | Native fetch / XHR (no axios dependency required). |
| Top-Level Flash | Supported (page.flash) |
Standard (page.flash). |