Skip to content

Inertia.js Reference

API reference for the Inertia.js plugin, request/response primitives, deferred/merged prop wrappers, session state helpers, and Laravel Precognition support.


Plugin, Middleware & Request Primitives

InertiaPlugin

Bases: InitPlugin

Inertia plugin.

This plugin configures Litestar for Inertia.js support, including: - Optional session-backed redirect state - Exception handler for Inertia responses - InertiaRequest and InertiaResponse as default classes - Type encoders for StaticProp and DeferredProp - Shared IPC transport and circuit breaker for SSR

Async Prop Resolution

Async optional()/defer()/lazy()/once() callbacks are pre-resolved by InertiaResponse on the request event loop before the body is serialized. This guarantees they share the loop with request-scoped async resources (asyncpg/aiosqlite/sqlspec sessions), so callbacks can safely use those resources.

Example
from litestar_vite.inertia import InertiaPlugin, InertiaConfig

app = Litestar(
    plugins=[InertiaPlugin(InertiaConfig())],
)
on_app_init
on_app_init(app_config)

Configure application for use with Vite.

Parameters:

Name Type Description Default
app_config AppConfig

The AppConfig instance.

required

Returns:

Type Description
AppConfig

The AppConfig instance.

InertiaMiddleware

Bases: AbstractMiddleware

Middleware for handling Inertia.js protocol requirements.

This middleware: 1. Detects version mismatches between client and server assets 2. Returns 409 Conflict with X-Inertia-Location header when versions differ 3. Triggers client-side hard refresh to reload the updated assets

InertiaRequest

Bases: Request[UserT, AuthT, StateT]

Inertia Request class to work with Inertia client.

Attributes:

Name Type Description
is_inertiabool

True if the request contained inertia headers.

is_partial_renderbool

True if the request is a partial reload.

partial_keysset[str]

Get the props to include in partial render.

partial_except_keysset[str]

Get the props to exclude from partial render (v2).

reset_keysset[str]

Get the props to reset on navigation (v2).

InertiaDetails

InertiaDetails holds all the values sent by Inertia client in headers and provide convenient properties.

Attributes:

Name Type Description
route_componentstr | None

Return the route component name.

partial_componentstr | None

Return the partial component name from headers.

partial_datastr | None

Return partial-data keys requested by the client.

partial_exceptstr | None

Return partial-except keys requested by the client.

except_once_propsstr | None

Return cached once-prop keys the client wants omitted.

reset_propsstr | None

Return comma-separated props to reset on navigation.

error_bagstr | None

Return the error bag name for scoped validation errors.

merge_intentstr | None

Return infinite-scroll merge intent (append/prepend).

versionstr | None

Return the Inertia asset version sent by the client.

refererstr | None

Return the referer value if present.

is_partial_renderbool

Return True when the request is a partial render.

partial_keyslist[str]

Return parsed partial-data keys.

partial_except_keyslist[str]

Return parsed partial-except keys (takes precedence over partial_keys).

except_once_props_keyslist[str]

Return parsed cached once-prop keys.

reset_keyslist[str]

Return parsed reset keys from headers.

is_precognitionbool

Return True when the request is a Precognition validation request.

precognition_validate_onlylist[str]

Return the fields to validate for partial Precognition validation.

InertiaHeaders

Bases: str, Enum

Enum for Inertia Headers.

See: https://inertiajs.com/the-protocol

This includes both core protocol headers and v2 extensions (partial excludes, reset, error bags, and infinite scroll merge intent).

PageProps

Bases: Generic[T]

Inertia v2 page object serialized to camelCase JSON via to_dict().

Attributes:

Name Type Description
componentstr

JavaScript page component name to render.

urlstr

Current request URL path and query string.

versionstr

Asset bundle version identifier used for 409 Conflict cache busting.

propsdict[str, Any]

Resolved dictionary of page and shared props passed to the frontend component.

encrypt_historybool

Whether the Inertia client should encrypt browser history state for this page.

clear_historybool

