Skip to content
Merged

3.x #39

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
31b0df8
v3
pascalbaljet Feb 10, 2026
10602bd
wip
pascalbaljet Feb 11, 2026
923a5d8
Update http-requests.mdx
pascalbaljet Feb 11, 2026
eb13bb1
Svelte 5 syntax
pascalbaljet Feb 11, 2026
c10a7ff
wip
pascalbaljet Feb 11, 2026
14e5546
wip
pascalbaljet Feb 11, 2026
b9286cf
Update the-protocol.mdx
pascalbaljet Feb 11, 2026
753bcb4
more v3
pascalbaljet Feb 20, 2026
70f79e3
Merge branch 'main' into 3.x
pascalbaljet Feb 20, 2026
af428e9
v2
pascalbaljet Feb 20, 2026
e660f2a
Update upgrade-guide.mdx
pascalbaljet Feb 20, 2026
905c774
more v3
pascalbaljet Feb 20, 2026
3e007af
Update upgrade-guide.mdx
pascalbaljet Feb 20, 2026
5f31bbe
v3
pascalbaljet Feb 20, 2026
aaaf068
ssr
pascalbaljet Feb 20, 2026
2a19aee
Update upgrade-guide.mdx
pascalbaljet Feb 20, 2026
cd00ede
fragments + nested props
pascalbaljet Feb 24, 2026
d6ec0d2
Update client-side-setup.mdx
pascalbaljet Feb 24, 2026
c908cf2
ssr
pascalbaljet Feb 25, 2026
f251857
Update server-side-rendering.mdx
pascalbaljet Feb 25, 2026
2c23657
protocol updates
pascalbaljet Feb 25, 2026
4dc58cc
instant visits
pascalbaljet Feb 25, 2026
c3240fe
Update optimistic-updates.mdx
pascalbaljet Feb 26, 2026
3779b95
typo
pascalbaljet Feb 26, 2026
f789bdf
Update upgrade-guide.mdx
pascalbaljet Feb 26, 2026
63c4cb1
Merge branch 'main' into 3.x
pascalbaljet Feb 26, 2026
00f97ea
Update events.mdx
pascalbaljet Feb 26, 2026
110a6dd
Update events.mdx
pascalbaljet Feb 26, 2026
f144065
Update events.mdx
pascalbaljet Feb 26, 2026
085a31c
v3 beta warning
pascalbaljet Mar 5, 2026
de0879d
Update upgrade-guide.mdx
pascalbaljet Mar 5, 2026
cd880a1
Update upgrade-guide.mdx
pascalbaljet Mar 5, 2026
1edf46c
Update demo-application.mdx
pascalbaljet Mar 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 112 additions & 1 deletion docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,93 @@
}
]
},
{
"version": "3.x",
"groups": [
{
"group": "Getting Started",
"pages": [
"v3/getting-started/index",
"v3/getting-started/demo-application",
"v3/getting-started/upgrade-guide"
]
},
{
"group": "Installation",
"pages": [
"v3/installation/server-side-setup",
"v3/installation/client-side-setup"
]
},
{
"group": "Core Concepts",
"pages": [
"v3/core-concepts/who-is-it-for",
"v3/core-concepts/how-it-works",
"v3/core-concepts/the-protocol"
]
},
{
"group": "The Basics",
"pages": [
"v3/the-basics/pages",
"v3/the-basics/responses",
"v3/the-basics/redirects",
"v3/the-basics/routing",
"v3/the-basics/title-and-meta",
"v3/the-basics/links",
"v3/the-basics/manual-visits",
"v3/the-basics/instant-visits",
"v3/the-basics/forms",
"v3/the-basics/http-requests",
"v3/the-basics/optimistic-updates",
"v3/the-basics/file-uploads",
"v3/the-basics/validation",
"v3/the-basics/layouts",
"v3/the-basics/view-transitions"
]
},
{
"group": "Data & Props",
"pages": [
"v3/data-props/shared-data",
"v3/data-props/flash-data",
"v3/data-props/partial-reloads",
"v3/data-props/deferred-props",
"v3/data-props/merging-props",
"v3/data-props/once-props",
"v3/data-props/polling",
"v3/data-props/prefetching",
"v3/data-props/load-when-visible",
"v3/data-props/infinite-scroll",
"v3/data-props/remembering-state"
]
},
{
"group": "Security",
"pages": [
"v3/security/authentication",
"v3/security/authorization",
"v3/security/csrf-protection",
"v3/security/history-encryption"
]
},
{
"group": "Advanced",
"pages": [
"v3/advanced/asset-versioning",
"v3/advanced/code-splitting",
"v3/advanced/error-handling",
"v3/advanced/events",
"v3/advanced/progress-indicators",
"v3/advanced/scroll-management",
"v3/advanced/server-side-rendering",
"v3/advanced/testing",
"v3/advanced/typescript"
]
}
]
},
{
"version": "1.x",
"groups": [
Expand Down Expand Up @@ -181,6 +268,10 @@
}
},
"redirects": [
{
"source": "/index",
"destination": "/v2/getting-started/index"
},
{
"source": "/demo-application",
"destination": "/v2/getting-started/demo-application"
Expand Down Expand Up @@ -253,6 +344,26 @@
"source": "/view-transitions",
"destination": "/v2/the-basics/view-transitions"
},
{
"source": "/instant-visits",
"destination": "/v3/the-basics/instant-visits"
},
{
"source": "/http-requests",
"destination": "/v3/the-basics/http-requests"
},
{
"source": "/optimistic-updates",
"destination": "/v3/the-basics/optimistic-updates"
},
{
"source": "/layout-props",
"destination": "/v3/the-basics/layouts"
},
{
"source": "/v3/the-basics/layout-props",
"destination": "/v3/the-basics/layouts"
},
{
"source": "/shared-data",
"destination": "/v2/data-props/shared-data"
Expand Down Expand Up @@ -342,4 +453,4 @@
"destination": "/v2/advanced/typescript"
}
]
}
}
1 change: 1 addition & 0 deletions snippets/v3-beta-warning.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<Warning>You are viewing the documentation for Inertia.js v3, which is currently in **beta**. For the current stable release, please visit the [v2 documentation](/v2/getting-started/index).</Warning>
24 changes: 12 additions & 12 deletions v2/advanced/events.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -486,24 +486,24 @@ The `error` event fires when validation errors are present on "successful" page
```js Vue icon="vuejs"
import { router } from '@inertiajs/vue3'

router.on('error', (errors) => {
console.log(errors)
router.on('error', (event) => {
console.log(event.detail.errors)
})
```

