Inertia X is a drop-in replacement for the Inertia client-side adapter for Svelte 5. It replaces Inertia's singleton router and page object with instantiable versions (meaning that one app can have multiple routers). This enables interesting new features:
The <Frame> component lets you embed one Inertia page inside another Inertia page, each with its own navigation. This is useful for modals, wizards, sidebars, and more.
<script>
import { Frame } from 'inertiax-svelte'
</script>
<Frame src="/users/1/edit">
Loading...
</Frame>The <Frame> component accepts these props:
| Prop | Default | Description |
|---|---|---|
name |
random | The frame's name. Use this to target the frame directly in responses. The top-level frame is always named _top. |
src |
null | The URL of the page to load. If not provided, no request is made and the initial component and page are shown. |
renderLayout |
true if name == _top |
Whether to render the component's layout. |
initialComponent |
null | The component to show before making the request. Can be a promise. |
initialPage |
null | The initial Inertia page object with initial props. Gets replaced after the request completes. |
onclick |
noop | An event handler that runs before the frame's own click handler. Call preventDefault on the event to skip the frame's default handler. |
Any other props are passed down to the page component.
If you don't set initialComponent, the child content shows until the request finishes. Use this to display loading spinners and animations.
When you make a request from inside a frame, the referer header still contains the current window location.
The new X-Inertia-Frame-Src header solves this. The Inertia router sets this header to the originating frame's URL. Use this header instead of referer when you want to redirect users back to the previous URL.
On the backend, you can get the originating frame's name from the X-Inertia-Frame header. The default top frame name is _top.
For all frames except _top, the preserveUrl and replace router visit options now default to true.
By default, navigation through links, router.visit calls, and form.submit calls render their response in the same frame that made the request.
To render a response in a different frame, you have several options:
- Use the new
framerouter visit option:router.visit('/url', {frame: 'otherFrame'}). - Set an
X-Inertia-Frameresponse header with the target frame's name. - Add a
data-target="frame"attribute to youratag.
You can also access a frame's router directly from the component:
<script>
function goSomewhereElse() {
frame.router.visit(...)
}
</script>
<Frame name="modal" bind:this={frame} />or get it globally:
import { getRouter } from 'inertiax-svelte'
getRouter("modal").post("/users")Inertia X lets you add custom callbacks to its navigation stack using the new pushExternal() function. When you call this function, it adds the callbacks to the "stack" and calls the arrive() function. When users navigate back with the browser's back button, the recede() function gets called. Future forward/back navigation will call arrive() and recede() as users move back and forth. Inertia's normal navigation handling stops during these states.
<script>
import { history } from 'inertiax-core'
function onclick() {
history.pushExternal(url, {
arrive() {
alert("You arrived at an external history state")
},
recede() {
alert("You navigated back from an external history state")
}
})
}
</script>
<button {onclick}>Push external state</button>Each frame component now has its own click handler. Clicks on elements with an href attribute get handled automatically. To disable this, add the data-inertia-ignore attribute to the element or any parent element. To disable globally, add data-inertia-ignore to the body element.
You can still use the inertia action and <Link> component as usual.
data-method: The HTTP methoddata-target: A target framedata-preserve-scroll: Preserve scrolldata-preserve-state: Preserve statedata-preserve-url: Preserve URLdata-replace: Replace history state (instead of pushing new state)
Note that in frames other than the top frame, replace and preserve-url default to true.
<a href="/session" data-method="delete">Log out</a>The global router and page stores have been removed. Each frame now has its own router and page store. Get them from the frame component's context. Parent frame context is also available via inertia:frame_name.
- import { router, page } from 'inertiax-svelte'
+ const { router, page } = getContext('inertia')
// OR
+ const { router, page } = getContext('inertia:_top')For convenience, the current Frame's router is also passed to the Frame's component as a prop:
const { router } = $props()When you use router.on('event', ...), you only receive events from that specific frame's router. To listen to events from all frames, use document.addEventListener('inertia:event', ...):
import { getContext } from "svelte";
const { router, frame } = getContext("inertia");
router.on("navigate", () => {
console.log("navigated inside frame ", frame);
})
// or listen to all frames:
document.addEventListener('inertia:navigate', ...)Follow the installation guide for your backend adapter on https://inertiajs.com, but replace the @inertiajs/svelte package with inertiax-svelte.
npm i -D inertiax-svelteThen use the package like you would use the original:
import { createInertiaApp } from 'inertiax-svelte'
createInertiaApp( ... ) {
// ...
}