Whether the Inertia client should clear previously encrypted history state.

merge_propslist[str] | None

Prop keys whose values should be appended during partial navigation.

prepend_propslist[str] | None

Prop keys whose values should be prepended during partial navigation.

deep_merge_propslist[str] | None

Prop keys whose nested dictionaries should be deep-merged during partial navigation.

match_props_onlist[str] | None

Dotted property paths (such as 'items.id') used to deduplicate merged array items.

deferred_propsdict[str, list[str]] | None

Mapping of deferred group names to lists of prop keys fetched after initial render.

once_propsdict[str, dict[str, str | int | None]] | None

Metadata mapping for props resolved once and cached client-side across navigations.

scroll_propsdict[str, ScrollPropsConfig] | None

Infinite scroll pagination metadata keyed by prop name.

flashdict[str, list[str]]

Top-level flash messages grouped by category (v2.3+, excluded from history state).

InertiaHeaderType

Bases: TypedDict

TypedDict describing Inertia.js HTTP request/response header values.

Attributes:

Name Type Description
enabledbool | None

Whether the X-Inertia protocol header is enabled ('true').

versionstr | None

Asset version string carried in the X-Inertia-Version header.

locationstr | None

External redirect URL carried in the X-Inertia-Location response header.

partial_datastr | None

Comma-separated prop keys requested via X-Inertia-Partial-Data.

partial_componentstr | None

Component name specified in X-Inertia-Partial-Component for partial reloads.

partial_exceptstr | None

Comma-separated prop keys excluded via X-Inertia-Partial-Except.

except_once_propsstr | None

Comma-separated cached once-prop keys omitted via X-Inertia-Except-Once-Props.

resetstr | None

Comma-separated prop keys to reset on client navigation via X-Inertia-Reset.

error_bagstr | None

Scoped validation error bag name sent in X-Inertia-Error-Bag.


Responses & Redirects

InertiaResponse

Bases: Response[T]

Inertia Response

Attributes:

Name Type Description
cookieslist[Cookie]
Default: [Cookie(key=key, value=value) for key, value in cookies.items()] if isinstance(cookies, Mapping) else list(cookies or [])
headersdict[str, Any]
Default: dict(headers) if isinstance(headers, Mapping) else {h.name: h.value for h in headers or {}}

InertiaRedirect

Bases: Redirect

Redirect to a specified URL with same-origin validation.

This class validates the redirect URL to prevent open redirect attacks. If the URL is not same-origin, it falls back to the application's base URL.

Note

Request cookies are intentionally NOT passed to the response to prevent cookie leakage in redirect responses.

InertiaBack

Bases: InertiaRedirect

Redirect back to the previous page using the Referer header.

This class safely validates the Referer header to prevent open redirect attacks. If the Referer is not same-origin or is missing, it falls back to the application's base URL.

Note

Request cookies are intentionally NOT passed to the response to prevent cookie leakage in redirect responses.

InertiaExternalRedirect

Bases: Response[Any]

External redirect via Inertia protocol or standard HTTP redirect.

For Inertia XHR requests, responds with a 409 Conflict status and an X-Inertia-Location header containing the destination URL. Inertia.js intercepts this response and triggers a client-side hard window.location redirect.

For standard non-Inertia clients (plain browser navigations, cURL, web crawlers, OAuth callbacks), responds with a standard HTTP redirect (307 Temporary Redirect for GET, 303 See Other for non-GET methods) and a Location header so non-Inertia consumers can navigate normally.

Unlike InertiaRedirect, this does NOT validate the redirect URL as same-origin because external redirects are explicitly intended for cross-origin navigation (e.g., OAuth callbacks, external payment pages).

Note

Request cookies are intentionally NOT passed to the response to prevent cookie leakage in redirect responses.


Prop Evaluation & Partial Reload Wrappers

defer

defer(key, callback, group=DEFAULT_DEFERRED_GROUP)

Create a deferred prop with optional grouping (v2 feature).

Deferred props are loaded lazily after the initial page render. Props in the same group are fetched together in a single request.