```jsx React icon="react"
import { router } from '@inertiajs/react'

router.on('error', (errors) => {
console.log(errors)
router.on('error', (event) => {
console.log(event.detail.errors)
})
```

```js Svelte icon="s"
import { router } from '@inertiajs/svelte'

router.on('error', (errors) => {
console.log(errors)
router.on('error', (event) => {
console.log(event.detail.errors)
})
```

Expand Down Expand Up @@ -732,23 +732,23 @@ The `prefetching` event fires when the router starts prefetching a page.
import { router } from '@inertiajs/vue3'

router.on('prefetching', (event) => {
console.log(`Prefetching ${event.detail.page.url}`)
console.log(`Prefetching ${event.detail.visit.url}`)
})
```

```jsx React icon="react"
import { router } from '@inertiajs/react'

router.on('prefetching', (event) => {
console.log(`Prefetching ${event.detail.page.url}`)
console.log(`Prefetching ${event.detail.visit.url}`)
})
```

```js Svelte icon="s"
import { router } from '@inertiajs/svelte'

router.on('prefetching', (event) => {
console.log(`Prefetching ${event.detail.page.url}`)
console.log(`Prefetching ${event.detail.visit.url}`)
})
```

Expand All @@ -766,23 +766,23 @@ The `prefetched` event fires when the router has successfully prefetched a page.
import { router } from '@inertiajs/vue3'

router.on('prefetched', (event) => {
console.log(`Prefetched ${event.detail.page.url}`)
console.log(`Prefetched ${event.detail.visit.url}`)
})
```

```jsx React icon="react"
import { router } from '@inertiajs/react'

router.on('prefetched', (event) => {
console.log(`Prefetched ${event.detail.page.url}`)
console.log(`Prefetched ${event.detail.visit.url}`)
})
```

```js Svelte icon="s"
import { router } from '@inertiajs/svelte'

router.on('prefetched', (event) => {
console.log(`Prefetched ${event.detail.page.url}`)
console.log(`Prefetched ${event.detail.visit.url}`)
})
```

Expand Down
65 changes: 65 additions & 0 deletions v3/advanced/asset-versioning.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
title: Asset Versioning
---

import V3BetaWarning from "/snippets/v3-beta-warning.mdx";

<V3BetaWarning />

One common challenge when building single-page apps is refreshing site assets when they've been changed. Thankfully, Inertia makes this easy by optionally tracking the current version of your site assets. When an asset changes, Inertia will automatically make a full page visit instead of a XHR visit on the next request.

## Configuration

To enable automatic asset refreshing, you need to tell Inertia the current version of your assets. This can be any arbitrary string (letters, numbers, or a file hash), as long as it changes when your assets have been updated.

Typically, your application's asset version can be specified within the `version` method of the Inertia `HandleInertiaRequests` middleware.

