Modern Inertia.js integration for Symfony 8 and PHP 8.2+. Build powerful single-page applications using Vue.js or React without the complexity of building an API.
- π Symfony 8 & PHP 8.2+ Support
- β‘ Inertia.js v2 Protocol (Deferred props, Lazy props, Merge props)
- π₯οΈ Server-Side Rendering (SSR) support
- π¦ Vite Integration with automatic version detection
- π οΈ Twig Helpers (
inertia(),inertiaHead()) - β
Testing Helpers (
assertInertia) - π Automatic Flash Data & Error Sharing
- PHP 8.2, 8.3, or 8.4
- Symfony 8.0+ (also compatible with Symfony 7.0+)
- Composer 2.0+
Install the bundle via Composer:
composer require creativspeed/inertia-bundleIf you're using Symfony Flex, the bundle will be automatically registered. Otherwise, add it manually to config/bundles.php:
<?php
return [
// ...
CreativSpeed\InertiaBundle\InertiaBundle::class => ['all' => true],
];Create config/packages/inertia.yaml:
inertia:
# Asset versioning for cache busting (optional)
version: '%env(default::APP_VERSION)%'
# Root Twig template (optional, default: 'app')
root_view: 'app'
# Server-side rendering (optional)
ssr:
enabled: false
url: 'http://127.0.0.1:13714'Create templates/inertia/app.html.twig:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title inertia>{{ page.props.title ?? 'My App' }}</title>
{{ vite_entry_link_tags('app') }}
</head>
<body>
<div id="app" data-page="{{ page|json_encode|e('html_attr') }}"></div>
{{ vite_entry_script_tags('app') }}
</body>
</html>Install frontend dependencies:
npm install @inertiajs/vue3 vue
npm install --save-dev @vitejs/plugin-vue viteCreate assets/app.js:
import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
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);
},
});Create assets/pages/Home.vue:
<template>
<div>
<h1>{{ title }}</h1>
<p>Welcome to Inertia.js with Symfony 8!</p>
</div>
</template>
<script setup>
defineProps({
title: String
});
</script><?php
namespace App\Controller;
use CreativSpeed\InertiaBundle\Service\InertiaInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
class HomeController extends AbstractController
{
#[Route('/', name: 'home')]
public function index(InertiaInterface $inertia): Response
{
return $inertia->render('Home', [
'title' => 'Hello from Symfony!'
]);
}
}return $inertia->render('Dashboard/Index', [
'user' => $this->getUser(),
'stats' => ['visits' => 100]
]);// In a controller or event listener
$inertia->share('auth', [
'user' => $this->getUser()
]);return $inertia->render('Users/Index', [
'users' => $userRepository->findAll(),
// Only loaded when specifically requested
'stats' => fn() => $this->calculateExpensiveStats()
]);// Redirect back
return $inertia->back();
// Redirect to URL
return $inertia->redirect('/dashboard');This bundle uses Symfony's modern AbstractBundle pattern (Symfony 6.1+) for cleaner, more maintainable code:
- β No separate Extension class needed
- β No separate Configuration class needed
- β Everything configured in the bundle class
- β Auto-wiring and auto-configuration enabled
inertia:
root_view: 'app' # Default for most pagesThen override per-request:
return $inertia->render('Admin/Dashboard', $props, [
'root_view' => 'admin' // Use templates/inertia/admin.html.twig
]);inertia:
version: '1.0.0' # Static version
# OR
version: '%env(APP_VERSION)%' # From environmentinertia:
ssr:
enabled: true
url: 'http://127.0.0.1:13714'composer testContributions are welcome! Please feel free to submit a Pull Request.
This bundle is open-sourced software licensed under the MIT license.
- π Bug Reports: GitHub Issues
- π‘ Feature Requests: GitHub Issues
- π§ Email: bachir@creativspeed.com
If you find this bundle helpful, please consider giving it a β on GitHub!
Made with β€οΈ by CreativSpeed