Parameters:

Name Type Description Default
key str

The key to store the value under.

required
callback Callable[..., T | Coroutine[Any, Any, T]]

A callable (sync or async) that returns the value.

required
group str

The group name for batched loading. Defaults to "default".

DEFAULT_DEFERRED_GROUP

Returns:

Type Description
DeferredProp[str, T]

A DeferredProp instance.

Example
defer("permissions", lambda: Permission.all())

defer("teams", lambda: Team.all(), group="attributes")
defer("projects", lambda: Project.all(), group="attributes")

defer("stats", lambda: compute_expensive_stats()).once()

once

once(key, value_or_callable)

Create a prop that resolves once and is cached client-side (v2.2.20+ feature).

Once props are included in the initial page load and resolved immediately. After resolution, the client caches the value and won't request it again on subsequent page visits, unless explicitly requested via partial reload.

This is useful for: - Expensive computations that rarely change - User preferences or settings - Feature flags - Static configuration

Unlike lazy props, once props ARE included in initial loads. The "once" behavior tells the client to cache the result.

Parameters:

Name Type Description Default
key str

The key to store the value under.

required
value_or_callable T | Callable[..., T | Coroutine[Any, Any, T]]

Either a static value or a callable that returns the value.

required

Returns:

Type Description
OnceProp[str, T]

An OnceProp instance.

Example
from litestar_vite.inertia import once, InertiaResponse

@get("/dashboard", component="Dashboard")
async def dashboard() -> InertiaResponse:
    return InertiaResponse({
        "user": current_user,
        "settings": once("settings", lambda: Settings.for_user(user_id)),
        "feature_flags": once("feature_flags", get_feature_flags()),
    })
See Also
  • defer: For deferred props that support .once() chaining
  • Inertia.js once props: https://inertiajs.com/partial-reloads#once

optional

optional(key, callback)

Create a prop only included when explicitly requested (v2 feature).

Optional props are NEVER included in initial page loads or standard partial reloads. They're only sent when the client explicitly requests them via only: ['prop_name'] in a partial reload.

This is designed for use with Inertia's WhenVisible component, which triggers a partial reload requesting specific props when an element becomes visible in the viewport.

The callback is only evaluated when requested, providing both bandwidth and CPU optimization.

Parameters:

Name Type Description Default
key str

The key to store the value under.

required
callback Callable[..., T | Coroutine[Any, Any, T]]

A callable (sync or async) that returns the value.

required

Returns:

Type Description
OptionalProp[str, T]

An OptionalProp instance.

Example
from litestar.params import FromPath
from litestar_vite.inertia import optional, InertiaResponse

@get("/posts/{post_id}", component="Posts/Show")
async def show_post(post_id: FromPath[int]) -> InertiaResponse:
    post = await Post.get(post_id)
    return InertiaResponse({
        "post": post,
        "comments": optional("comments", lambda: Comment.for_post(post_id)),
        "related_posts": optional("related_posts", lambda: Post.related(post_id)),
    })

Frontend usage with WhenVisible:

<WhenVisible data="comments" :params="{ only: ['comments'] }">
    <template #fallback>
        <LoadingSpinner />
    </template>
    <CommentList :comments="comments" />
</WhenVisible>
See Also
  • Inertia.js WhenVisible: https://inertiajs.com/load-when-visible

lazy

lazy(key, value_or_callable=None)

Create a lazy prop only included during partial reloads.

Lazy props are excluded from the initial page load and only sent when explicitly requested via partial reload (X-Inertia-Partial-Data header). This optimizes initial page load by deferring non-critical data.

There are two use cases for lazy():

1. Static Value (bandwidth optimization): The value is computed eagerly but only sent during partial reloads. Use when the value is cheap to compute but you want to reduce initial payload.

>>> lazy("user_count", len(users))

2. Callable (bandwidth + CPU optimization): The callable is only invoked during partial reloads. Use when the value is expensive to compute.

>>> lazy("permissions", lambda: Permission.all())
Warning

