Symfony bundle implementing the Inertia.js v2 server-side protocol — the Symfony equivalent of inertiajs/inertia-laravel.
Inertia lets you build modern React, Vue, or Svelte single-page applications without building a separate API. You keep your Symfony controllers, routing, middleware, and authentication exactly as they are - controllers just return a component name and props instead of a Twig template.
On the first visit the server returns a full HTML page. On subsequent navigations it returns a lightweight JSON response and the JavaScript adapter swaps the component client-side without a full reload.
PHP ^8.1 · Symfony ^6.4 / ^7.4 / ^8.0 · Twig ^3.0
composer require nytodev/inertia-bundle
Without Symfony Flex, register the bundle manually in config/bundles.php:
Nytodev\InertiaBundle\InertiaBundle::class => ['all' => true],
{# templates/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
{{ inertiaHead(page) }}
{{ encore_entry_link_tags('app') }}
</head>
<body>
{{ inertia(page) }}
{{ encore_entry_script_tags('app') }}
</body>
</html>
inertia(page) outputs <div id="app" data-page='...'></div>.inertiaHead(page) outputs SSR-rendered head tags (safe to include even without SSR).
use Nytodev\InertiaBundle\Service\Inertia;
class UserController
{
#[Route('/users')]
public function index(Inertia $inertia): Response
{
return $inertia->render('Users/Index', [
'users' => $this->repository->findAll(),
]);
}
#[Route('/users/{id}')]
public function show(User $user, Inertia $inertia): Response
{
return $inertia->render('Users/Show', [
'user' => $user,
]);
}
}
npm install @inertiajs/react react react-dom
// assets/app.jsx
import { createInertiaApp } from '@inertiajs/react'
import { createRoot } from 'react-dom/client'
createInertiaApp({
resolve: name => {
const pages = import.meta.glob('./Pages/**/*.jsx', { eager: true })
return pages[`./Pages/${name}.jsx`]
},
setup({ el, App, props }) {
createRoot(el).render(<App {...props} />)
},
})
// assets/Pages/Users/Index.jsx
export default function UsersIndex({ users }) {
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
)
}
That's it. The bundle handles first-visit HTML, subsequent XHR JSON responses, asset versioning, 302→303 redirect conversion, and partial reloads automatically.
Set props that are available on every page (e.g. authenticated user, flash messages):
// src/EventListener/InertiaShareListener.php
class InertiaShareListener
{
public function __construct(
private readonly Inertia $inertia,
private readonly Security $security,
) {}
public function onKernelRequest(RequestEvent $event): void
{
$this->inertia->share('auth', [
'user' => $this->security->getUser()?->getUserIdentifier(),
]);
}
}
# config/services.yaml
App\EventListener\InertiaShareListener:
tags:
- { name: kernel.event_listener, event: kernel.request }
| Method | Behaviour |
|---|---|
$inertia->lazy(fn) / optional(fn) |
Never sent on full render, only on explicit partial reload |
$inertia->always(fn) |
Always sent, even in partial reloads that filter other props |
$inertia->defer(fn) |
Fetched by the client in a separate XHR after page load |
$inertia->once(fn) |
Sent once, cached by the client |
$inertia->merge(fn) |
Merged into the existing client value (infinite scroll) |
return $inertia->render('Feed/Index', [
'posts' => $inertia->merge(fn () => $this->postRepo->paginate($page)),
'stats' => $inertia->defer(fn () => $this->buildStats()),
'comments' => $inertia->lazy(fn () => $this->commentRepo->findAll()),
]);
# config/packages/inertia.yaml
inertia:
root_view: base.html.twig # Root Twig template (default: base.html.twig)
version: null # Asset version string — triggers full reload on change
encrypt_history: false # Globally encrypt browser history state
ssr_enabled: false # Enable SSR (requires symfony/http-client)
ssr_url: 'http://127.0.0.1:13714'
ssr_bundle: null # Path to SSR JS bundle, auto-detected if null
| Topic | Link |
|---|---|
| Installation & configuration | docs/installation.md |
| Rendering & shared props | docs/rendering.md |
| All prop types | docs/props.md |
| Asset versioning, redirects, history | docs/features.md |
| Flash & validation errors | docs/flash-errors.md |
| Server-Side Rendering | docs/ssr.md |
| Testing | docs/testing.md |
MIT — see LICENSE.