Overview
once() marks props that Inertia can remember on the client and skip re-sending on later visits. This is useful for expensive or rarely-changing data like plans, reference data, and feature flags.
Basic Usage
Wrap a value or callable with once():
from cross_inertia import once
from cross_inertia.fastapi import InertiaDep
@app.get("/billing")
def billing(inertia: InertiaDep):
return inertia.render(
"Billing/Plans",
{
"plans": once(load_plans),
"permissions": once(load_permissions),
},
)On the initial visit, the prop is included as normal. On later visits, the Inertia client can tell the server it already has that prop and the server will omit the value while still sending onceProps metadata.
Expiration
Use until= to expire remembered props automatically:
from datetime import timedelta
from cross_inertia import once
@app.get("/billing")
def billing(inertia: InertiaDep):
return inertia.render(
"Billing/Plans",
{
"exchange_rates": once(load_rates, until=timedelta(days=1)),
},
)You can pass:
timedeltadatetime- An integer Unix timestamp in seconds
Custom Keys
By default, Cross-Inertia uses the prop path as the once key. You can override that with key=:
from cross_inertia import once
return inertia.render(
"Team/Invite",
{
"available_roles": once(load_roles, key="roles"),
},
)Custom keys are helpful when the same logical data appears under different prop names or shared/page boundaries.
Forced Refresh
Use fresh=True when the prop should always be recomputed, even if the client says it already has a remembered value:
from cross_inertia import once
return inertia.render(
"Billing/Plans",
{
"feature_flags": once(load_flags, fresh=request.query_params.get("refresh") == "1"),
},
)Shared Data
once() works in shared-data hooks too:
from datetime import timedelta
from fastapi import Request
from cross_inertia import once
from cross_inertia.fastapi import inertia_share
@inertia_share
def share_reference_data(request: Request) -> dict:
return {
"countries": once(load_countries, key="countries", until=timedelta(days=1)),
"feature_flags": once(
load_flags,
fresh=request.query_params.get("refresh") == "1",
),
}The same pattern works in Django SHARE functions.
Combining With Deferred Props
You can compose once() with defer():
from cross_inertia import defer, once
return inertia.render(
"Billing/Plans",
{
"permissions": once(
defer(load_permissions, group="sidebar"),
key="permissions",
),
},
)This lets you defer the first load and then avoid re-sending the resolved value on later visits.
Refreshing From The Client
Refreshing a once prop uses the normal Inertia partial reload flow:
import { router } from '@inertiajs/react'
router.reload({ only: ['plans'] })If a once prop is explicitly requested via only, Cross-Inertia recomputes it even if the client had previously remembered it.