False Lazy Pitfall — pass the callable reference (lazy("data", expensive_fn)) rather than invoking it eagerly (lazy("data", expensive_fn())).

Parameters:

Name Type Description Default
key str

The key to store the value under in the props dict.

required
value_or_callable T | Callable[..., Coroutine[Any, Any, None]] | Callable[..., T] | Callable[..., T | Coroutine[Any, Any, T]] | None

Either a static value (computed eagerly, sent lazily) or a callable (computed and sent lazily). If None, creates a lazy prop with None value.

None

Returns:

Type Description
StaticProp[str, None] | StaticProp[str, T] | DeferredProp[str, T] | DeferredProp[str, None]

StaticProp if value_or_callable is not callable, DeferredProp otherwise.

See Also
  • defer: For v2 grouped deferred props loaded after page render
  • Inertia.js partial reloads: https://inertiajs.com/partial-reloads

always

always(key, value)

Create a prop always included, even during partial reloads (v2 feature).

Always props bypass partial reload filtering entirely. They're included in every response regardless of what keys the client requests.

Use for critical data that must always be present: - Authentication state - Permission flags - Feature toggles - Error states

Parameters:

Name Type Description Default
key str

The key to store the value under.

required
value T

The value (evaluated eagerly).

required

Returns:

Type Description
AlwaysProp[str, T]

An AlwaysProp instance.

Example
from litestar_vite.inertia import always, lazy, InertiaResponse

@get("/dashboard", component="Dashboard")
async def dashboard(request: Request) -> InertiaResponse:
    return InertiaResponse({
        "auth": always("auth", {"user": request.user, "can": permissions}),
        "analytics": lazy("analytics", get_analytics),
        "reports": lazy("reports", get_reports),
    })
See Also
  • lazy: For props excluded from initial load
  • optional: For props only included when explicitly requested

merge

merge(key, value, strategy='append', match_on=None)

Create a merge prop for combining data during partial reloads (v2 feature).

Merge props allow new data to be combined with existing props rather than replacing them entirely. This is useful for infinite scroll, load more buttons, and similar patterns.

Note: Prop merging only works during partial reloads. Full page visits will always replace props entirely.

Parameters:

Name Type Description Default
key str

The prop key.

required
value T

The value to merge.

required
strategy Literal['append', 'prepend', 'deep']

How to merge the data: - 'append': Add new items to the end (default) - 'prepend': Add new items to the beginning - 'deep': Recursively merge nested objects

'append'
match_on str | list[str] | None

Optional key(s) to match items on during merge, useful for updating existing items instead of duplicating.

None

Returns:

Type Description
MergeProp[str, T]

A MergeProp instance.

Example
merge("posts", new_posts)
merge("messages", new_messages, strategy="prepend")
merge("user_data", updates, strategy="deep")
merge("posts", updated_posts, match_on="id")

scroll_props

scroll_props(
    page_name="page", current_page=1, previous_page=None, next_page=None
)

Create scroll props configuration for infinite scroll (v2 feature).

Scroll props allow Inertia to manage pagination state for infinite scroll patterns, providing next/previous page information to the client.

Parameters:

Name Type Description Default
page_name str

The query parameter name for pagination. Defaults to "page".

'page'
current_page int

The current page number. Defaults to 1.

1
previous_page int | None

The previous page number, or None if at first page.

None
next_page int | None

The next page number, or None if at last page.

None

Returns:

Type Description
ScrollPropsConfig

A ScrollPropsConfig instance for use in InertiaResponse.

Example
from litestar.params import FromQuery
from litestar_vite.inertia import scroll_props, InertiaResponse

@get("/posts", component="Posts")
async def list_posts(page: FromQuery[int] = 1) -> InertiaResponse:
    posts = await Post.paginate(page=page, per_page=20)
    return InertiaResponse(
        {"posts": merge("posts", posts.items)},
        scroll_props=scroll_props(
            current_page=page,
            previous_page=page - 1 if page > 1 else None,
            next_page=page + 1 if posts.has_more else None,
        ),
    )

