Inertia v3 beta is a major pre-release milestone that ships a built-in XHR HTTP client, a new useHttp hook for standalone HTTP requests, optimistic updates across the router and form APIs, instant visits, and more.
- Built-in XHR HTTP client; Axios is now an optional peer dependency
- New
useHttphook for standalone HTTP requests - Optimistic updates for
router,useForm, anduseHttp - Instant visits
- SSR support in Vite development mode with simplified setup
- Layout props helpers and
layoutoption increateInertiaApp() - And more
Here's the full talk of Joe Tannenbaum introducing Inertia v3 at Laracon EU 2026:
What's New
Built-in XHR HTTP Client
Inertia now ships its own XHR-based HTTP client, making Axios an optional peer dependency rather than a required one. Applications that don't need Axios can drop it entirely; those that prefer it can continue using it by installing it as a peer dependency:
import { axiosAdapter } from '@inertiajs/core' createInertiaApp({ // ... http: axiosAdapter(),})
PR: #2833
useHttp Hook for Standalone HTTP Requests
A new useHttp hook allows you to make HTTP requests outside of Inertia's visit system. It provides the same developer experience as useForm — including processing, errors, progress, and isDirty state — but returns response data instead of triggering page navigation. It supports withAllErrors for surfacing all validation errors, not just the first.
const http = useHttp({ query: '',}) const search = () => { http.get('/api/search').then((results) => { console.log('Found:', results.length) })}
Optimistic Updates
Optimistic update support has been added across router, useForm, and useHttp, including support for concurrent optimistic updates. The update callback receives the current props and returns the optimistic state to apply immediately, with automatic rollback on validation errors, server errors, or interrupted visits.
The router supports both a fluent API and an inline option:
// Fluentrouter .optimistic((props) => ({ todos: [...props.todos, { id: Date.now(), name, done: false }], })) .post('/todos', { name }) // Inline optionrouter.post('/todos', { name }, { optimistic: (props) => ({ todos: [...props.todos, { id: Date.now(), name, done: false }], }),})
The useForm hook works the same way:
const form = useForm({ name: '' }) const addTodo = () => { form .optimistic((props) => ({ todos: [...props.todos, { id: Date.now(), name: form.name, done: false }], })) .post('/todos')}
The <Form> component also gains an optimistic prop for declarative handling.
Instant Visits
Instant visits allow navigation to feel immediate by rendering the destination page before the server response completes.
PR: #2907
URL Fragment Preservation
A new server-side preserveFragment option keeps the URL hash fragment intact across redirects. In Laravel, chain preserveFragment() on a redirect response:
return redirect('/users')->preserveFragment();
When the server includes preserveFragment: true in the Inertia page object, the client retains the original request's URL fragment even when the response URL differs. Hash fragment redirect support has also been added.
preserveErrors Option for Partial Requests
A preserveErrors option has been added to preserve existing validation errors when making partial requests, preventing errors from being cleared when only part of a page is refreshed.
PR: #2819
SSR Support in Vite Development Mode
Inertia now supports SSR in Vite development mode with a simplified setup, removing friction from SSR development workflows.
PR: #2864
Progress Bar Rewritten with the Popover API
The progress bar implementation has been rewritten to use the browser's native Popover API, replacing the previous approach.
PR: #2917
Layout Props Helpers and layout Option in createInertiaApp()
Layout props helpers have been added to improve how layout data is organized and passed. A layout option is now available directly in createInertiaApp(), and the function can also be called without arguments.
strictMode Option for React
React's createInertiaApp gains a strictMode option to opt into React's strict mode rendering. When setup is not provided, enabling this option wraps the app in React's <StrictMode>. When using a custom setup function, wrap components manually.
createInertiaApp({ strictMode: true, // ...})
PR: #2909
reloading Slot Prop on <Deferred>
The <Deferred> component now exposes a reloading slot prop, allowing you to show a loading indicator when deferred content is being refreshed via a partial reload. Unlike the fallback slot, the existing content stays visible during the reload — only the reloading state changes.
<Deferred data="users"> <template #fallback> <span>Loading...</span> </template> <template #default="{ reloading }"> <span v-if="reloading">Reloading...</span> <div v-for="user in users" :key="user.id"> {{ user.name }} </div> </template></Deferred>
PR: #2860
Generics in <Form> Component
The <Form> component now supports TypeScript generics for improved type inference on form data.
PR: #2849
onHttpException for Server-Rendered Error Pages
Server-rendered Inertia error pages now fire the onHttpException event, giving you a consistent place to handle HTTP exceptions regardless of how they are rendered.
PR: #2927
Breaking Changes
This is a beta release with significant breaking changes. Review these carefully before upgrading.
Dropped framework support:
- React below v19 is no longer supported (#2712)
- Svelte 4 is no longer supported; Svelte 5 is required (#2713)
Node.js: The minimum Node.js version is now v24 (#2847)
ESM-only: CommonJS builds have been dropped. Inertia now ships ESM-only output (#2873)
Axios: Axios is no longer a required dependency. Install it manually as a peer dependency if your application uses it (#2833)
Removed exports: hideProgress() and revealProgress() have been removed (#2852)
Renamed config: useDataElementForInitialPage has been renamed to useDataAttributeForInitialPage; the legacy option has been removed (#2871, #2887)
Renamed events: The invalid and exception events have been renamed; visit callbacks have been added (#2869)
resolve() signature: The resolve function in createInertiaApp() now receives the full page object as an optional second argument, giving resolvers access to props, URL, version, and other page context (#2485):
// Beforeresolve: (name) => resolvePageComponent(name, import.meta.glob('./Pages/**/*.vue')), // Afterresolve: (name, page) => resolvePageComponent(name, import.meta.glob('./Pages/**/*.vue')),
useForm behavior: processing and progress now only reset in onFinish, not earlier in the lifecycle (#2838)
This is a beta release and not recommended for production use. Refer to the full changelog for the complete list of changes before upgrading.
References