Inertiajs Docs
Inertiajs Docs
js
inertiajs /
inertia-django
MIT license
Public repository
inertia Fixed 303 redirect for PUT method (#27) 6 months ago
README.md Add examples to Readme, add Django Svelte Te… 3 months ago
Installation
Backend
Install the following python package via pip
INSTALLED_APPS = [
# django apps,
'inertia',
https://github.com/inertiajs/inertia-django?tab=readme-ov-file 1/5
3/25/24, 9:59 AM inertiajs/inertia-django: The Django adapter for Inertia.js
# your project's apps,
]
MIDDLEWARE = [
# django middleware,
'inertia.middleware.InertiaMiddleware',
# your project's middleware,
]
Finally, create a layout which exposes {% block inertia %}{% endblock %} in the body and set the path to this layout as INERTIA_LAYOUT in
your settings.py file.
Frontend
Django specific frontend docs coming soon. For now, we recommend installing django_vite and following the commits on the Django Vite
example repo. Once Vite is setup with your frontend of choice, just replace the contents of entry.js with this file (example in react)
You can also check out the official Inertia docs at https://inertiajs.com/.
CSRF
Django's CSRF tokens are tightly coupled with rendering templates so Inertia Django automatically handles adding the CSRF cookie for you to
each Inertia response. Because the default names Django users for the CSRF headers don't match Axios (the Javascript request library Inertia
uses), we'll need to either modify Axios's defaults OR Django's settings.
You only need to choose one of the following options, just pick whichever makes the most sense to you!
axios.defaults.xsrfHeaderName = "X-CSRFToken"
axios.defaults.xsrfCookieName = "csrftoken"
OR
CSRF_HEADER_NAME = 'HTTP_X_XSRF_TOKEN'
CSRF_COOKIE_NAME = 'XSRF-TOKEN'
Usage
Responses
Render Inertia responses is simple, you can either use the provided inertia render function or, for the most common use case, the inertia
decorator. The render function accepts four arguments, the first is your request object. The second is the name of the component you want to
render from within your pages directory (without extension). The third argument is a dict of props that should be provided to your
components. The final argument is template_data , for any variables you want to provide to your template, but this is much less common.
def index(request):
return render(request, 'Event/Index', props={
'events': Event.objects.all()
})
Or use the simpler decorator for the most common use cases
https://github.com/inertiajs/inertia-django?tab=readme-ov-file 2/5
3/25/24, 9:59 AM inertiajs/inertia-django: The Django adapter for Inertia.js
@inertia('Event/Index')
def index(request):
return {
'events': Event.objects.all(),
}
Shared Data
If you have data that you want to be provided as a prop to every component (a common use-case is information about the authenticated user)
you can use the share method. A common place to put this would be in some custom middleware.
def inertia_share(get_response):
def middleware(request):
share(request,
app_name=settings.APP_NAME,
user_count=lambda: User.objects.count(), # evaluated lazily at render time
user=lambda: request.user, # evaluated lazily at render time
)
return get_response(request)
return middleware
Lazy Props
On the front end, Inertia supports the concept of "partial reloads" where only the props requested are returned by the server. Sometimes, you
may want to use this flow to avoid processing a particularly slow prop on the intial load. In this case, you can use Lazy props . Lazy props aren't
evaluated unless they're specifically requested by name in a partial reload.
@inertia('ExampleComponent')
def example(request):
return {
'name': lambda: 'Brandon', # this will be rendered on the first load as usual
'data': lazy(lambda: some_long_calculation()), # this will only be run when specifically requested by partial props and WILL
}
Json Encoding
Inertia Django ships with a custom JsonEncoder at inertia.utils.InertiaJsonEncoder that extends Django's DjangoJSONEncoder with
additional logic to handle encoding models and Querysets. If you have other json encoding logic you'd prefer, you can set a new JsonEncoder
via the settings.
SSR
Backend
Frontend
Coming Soon!
https://github.com/inertiajs/inertia-django?tab=readme-ov-file 3/5
3/25/24, 9:59 AM inertiajs/inertia-django: The Django adapter for Inertia.js
Settings
Inertia Django has a few different settings options that can be set from within your project's settings.py file. Some of them have defaults.
Testing
Inertia Django ships with a custom TestCase to give you some nice helper methods and assertions. To use it, just make sure your TestCase
inherits from InertiaTestCase . InertiaTestCase inherits from Django's django.test.TestCase so it includes transaction support and a client.
class ExampleTestCase(InertiaTestCase):
def test_show_assertions(self):
self.client.get('/events/')
# access props
self.assertEquals(self.props()['name'], 'Brandon')
# template data
self.assertHasExactTemplateData({name: 'Brian', sport: 'basketball'})
self.assertIncludesTemplateData({sport: 'basketball'})
The inertia test helper also includes a special inertia client that pre-sets the inertia headers for you to simulate an inertia response. You can
access and use it just like the normal client with commands like self.inertia.get('/events/') . When using the inertia client, inertia custom
assertions are not enabled though, so only use it if you want to directly assert against the json response.
Examples
Django Svelte Template - A Django template and example project demonstrating Inertia with Svelte and SSR.
Thank you
A huge thank you to the community members who have worked on InertiaJS for Django before us. Parts of this repo were particularly inspired
by Andres Vargas and Samuel Girardin. Additional thanks to Andres for the Pypi project.
https://github.com/inertiajs/inertia-django?tab=readme-ov-file 4/5
3/25/24, 9:59 AM inertiajs/inertia-django: The Django adapter for Inertia.js
Releases
No releases published
Packages
No packages published
Contributors 8
Languages
https://github.com/inertiajs/inertia-django?tab=readme-ov-file 5/5
3/25/24, 10:17 AM Demo application - Inertia.js
Demo application
We've setup a demo app for Inertia.js called Ping CRM. This application is built
using Laravel and Vue. You can find the source code on GitHub.
The Ping CRM demo is hosted on Heroku and the database is reset every hour. Please
be respectful when editing data.
https://inertiajs.com/demo-application 1/2
3/25/24, 10:17 AM Demo application - Inertia.js
In addition to the Vue version of Ping CRM, we also maintain a Svelte version of the
application, which you can find on GitHub.
Third party
Beyond our official demo app, Ping CRM has also been translated into numerous
different languages and frameworks.
https://inertiajs.com/demo-application 2/2
3/25/24, 10:18 AM Upgrade guide - Inertia.js
Upgrade guide
What's new
This release focuses on simplifying the overall architecture of the project with the
goal of making Inertia easier to maintain and easier to use.
For a complete list of all the changes, see the release notes.
New dependencies
To use previous Inertia releases, you had to install a number of libraries, including
the core library ( @inertiajs/inertia ), the adapter of your choice
( @inertiajs/inertia-vue|vue3|react|svelte ), the progress library ( @inertiajs/progress ),
and if you were using server-side rendering, the server library ( @inertiajs/server ).
https://inertiajs.com/upgrade-guide 1/6
3/25/24, 10:18 AM Upgrade guide - Inertia.js
Moving forward you are now only required to install a single library — the adapter
of your choice (Vue, React, or Svelte), and all other core libraries are automatically
installed for you.
Next, install the new Inertia adapter of your choice. The new adapter libraries have
been renamed, and no longer include inertia- in them.
Renamed imports
Next, update all the Inertia related imports in your project to use the new adapter
library name. All imports are now available from the adapter library, meaning you
no longer import anything from the Inertia core library, progress library, or server
library.
It is no longer possible to manually configure Inertia using the App export. Instead,
you should use the createInertiaApp() helper. See the client-side setup
documentation for more information.
Progress
https://inertiajs.com/upgrade-guide 3/6
3/25/24, 10:18 AM Upgrade guide - Inertia.js
- InertiaProgress.init()
Finally, if you have defined any progress customizations, you can move them to the
progress property of the createInertiaApp() helper.
createInertiaApp({
progress: {
color: '#29d',
},
// ...
})
If you're using a custom progress indicator, you can disable the default progress
indicator by setting the progress property to false .
https://inertiajs.com/upgrade-guide 4/6
3/25/24, 10:18 AM Upgrade guide - Inertia.js
createInertiaApp({
progress: false,
// ...
})
Setup arguments
We've removed the previously deprecated lowercase app argument from the
setup() method in createInertiaApp() . Use App instead.
createInertiaApp({
// ...
- setup({ app, props }) {
+ setup({ App, props }) {
// ...
},
})
Simplified usePage
In the Vue 3 adapter, we simplified the usePage() hook to no longer require adding
.value after the component , props , url and version properties.
https://inertiajs.com/upgrade-guide 5/6
3/25/24, 10:18 AM Upgrade guide - Inertia.js
https://inertiajs.com/upgrade-guide 6/6
3/25/24, 10:18 AM Server-side setup - Inertia.js
Server-side setup
The first step when installing Inertia is to configure your server-side framework.
Inertia maintains an official server-side adapter for Laravel. For other frameworks,
please see the community adapters.
Laravel's starter kits, Breeze and Jetstream, provide out-of-the-box scaffolding for
new Inertia applications. These starter kits are the absolute fastest way to start
building a new Inertia project using Laravel and Vue or React. However, if you
would like to manually install Inertia into your application, please consult the
documentation below.
Install dependencies
https://inertiajs.com/server-side-setup 1/4
3/25/24, 10:18 AM Server-side setup - Inertia.js
First, install the Inertia server-side adapter using the Composer package manager.
Root template
Next, setup the root template that will be loaded on the first page visit to your
application. This will be used to load your site assets (CSS and JavaScript), and will
also contain a root <div> in which to boot your JavaScript application.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=
@vite('resources/js/app.js')
@inertiaHead
</head>
<body>
@inertia
</body>
</html>
This template should include your assets, as well as the @inertia and @inertiaHead
directives.
By default, Inertia's Laravel adapter will assume your root template is named
app.blade.php . If you would like to use a different root view, you can change it using
the Inertia::setRootView() method.
https://inertiajs.com/server-side-setup 2/4
3/25/24, 10:18 AM Server-side setup - Inertia.js
Middleware
Next we need to setup the Inertia middleware. You can accomplish this by
publishing the HandleInertiaRequests middleware to your application, which can be
done using the following Artisan command.
file.
use App\Http\Middleware\HandleInertiaRequests;
This middleware provides a version() method for setting your asset version, as well
as a share() method for defining shared data.
Creating responses
That's it, you're all ready to go server-side! Now you're ready to start creating
Inertia pages and rendering them via responses.
use Inertia\Inertia;
https://inertiajs.com/server-side-setup 3/4
3/25/24, 10:18 AM Server-side setup - Inertia.js
https://inertiajs.com/server-side-setup 4/4
3/25/24, 10:18 AM Client-side setup - Inertia.js
Client-side setup
Once you have your server-side framework configured, you then need to setup
your client-side framework. Inertia currently provides support for React, Vue, and
Svelte.
Laravel's starter kits, Breeze and Jetstream, provide out-of-the-box scaffolding for
new Inertia applications. These starter kits are the absolute fastest way to start
building a new Inertia project using Laravel and Vue or React. However, if you
would like to manually install Inertia into your application, please consult the
documentation below.
Install dependencies
https://inertiajs.com/client-side-setup 1/3
3/25/24, 10:18 AM Client-side setup - Inertia.js
Next, update your main JavaScript file to boot your Inertia app. To accomplish
this, we'll initialize the client-side framework with the base Inertia component.
createInertiaApp({
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
return pages[`./Pages/${name}.vue`]
},
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.mount(el)
},
})
Resolving components
The resolve callback tells Inertia how to load a page component. It receives a
page name (string), and returns a page component module. How you implement
this callback depends on which bundler (Vite or Webpack) you're using.
https://inertiajs.com/client-side-setup 2/3
3/25/24, 10:18 AM Client-side setup - Inertia.js
// Vite
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
return pages[`./Pages/${name}.vue`]
},
// Webpack
resolve: name => require(`./Pages/${name}`),
By default, Inertia assumes that your application's root template has a root
element with an id of app . If your application's root element has a different id ,
createInertiaApp({
id: 'my-app',
// ...
})
https://inertiajs.com/client-side-setup 3/3
3/25/24, 10:19 AM Who is Inertia.js for? - Inertia.js
Inertia was crafted for development teams and solo hackers who typically build
server-side rendered applications using frameworks like Laravel, Ruby on Rails, or
Django. You're used to creating controllers, retrieving data from the database (via
an ORM), and rendering views.
But what happens when you want to replace your server-side rendered views with
a modern, JavaScript-based single-page application frontend? The answer is
always "you need to build an API". Because that's how modern SPAs are built.
This means building a REST or GraphQL API. It means figuring out authentication
and authorization for that API. It means client-side state management. It means
setting up a new Git repository. It means a more complicated deployment
strategy. And this list goes on. It's a complete paradigm shift, and often a
complete mess. We think there is a better way.
Inertia works just like a classic server-side rendered application. You create
controllers, you get data from the database (via your ORM), and you render views.
But, Inertia views are JavaScript page components written in React, Vue, or Svelte.
https://inertiajs.com/who-is-it-for 1/2
3/25/24, 10:19 AM Who is Inertia.js for? - Inertia.js
This means you get all the power of a client-side application and modern SPA
experience, but you don't need to build an API. We think it's a breath of fresh air
that will supercharge your productivity.
https://inertiajs.com/who-is-it-for 2/2
3/25/24, 10:19 AM How it works - Inertia.js
How it works
With Inertia you build applications just like you've always done with your server-
side web framework of choice. You use your framework's existing functionality for
routing, controllers, middleware, authentication, authorization, data fetching, and
more.
However, Inertia replaces your application's view layer. Instead of using server-side
rendering via PHP or Ruby templates, the views returned by your application are
JavaScript page components. This allows you to build your entire frontend using
React, Vue, or Svelte, while still enjoying the productivity of Laravel or your
preferred server-side framework.
As you might expect, simply creating your frontend in JavaScript doesn't give you
a single-page application experience. If you were to click a link, your browser
would make a full page visit, which would then cause your client-side framework
to reboot on the subsequent page load. This is where Inertia changes everything.
At its core, Inertia is essentially a client-side routing library. It allows you to make
page visits without forcing a full page reload. This is done using the <Link>
component, a light-weight wrapper around a normal anchor link. When you click
an Inertia link, Inertia intercepts the click and makes the visit via XHR instead. You
can even make these visits programmatically in JavaScript using router.visit() .
https://inertiajs.com/how-it-works 1/2
3/25/24, 10:19 AM How it works - Inertia.js
When Inertia makes an XHR visit, the server detects that it's an Inertia visit and,
instead of returning a full HTML response, it returns a JSON response with the
JavaScript page component name and data (props). Inertia then dynamically
swaps out the previous page component with the new page component and
updates the browser's history state.
To learn more about the nitty-gritty, technical details of how Inertia works under
the hood, check out the protocol page.
https://inertiajs.com/how-it-works 2/2
3/25/24, 10:19 AM The protocol - Inertia.js
The protocol
This page contains a detailed specification of the Inertia protocol. Be sure to read
the how it works page first for a high-level overview.
HTML responses
The very first request to an Inertia app is just a regular, full-page browser request,
with no special Inertia headers or data. For these requests, the server returns a full
HTML document.
This HTML response includes the site assets (CSS, JavaScript) as well as a root
<div> in the page's body. The root <div> serves as a mounting point for the client-
side app, and includes a data-page attribute with a JSON encoded page object
for the initial page. Inertia uses this information to boot your client-side framework
and display the initial page component.
REQUEST
GET: http://example.com/events/80
Accept: text/html, application/xhtml+xml
RESPONSE
HTTP/1.1 200 OK
https://inertiajs.com/the-protocol 1/6
3/25/24, 10:19 AM The protocol - Inertia.js
<html>
<head>
<title>My app</title>
<link href="/css/app.css" rel="stylesheet">
<script src="/js/app.js" defer></script>
</head>
<body>
</body>
</html>
While the initial response is HTML, Inertia does not server-side render the JavaScript
page components.
Inertia responses
Once the Inertia app has been booted, all subsequent requests to the site are
made via XHR with a X-Inertia header set to true . This header indicates that the
request is being made by Inertia and isn't a standard full-page visit.
When the server detects the X-Inertia header, instead of responding with a full
HTML document, it returns a JSON response with an encoded page object.
REQUEST
GET: http://example.com/events/80
Accept: text/html, application/xhtml+xml
X-Requested-With: XMLHttpRequest
X-Inertia: true
X-Inertia-Version: 6b16b94d7c51cbe5b1fa42aac98241d5
https://inertiajs.com/the-protocol 2/6
3/25/24, 10:19 AM The protocol - Inertia.js
RESPONSE
HTTP/1.1 200 OK
Content-Type: application/json
Vary: Accept
X-Inertia: true
{
"component": "Event",
"props": {
"event": {
"id": 80,
"title": "Birthday party",
"start_date": "2019-06-02",
"description": "Come out and celebrate Jonathan's 36th birthday party!"
}
},
"url": "/events/80",
"version": "c32b8e4965f418ad16eaebba1d4e960f"
}
Inertia shares data between the server and client via a page object. This object
includes the necessary information required to render the page component,
update the browser's history state, and track the site's asset version. The page
object includes the following four properties:
On standard full page visits, the page object is JSON encoded into the data-page
attribute in the root <div> . On Inertia visits, the page object is returned as the
JSON payload.
https://inertiajs.com/the-protocol 3/6
3/25/24, 10:19 AM The protocol - Inertia.js
Asset versioning
One common challenge with single-page apps is refreshing site assets when
they've been changed. Inertia makes this easy by optionally tracking the current
version of the site's assets. In the event that an asset changes, Inertia will
automatically make a full-page visit instead of an XHR visit.
The Inertia page object includes a version identifier. This version identifier is set
server-side and can be a number, string, file hash, or any other value that
represents the current "version" of your site's assets, as long as the value changes
when the site's assets have been updated.
Whenever an Inertia request is made, Inertia will include the current asset version
in the X-Inertia-Version header. When the server receives the request, it compares
the asset version provided in the X-Inertia-Version header with the current asset
version. This is typically handled in the middleware layer of your server-side
framework.
If the asset versions are the same, the request simply continues as expected.
However, if the asset versions are different, the server immediately returns a
409 Conflict response, and includes the URL in a X-Inertia-Location header. This
header is necessary, since server-side redirects may have occurred. This tells
Inertia what the final intended destination URL is.
Note, 409 Conflict responses are only sent for GET requests, and not for
POST/PUT/PATCH/DELETE requests. That said, they will be sent in the event that a GET
If "flash" session data exists when a 409 Conflict response occurs, Inertia's server-
side framework adapters will automatically reflash this data.
REQUEST
GET: http://example.com/events/80
https://inertiajs.com/the-protocol 4/6
3/25/24, 10:19 AM The protocol - Inertia.js
RESPONSE
409: Conflict
X-Inertia-Location: http://example.com/events/80
Partial reloads
When making Inertia requests, the partial reload option allows you to request a
subset of the props (data) from the server on subsequent visits to the same page
component. This can be a helpful performance optimization if it's acceptable that
some page data becomes stale.
When a partial reload request is made, Inertia includes two additional headers
with the request: X-Inertia-Partial-Data and X-Inertia-Partial-Component .
REQUEST
GET: http://example.com/events
Accept: text/html, application/xhtml+xml
X-Requested-With: XMLHttpRequest
X-Inertia: true
https://inertiajs.com/the-protocol 5/6
3/25/24, 10:19 AM The protocol - Inertia.js
X-Inertia-Version: 6b16b94d7c51cbe5b1fa42aac98241d5
X-Inertia-Partial-Data: events
X-Inertia-Partial-Component: Events
RESPONSE
HTTP/1.1 200 OK
Content-Type: application/json
{
"component": "Events",
"props": {
"auth": {...}, // NOT included
"categories": [...], // NOT included
"events": [...] // included
},
"url": "/events/80",
"version": "c32b8e4965f418ad16eaebba1d4e960f"
}
https://inertiajs.com/the-protocol 6/6
3/25/24, 10:19 AM Pages - Inertia.js
Pages
When building applications using Inertia, each page in your application typically
has its own controller / route and a corresponding JavaScript component. This
allows you to retrieve just the data necessary for that page - no API required.
In addition, all of the data needed for the page can be retrieved before the page
is ever rendered by the browser, eliminating the need for displaying "loading"
states when users visit your application.
Creating pages
Inertia pages are simply JavaScript components. If you have ever written a Vue,
React, or Svelte component, you will feel right at home. As you can see in the
example below, pages receive data from your application's controllers as props.
<script setup>
import Layout from './Layout'
import { Head } from '@inertiajs/vue3'
https://inertiajs.com/pages 1/6
3/25/24, 10:19 AM Pages - Inertia.js
</script>
<template>
<Layout>
<Head title="Welcome" />
<h1>Welcome</h1>
<p>Hello {{ user.name }}, welcome to your first Inertia app!</p>
</Layout>
</template>
Given the page above, you can render the page by returning an Inertia response
from a controller or route. In this example, let's assume this page is stored at
resources/js/Pages/User/Show.vue within a Laravel application.
use Inertia\Inertia;
Creating layouts
While not required, for most projects it makes sense to create a site layout that all
of your pages can extend. You may have noticed in our page example above that
we're wrapping the page content within a <Layout> component. Here's an example
of such a component:
https://inertiajs.com/pages 2/6
3/25/24, 10:19 AM Pages - Inertia.js
<script setup>
import { Link } from '@inertiajs/vue3'
</script>
<template>
<main>
<header>
<Link href="/">Home</Link>
<Link href="/about">About</Link>
<Link href="/contact">Contact</Link>
</header>
<article>
<slot />
</article>
</main>
</template>
As you can see, there is nothing Inertia specific within this template. This is just a
typical Vue component.
Persistent layouts
For example, maybe you have an audio player on a podcast website that you
want to continue playing as users navigate the site. Or, maybe you simply want to
maintain the scroll position in your sidebar navigation between page visits. In
these situations, the solution is to leverage Inertia's persistent layouts.
https://inertiajs.com/pages 3/6
3/25/24, 10:19 AM Pages - Inertia.js
<script>
import Layout from './Layout'
export default {
// Using a render function...
layout: (h, page) => h(Layout, [page]),
<script setup>
defineProps({ user: Object })
</script>
<template>
<H1>Welcome</H1>
<p>Hello {{ user.name }}, welcome to your first Inertia app!</p>
</template>
You can also create more complex layout arrangements using nested layouts.
<script>
import SiteLayout from './SiteLayout'
import NestedLayout from './NestedLayout'
export default {
// Using a render function...
layout: (h, page) => {
return h(SiteLayout, () => h(NestedLayout, () => page))
},
<script setup>
https://inertiajs.com/pages 4/6
3/25/24, 10:19 AM Pages - Inertia.js
<template>
<H1>Welcome</H1>
<p>Hello {{ user.name }}, welcome to your first Inertia app!</p>
</template>
If you're using Vue 2.7 or Vue 3, you can alternatively use the defineOptions plugin
to define a layout within <script setup> :
<script setup>
import Layout from './Layout'
Default layouts
If you're using persistent layouts, you may find it convenient to define the default
page layout in the resolve() callback of your application's main JavaScript file.
createInertiaApp({
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
let page = pages[`./Pages/${name}.vue`]
page.default.layout = page.default.layout || Layout
return page
},
https://inertiajs.com/pages 5/6
3/25/24, 10:19 AM Pages - Inertia.js
// ...
})
This will automatically set the page layout to Layout if a layout has not already
been set for that page.
You can even go a step further and conditionally set the default page layout
based on the page name , which is available to the resolve() callback. For
example, maybe you don't want the default layout to be applied to your public
pages.
createInertiaApp({
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
let page = pages[`./Pages/${name}.vue`]
page.default.layout = name.startsWith('Public/') ? undefined : Layout
return page
},
// ...
})
https://inertiajs.com/pages 6/6
3/25/24, 10:21 AM Responses - Inertia.js
Responses
Creating responses
method within your controller or route, providing both the name of the JavaScript
page component that you wish to render, as well as any props (data) for the page.
In the example below, we will pass a single prop ( event ) which contains four
attributes ( id , title , start_date and description ) to the Event/Show page
component.
use Inertia\Inertia;
https://inertiajs.com/responses 1/3
3/25/24, 10:21 AM Responses - Inertia.js
Within Laravel applications, the Event/Show page would typically correspond to the file located
at resources/js/Pages/Event/Show.(js|vue|svelte).
To ensure that pages load quickly, only return the minimum data required for the
page. Also, be aware that all data returned from the controllers will be visible client-
side, so be sure to omit sensitive information.
There are situations where you may want to access your prop data in your
application's root Blade template. For example, you may want to add a meta
description tag, Twitter card meta tags, or Facebook Open Graph meta tags. You
can access this data via the $page variable.
Sometimes you may even want to provide data to the root template that will not
be sent to your JavaScript page / component. This can be accomplished by
invoking the withViewData method.
https://inertiajs.com/responses 2/3
3/25/24, 10:21 AM Responses - Inertia.js
After invoking the withViewData method, you can access the defined data as you
would typically access a Blade template variable.
To enable client-side history navigation, all Inertia server responses are stored in
the browser's history state. However, keep in mind that some browsers impose a
size limit on how much data can be saved within the history state.
For example, Firefox has a size limit of 640k characters and throws a
NS_ERROR_ILLEGAL_VALUE error if you exceed this limit. Typically, this is much more data
than you'll ever practically need when building applications.
https://inertiajs.com/responses 3/3
3/25/24, 10:21 AM Redirects - Inertia.js
Redirects
When making a non-GET Inertia request manually or via a <Link> element, you
should ensure that you always respond with a proper Inertia redirect response.
For example, if your controller is creating a new user, your "store" endpoint should
return a redirect back to a standard GET endpoint, such as your user "index" page.
Inertia will automatically follow this redirect and update the page accordingly.
return to_route('users.index');
https://inertiajs.com/redirects 1/2
3/25/24, 10:21 AM Redirects - Inertia.js
}
}
When redirecting after a PUT , PATCH , or DELETE request, you must use a 303
response code, otherwise the subsequent request will not be treated as a GET
request. A 303 redirect is very similar to a 302 redirect; however, the follow-up
request is explicitly changed to a GET request.
If you're using one of our official server-side adapters, all redirects will
automatically be converted to 303 redirects.
External redirects
return Inertia::location($url);
The Inertia::location() method will generate a 409 Conflict response and include
the destination URL in the X-Inertia-Location header. When this response is
received client-side, Inertia will automatically perform a window.location = url visit.
https://inertiajs.com/redirects 2/2
3/25/24, 10:21 AM Routing - Inertia.js
Routing
Defining routes
When using Inertia, all of your application's routes are defined server-side. This
means that you don't need Vue Router or React Router. Instead, you can simply
define Laravel routes and return Inertia responses from those routes.
Shorthand routes
If you have a page that doesn't need a corresponding controller method, like an
"FAQ" or "about" page, you can route directly to a component via the
Route::inertia() method.
Route::inertia('/about', 'About');
Generating URLs
https://inertiajs.com/routing 1/3
3/25/24, 10:21 AM Routing - Inertia.js
Some server-side frameworks allow you to generate URLs from named routes.
However, you will not have access to those helpers client-side. Here are a couple
ways to still use named routes with Inertia.
The first option is to generate URLs server-side and include them as props. Notice
in this example how we're passing the edit_url and create_url to the Users/Index
component.
However, when using Laravel, the Ziggy library can make your named, server-side
routes available to you via a global route() function. In fact, if you are developing
an application using one of Laravel's starter kits, Ziggy is already configured for
you.
If you're using Ziggy with Vue, it's helpful to make this function available as a
custom $route property so you can use it directly in your templates.
Vue 2 Vue 3
https://inertiajs.com/routing 2/3
3/25/24, 10:21 AM Routing - Inertia.js
app.config.globalProperties.$route = route
https://inertiajs.com/routing 3/3
3/25/24, 10:21 AM Title & meta - Inertia.js
Since Inertia powered JavaScript apps are rendered within the document <body> ,
they are unable to render markup to the document <head> , as it's outside of their
scope. To help with this, Inertia ships with a <Head> component which can be used
to set the page <title> , <meta> tags, and other <head> elements.
The <Head> component will only replace <head> elements that are not in your server-
side root template.
The <Head> component is not available in the Svelte adapter, as Svelte already ships
with its own <svelte:head> component.
Head component
To add <head> elements to your page, use the <Head> component. Within this
component, you can include the elements that you wish to add to the document
<head> .
https://inertiajs.com/title-and-meta 1/5
3/25/24, 10:21 AM Title & meta - Inertia.js
<Head>
<title>Your page title</title>
<meta name="description" content="Your page description">
</Head>
Title shorthand
If you only need to add a <title> to the document <head> , you may simply pass
the title as a prop to the <Head> component.
Title callback
You can globally modify the page <title> using the title callback in the
createInertiaApp setup method. Typically, this method is invoked in your
application's main JavaScript file. A common use case for the title callback is
automatically adding an app name before or after each page title.
createInertiaApp({
title: title => `${title} - My App`,
// ...
})
https://inertiajs.com/title-and-meta 2/5
3/25/24, 10:21 AM Title & meta - Inertia.js
After defining the title callback, the callback will automatically be invoked when
you set a title using the <Head> component.
<Head title="Home">
<title>Home - My App</title>
The title callback will also be invoked when you set the title using a <title> tag
within your <Head> component.
<Head>
<title>Home</title>
</Head>
It's possible to have multiple instances of the <Head> component throughout your
application. For example, your layout can set some default <Head> elements, and
then your individual pages can override those defaults.
https://inertiajs.com/title-and-meta 3/5
3/25/24, 10:21 AM Title & meta - Inertia.js
// Layout.vue
<Head>
<title>My app</title>
<meta head-key="description" name="description" content="This is the default descripti
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
</Head>
// About.vue
<Head>
<title>About - My app</title>
<meta head-key="description" name="description" content="This is a page specific descr
</Head>
Inertia will only ever render one <title> tag; however, all other tags will be stacked
since it's valid to have multiple instances of them. To avoid duplicate tags in your
<head> , you can use the head-key property, which will make sure the tag is only
rendered once. This is illustrated in the example above for the
<meta name="description"> tag.
<head>
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>About - My app</title>
<meta name="description" content="This is a page specific description" />
</head>
https://inertiajs.com/title-and-meta 4/5
3/25/24, 10:21 AM Title & meta - Inertia.js
Head extension
<script setup>
import { Head } from '@inertiajs/vue3'
<template>
<Head :title="title ? `${title} - My App` : 'My App'">
<slot />
</Head>
</template>
Once you have created the custom component, you may simply start using the
custom component in your pages.
https://inertiajs.com/title-and-meta 5/5
3/25/24, 10:21 AM Links - Inertia.js
Links
To create links to other pages within an Inertia app, you will typically use the
Inertia <Link> component. This component is a light wrapper around a standard
anchor <a> link that intercepts click events and prevents full page reloads. This is
how Inertia provides a single-page app experience once your application has
been loaded.
Creating links
To create an Inertia link, use the Inertia <Link> component. Any attributes you
provide to this component will be proxied to the underlying HTML tag.
<Link href="/">Home</Link>
By default, Inertia renders links as anchor <a> elements. However, you can change
the tag using the as attribute.
https://inertiajs.com/links 1/6
3/25/24, 10:21 AM Links - Inertia.js
// Renders as...
<button type="button">Logout</button>
Creating POST / PUT / PATCH / DELETE anchor <a> links is discouraged as it causes
"Open Link in New Tab / Window" accessibility issues. Instead, consider using a more
appropriate element, such as a <button> .
Method
You can specify the HTTP request method for an Inertia link request using the
method attribute. The default method used by links is GET , but you can use the
method attribute to make POST , PUT , PATCH , and DELETE requests via links.
Data
When making POST or PUT requests, you may wish to add additional data to the
request. You can accomplish this using the data attribute. The provided data can
https://inertiajs.com/links 2/6
3/25/24, 10:21 AM Links - Inertia.js
Custom headers
The headers attribute allows you to add custom headers to an Inertia link.
However, the headers Inertia uses internally to communicate its state to the server
take priority and therefore cannot be overwritten.
Browser history
The replace attribute allows you to specify the browser's history behaviour. By
default, page visits push (new) state ( window.history.pushState ) into the history;
however, it's also possible to replace state ( window.history.replaceState ) by setting
the replace attribute to true. This will cause the visit to replace the current history
state instead of adding a new history state to the stack.
https://inertiajs.com/links 3/6
3/25/24, 10:21 AM Links - Inertia.js
State preservation
You can preserve a page component's local state using the preserve-state
attribute. This will prevent a page component from fully re-rendering. The
preserve-state attribute is especially helpful on pages that contain forms, since you
can avoid manually repopulating input fields and can also maintain a focused
input.
Scroll preservation
You can use the preserve-scroll attribute to prevent Inertia from automatically
resetting the scroll position when making a page visit.
https://inertiajs.com/links 4/6
3/25/24, 10:21 AM Links - Inertia.js
Partial reloads
The only attribute allows you to specify that only a subset of a page's props
(data) should be retrieved from the server on subsequent visits to that page.
For more information on this topic, please consult the complete documentation on
partial reloads.
Active states
It's often desirable to set an active state for navigation links based on the current
page. This can be accomplished when using Inertia by inspecting the page object
and doing string comparisons against the page.url and page.component properties.
https://inertiajs.com/links 5/6
3/25/24, 10:21 AM Links - Inertia.js
You can perform exact match comparisons ( === ), startsWith() comparisons (useful
for matching a subset of pages), or even more complex comparisons using regular
expressions.
Using this approach, you're not limited to just setting class names. You can use this
technique to conditionally render any markup on active state, such as different link
text or even an SVG icon that represents the link is active.
https://inertiajs.com/links 6/6
3/25/24, 10:21 AM Manual visits - Inertia.js
Manual visits
In addition to creating links, it's also possible to manually make Inertia visits /
requests programatically via JavaScript. This is accomplished via the
router.visit() method.
router.visit(url, {
method: 'get',
data: {},
replace: false,
preserveState: false,
preserveScroll: false,
only: [],
headers: {},
errorBag: null,
forceFormData: false,
onCancelToken: cancelToken => {},
onCancel: () => {},
onBefore: visit => {},
onStart: visit => {},
onProgress: progress => {},
onSuccess: page => {},
onError: errors => {},
https://inertiajs.com/manual-visits 1/10
3/25/24, 10:21 AM Manual visits - Inertia.js
However, it's generally more convenient to use one of Inertia's shortcut request
methods. These methods share all the same options as router.visit() .
Method
When making manual visits, you may use the method option to set the request's
HTTP method to get , post , put , patch or delete . The default method is get .
https://inertiajs.com/manual-visits 2/10
3/25/24, 10:21 AM Manual visits - Inertia.js
Uploading files via put or patch is not supported in Laravel. Instead, make the
request via post , including a _method field set to put or patch . This is called form
method spoofing.
Data
You may use the data option to add data to the request.
router.visit('/users', {
method: 'post',
data: {
name: 'John Doe',
email: 'john.doe@example.com',
},
})
For convenience, the get() , post() , put() , and patch() methods all accept data
router.post('/users', {
name: 'John Doe',
https://inertiajs.com/manual-visits 3/10
3/25/24, 10:21 AM Manual visits - Inertia.js
email: 'john.doe@example.com',
})
Custom headers
router.post('/users', data, {
headers: {
'Custom-Header': 'value',
},
})
The headers Inertia uses internally to communicate its state to the server take priority
and therefore cannot be overwritten.
File uploads
When making visits / requests that include files, Inertia will automatically convert
the request data into a FormData object. If you would like the request to always use
a FormData object, you may use the forceFormData option.
https://inertiajs.com/manual-visits 4/10
3/25/24, 10:21 AM Manual visits - Inertia.js
router.post('/companies', data, {
forceFormData: true,
})
For more information on uploading files, please consult the dedicated file uploads
documentation.
Browser history
When making visits, Inertia automatically adds a new entry into the browser
history. However, it's also possible to replace the current history entry by setting the
replace option to true .
State preservation
By default, page visits to the same page create a fresh page component instance.
This causes any local state, such as form inputs, scroll positions, and focus states
to be lost.
However, in some situations, it's necessary to preserve the page component state.
For example, when submitting a form, you need to preserve your form data in the
https://inertiajs.com/manual-visits 5/10
3/25/24, 10:21 AM Manual visits - Inertia.js
You can instruct Inertia to preserve the component's state by setting the
preserveState option to true .
You can also lazily evaluate the preserveState option based on the response by
providing a callback to the preserveState option.
router.post('/users', data, {
preserveState: (page) => Object.keys(page.props.errors).length,
})
For convenience, the post , put , patch , delete , and reload methods all set the
preserveState option to true by default.
Scroll preservation
You can also lazily evaluate the preserveScroll option based on the response by
providing a callback.
router.post('/users', data, {
preserveScroll: (page) => Object.keys(page.props.errors).length,
})
For more information regarding this feature, please consult the scroll management
documentation.
Partial reloads
The only option allows you to request a subset of the props (data) from the server
on subsequent visits to the same page, thus making your application more
efficient since it does not need to retrieve data that the page is not interested in
refreshing.
https://inertiajs.com/manual-visits 7/10
3/25/24, 10:21 AM Manual visits - Inertia.js
For more information on this feature, please consult the partial reloads
documentation.
Visit cancellation
You can cancel a visit using a cancel token, which Inertia automatically generates
and provides via the onCancelToken() callback prior to making the visit.
router.post('/users', data, {
onCancelToken: (cancelToken) => (this.cancelToken = cancelToken),
})
The onCancel() and onFinish() event callbacks will be executed when a visit is
cancelled.
Event callbacks
https://inertiajs.com/manual-visits 8/10
3/25/24, 10:21 AM Manual visits - Inertia.js
router.post('/users', data, {
onBefore: (visit) => {},
onStart: (visit) => {},
onProgress: (progress) => {},
onSuccess: (page) => {},
onError: (errors) => {},
onCancel: () => {},
onFinish: visit => {},
})
Returning false from the onBefore() callback will cause the visit to be cancelled.
router.delete(`/users/${user.id}`, {
onBefore: () => confirm('Are you sure you want to delete this user?'),
})
It's also possible to return a promise from the onSuccess() and onError() callbacks.
When doing so, the "finish" event will be delayed until the promise has resolved.
router.post(url, {
onSuccess: () => {
return Promise.all([
this.doThing(),
https://inertiajs.com/manual-visits 9/10
3/25/24, 10:21 AM Manual visits - Inertia.js
this.doAnotherThing()
])
}
onFinish: visit => {
// This won't be called until doThing()
// and doAnotherThing() have finished.
},
})
https://inertiajs.com/manual-visits 10/10
3/25/24, 10:21 AM Forms - Inertia.js
Forms
Submitting forms
While it's possible to make classic HTML form submissions with Inertia, it's not
recommended since they cause full-page reloads. Instead, it's better to intercept
form submissions and then make the request using Inertia.
<script setup>
import { reactive } from 'vue'
import { router } from '@inertiajs/vue3'
function submit() {
router.post('/users', form)
}
</script>
<template>
<form @submit.prevent="submit">
<label for="first_name">First name:</label>
https://inertiajs.com/forms 1/9
3/25/24, 10:21 AM Forms - Inertia.js
As you may have noticed in the example above, when using Inertia, you don't
typically need to inspect form responses client-side like you would when making
XHR / fetch requests manually.
return to_route('users.index');
}
}
https://inertiajs.com/forms 2/9
3/25/24, 10:21 AM Forms - Inertia.js
Server-side validation
However, when using Inertia, a 422 response is never returned by your server.
Instead, as we saw in the example above, your routes / controllers will typically
return a redirect response - much like a classic, full-page form submission.
For a full discussion on handling and displaying validation errors with Inertia,
please consult the validation documentation.
Form helper
Since working with forms is so common, Inertia includes a form helper designed to
help reduce the amount of boilerplate code needed for handling typical form
submissions.
<script setup>
import { useForm } from '@inertiajs/vue3'
<template>
<form @submit.prevent="form.post('/login')">
<!-- email -->
https://inertiajs.com/forms 3/9
3/25/24, 10:21 AM Forms - Inertia.js
To submit the form, you may use the get , post , put , patch and delete methods.
The submit methods support all of the typical visit options, such as preserveState ,
preserveScroll , and event callbacks, which can be helpful for performing tasks on
successful form submissions. For example, you might use the onSuccess callback to
reset inputs to their original state.
form.post('/profile', {
preserveScroll: true,
onSuccess: () => form.reset('password'),
})
https://inertiajs.com/forms 4/9
3/25/24, 10:21 AM Forms - Inertia.js
If you need to modify the form data before it's sent to the server, you can do so via
the transform() method.
form
.transform((data) => ({
...data,
remember: data.remember ? 'on' : '',
}))
.post('/login')
You can use the processing property to track if a form is currently being submitted.
This can be helpful for preventing double form submissions by disabling the submit
button.
If your form is uploading files, the current progress event is available via the
progress property, allowing you to easily display the upload progress.
https://inertiajs.com/forms 5/9
3/25/24, 10:21 AM Forms - Inertia.js
If there are form validation errors, they are available via the errors property. When
building Laravel powered Inertia applications, form errors will automatically be
populated when your application throws instances of ValidationException , such as
when using $request->validate() .
For a more thorough discussion of form validation and errors, please consult the
validation documentation.
To determine if a form has any errors, you may use the hasErrors property. To clear
form errors, use the clearErrors() method.
https://inertiajs.com/forms 6/9
3/25/24, 10:21 AM Forms - Inertia.js
Unlike an actual form submission, the page's props remain unchanged when manually
setting errors on a form instance.
When a form has been successfully submitted, the wasSuccessful property will be
true . In addition to this, forms have a recentlySuccessful property, which will be set
to true for two seconds after a successful form submission. This property can be
utilized to show temporary success messages.
To reset the form's values back to their default values, you can use the reset()
method.
If your form's default values become outdated, you can use the defaults() method
to update them. Then, the form will be reset to the correct values the next time the
reset() method is invoked.
https://inertiajs.com/forms 7/9
3/25/24, 10:21 AM Forms - Inertia.js
To determine if a form has any changes, you may use the isDirty property.
form.cancel()
To instruct Inertia to store a form's data and errors in history state, you can provide
a unique form key as the first argument when instantiating your form.
https://inertiajs.com/forms 8/9
3/25/24, 10:21 AM Forms - Inertia.js
File uploads
When making requests or form submissions that include files, Inertia will
automatically convert the request data into a FormData object.
For a more thorough discussion of file uploads, please consult the file uploads
documentation.
Using Inertia to submit forms works great for the vast majority of situations;
however, in the event that you need more control over the form submission, you're
free to make plain XHR or fetch requests instead using the library of your choice.
https://inertiajs.com/forms 9/9
3/25/24, 10:21 AM File uploads - Inertia.js
File uploads
FormData conversion
When making Inertia requests that include files (even nested files), Inertia will
automatically convert the request data into a FormData object. This conversion is
necessary in order to submit a multipart/form-data request via XHR.
If you would like the request to always use a FormData object regardless of whether
a file is present in the data, you may provide the forceFormData option when
making the request.
router.post('/users', data, {
forceFormData: true,
})
You can learn more about the FormData interface via its MDN documentation.
https://inertiajs.com/file-uploads 1/3
3/25/24, 10:21 AM File uploads - Inertia.js
Prior to version 0.8.0, Inertia did not automatically convert requests to FormData . If
you're using an Inertia release prior to this version, you will need to manually perform
this conversion.
Let's examine a complete file upload example using Inertia. This example includes
both a name text input and an avatar file input.
<script setup>
import { useForm } from '@inertiajs/vue3'
function submit() {
form.post('/users')
}
</script>
<template>
<form @submit.prevent="submit">
<input type="text" v-model="form.name" />
<input type="file" @input="form.avatar = $event.target.files[0]" />
<progress v-if="form.progress" :value="form.progress.percentage" max="100">
{{ form.progress.percentage }}%
</progress>
<button type="submit">Submit</button>
</form>
</template>
https://inertiajs.com/file-uploads 2/3
3/25/24, 10:21 AM File uploads - Inertia.js
This example uses the Inertia form helper for convenience, since the form helper
provides easy access to the current upload progress. However, you are free to
submit your forms using manual Inertia visits as well.
Multipart limitations
request instead.
However, some frameworks, such as Laravel and Rails, support form method
spoofing, which allows you to upload the files using POST , but have the framework
handle the request as a PUT or PATCH request. This is done by including a _method
router.post(`/users/${user.id}`, {
_method: 'put',
avatar: form.avatar,
})
https://inertiajs.com/file-uploads 3/3
3/25/24, 10:21 AM Validation - Inertia.js
Validation
How it works
responses and manually update the form's error state - because Inertia never
receives 422 responses. Instead, Inertia operates much more like a standard full
page form submission. Here's how:
First, you submit your form using Inertia. If there are server-side validation errors,
you don't return those errors as a 422 JSON response. Instead, you redirect (server-
side) the user back to the form page they were previously on, flashing the
validation errors in the session. Some frameworks, such as Laravel, do this
automatically.
Next, any time these validation errors are present in the session, they
automatically get shared with Inertia, making them available client-side as page
props which you can display in your form. Since props are reactive, they are
automatically shown when the form submission completes.
Finally, since Inertia apps never generate 422 responses, Inertia needs another
way to determine if a response includes validation errors. To do this, Inertia checks
https://inertiajs.com/validation 1/5
3/25/24, 10:21 AM Validation - Inertia.js
the page.props.errors object for the existence of any errors. In the event that errors
are present, the request's onError() callback will be called instead of the
onSuccess() callback.
Sharing errors
Displaying errors
Since validation errors are made available client-side as page component props,
you can conditionally display them based on their existence. Remember, when
using our first-party server adapters (such as the Laravel adapter), the errors
<script setup>
import { reactive } from 'vue'
import { router } from '@inertiajs/vue3'
https://inertiajs.com/validation 2/5
3/25/24, 10:21 AM Validation - Inertia.js
function submit() {
router.post('/users', form)
}
</script>
<template>
<form @submit.prevent="submit">
<label for="first_name">First name:</label>
<input id="first_name" v-model="form.first_name" />
<div v-if="errors.first_name">{{ errors.first_name }}</div>
<label for="last_name">Last name:</label>
<input id="last_name" v-model="form.last_name" />
<div v-if="errors.last_name">{{ errors.last_name }}</div>
<label for="email">Email:</label>
<input id="email" v-model="form.email" />
<div v-if="errors.email">{{ errors.email }}</div>
<button type="submit">Submit</button>
</form>
</template>
When using the Vue adapters, you may also access the errors via the
$page.props.errors object.
Repopulating input
While handling errors in Inertia is similar to full page form submissions, Inertia offers
even more benefits. In fact, you don't even need to manually repopulate old form
input data.
When validation errors occur, the user is typically redirected back to the form
page they were previously on. And, by default, Inertia automatically preserves the
component state for post , put , patch , and delete requests. Therefore, all the old
form input data remains exactly as it was when the user submitted the form.
So, the only work remaining is to display any validation errors using the errors
prop.
https://inertiajs.com/validation 3/5
3/25/24, 10:21 AM Validation - Inertia.js
Error bags
If you're using the form helper, it's not necessary to use error bags since validation
errors are automatically scoped to the form object making the request.
For pages that have more than one form, it's possible to encounter conflicts when
displaying validation errors if two forms share the same field names. For example,
imagine a "create company" form and a "create user" form that both have a name
field. Since both forms will be displaying the page.props.errors.name validation error,
generating a validation error for the name field in either form will cause the error to
appear in both forms.
To solve this issue, you can use "error bags". Error bags scope the validation errors
returned from the server within a unique key specific to that form. Continuing with
our example above, you might have a createCompany error bag for the first form and
a createUser error bag for the second form.
router.post('/companies', data, {
errorBag: 'createCompany',
})
router.post('/users', data, {
errorBag: 'createUser',
})
Specifying an error bag will cause the validation errors to come back from the
server within page.props.errors.createCompany and page.props.errors.createUser .
https://inertiajs.com/validation 4/5
3/25/24, 10:21 AM Validation - Inertia.js
https://inertiajs.com/validation 5/5
3/25/24, 10:21 AM Shared data - Inertia.js
Shared data
Sometimes you need to access specific pieces of data on numerous pages within
your application. For example, you may need to display the current user in the site
header. Passing this data manually in each response across your entire application
is cumbersome. Thankfully, there is a better option: shared data.
Sharing data
// Lazily...
'auth.user' => fn () => $request->user()
? $request->user()->only('id', 'name', 'email')
: null,
]);
}
}
The HandleInertiaRequests middleware provides a "share" method where you can define the
data that is automatically shared with each Inertia response.
Alternatively, you can manually share data using the Inertia::share method.
use Inertia\Inertia;
// Synchronously...
Inertia::share('appName', config('app.name'));
// Lazily...
Inertia::share('user', fn (Request $request) => $request->user()
? $request->user()->only('id', 'name', 'email')
: null
);
Shared data should be used sparingly as all shared data is included with every
response.
Page props and shared data are merged together, so be sure to namespace your
shared data appropriately to avoid collisions.
https://inertiajs.com/shared-data 2/4
3/25/24, 10:21 AM Shared data - Inertia.js
Once you have shared the data server-side, you will be able to access it within
any of your pages or components. Here's an example of how to access shared
data in a layout component.
<script setup>
import { computed } from 'vue'
import { usePage } from '@inertiajs/vue3'
<template>
<main>
<header>
You are logged in as: {{ user.name }}
</header>
<content>
<slot />
</content>
</main>
</template>
Flash messages
Another great use-case for shared data is flash messages. These are messages
stored in the session only for the next request. For example, it's common to set a
flash message after completing a task and before redirecting to a different page.
Here's a simple way to implement flash messages in your Inertia applications. First,
share the flash message on each request.
https://inertiajs.com/shared-data 3/4
3/25/24, 10:21 AM Shared data - Inertia.js
Next, display the flash message in a frontend component, such as the site layout.
<template>
<main>
<header></header>
<content>
<div v-if="$page.props.flash.message" class="alert">
{{ $page.props.flash.message }}
</div>
<slot />
</content>
<footer></footer>
</main>
</template>
https://inertiajs.com/shared-data 4/4
3/25/24, 10:22 AM Events - Inertia.js
Events
Inertia provides an event system that allows you to "hook into" the various lifecycle
events of the library.
Registering listeners
Under the hood, Inertia uses native browser events, so you can also interact with
Inertia events using the typical event methods you may already be familiar with -
just be sure to prepend inertia: to the event name.
https://inertiajs.com/events 1/10
3/25/24, 10:22 AM Events - Inertia.js
Removing listeners
When you register an event listener, Inertia automatically returns a callback that
can be invoked to remove the event listener.
Combined with hooks, you can automatically remove the event listener when
components unmount.
onUnmounted(
https://inertiajs.com/events 2/10
3/25/24, 10:22 AM Events - Inertia.js
Alternatively, if you're using native browser events, you can remove the event
listener using removeEventListener() .
document.addEventListener('inertia:start', startEventListener)
Cancelling events
Some events, such as before , invalid , and error , support cancellation, allowing
you to prevent Inertia's default behaviour. Just like native events, the event will be
cancelled if only one event listener calls event.preventDefault() .
https://inertiajs.com/events 3/10
3/25/24, 10:22 AM Events - Inertia.js
}
})
For convenience, if you register your event listener using router.on() , you can
cancel the event by returning false from the listener.
Note, browsers do not allow cancelling the native popstate event, so preventing
forward and back history visits while using Inertia.js is not possible.
Before
The before event fires when a request is about to be made to the server. This is
useful for intercepting visits.
The primary purpose of this event is to allow you to prevent a visit from happening.
https://inertiajs.com/events 4/10
3/25/24, 10:22 AM Events - Inertia.js
Start
The start event fires when a request to the server has started. This is useful for
displaying loading indicators.
Progress
https://inertiajs.com/events 5/10
3/25/24, 10:22 AM Events - Inertia.js
Success
The success event fires on successful page visits, unless validation errors are
present. However, this does not include history visits.
Error
The error event fires when validation errors are present on "successful" page visits.
https://inertiajs.com/events 6/10
3/25/24, 10:22 AM Events - Inertia.js
Invalid
The invalid event fires when a non-Inertia response is received from the server,
such as an HTML or vanilla JSON response. A valid Inertia response is a response
that has the X-Inertia header set to true with a json payload containing the
page object.
This event is fired for all response types, including 200 , 400 , and 500 response
codes.
You may cancel the invalid event to prevent Inertia from showing the non-Inertia
response modal.
https://inertiajs.com/events 7/10
3/25/24, 10:22 AM Events - Inertia.js
Exception
The exception event fires on unexpected XHR errors such as network interruptions.
In addition, this event fires for errors generated when resolving page components.
You may cancel the exception event to prevent the error from being thrown.
https://inertiajs.com/events 8/10
3/25/24, 10:22 AM Events - Inertia.js
This event will not fire for XHR requests that receive 400 and 500 level responses or
for non-Inertia responses, as these situations are handled in other ways by Inertia.
Please consult the error handling documentation for more information.
Finish
The finish event fires after an XHR request has completed for both "successful"
and "unsuccessful" responses. This event is useful for hiding loading indicators.
Navigate
The navigate event fires on successful page visits, as well as when navigating
through history.
https://inertiajs.com/events 9/10
3/25/24, 10:22 AM Events - Inertia.js
Event callbacks
In addition to the global events described throughout this page, Inertia also
provides a number of event callbacks that fire when manually making Inertia visits.
https://inertiajs.com/events 10/10
3/25/24, 10:22 AM Testing - Inertia.js
Testing
There are many different ways to test an Inertia application. This page provides a
quick overview of the tools available.
End-to-end tests
https://inertiajs.com/testing 1/6
3/25/24, 10:22 AM Testing - Inertia.js
Endpoint tests
In addition to testing your JavaScript page components, you will likely want to
also test the Inertia responses that are returned by your server-side framework. A
popular approach to doing this is using endpoint tests, where you make requests
to your application and examine the responses. Laravel provides tooling for
executing these types of tests.
However, to make this process even easier, Inertia's Laravel adapter provides
additional HTTP testing tools. Let's take a look at an example.
https://inertiajs.com/testing 2/6
3/25/24, 10:22 AM Testing - Inertia.js
}
}
As you can see in the example above, you may use these assertion methods to
assert against the content of the data provided to the Inertia response. In
addition, you may assert that array data has a given length as well as scope your
assertions.
Let's dig into the available assertions in detail. First, to assert that the Inertia
response has a property, you may use the has method. You can think of this
method as being similar to PHP's isset function.
To assert that an Inertia property has a specified amount of items, you may
provide the expected size as the second argument to the has method.
The has method may also be used to scope properties in order to lessen repetition
when asserting against nested properties.
https://inertiajs.com/testing 3/6
3/25/24, 10:22 AM Testing - Inertia.js
When scoping into Inertia properties that are arrays or collections, you may also
assert that a specified number of items are present in addition to scoping into the
first item.
To assert that an Inertia property has an expected value, you may use the where
assertion.
Inertia's testing methods will automatically fail when you haven't interacted with at
least one of the props in a scope. While this is generally useful, you might run into
situations where you're working with unreliable data (such as from an external
feed), or with data that you really don't want interact with in order to keep your
test simple. For these situations, the etc method exists.
The missing method is the exact opposite of the has method, ensuring that the
property does not exist. This method makes a great companion to the etc
method.
https://inertiajs.com/testing 5/6
3/25/24, 10:22 AM Testing - Inertia.js
https://inertiajs.com/testing 6/6
3/25/24, 10:22 AM Partial reloads - Inertia.js
Partial reloads
When making visits to the same page you are already on, it's not always
necessary to re-fetch all of the page's data from the server. In fact, selecting only
a subset of the data can be a helpful performance optimization if it's acceptable
that some page data becomes stale. Inertia makes this possible via its "partial
reload" feature.
As an example, consider a "user index" page that includes a list of users, as well as
an option to filter the users by their company. On the first request to the page,
both the users and companies props are passed to the page component. However,
on subsequent visits to the same page (maybe to filter the users), you can request
only the users data from the server without requesting the companies data. Inertia
will then automatically merge the partial data returned from the server with the
data it already has in memory client-side.
Partial reloads only work for visits made to the same page component.
https://inertiajs.com/partial-reloads 1/3
3/25/24, 10:22 AM Partial reloads - Inertia.js
To perform a partial reload, use the only property to specify which data the server
should return. This option should be an array of keys which correspond to the keys
of the props.
router.visit(url, {
only: ['users'],
})
Since partial reloads can only be made to the same page component the user is
already on, it almost always makes sense to just use the router.reload() method,
which automatically uses the current URL.
It's also possible to perform partial reloads with Inertia links using the only
property.
https://inertiajs.com/partial-reloads 2/3
3/25/24, 10:22 AM Partial reloads - Inertia.js
For partial reloads to be most effective, be sure to also use lazy data evaluation
when returning props from your server-side routes or controllers. This can be
accomplished by wrapping all optional page data in a closure.
When Inertia performs a request, it will determine which data is required and only
then will it evaluate the closure. This can significantly increase the performance of
pages that contain a lot of optional data.
return Inertia::render('Users/Index', [
// ALWAYS included on first visit...
// OPTIONALLY included on partial reloads...
// ALWAYS evaluated...
'users' => User::get(),
https://inertiajs.com/partial-reloads 3/3
3/25/24, 10:22 AM Scroll management - Inertia.js
Scroll management
Scroll resetting
Scroll preservation
Sometimes it's desirable to prevent the default scroll resetting behavior when
making visits. You can disable this behaviour using the preserveScroll option when
manually making visits.
You can also lazily evaluate the preserveScroll option based on the server's
response by providing a callback to the option.
https://inertiajs.com/scroll-management 1/2
3/25/24, 10:22 AM Scroll management - Inertia.js
router.post('/users', data, {
preserveScroll: (page) => Object.keys(page.props.errors).length,
})
You can also preserve the scroll position when using Inertia links using the
preserve-scroll attribute.
Scroll regions
If your app doesn't use document body scrolling, but instead has scrollable
elements (using the overflow CSS property), scroll resetting will not work. In these
situations, you must tell Inertia which scrollable elements to manage by adding a
scroll-region attribute to the element.
https://inertiajs.com/scroll-management 2/2
3/25/24, 10:22 AM Authentication - Inertia.js
Authentication
One of the benefits of using Inertia is that you don't need a special authentication
system such as OAuth to connect to your data provider (API). Also, since your data
is provided via your controllers, and housed on the same domain as your
JavaScript components, you don't have to worry about setting up CORS.
Rather, when using Inertia, you can simply use whatever authentication system
your server-side framework ships with. Typically, this will be a session based
authentication system such as the authentication system included with Laravel.
Laravel's starter kits, Breeze and Jetstream, provide out-of-the-box scaffolding for
new Inertia applications, including authentication.
https://inertiajs.com/authentication 1/1
3/25/24, 10:22 AM Authorization - Inertia.js
Authorization
The simplest approach to solving this problem is to pass the results of your
authorization checks as props to your page components.
https://inertiajs.com/authorization 1/2
3/25/24, 10:22 AM Authorization - Inertia.js
]);
}
}
https://inertiajs.com/authorization 2/2
3/25/24, 10:22 AM CSRF protection - Inertia.js
CSRF protection
Making requests
Laravel automatically includes the proper CSRF token when making requests via
Inertia or Axios. However, if you're using Laravel, be sure to omit the csrf-token meta
tag from your project, as this will prevent the CSRF token from refreshing properly.
https://inertiajs.com/csrf-protection 1/4
3/25/24, 10:22 AM CSRF protection - Inertia.js
router.post('/users', {
name: this.name,
email: this.email,
_token: this.$page.props.csrf_token,
})
You can even use Inertia's shared data functionality to automatically include the
csrf_token with each response.
However, a better approach is to use the CSRF functionality already built into
axios for this. Axios is the HTTP library that Inertia uses under the hood.
Axios automatically checks for the existence of an XSRF-TOKEN cookie. If it's present,
it will then include the token in an X-XSRF-TOKEN header for any requests it makes.
The easiest way to implement this is using server-side middleware. Simply include
the XSRF-TOKEN cookie on each response, and then verify the token using the
X-XSRF-TOKEN header sent in the requests from axios.
Handling mismatches
When a CSRF token mismatch occurs, your server-side framework will likely throw
an exception that results in an error response. For example, when using Laravel, a
TokenMismatchException is thrown which results in a 419 error page. Since that isn't a
valid Inertia response, the error is shown in a modal.
https://inertiajs.com/csrf-protection 2/4
3/25/24, 10:22 AM CSRF protection - Inertia.js
0:00 / 0:03
Obviously, this isn't a great user experience. A better way to handle these errors is
to return a redirect back to the previous page, along with a flash message that
the page expired. This will result in a valid Inertia response with the flash message
available as a prop which you can then display to the user. Of course, you'll need
to share your flash messages with Inertia for this to work.
When using Laravel, you may modify your application's exception handler to
automatically redirect the user back to the page they were previously on while
flashing a message to the session. To accomplish this, you may use the respond
exception method in your application's bootstrap/app.php file.
use Symfony\Component\HttpFoundation\Response;
]);
}
return $response;
});
});
The end result is a much better experience for your users. Instead of seeing the
error modal, the user is instead presented with a message that the page "expired"
and are asked to try again.
0:00 / 0:02
https://inertiajs.com/csrf-protection 4/4
3/25/24, 10:22 AM Error handling - Inertia.js
Error handling
Development
The challenge is, if you're making an XHR request (which Inertia does) and you hit a
server-side error, you're typically left digging through the network tab in your
browser's devtools to diagnose the problem.
Inertia solves this issue by showing all non-Inertia responses in a modal. This
means you get the same beautiful error-reporting you're accustomed to, even
though you've made that request over XHR.
https://inertiajs.com/error-handling 1/4
3/25/24, 10:22 AM Error handling - Inertia.js
Loading…
Production
In production you will want to return a proper Inertia error response instead of
relying on the modal-driven error reporting that is present during development. To
accomplish this, you'll need to update your framework's default exception handler
to return a custom error page.
When building Laravel applications, you can accomplish this by using the respond
use Illuminate\Http\Request;
use Illuminate\Http\Response;
https://inertiajs.com/error-handling 2/4
3/25/24, 10:22 AM Error handling - Inertia.js
use Inertia\Inertia;
return $response;
});
})
You may have noticed we're returning an Error page component in the example
above. You'll need to actually create this component, which will serve as the
generic error page for your application. Here's an example error component you
can use as a starting point.
<script setup>
import { computed } from 'vue'
https://inertiajs.com/error-handling 3/4
3/25/24, 10:22 AM Error handling - Inertia.js
return {
503: 'Sorry, we are doing some maintenance. Please check back soon.',
500: 'Whoops, something went wrong on our servers.',
404: 'Sorry, the page you are looking for could not be found.',
403: 'Sorry, you are forbidden from accessing this page.',
}[props.status]
})
</script>
<template>
<div>
<H1>{{ title }}</H1>
<div>{{ description }}</div>
</div>
</template>
https://inertiajs.com/error-handling 4/4
3/25/24, 10:22 AM Asset versioning - Inertia.js
Asset versioning
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
https://inertiajs.com/asset-versioning 1/2
3/25/24, 10:22 AM Asset versioning - Inertia.js
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.
If you're using Laravel Mix, you can do this automatically by enabling versioning in
your webpack.mix.js file. When using Laravel's Vite integration, asset versioning is
done automatically.
https://inertiajs.com/asset-versioning 2/2
3/25/24, 10:22 AM Progress indicators - Inertia.js
Progress indicators
Since Inertia requests are made via XHR, there would typically not be a browser
loading indicator when navigating from one page to another. To solve this, Inertia
displays a progress indicator at the top of the page whenever you make an Inertia
visit.
Of course, if you prefer, you can disable Inertia's default loading indicator and
provide your own custom implementation. We'll discuss both approaches below.
Default
function.
createInertiaApp({
progress: {
// The delay after which the progress bar will appear, in milliseconds...
delay: 250,
https://inertiajs.com/progress-indicators 1/7
3/25/24, 10:22 AM Progress indicators - Inertia.js
You can disable Inertia's default loading indicator by setting the progress property
to false .
createInertiaApp({
progress: false,
// ...
})
Custom
It's also possible to setup your own custom page loading indicators using Inertia
events. Let's explore how to do this using the NProgress library as an example.
createInertiaApp({
progress: false,
// ...
})
https://inertiajs.com/progress-indicators 2/7
3/25/24, 10:22 AM Progress indicators - Inertia.js
After installation, you'll need to add the NProgress styles to your project. You can
do this using a CDN hosted copy of the styles.
Next, import both NProgress and the Inertia router into your application.
Next, let's add a start event listener. We'll use this listener to show the progress
bar when a new Inertia visit begins.
Then, let's add a finish event listener to hide the progress bar when the page visit
finishes.
https://inertiajs.com/progress-indicators 3/7
3/25/24, 10:22 AM Progress indicators - Inertia.js
That's it! Now, as you navigate from one page to another, the progress bar will be
added and removed from the page.
While this custom progress implementation works great for page visits that finish
properly, it would be nice to handle cancelled visits as well. First, for interrupted
visits (those that get cancelled as a result of a new visit), the progress bar should
simply be reset back to the start position. Second, for manually cancelled visits,
the progress bar should be immediately removed from the page.
Let's take this a step further. When files are being uploaded, it would be great to
update the loading indicator to reflect the upload progress. This can be done
using the progress event.
https://inertiajs.com/progress-indicators 4/7
3/25/24, 10:22 AM Progress indicators - Inertia.js
Now, instead of the progress bar "trickling" while the files are being uploaded, it will
actually update it's position based on the progress of the request. We limit the
progress here to 90%, since we still need to wait for a response from the server.
The last thing we're going to implement is a loading indicator delay. It's often
preferable to delay showing the loading indicator until a request has taken longer
than 250-500 milliseconds. This prevents the loading indicator from appearing
constantly on quick page visits, which can be visually distracting.
To implement the delay behaviour, we'll use the setTimeout and clearTimeout
Next, let's update the start event listener to start a new timeout that will show the
progress bar after 250 milliseconds.
router.on('start', () => {
timeout = setTimeout(() => NProgress.start(), 250)
})
https://inertiajs.com/progress-indicators 5/7
3/25/24, 10:22 AM Progress indicators - Inertia.js
Next, we'll update the finish event listener to clear any existing timeouts in the
event that the page visit finishes before the timeout does.
In the finish event listener, we need to determine if the progress bar has actually
started displaying progress, otherwise we'll inadvertently cause it to show before
the timeout has finished.
And, finally, we need to do the same check in the progress event listener.
That's it, you now have a beautiful custom page loading indicator!
https://inertiajs.com/progress-indicators 6/7
3/25/24, 10:22 AM Progress indicators - Inertia.js
Complete example
For convenience, here is the full source code of the final version of our custom
loading indicator.
router.on('start', () => {
timeout = setTimeout(() => NProgress.start(), 250)
})
https://inertiajs.com/progress-indicators 7/7
3/25/24, 10:22 AM Remembering state - Inertia.js
Remembering state
When navigating browser history, Inertia restores pages using prop data cached in
history state. However, Inertia does not restore local page component state since
this is beyond its reach. This can lead to outdated pages in your browser history.
For example, if a user partially completes a form, then navigates away, and then
returns back, the form will be reset and their work will be lost.
To mitigate this issue, you can tell Inertia which local component state to save in
the browser history.
To save local component state to the history state, use the remember feature to tell
Inertia which data it should remember.
https://inertiajs.com/remembering-state 1/4
3/25/24, 10:22 AM Remembering state - Inertia.js
last_name: null,
})
Use the "useRemember" hook to tell Inertia which data it should remember.
Now, whenever your local form state changes, Inertia will automatically save this
data to the history state and will also restore it on history navigation.
Multiple components
If your page contains multiple components that use the remember functionality
provided by Inertia, you need to provide a unique key for each component so that
Inertia knows which data to restore to each component.
If you have multiple instances of the same component on the page using the
remember functionality, be sure to also include a unique key for each component
instance, such as a model identifier.
https://inertiajs.com/remembering-state 2/4
3/25/24, 10:22 AM Remembering state - Inertia.js
Form helper
If you're using the Inertia form helper, you can pass a unique form key as the first
argument when instantiating your form. This will cause the form data and errors to
automatically be remembered.
The remember property in Vue 2, and the useRemember hook in Vue 3, React, and
Svelte all watch for data changes and automatically save those changes to the
history state. Then, Inertia will restore the data on page load.
https://inertiajs.com/remembering-state 3/4
3/25/24, 10:22 AM Remembering state - Inertia.js
However, it's also possible to manage this manually using the underlying
remember() and restore() methods in Inertia.
https://inertiajs.com/remembering-state 4/4
3/25/24, 10:22 AM Server-side rendering (SSR) - Inertia.js
If you are using Laravel Breeze or Jetstream, you may install the starter kit's
scaffolding with Inertia SSR support pre-configured using the --ssr flag.
https://inertiajs.com/server-side-rendering 1/7
3/25/24, 10:22 AM Server-side rendering (SSR) - Inertia.js
Install dependencies
If you are not using a Laravel starter kit and would like to manually configure SSR,
we'll first install the additional dependencies required for server-side rendering.
This is only necessary for the Vue adapters, so you can skip this step if you're using
React or Svelte.
Then, make sure you have the latest version of the Inertia Laravel adapter
installed.
Next, we'll create a resources/js/ssr.js file within our Laravel project that will serve
as our SSR entry point.
touch resources/js/ssr.js
This file is going to look very similar to your resources/js/app.js file, except it's not
going to run in the browser, but rather in Node.js. Here's a complete example.
https://inertiajs.com/server-side-rendering 2/7
3/25/24, 10:22 AM Server-side rendering (SSR) - Inertia.js
createServer(page =>
createInertiaApp({
page,
render: renderToString,
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
return pages[`./Pages/${name}.vue`]
},
setup({ App, props, plugin }) {
return createSSRApp({
render: () => h(App, props),
}).use(plugin)
},
}),
)
When creating this file, be sure to add anything that's missing from your app.js file
that makes sense to run in SSR mode, such as plugins or custom mixins.
Setup Vite
Next, we need to update our Vite configuration to build our new ssr.js file. We
can do this by adding a ssr property to Laravel's Vite plugin configuration in our
vite.config.js file.
https://inertiajs.com/server-side-rendering 3/7
3/25/24, 10:22 AM Server-side rendering (SSR) - Inertia.js
+ ssr: 'resources/js/ssr.js',
refresh: true,
}),
// ...
],
})
Next, let's update the build script in our package.json file to also build our new
ssr.js file.
"scripts": {
"dev": "vite",
- "build": "vite build"
+ "build": "vite build && vite build --ssr"
},
Now you can build both your client-side and server-side bundles.
Now that you have built both your client-side and server-side bundles, you should
be able run the Node-based Inertia SSR server using the following command.
https://inertiajs.com/server-side-rendering 4/7
3/25/24, 10:22 AM Server-side rendering (SSR) - Inertia.js
With the server running, you should be able to access your app within the browser
with server-side rendering enabled. In fact, you should be able to disable
JavaScript entirely and still navigate around your application.
Since your website is now being server-side rendered, you can instruct Vue to
"hydrate" the static markup and make it interactive instead of re-rendering all the
HTML that we just generated.
To enable client-side hydration in a Vue 3 app, update your app.js file to use
createSSRApp instead of createApp :
createInertiaApp({
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
return pages[`./Pages/${name}.vue`]
},
setup({ el, App, props, plugin }) {
- createApp({ render: () => h(App, props) })
+ createSSRApp({ render: () => h(App, props) })
.use(plugin)
.mount(el)
},
})
Deployment
https://inertiajs.com/server-side-rendering 5/7
3/25/24, 10:22 AM Server-side rendering (SSR) - Inertia.js
When deploying your SSR enabled app to production, you'll need to build both the
client-side ( app.js ) and server-side bundles ( ssr.js ), and then run the SSR server
as a background process, typically using a process monitoring tool such as
Supervisor.
To stop the SSR server, for instance when you deploy a new version of your website,
you may utilize the inertia:stop-ssr Artisan command. Your process monitor (such
as Supervisor) should be responsible for automatically restarting the SSR server
after it has stopped.
Laravel Forge
To run the SSR server on Forge, you should create a new daemon that runs
php artisan inertia:start-ssr from the root of your app. Or, you may utilize the
built-in Inertia integration from your Forge application's management dashboard.
Next, whenever you deploy your application, you can automatically restart the
SSR server by calling the php artisan inertia:stop-ssr command. This will stop the
existing SSR server, forcing a new one to be started by your process monitor.
Heroku
To run the SSR server on Heroku, update the web configuration in your Procfile to
run the SSR server before starting your web server.
https://inertiajs.com/server-side-rendering 6/7
3/25/24, 10:22 AM Server-side rendering (SSR) - Inertia.js
Note, you must have the heroku/nodejs buildpack installed in addition to the
heroku/php buildback for the SSR server to run.
https://inertiajs.com/server-side-rendering 7/7