Your first page
This walkthrough assumes Installation is done: provider, middleware, root view, and a Vite client that resolves Pages/*.
1. Render from a route
Section titled “1. Render from a route”router.get("/") { Inertia.render( "Pages/Welcome", mapOf( "title" to "Hello", "message" to "First Inertia page", ), )}router.get("/", request -> Inertia.render( "Pages/Welcome", Map.of( "title", "Hello", "message", "First Inertia page" ) ));Inertia.render requires a current request (set by HandleInertiaRequests) unless you pass the Request explicitly. See Rendering.
2. First visit (full HTML)
Section titled “2. First visit (full HTML)”Browser navigates to / with no X-Inertia header.
- Middleware sets the request on
InertiaManager, merges shared props, checks version (none on first document load). - Your route returns an Inertia response.
- Manager builds an
InertiaPageand renders the root Crema view (inertia.root_view) with:pageAttr— HTML-escaped JSON of the page objectvite— script/link tags for the client entry
- Response is
text/html.
Inspect #app:
<div id="app" data-page="{"component":"Pages/Welcome","props":{"title":"Hello",…},"url":"/","version":"1"}"></div>The Vue/React/Svelte entry hydrates that JSON into Pages/Welcome.
3. Inertia visit (JSON)
Section titled “3. Inertia visit (JSON)”After the client is mounted, an Inertia link or router.visit sends:
GET / HTTP/1.1X-Inertia: trueX-Inertia-Version: 1Accept: text/html, application/xhtml+xmlX-Requested-With: XMLHttpRequest(Exact client headers depend on the adapter; X-Inertia: true is required for JSON mode.)
Server behavior:
- Version header matches → continue.
- Route renders the same
Inertia.render(…). - Response body is JSON (not the Crema shell):
{ "component": "Pages/Welcome", "props": { "title": "Hello", "message": "First Inertia page" }, "url": "/", "version": "1"}Headers include X-Inertia: true, Vary: X-Inertia, and X-Inertia-Version when a version is configured.
4. Version conflict
Section titled “4. Version conflict”If the client sends a stale X-Inertia-Version, middleware returns 409 so the adapter can force a full reload and pick up new assets. Configure inertia.version (or override version(request) on your middleware). See Asset versioning.
5. Shared props
Section titled “5. Shared props”Flash messages, auth user, and ziggy-style URLs belong in middleware share(request) or Inertia.share(…) — not in every controller. See Shared data.
6. Client page component
Section titled “6. Client page component”Match the server name. Vue example (js/Pages/Welcome.vue):
<script setup>defineProps({ title: String, message: String });</script><template> <h1>{{ title }}</h1> <p>{{ message }}</p></template>- Frontend clients — mount details per stack
- Requests & responses — headers and status codes
- External redirects —
Inertia.location