HTML Responses
The very first request to an Inertia app is just a regular, full-page browser request, with no special Inertia headers or data. For these requests, the server returns a full HTML document. This HTML response includes the site assets (CSS, JavaScript) as well as a root<div> in the page’s body. The root <div> serves as a mounting point for the client-side app. A <script type="application/json"> element contains the JSON-encoded page object for the initial page. Inertia uses this information to boot your client-side framework and display the initial page component.
Inertia Responses
Once the Inertia app has been booted, all subsequent requests to the site are made via XHR with aX-Inertia header set to true. This header indicates that the request is being made by Inertia and isn’t a standard full-page visit.
The server detects the X-Inertia header and returns a JSON response with an encoded page object instead of a full HTML document.
Request Lifecycle Diagram
The diagram below illustrates the request lifecycle within an Inertia application. The initial visit generates a standard request to the server, which returns an HTML application skeleton containing a root element with hydrated data. For subsequent user interactions and navigation, Inertia sends XHR requests that return JSON data. Inertia uses this response to dynamically hydrate and swap the page component without a full-page reload.How the Client Handles Responses
After each request, the client inspects the response before touching the page. Dispatch follows a small set of rules:- An Inertia response (
X-Inertia: true) is rendered directly: the client applies the page object and swaps the component. - A
409 ConflictcarryingX-Inertia-Locationtriggers a fullwindow.locationvisit to that URL, loading fresh assets. Background requests are exempt when the version changed, since reloading a visit the user never initiated would discard unsaved state. - A
409 ConflictcarryingX-Inertia-Redirecttriggers a fresh InertiaGETvisit to that URL. - Any other response, such as an HTML document, plain JSON, or an error page, is treated as an exception. The client fires a cancelable HTTP exception event and, unless you cancel it, shows an error modal rather than silently navigating.
3xx redirects never reach these rules. The browser follows them transparently, replaying the request headers against the new location, so X-Inertia reaches the redirect target and the client only ever inspects the final response in the chain. See redirects for the statuses a server returns to steer this.
A valid Inertia response with a status of 400 or greater fires that same cancelable HTTP exception event before rendering. Canceling it there suppresses the render, letting you handle the failure yourself.
Request Headers
The following headers are automatically sent by Inertia when making requests. You don’t need to set these manually; they’re handled by the Inertia client-side adapter.boolean
Set to
true to indicate this is an Inertia request.string
Set to
XMLHttpRequest on all Inertia requests.string
Set to
text/html, application/xhtml+xml to indicate acceptable response
types.string
Set to
application/json for requests that do not include file uploads.string
The current asset version to check for asset mismatches.
string
The CSRF token read from the
XSRF-TOKEN cookie. The cookie and header names
are configurable.string
The component name for partial reloads.
string
Comma-separated list of props to include in partial reloads.
string
Comma-separated list of props to exclude from partial reloads.
string
Comma-separated list of props to reset on navigation.
string
Set to
no-cache for reload requests to prevent serving stale content.string
Specifies which error bag to use for validation
errors.
string
Indicates whether the requested data should be appended or prepended when
using Infinite scroll.
string
Comma-separated list of non-expired once prop
keys already loaded on the client. The server will skip resolving these props
unless explicitly requested via a partial reload or force refreshed
server-side.
boolean
Set to
true to indicate this is a Precognition validation request.string
Comma-separated list of field names to validate.
Response Headers
The following headers are set on an Inertia JSON page response. Official server-side adapters handle these automatically.boolean
Set to
true to indicate this is an Inertia response.string
Set to
X-Inertia to help browsers correctly differentiate between HTML and
JSON responses.409 Conflict control responses rather than page responses. A 409 carries no X-Inertia header, since it instructs the client to navigate rather than render a page.
string
The destination URL for a full
window.location visit. Set on an external
location visit and on an asset-version mismatch reload.string
The full redirect URL, including its fragment, for a redirect whose target
contains a URL fragment. Triggers a fresh Inertia
GET visit instead of a
full-page reload.string
The current asset version, echoed on a version-mismatch
409 so the client
may observe it.string
Set to
true to indicate this is a Precognition validation response.string
Set to
true when validation passes with no errors, combined with a 204 No Content status code.string
Set to
Precognition on all responses when the Precognition middleware is
applied.The Page Object
Inertia shares data between the server and client via a page object. This object includes the necessary information to render the page component, update the browser’s history state, and track the site’s asset version. The page object may include the following properties:string
The name of the JavaScript page component.
object
The page props. Contains all of the page data along with an
errors object
(defaults to {} if there are no errors).string
The page URL.
string|number
The current asset version.
boolean
Whether or not to encrypt the current page’s history
state. Only included when
true.boolean
Whether or not to clear any encrypted history
state. Only included when
true.boolean
Whether to preserve the URL fragment from the original request across a redirect.
array
Array of prop keys that should be deep
merged during navigation.
array
Array of prop keys to use for matching when merging
props.
object
Configuration for infinite scroll prop
merging behavior.
object
Configuration for client-side lazy loading of
props.
array
Array of deferred prop keys
that failed to resolve and were rescued server-side. Used by the client to
render the
rescue slot on the <Deferred> component.Array of top-level prop keys registered via
Inertia::share(). Used by the
client to carry shared props over during instant
visits.object
Configuration for once props that should only be
resolved once and reused on subsequent pages. Each entry maps a key to an
object containing the
prop name and optional expiresAt timestamp (in
milliseconds).object
Flash session data for the current request. Only included when flash data
exists. The client exposes it through the
inertia:flash event and strips it
from persisted history state.component, props, url, and version are present on every page object, so a minimal one looks like this:
false, so a server may omit an empty field or emit it explicitly with equivalent results.
Prop Evaluation Model
Every prop your server returns falls into one or more categories. The category determines whether the prop is resolved for a given request and what metadata, if any, the page object carries to describe it. These rules are purely a server-side resolution concern; the client applies whatever metadata it receives. Resolution differs between the two request modes. A full visit resolves the complete set of eligible props. A partial reload resolves only the props the client asked for, keyed on the page component. Full visit
Partial reload
A few metadata fields are mode-specific:
deferredPropsis populated on full visits only. It is empty or absent on partial reloads, since deferred props resolve in the follow-up request.rescuedPropsis populated on partial reloads only, listing deferred props that failed to resolve.- Merge, scroll, and once metadata is emitted per response, alongside whichever props carry those behaviors.
Always Props
Always props are resolved on every response in both modes. They ignore the partial reload filters entirely, so an always prop is sent even when a request lists it inexcept. They carry no page-object metadata, being purely a server-side resolution rule. The errors prop is an always prop, which is why every page object includes an errors object.
Composing Categories
A prop may belong to several categories at once. A prop may be deferred and mergeable, once and deferred, or scroll and deferred. The metadata fields are independent, so the page object carries every label that applies, subject to the mode, partial filters, and reset rules above.Partial Reloads
The partial reload option lets you request a subset of the props (data) from the server on subsequent visits to the same page component. This may be a helpful performance optimization if it’s acceptable that some page data becomes stale. See the partial reloads documentation for details. A partial reload request includes theX-Inertia-Partial-Component header and may include X-Inertia-Partial-Data and/or X-Inertia-Partial-Except headers with the request.
The X-Inertia-Partial-Data header is a comma-separated list of the desired props (data) keys that should be returned.
The X-Inertia-Partial-Except header is a comma-separated list of the props (data) keys that should not be returned. Including only the X-Inertia-Partial-Except header sends all props (data) except those listed. Both headers may be sent together, in which case the X-Inertia-Partial-Data list narrows the response first and the X-Inertia-Partial-Except list is then removed from it, so a prop named in both is excluded.
The X-Inertia-Partial-Component header includes the name of the component that is being partially reloaded. This is necessary, since partial reloads only work for requests made to the same page component. If the final destination differs for some reason (e.g. the user was logged out and is now on the login page), no partial reloading occurs.
Resetting Props
TheX-Inertia-Reset header lists prop paths the client wants to reset before new data is applied. A reset prop is re-resolved and returned unlabeled, present in props but absent from every merge array, so the client replaces the value instead of merging into it. The client sends reset paths in both the X-Inertia-Reset header and the only list. For scroll props, the server also sets scrollProps[path].reset in the metadata, which the infinite scroll component uses to re-sync its pagination state to the returned page. See resetting props for the client-side API.
Deferred and Optional Props
Deferred props let the server announce data that will load in a follow-up request. On a full visit the prop is skipped and its key is listed underdeferredProps, grouped by the request group it belongs to. The client issues one partial reload per group to fetch them, and the group names themselves are arbitrary. See the deferred props documentation.
only or except.
Rescued Deferred Props
A deferred prop resolved withrescue: true that throws does not fail the response, which is still a 200 carrying every other prop. The server reports the exception through your framework’s error handling, omits the prop from props entirely (it is not sent as null), and adds its key to the top-level rescuedProps array. The client uses this list to render the rescue slot on the <Deferred> component. See error handling.
Merging Props
Merge props instruct the client to combine incoming prop data with data already on the page instead of replacing it. Arrays are appended or prepended, and objects are shallow or deep merged. The page object labels each merging prop undermergeProps (append), prependProps (prepend), or deepMergeProps (deep merge). Merging applies on partial reloads only, so a full visit always replaces the prop even when it carries a merge label. See the merging props documentation.
Matching Items
ThematchPropsOn array tells the client which field identifies each item so existing entries may be updated in place rather than duplicated. Each entry has the form "<propPath>.<keyField>" and is split on the last dot: everything before the final segment is the prop path, and the final segment is the key field. conversations.data.id keys the array at conversations.data on its id field. See matching items.
Once Props
Once props are resolved a single time and remembered by the client, then reused on subsequent pages that include the same prop. The page object carries anonceProps configuration. Each entry maps a key to the prop name and an optional expiration timestamp in milliseconds. See the once props documentation.
X-Inertia-Except-Once-Props header. The server skips resolving those props and excludes them from the response, and the client reuses the previously loaded values.
plans is included in onceProps but not in props since it was already loaded on the client. The onceProps key identifies the once prop across pages, while prop specifies the actual prop name. These may differ when using custom keys.
Force-Fresh and Partial Reloads
The server may send a fresh value for a once prop even when its key appears inX-Inertia-Except-Once-Props, for example when the underlying data has changed. The returned value and its new expiresAt replace the client’s copy. On a partial reload the except-once header is ignored, so a requested once prop is always resolved.
Infinite Scroll
Infinite scroll builds on merge props. The prop’s inner array is labeled for merging (typically<path>.data), and the page object carries a scrollProps entry describing the paginator’s cursor. See the infinite scroll documentation.
scrollProps[path].reset to true, which tells the client to re-sync its pagination state to the returned page. A deferred scroll prop emits no scrollProps on the full visit, since it resolves in the follow-up request.
Asset Versioning
The page object carries aversion identifier representing the current version of your site’s assets. It may be a number, string, or file hash, as long as the value changes when the assets do, and a server that does not track asset versions should send an empty string. The client echoes the active page’s version back in the X-Inertia-Version header, and the server compares the two, typically in its middleware layer.
Matching versions let the request continue as normal. A mismatch on a GET request causes the server to immediately return a 409 Conflict with the target URL in an X-Inertia-Location header and its current version in X-Inertia-Version, so the client lands on the correct destination even after a server-side redirect. Non-GET requests never receive a mismatch 409, though the GET redirect that follows one still may. Server-side adapters also reflash any flash session data on a 409 so it survives the follow-up request.
Redirects
Inertia relies on standard HTTP redirects for navigation after a server-side action. A302 Found returned after a PUT, PATCH, or DELETE is converted to 303 See Other so the browser issues a GET to the redirect target, avoiding a repeated non-GET request.
External redirects point outside your Inertia app, where the Inertia request headers cannot survive the hop, so an XHR visit may not follow them. The server returns a 409 Conflict with an X-Inertia-Location header instead, and the client performs a full window.location visit.
A non-prefetch redirect whose target contains a URL fragment is returned as a 409 Conflict with an X-Inertia-Redirect header holding the full URL, and the client makes a fresh Inertia GET visit to that URL. This is distinct from the preserveFragment page-object field, which carries the original request’s fragment across an ordinary redirect. See the redirects documentation.
Validation Errors
Validation errors are shared through theerrors prop. The Laravel adapter registers errors as an always prop, so it is present on every page object and defaults to {} when there are no errors.
Each key may map to either a single message or an array of messages, and the client renders whichever shape it receives. The choice is left to the server, so the Laravel adapter sends the first error per field by default and may be configured to send all error messages for each field.
Requests may scope errors to a named error bag with the X-Inertia-Error-Bag header. The server namespaces the returned errors under that bag, so multiple forms on a page may keep their errors separate. See the validation documentation.
HTTP Status Codes
Inertia uses specific HTTP status codes to handle different scenarios.
The following status codes are used for Precognition validation requests.
Server-Side Rendering
Inertia does not server-side render the page components by default. Enabling SSR introduces a second wire contract, this time between your server-side adapter and Inertia’s Node SSR server. The adapter POSTs the page object to the SSR server, which returns the pre-rendered markup for the HTML document.<x-inertia::head> and <x-inertia::app> Blade components. The head array holds the elements belonging in the document’s <head>, such as the title and meta tags. The body string takes the place of the page object script tag and root <div> that a non-SSR document would render, since the SSR server already includes both in its markup, and it carries data-server-rendered="true" so the client hydrates the existing DOM instead of mounting a fresh app. Slash escaping within the embedded page object is handled by the SSR server, so the adapter may print the body markup as-is.
The SSR server exposes two additional endpoints. A GET request to /health returns {"status":"OK"} and may be used to verify the process is running before dispatching a render. A POST to /shutdown stops the process, which is how the Laravel adapter’s inertia:stop-ssr command works.
A failed render returns a 500 response whose JSON body classifies the error rather than just reporting it.
error message, hint, and timestamp are always present, while component, url, stack, and sourceLocation appear whenever the SSR server can determine them. The type narrows the cause to browser-api for a browser global touched during render, which also sets browserApi to the offending API, component-resolution for a page component that could not be resolved, or render for anything else thrown by your components.
Adapters should treat a failed render as non-fatal, reporting the payload through the application’s error handling and falling back to the standard client-side rendered document, so a broken SSR build never takes the site down. The Laravel adapter surfaces it as an SsrRenderFailed event and adds a connection type of its own when the SSR server cannot be reached at all.