Inertia SSR (JS)#
InertiaConfig(ssr=True) renders initial HTML responses through Vite in development
and a managed stdio worker in production. Litestar sends the full Inertia page object
and injects the returned head tags and body markup into the HTML response.
For existing HTTP SSR integrations, see Migrating to 0.32.
This SSR path is distinct from framework proxy mode:
Inertia SSR:
InertiaConfig(ssr=True)Meta-framework proxy mode:
ViteConfig(mode="framework")or aliasmode="ssr"
In development mode, Litestar sends the page object to the running Vite dev server’s
/__litestar_ssr__ endpoint, which evaluates your SSR entrypoint via Vite’s
RunnableDevEnvironment.runner. In production mode, Litestar spawns the built SSR bundle over
StdioIPCTransport and uses the returned head and body fields when building the
initial HTML response.
Typical file layout:
Browser entry:
resources/main.tsxorresources/main.tsNode SSR entry:
resources/ssr.tsxorresources/ssr.ts
Process management#
InertiaSSRConfig.command configures the production stdio worker command started on the first render request:
from litestar_vite import InertiaConfig, InertiaSSRConfig
InertiaConfig(
ssr=InertiaSSRConfig(
command=["node", "resources/bootstrap/ssr/ssr.js"],
timeout=2.0,
fallback_to_client=True,
)
)
When dev_mode=False, litestar-vite starts the configured command lazily on the first render request and closes its stdin pipe on shutdown. When fallback_to_client=True (the default), SSR errors or circuit breaker trips fall back gracefully to the client-side SPA shell. Set fallback_to_client=False to propagate SSR failures.
When command is omitted, the worker loads ssr.js from
PathConfig.ssr_output_dir when configured, or from
<resource_dir>/bootstrap/ssr otherwise. Relative paths are anchored to the
project root. With resource_dir="resources", this is
resources/bootstrap/ssr/ssr.js; the default resource_dir="src" instead uses
src/bootstrap/ssr/ssr.js. Explicit command and cwd settings remain available. Each application worker owns its SSR subprocess.
Plugin boundary#
Generated Litestar scaffolds do not install @inertiajs/vite by default. The default frontend
bridge remains litestar-vite-plugin because it owns Litestar-specific behavior:
writing and reading the
.litestar.jsonbridge contract;dev/prod asset resolution and proxy integration;
route and schema type generation;
CSRF helper wiring for generated Inertia entries;
the
resolvePageComponent()wrapper used by the templates.
The upstream @inertiajs/vite plugin may be useful if an application wants to experiment with
its page shorthand or Laravel-centered SSR automation, but it must not replace the
litestar-vite-plugin bridge/proxy/typegen responsibilities. If both plugins are combined,
keep litestar-vite-plugin as the bridge owner and treat @inertiajs/vite as application
owned integration code.
When you use the default script-element bootstrap transport:
Inertia v3 clients use the script-element bootstrap by default, so no extra client
defaultsblock is required.Inertia v2 clients must keep
defaults.future.useScriptElementForInitialPagein the browser entry so hydration reads the initial page payload correctly instead of expecting the defaultdata-pageattribute.Inertia v2 SSR entries should mirror the same option because Inertia applies the same defaults during server rendering.
Set
use_script_element=Falseif you need to keep the legacydata-pageattribute bootstrap.
Note
This guidance is intentionally version-scoped. Inertia v2 still uses the future namespace
for script-element bootstrap, while Inertia v3 removes that extra client configuration.
Selector behavior follows SPAConfig.app_selector. If you render into #root instead of
#app, keep the browser template, SSR output, and app selector aligned so Litestar can replace
the correct wrapper element during the initial SSR response.
- class litestar_vite.config.InertiaSSRConfig[source]#
Bases:
objectServer-side rendering settings for Inertia.js.
In development mode, Inertia SSR uses Vite 7+’s
RunnableDevEnvironment.runnerinside the already-running Vite dev server over/__litestar_ssr__.In production mode, Litestar spawns the built SSR bundle as a managed subprocess communicating over
stdin/stdoutpipes (StdioIPCTransport).- target_selector: str = '#app'#
CSS selector for the element whose outer HTML is replaced by the SSR-rendered body.
Used by
_render_template(template mode) to locate the mount point in the rendered Jinja HTML. Defaults to#appto match Inertia’s convention.For
mode="hybrid",SPAConfig.app_selectoris the source of truth and this field is ignored — SPA config already governs the SPA shell selector.
- command: list[str] | None = None#
Command to start the production stdio SSR worker.
When
None, runs Node with the absolute path tossr.jsunderPathConfig.ssr_output_diror<resource_dir>/bootstrap/ssr. Relative output directories resolve against the project root, independently ofcwd.
- cwd: Path | None = None#
Working directory for the SSR command. Defaults to
ViteConfig.root_dirwhen None.
- fallback_to_client: bool = True#
Whether to fall back gracefully to client-side hydration if SSR rendering fails.
- circuit_breaker_enabled: bool = True#
Whether to enable the in-memory circuit breaker protecting the SSR rendering pipeline.
- circuit_breaker_failure_threshold: int = 3#
Number of consecutive failures before the circuit breaker trips to OPEN state.
- circuit_breaker_reset_timeout: float = 30.0#
Cooldown seconds to wait before probing SSR worker health after tripping.
- __init__(enabled: bool = True, timeout: float = 2.0, target_selector: str = '#app', command: list[str] | None = None, cwd: Path | None = None, fallback_to_client: bool = True, circuit_breaker_enabled: bool = True, circuit_breaker_failure_threshold: int = 3, circuit_breaker_reset_timeout: float = 30.0) None#