March 6th, 2026

Inertia 3 Beta Is Here - And It's a Big One

Inertia 3 Beta Is Here - And It's a Big One
Sponsored by
Table of Contents

Taylor Otwell dropped the announcement earlier today: Inertia 3 is in beta. If you've been building Laravel + Inertia apps for a while, this release is worth paying attention to. There's a lot here - a new Vite plugin, optimistic updates, instant navigation, layout props, a useHttp hook, simplified SSR, and Axios being replaced with a built-in XHR client. Let's go through it.


A New Vite Plugin

The @inertiajs/vite plugin is the headline change in terms of developer experience. It takes over page resolution, code splitting, and SSR setup automatically. Your entire entry point can now be a single function call:

1// vite.config.js
2export default defineConfig({
3 plugins: [
4 laravel({
5 input: ['resources/js/app.js'],
6 refresh: true,
7 }),
8 inertia(),
9 vue(),
10 ],
11})
12 
13// resources/js/app.js
14import { createInertiaApp } from '@inertiajs/vue3'
15 
16createInertiaApp()

That's it. No manual glob imports, no resolver config, no SSR entry file to maintain separately.

Speaking of SSR - development SSR no longer requires a separate Node.js server. With the Vite plugin, composer dev is all you need. No separate build step, no separate process, and error reporting is significantly better.


Optimistic Updates

Optimistic updates are now a first-class feature. Chain .optimistic() before any router visit to apply prop changes immediately on the client. If the server request fails, the props revert automatically - no manual rollback logic needed:

1import { router } from '@inertiajs/vue3'
2 
3router
4 .optimistic((props) => ({
5 post: {
6 ...props.post,
7 is_favorite: !props.post.is_favorite,
8 },
9 }))
10 .post(`/posts/${post.id}/favorite`)

Clean, predictable, and you don't have to wire up your own state management just to make a toggle feel instant.


Instant Visits

Instant visits let you swap to the target page component immediately while the server request fires in the background. The user sees the new page right away using shared props, and the full data merges in once the response arrives.

You can do this declaratively via the Link component:

1<template>
2 <Link
3 href="/features/navigation/target"
4 component="Features/Navigation/Target"
5 >
6 Navigate Instantly
7 </Link>
8</template>

Or programmatically with placeholder props:

1// Or programmatically with placeholder props...
2router.visit(url, {
3 component: 'Features/Navigation/Target',
4 pageProps: (currentProps, sharedProps) => ({
5 ...sharedProps,
6 greeting: 'Loading from server...',
7 items: [],
8 }),
9})

The useHttp Hook

This is a useful one for apps that mix Inertia navigation with direct API calls. useHttp gives you the same developer experience as useForm, but for plain HTTP requests - reactive state, error handling, file upload progress, and request cancellation, all without triggering a page visit:

1<script setup>
2import { useHttp } from '@inertiajs/vue3'
3 
4const http = useHttp({ name: '' })
5 
6function postToApi() {
7 http.post('/api/endpoint', {
8 onSuccess: (response) => {
9 console.log(response)
10 },
11 })
12}
13</script>
14 
15<template>
16 <input v-model="form.name" />
17 <button :disabled="form.processing" @click="postToApi">
18 {{ form.processing ? 'Sending...' : 'Send Request' }}
19 </button>
20</template>

If you've ever hacked around Inertia's form helper to make API calls that don't need a full page visit, this is the proper solution.


Layout Props

The new useLayoutProps hook lets layouts declare default values that pages can override. Layouts consume useLayoutProps to get reactive state, and pages call setLayoutProps() to push their own values in:

1<!-- AppLayout.vue -->
2<script setup>
3import { useLayoutProps } from '@inertiajs/vue3'
4 
5const layout = useLayoutProps({
6 subtitle: '',
7})
8</script>
9 
10<template>
11 <div v-if="layout.subtitle" class="banner">
12 {{ layout.subtitle }}
13 </div>
14 <slot />
15</template>

From any page:

1<!-- Any page -->
2<script setup>
3import { setLayoutProps, resetLayoutProps } from '@inertiajs/vue3'
4 
5setLayoutProps({ subtitle: 'Welcome back!' })
6 
7// Reset to defaults...
8resetLayoutProps()
9</script>

Nested layouts are supported too. This replaces the various workarounds people have been using - emitting events upward, using a store just for layout state, or reaching into $parent.


Better Exception Handling

Custom error pages for 500s and other HTTP exceptions now have a proper API. The handleExceptionsUsing() method lets you render Inertia error pages with full access to shared data:

1// app/Providers/AppServiceProvider.php
2use Inertia\ExceptionResponse;
3use Inertia\Inertia;
4 
5Inertia::handleExceptionsUsing(
6 function (ExceptionResponse $response) {
7 if (in_array($response->statusCode(), [
8 403, 404, 419, 429, 500, 503
9 ])) {
10 return $response
11 ->render('ErrorPage', [
12 'status' => $response->statusCode(),
13 ])
14 ->withSharedData();
15 }
16 }
17);

The ->withSharedData() call is the key part - your error page gets the same auth state, flash messages, and other shared data as any other Inertia page.


Axios Is Gone

Axios has been replaced with a built-in XHR client. Smaller bundle, fewer dependencies. Built-in HTTP interceptors cover the same extension points Axios adapters provided, and if you're heavily invested in Axios-specific behavior, there's an Axios adapter available to keep using it.


Smaller Additions

Beyond the headline features, v3 also ships: nested prop types with dot-notation support, a default layout option in createInertiaApp, TypeScript form component generics, enum support in Inertia::render(), and a preserveErrors option for partial reloads.


Should You Upgrade Now?

It's a beta, so production apps should wait. But if you have a test project or a staging environment, now is a good time to kick the tires and report issues. The Vite plugin alone is going to clean up a lot of boilerplate in existing codebases.

The official docs and upgrade guide should be available on inertiajs.com - keep an eye there for the stable release.

If you enjoyed this article, please consider supporting our work for as low as $5 / month.

Sponsor
Marian Pop

Written by

Marian Pop

Writing and maintaining @LaravelMagazine. Host of "The Laravel Magazine Podcast". Pronouns: vi/vim.

Comments

Stay Updated

Subscribe to our newsletter

Get latest news, tutorials, community articles and podcast episodes delivered to your inbox.

Weekly articles
We send a new issue of the newsletter every week on Friday.
No spam
We'll never share your email address and you can opt out at any time.