only

only(*keys)

Create a filter that only includes the specified prop keys.

Use this to explicitly limit which props are sent during partial reloads. Only the specified props will be included in the response.

Parameters:

Name Type Description Default
*keys str

The prop keys to include.

()

Returns:

Type Description
PropFilter

A PropFilter configured to include only the specified keys.

Example
from litestar_vite.inertia import only, InertiaResponse

@get("/users", component="Users")
async def list_users(
    request: InertiaRequest,
    user_service: UserService,
) -> InertiaResponse:
    return InertiaResponse(
        {
            "users": user_service.list(),
            "teams": team_service.list(),
            "stats": stats_service.get(),
        },
        prop_filter=only("users"),
    )
Note

This is a server-side helper. The client should use Inertia's router.reload({ only: ['users'] }) for client-initiated filtering.

except_

except_(*keys)

Create a filter that excludes the specified prop keys.

Use this to explicitly exclude certain props during partial reloads. All props except the specified ones will be included in the response.

Parameters:

Name Type Description Default
*keys str

The prop keys to exclude.

()

Returns:

Type Description
PropFilter

A PropFilter configured to exclude the specified keys.

Example
from litestar_vite.inertia import except_, InertiaResponse

@get("/users", component="Users")
async def list_users(
    request: InertiaRequest,
    user_service: UserService,
) -> InertiaResponse:
    return InertiaResponse(
        {
            "users": user_service.list(),
            "teams": team_service.list(),
            "stats": expensive_stats(),
        },
        prop_filter=except_("stats"),
    )
Note

The function is named except_ with a trailing underscore to avoid conflicting with Python's except keyword.


Prop Wrapper Classes & Extractors

DeferredProp

Bases: Generic[PropKeyT, T]

A wrapper for deferred property evaluation.

Attributes:

Name Type Description
groupstr

The deferred group this prop belongs to.

keyPropKeyT

Return the prop key.

is_oncebool

Whether this prop should only be resolved once and cached client-side.

MergeProp

Bases: Generic[PropKeyT, T]

A wrapper for merge prop configuration (v2 feature).

Merge props allow data to be combined with existing props during partial reloads instead of replacing them entirely.

Attributes:

Name Type Description
keyPropKeyT

Return the prop key.

valueT

Return the prop value to merge.

strategyLiteral['append', 'prepend', 'deep']

Return the configured merge strategy ('append', 'prepend', or 'deep').

match_onlist[str] | None

Return the optional list of property keys used to deduplicate merged items.

OnceProp

Bases: Generic[PropKeyT, T]

A wrapper for once-only property evaluation (v2.2.20+ feature).

Once props are resolved once and cached client-side. They won't be re-fetched on subsequent page visits unless explicitly requested via partial reload with only: ['key'].

This is useful for expensive computations that rarely change (e.g., user preferences, feature flags, static configuration).

Unlike lazy props, once props ARE included in the initial page load. The "once" behavior tells the client to cache the value and not request it again on future visits.

Attributes:

Name Type Description
keyPropKeyT

Return the prop key.

OptionalProp

Bases: Generic[PropKeyT, T]

A wrapper for optional property evaluation (v2 feature).

Optional props are NEVER included in initial page loads or standard partial reloads. They're only sent when the client explicitly requests them via only: ['prop_name'].

This is designed for use with Inertia's WhenVisible component, which loads data only when an element becomes visible in the viewport.

The callback is only evaluated when the prop is explicitly requested, providing both bandwidth and CPU optimization.

Attributes:

Name Type Description
keyPropKeyT

Return the prop key.

AlwaysProp

Bases: Generic[PropKeyT, T]

A wrapper for always-included property evaluation (v2 feature).

Always props are ALWAYS included in responses, even during partial reloads. This is the opposite of lazy props - they bypass any partial reload filtering.

Use for critical data that must always be present, such as: - Authentication state - Permission flags - Feature toggles - Error states

Attributes:

Name Type Description
keyPropKeyT

Return the prop key.

