PHPackages                             unoptimised/inertia-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Framework](/categories/framework)
4. /
5. unoptimised/inertia-bundle

ActiveSymfony-bundle[Framework](/categories/framework)

unoptimised/inertia-bundle
==========================

A Symfony bundle for Inertia.js

1.0.0(2mo ago)026↓50%MITPHPCI passing

Since Mar 3Pushed 2mo agoCompare

[ Source](https://github.com/unoptimised/inertia-bundle)[ Packagist](https://packagist.org/packages/unoptimised/inertia-bundle)[ RSS](/packages/unoptimised-inertia-bundle/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (6)Versions (2)Used By (0)

InertiaBundle for Symfony
=========================

[](#inertiabundle-for-symfony)

A Symfony 5.4+ bundle that implements the [Inertia.js v1 server-side protocol](https://inertiajs.com/docs/v1/core-concepts/the-protocol), letting you build modern single-page React / Vue / Svelte apps while keeping classic Symfony routing and controllers — no REST API required.

---

How Inertia v1 Works (Protocol Summary)
---------------------------------------

[](#how-inertia-v1-works-protocol-summary)

ScenarioWhat the server returnsFirst browser visit (no `X-Inertia` header)Full HTML page with a `` mount pointSubsequent XHR navigation (`X-Inertia: true`)JSON page object (`component`, `props`, `url`, `version`)Asset version mismatch (stale client)`409 Conflict` with `X-Inertia-Location` header → client does full reloadRedirect after PUT/PATCH/DELETE`302 → 303` conversion so browser uses GET for the redirectPartial reload (`X-Inertia-Partial-Data`)JSON with only the requested prop keys (plus `errors` always)---

Installation
------------

[](#installation)

```
composer require unoptimised/inertia-bundle
```

Register the bundle in `config/bundles.php`:

```
return [
    // ...
    Unoptimised\InertiaBundle\UnoptimisedInertiaBundle::class => ['all' => true],
];
```

---

Configuration
-------------

[](#configuration)

Create `config/packages/inertia.yaml`:

```
inertia:
    # The Twig template used as the root layout
    root_view: 'base.html.twig'

    # Asset version — change on every deploy to force full reloads on clients
    # Can be a static string, a git SHA, or a file hash
    version: null
```

### Dynamic version from file hash

[](#dynamic-version-from-file-hash)

```
# config/packages/inertia.yaml
inertia:
    version: '%env(resolve:ASSET_VERSION)%'
```

Or set it programmatically in a subscriber/listener:

```
$inertia->version(md5_file(public_path('build/manifest.json')));
```

---

Root Layout Template
--------------------

[](#root-layout-template)

Copy `vendor/your-vendor/inertia-bundle/templates/base.html.twig` to `templates/base.html.twig` and adjust it to your needs:

```

    My App

    {# Renders:  #}
    {{ inertia(page) }}

```

The `{{ inertia(page) }}` Twig function is provided by the bundle and outputs the root `` with the JSON-encoded page object in `data-page`.

---

Usage in Controllers
--------------------

[](#usage-in-controllers)

### Option A — Inject `Inertia` directly (recommended with autowiring)

[](#option-a--inject-inertia-directly-recommended-with-autowiring)

```
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Unoptimised\InertiaBundle\Service\Inertia;

class EventController extends AbstractController
{
    public function __construct(private readonly Inertia $inertia) {}

    #[Route('/events/{id}', name: 'events.show')]
    public function show(Event $event): Response
    {
        return $this->inertia->render('Events/Show', [
            'event' => [
                'id'          => $event->getId(),
                'title'       => $event->getTitle(),
                'description' => $event->getDescription(),
            ],
        ]);
    }
}
```

---

Shared Props
------------

[](#shared-props)

Shared props are merged into every Inertia response. Set them in a kernel event subscriber or middleware:

```
// src/EventSubscriber/InertiaShareSubscriber.php
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Security;
use Unoptimised\InertiaBundle\Service\Inertia;

class InertiaShareSubscriber implements EventSubscriberInterface
{
    public function __construct(
        private readonly Inertia $inertia,
        private readonly Security $security,
    ) {}

    public static function getSubscribedEvents(): array
    {
        return [KernelEvents::REQUEST => 'onRequest'];
    }

    public function onRequest(RequestEvent $event): void
    {
        if (!$event->isMainRequest()) {
            return;
        }

        // Plain value
        $this->inertia->share('appName', 'My App');

        // Lazy callable — resolved only when Inertia renders a response
        $this->inertia->share('auth', function () {
            $user = $this->security->getUser();
            return $user ? ['name' => $user->getUserIdentifier()] : null;
        });

        // Multiple keys at once
        $this->inertia->share([
            'flash' => fn () => [], // wire up your flash messages here
        ]);
    }
}
```

---

Lazy Props
----------

[](#lazy-props)

Pass a callable as a prop value so it is only evaluated if not excluded by a partial reload:

```
return $this->inertia->render('Reports/Show', [
    // Always resolved
    'title' => $report->getTitle(),

    // Only resolved when this prop is included in the response
    'data' => fn () => $this->reportService->computeHeavyData($report),
]);
```

---

Partial Reloads
---------------

[](#partial-reloads)

The Inertia client sends `X-Inertia-Partial-Data` (comma-separated prop names to include) and/or `X-Inertia-Partial-Except` (names to exclude). The bundle handles this transparently — `errors` is always included regardless.

```
X-Inertia-Partial-Component: Events/Index
X-Inertia-Partial-Data: events          ← only return this prop
X-Inertia-Partial-Except: sidebar       ← return everything except this

```

---

Validation Errors
-----------------

[](#validation-errors)

Symfony's form validation errors should be placed under the `errors` key in props. A common pattern using Symfony's `ValidatorInterface`:

```
$errors = [];
$violations = $this->validator->validate($dto);
foreach ($violations as $violation) {
    $field = $violation->getPropertyPath();
    $errors[$field] = $violation->getMessage();
}

return $this->inertia->render('User/Edit', [
    'user'   => $dto,
    'errors' => $errors,
]);
```

The Inertia client automatically makes validation errors available to your form components.

---

Asset Versioning
----------------

[](#asset-versioning)

Set `inertia.version` in config (or call `$inertia->version(...)` at runtime). On every request the bundle compares the client-sent `X-Inertia-Version` header against the server version. If they differ the bundle returns:

```
HTTP/1.1 409 Conflict
X-Inertia-Location: https://example.com/current-url

```

The Inertia JS client then performs a full page reload to pick up new assets.

---

Redirect Behaviour
------------------

[](#redirect-behaviour)

MethodServer 302What Inertia seesGET302302 (unchanged)PUT / PATCH / DELETE302**303** (converted by listener)The 302→303 conversion is handled automatically by `InertiaListener::onKernelResponse()`.

---

Running Tests
-------------

[](#running-tests)

```
composer install
./vendor/bin/phpunit
```

###  Health Score

35

—

LowBetter than 80% of packages

Maintenance86

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity33

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

68d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/655c645edca1c838f450ed74443a890b3e6e35bfec777e0f9aa7e14226625589?d=identicon)[unoptimised](/maintainers/unoptimised)

---

Top Contributors

[![unoptimised](https://avatars.githubusercontent.com/u/262098027?v=4)](https://github.com/unoptimised "unoptimised (12 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/unoptimised-inertia-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/unoptimised-inertia-bundle/health.svg)](https://phpackages.com/packages/unoptimised-inertia-bundle)
```

###  Alternatives

[symfony/framework-bundle

Provides a tight integration between Symfony components and the Symfony full-stack framework

3.6k235.4M9.7k](/packages/symfony-framework-bundle)[shopware/platform

The Shopware e-commerce core

3.3k1.5M3](/packages/shopware-platform)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.3M152](/packages/sulu-sulu)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.0k15.4k](/packages/prestashop-prestashop)[drupal/core

Drupal is an open source content management platform powering millions of websites and applications.

19462.3M1.3k](/packages/drupal-core)[contao/core-bundle

Contao Open Source CMS

1231.6M2.3k](/packages/contao-core-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