```php
class HandleInertiaRequests extends Middleware
{
public function version(Request $request)
{
return parent::version($request);
}
}
```

Alternatively, the asset version can be provided manually using the `Inertia::version()` method.

```php
use Inertia\Inertia;

Inertia::version($version);
Inertia::version(fn () => $version); // Lazily...
```

## Cache Busting

Asset refreshing in Inertia works on the assumption that a hard page visit will trigger your assets to reload. However, Inertia doesn't actually do anything to force this. Typically this is done with some form of cache busting. For example, appending a version query parameter to the end of your asset URLs.

With Laravel's Vite integration, asset versioning is done automatically. If you're using Laravel Mix, you can do this automatically by enabling [versioning](https://laravel.com/docs/mix#versioning-and-cache-busting) in your `webpack.mix.js` file.

## Manual Refreshing

If you want to take asset refreshing into your control, you can return a fixed value from the `version` method in the `HandleInertiaRequests` middleware. This disables Inertia's automatic asset versioning.

For example, if you want to notify users when a new version of your frontend is available, you can still expose the actual asset version to the frontend by including it as [shared data](/v3/data-props/shared-data).

```php
class HandleInertiaRequests extends Middleware
{
public function version(Request $request)
{
return null;
}

public function share(Request $request)
{
return array_merge(parent::share($request), [
'version' => parent::version($request),
]);
}
}
```

On the frontend, you can watch the `version` property and show a notification when a new version is detected.
106 changes: 106 additions & 0 deletions v3/advanced/code-splitting.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: Code Splitting
---

import V3BetaWarning from "/snippets/v3-beta-warning.mdx";

<V3BetaWarning />

By default, Inertia lazy-loads page components, splitting each page into its own bundle that is loaded on demand. This reduces the initial JavaScript bundle size but requires additional requests when visiting new pages.

You may disable lazy loading to eagerly bundle all pages into a single file. Eager loading eliminates per-page requests but increases the initial bundle size.

## Vite Plugin

The `lazy` option in the `pages` shorthand controls how page components are loaded. It defaults to `true`.

```js
createInertiaApp({
pages: {
lazy: false, // Bundle all pages into a single file
},
// ...
})
```

## Manual Vite

You may configure code splitting manually using Vite's `import.meta.glob()` function when not using the Inertia Vite plugin. Pass `{ eager: true }` to bundle all pages, or omit it to lazy-load them.

<CodeGroup>

```js Vue icon="vuejs"
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue') // [!code --:2]
return pages[`./Pages/${name}.vue`]()
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true }) // [!code ++:2]
return pages[`./Pages/${name}.vue`]
},
```

```js React icon="react"
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.jsx') // [!code --:2]
return pages[`./Pages/${name}.jsx`]()
const pages = import.meta.glob('./Pages/**/*.jsx', { eager: true }) // [!code ++:2]
return pages[`./Pages/${name}.jsx`]
},
```

```js Svelte icon="s"
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.svelte') // [!code --:2]
return pages[`./Pages/${name}.svelte`]()
const pages = import.meta.glob('./Pages/**/*.svelte', { eager: true }) // [!code ++:2]
return pages[`./Pages/${name}.svelte`]
},
```

</CodeGroup>

## Webpack

To use code splitting with Webpack, you will first need to enable [dynamic imports](https://github.com/tc39/proposal-dynamic-import) via a Babel plugin. Let's install it now.

```bash
npm install @babel/plugin-syntax-dynamic-import
```

Next, create a `.babelrc` file in your project with the following configuration:

```json
{
"plugins": ["@babel/plugin-syntax-dynamic-import"]
}
```

If you're using Laravel Mix, the dynamic imports Babel plugin is already installed and configured, and you can skip these steps. We recommend using Laravel Mix 6 or above, as there are known issues with older versions.

Finally, update the `resolve` callback in your app's initialization code to use `import` instead of `require`.

<CodeGroup>

```js Vue icon="vuejs"
resolve: name => require(`./Pages/${name}`), // [!code --]
resolve: name => import(`./Pages/${name}`), // [!code ++]
```

```js React icon="react"
resolve: name => require(`./Pages/${name}`), // [!code --]
resolve: name => import(`./Pages/${name}`), // [!code ++]
```

```js Svelte icon="s"
resolve: name => require(`./Pages/${name}.svelte`), // [!code --]
resolve: name => import(`./Pages/${name}.svelte`), // [!code ++]
```

</CodeGroup>

You should also consider using cache busting to force browsers to load the latest version of your assets. To accomplish this, add the following configuration to your webpack configuration file.

```js
output: {
chunkFilename: 'js/[name].js?id=[chunkhash]',
}
```
Loading