valueT

Return the eagerly evaluated prop value.

StaticProp

Bases: Generic[PropKeyT, StaticT]

A wrapper for static property evaluation.

Attributes:

Name Type Description
keyPropKeyT

Return the prop key.

PropFilter

Configuration for prop filtering (only / except_) during partial reloads.

Attributes:

Name Type Description
includeset[str] | None

Set of prop keys to explicitly include in the response.

excludeset[str] | None

Set of prop keys to explicitly exclude from the response.

ScrollPropsConfig

Configuration for Inertia v2 infinite scroll pagination metadata.

Attributes:

Name Type Description
page_namestr

Query parameter name used to request a specific page.

previous_pageint | None

Previous page number, or None when on the first page.

next_pageint | None

Next page number, or None when on the last page.

current_pageint

Current 1-based page number.

extract_deferred_props

extract_deferred_props(props)

Extract deferred props metadata for the Inertia v2 protocol.

This extracts all DeferredProp instances from the props dict and groups them by their group name, returning a dict mapping group -> list of prop keys.

Note: DeferredProp instances with is_once=True are excluded from the result because once props should not be re-fetched after initial resolution.

Parameters:

Name Type Description Default
props Mapping[str, Any]

The props dictionary to scan.

required

Returns:

Type Description
dict[str, list[str]]

A dict mapping group names to lists of prop keys in that group.

dict[str, list[str]]

Empty dict if no deferred props found.

Example
props = {
    "users": [...],
    "teams": defer("teams", get_teams, group="attributes"),
    "projects": defer("projects", get_projects, group="attributes"),
    "permissions": defer("permissions", get_permissions),
}
result = extract_deferred_props(props)

The result is {"default": ["permissions"], "attributes": ["teams", "projects"]}.

extract_merge_props

extract_merge_props(props)

Extract merge props metadata for the Inertia v2 protocol.

This extracts all MergeProp instances from the props dict and categorizes them by their merge strategy, returning the appropriate lists for the page response.

Parameters:

Name Type Description Default
props Mapping[str, Any]

The props dictionary to scan.

required

Returns:

Type Description
list[str]

A tuple of (merge_props, prepend_props, deep_merge_props, match_props_on)

list[str]

where each list contains the prop keys for that strategy, and match_props_on

list[str]

is a flat list of property paths such as items.id.

Example
props = {
    "users": [...],
    "posts": merge("posts", new_posts),
    "messages": merge("messages", new_msgs, strategy="prepend"),
    "data": merge("data", updates, strategy="deep"),
    "items": merge("items", items, match_on="id"),
}
merge_props, prepend_props, deep_merge_props, match_props_on = extract_merge_props(props)

The returned values then contain:

  • merge_props: ["posts", "items"]
  • prepend_props: ["messages"]
  • deep_merge_props: ["data"]
  • match_props_on: ["items.id"]

extract_once_props

extract_once_props(props, partial_data=None, partial_except=None)

Extract once props for the Inertia v2.2.20+ protocol.

Once props are cached client-side after first resolution. This function extracts all OnceProp instances and DeferredProp instances with is_once=True.

Parameters:

Name Type Description Default
props Mapping[str, Any]

The props dictionary to scan.

required
partial_data set[str] | None

Optional set of requested partial prop keys.

None
partial_except set[str] | None

Optional set of prop keys excluded from the partial response.

None

Returns:

Type Description
list[str]

A list of prop keys that should be cached client-side.

list[str]

Empty list if no once props found.

Example
props = {
    "user": current_user,
    "settings": once("settings", get_settings),
    "stats": defer("stats", get_stats).once(),
}
result = extract_once_props(props)

The result is ["settings", "stats"].

should_render

should_render(
    value,
    partial_data=None,
    partial_except=None,
    except_once_props=None,
    key=None,
)

Check if value should be rendered based on partial reload filtering.

For v2 protocol, partial_except takes precedence over partial_data. When a key is provided, filtering applies to all props (not just lazy props).

Prop types have different behaviors: - AlwaysProp: Always included, bypasses all filtering - OptionalProp: Only included when explicitly requested via partial_data - LazyProp (StaticProp/DeferredProp): Excluded from initial load, included on partial reload - OnceProp: Included in initial load, cached client-side - Regular values: Follow standard partial reload filtering

Parameters:

Name Type Description Default
value Any

Any value to check

required
partial_data set[str] | None

Optional set of keys to include (X-Inertia-Partial-Data)

None
partial_except set[str] | None

Optional set of keys to exclude (X-Inertia-Partial-Except, v2)

None
except_once_props set[str] | None

Optional set of once-prop keys already cached client-side.

None
key str | None

Optional key name for this prop (enables key-based filtering for all props)

None

Returns:

Name Type Description
bool bool

True if value should be rendered


Shared Props, Flash Messages & History State

share

share(connection, key, value)

Stage a shared value for the current Inertia response.

Shared values are included in the props of every Inertia response for the current request. This is useful for data that should be available to all components (e.g., authenticated user, permissions, settings). Top-level special props remain raw in request scope and are materialized lazily in the handler frame only when the response includes them. Redirect responses persist supported synchronous values when the request exposes a session transport. Async special props remain available to the current response but cannot cross a redirect.

Parameters:

Name Type Description Default
connection ASGIConnection[Any, Any, Any, Any]

The ASGI connection.

required
key str

The key to store the value under.

required
value Any

The value to store.

required

Returns:

Type Description
bool

True when the value was staged for the current request.

get_shared_props

get_shared_props(
    request, partial_data=None, partial_except=None, except_once_props=None
)

Return shared session props for a request.

For v2 protocol, partial_except takes precedence over partial_data.

Parameters:

Name Type Description Default
request ASGIConnection[Any, Any, Any, Any]

The ASGI connection.

required
partial_data set[str] | None

Optional set of keys to include (X-Inertia-Partial-Data).

None
partial_except set[str] | None

Optional set of keys to exclude (X-Inertia-Partial-Except, v2).

None
except_once_props set[str] | None

Optional cached once-prop keys sent by the client.

None

Returns:

Type Description
dict[str, Any]

The shared props. Includes a special _once_props key (list of prop keys

dict[str, Any]

that were OnceProp instances) for protocol metadata generation.

Note

Be sure to call this before self.create_template_context if you would like to include the flash message details.

flash

flash(connection, message, category='info')

Stage a flash message for the current Inertia response.

Flash messages are consumed into the top-level flash page field. Redirect responses persist them when the request exposes a session transport.

This function works without requiring Litestar's FlashPlugin or any Jinja2 template configuration, making it ideal for SPA-only Inertia applications.

Parameters:

Name Type Description Default
connection ASGIConnection[Any, Any, Any, Any]

The ASGI connection (Request or WebSocket).

required
message str

The message text to display.

required
category str

The message category (e.g., "success", "error", "warning", "info"). Defaults to "info".

'info'

Returns:

Type Description
bool

True when the flash message was staged for the current request.

Example
from litestar_vite.inertia import flash

@post("/create")
async def create_item(request: Request) -> InertiaResponse:
    flash(request, "Item created successfully!", "success")
    return InertiaResponse(...)

error

error(connection, key, message)

Stage an error message for the current Inertia response.

Error messages are included in the errors prop of Inertia responses, typically used for form validation errors. The key usually corresponds to a form field name.

Parameters:

Name Type Description Default
connection ASGIConnection[Any, Any, Any, Any]

The ASGI connection.

required
key str

The key to store the error under (usually a field name).

required
message str

The error message.

required

Returns:

Type Description
bool

True when the error was staged for the current request.

clear_history

clear_history(connection)

Mark that the next response should clear client history encryption keys.

This function stages a request-local flag consumed by the current InertiaResponse. Redirect responses persist the flag when the request exposes a session transport.

This should typically be called during logout to ensure sensitive data cannot be recovered from browser history after a user logs out.

Parameters:

Name Type Description Default
connection ASGIConnection[Any, Any, Any, Any]

The ASGI connection (Request).

required
Example
from litestar_vite.inertia import clear_history

@post("/logout")
async def logout(request: Request) -> InertiaRedirect:
    request.session.clear()
    clear_history(request)
    return InertiaRedirect(request, redirect_to="/login")

Laravel Precognition & Exception Handling

precognition

precognition(fn)

Decorator to enable Precognition on a route handler.

When a Precognition request passes DTO validation, this decorator returns a 204 No Content response instead of executing the handler body. This prevents side effects (database writes, emails, etc.) during validation.

Parameters:

Name Type Description Default
fn Callable[..., Any]

The route handler function to wrap.

required

Returns:

Type Description
Callable[..., Any]

A wrapped handler that short-circuits on valid Precognition requests.

Example
from litestar import post
from litestar_vite.inertia import precognition, InertiaRedirect

@post("/users")
@precognition
async def create_user(data: UserDTO) -> InertiaRedirect:
    # This only runs for actual form submissions
    # Precognition validation requests return 204 automatically
    user = await User.create(**data.dict())
    return InertiaRedirect(request, f"/users/{user.id}")
Note
  • Validation errors are handled by the exception handler (automatic)
  • This decorator handles the success case (prevents handler execution)
  • The decorator checks for Precognition header AFTER DTO validation

PrecognitionResponse

Bases: Response[Any]

Response for successful Precognition validation.

Returns 204 No Content with Precognition-Success header.

create_precognition_exception_handler

create_precognition_exception_handler(*, fallback_handler=None)

Create an exception handler for ValidationException that supports Precognition.

This handler checks if the request is a Precognition request and returns errors in Laravel's format. For non-Precognition requests, it either uses the fallback handler or returns Litestar's default format.

Parameters:

Name Type Description Default
fallback_handler Callable[[Request[Any, Any, Any], ValidationException], Response[Any]] | None

Optional handler for non-Precognition requests. If not provided, returns a standard JSON error response.

None

Returns:

Type Description
Callable[[Request[Any, Any, Any], ValidationException], Response[Any]]

An exception handler function suitable for Litestar's exception_handlers.

normalize_validation_errors

normalize_validation_errors(exc, validate_only=None)

Normalize Litestar validation errors to Laravel format.

Laravel's Precognition protocol expects errors in this format:

{
    "message": "The given data was invalid.",
    "errors": {
        "email": ["The email field is required."],
        "password": ["The password must be at least 8 characters."]
    }
}

Parameters:

Name Type Description Default
exc ValidationException

The ValidationException from Litestar.

required
validate_only set[str] | None

If provided, only include errors for these fields. Used for partial field validation as the user types.

None

Returns:

Type Description
dict[str, Any]

A dict in Laravel's validation error format.

create_inertia_exception_response

create_inertia_exception_response(request, exc)

Create the inertia exception response.

This function handles exceptions for Inertia-enabled routes, returning appropriate responses based on the exception type and status code.

Note

This function uses defensive programming techniques to handle edge cases: - Type-safe handling of exception extra attribute (may be string, list, dict, or None) - Graceful handling when InertiaPlugin is not registered - Broad exception handling for flash() calls (non-critical operation)

Parameters:

Name Type Description Default
request Request[UserT, AuthT, StateT]

The request object.

required
exc Exception

The exception to handle.

required

Returns:

Type Description
Response[Any]

The response object, either an InertiaResponse, InertiaRedirect, or InertiaBack.

exception_to_http_response

exception_to_http_response(request, exc)

Handler for all exceptions subclassed from HTTPException.

Inertia detection:

  • For InertiaRequest instances, uses the request's derived flags (route component + headers).
  • For plain Request instances (e.g., before routing/when middleware didn't run), falls back to checking the X-Inertia header.

Parameters:

Name Type Description Default
request Request[UserT, AuthT, StateT]

The request object.

required
exc Exception

The exception to handle.

required

Returns:

Type Description
Response[Any]

The response object.