PHPackages                             tinymvc/inertia-php - 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. tinymvc/inertia-php

ActiveLibrary[Framework](/categories/framework)

tinymvc/inertia-php
===================

An Inertia.js v3 server adapter for the TinyMVC framework.

v2.0.0(3w ago)22011MITPHPPHP &gt;=8.2

Since Feb 18Pushed 3w agoCompare

[ Source](https://github.com/tinymvc/inertia-php)[ Packagist](https://packagist.org/packages/tinymvc/inertia-php)[ RSS](/packages/tinymvc-inertia-php/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (4)Dependencies (1)Versions (5)Used By (1)

Inertia.js v3 Adapter for TinyMVC
=================================

[](#inertiajs-v3-adapter-for-tinymvc)

A server-side [Inertia.js v3](https://inertiajs.com/docs/v3) adapter for [TinyMVC](https://github.com/tinymvc/tinycore). It implements client-side rendering only; SSR is intentionally not included.

The adapter requires PHP 8.2 or newer and TinyCore 3.x.

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

[](#installation)

```
composer require tinymvc/inertia-php
```

Register the provider:

```
// bootstrap/providers.php
return [
    \Inertia\InertiaServiceProvider::class,
];
```

The provider registers the Inertia singleton, the `@inertia` Blade directive, and the `Route::inertia()` macro.

Root template
-------------

[](#root-template)

```

    @vite(['app.tsx', 'app.css'])

    @inertia

```

In v3, the initial page object is stored in a JSON script element:

```
{"component":"Home", ...}

```

Use `@inertia('portal')` for a custom mount id. The root Blade view and DOM mount id are configured independently:

```
Inertia::setRootView('layouts.admin');
Inertia::setRootElementId('portal');
```

Your client-side `createInertiaApp()` configuration must use the same mount id.

Responses
---------

[](#responses)

```
use Inertia\Facades\Inertia;

return Inertia::render('Users/Index', [
    'users' => User::all(),
]);

// Equivalent helper:
return inertia('Users/Index', ['users' => User::all()]);
```

Simple routes may use the router macro:

```
Route::inertia('/about', 'About');
```

The adapter automatically adds an empty `errors` prop, performs partial prop resolution, checks asset versions, emits v3 page metadata, and returns the required `X-Inertia` and `Vary` response headers.

Shared data
-----------

[](#shared-data)

```
Inertia::share('appName', config('app.name'));

Inertia::share([
    'auth' => fn () => [
        'user' => request()->user(),
    ],
    'locale' => 'en',
]);
```

Shared keys are exposed in the v3 page object's `sharedProps` metadata for instant visits. Component props take precedence over shared props.

Authentication data is not shared implicitly. Define it explicitly so each application controls its own shape and authorization boundary.

Prop types
----------

[](#prop-types)

Regular closures are evaluated only when their prop survives partial-reload filtering:

```
return inertia('Users/Index', [
    'users' => fn () => User::all(),
    'companies' => fn () => Company::all(),
]);
```

### Optional and always

[](#optional-and-always)

```
return inertia('Reports', [
    // Excluded until explicitly requested with `only`.
    'details' => Inertia::optional(fn () => Report::details()),

    // Included even when a partial reload did not request it.
    'notifications' => Inertia::always(fn () => Notification::count()),
]);
```

```
router.reload({ only: ['details'] })
```

Inertia v3 removed `lazy()` and `LazyProp`; use `optional()` instead.

### Deferred

[](#deferred)

```
return inertia('Dashboard', [
    'permissions' => Inertia::defer(fn () => Permission::all()),
    'teams' => Inertia::defer(fn () => Team::all(), 'attributes'),
    'projects' => Inertia::defer(fn () => Project::all(), 'attributes'),
]);
```

Deferred failures can be rescued and reported to the client's ``rescue slot:

```
'permissions' => Inertia::defer(
    fn () => Permission::all(),
    rescue: true,
),
```

### Merge

[](#merge)

```
return inertia('Feed', [
    // Append at the prop root.
    'tags' => Inertia::merge($tags),

    // Append only `data`, replacing the other pagination fields.
    'users' => Inertia::merge(fn () => User::paginate())
        ->append('data', matchOn: 'id'),

    // Prepend one nested collection and append another.
    'dashboard' => Inertia::merge($dashboard)
        ->prepend('announcements')
        ->append('activities'),

    // Deep merge the whole value and match nested messages by id.
    'chat' => Inertia::deepMerge($chat)->matchOn('messages.id'),
]);
```

Merge metadata is omitted for props named in the `X-Inertia-Reset` header, as required by the v3 protocol.

### Once

[](#once)

```
return inertia('Billing', [
    'plans' => Inertia::once(fn () => Plan::all()),
    'rates' => Inertia::once(fn () => Rate::all())->until(3600),
    'roles' => Inertia::once(fn () => Role::all())->as('shared-roles'),
    'features' => Inertia::once(fn () => Feature::all())->fresh($changed),
]);
```

Once behavior can also be combined with optional, deferred, and merge props:

```
'report' => Inertia::optional(fn () => Report::make())->once(),
'stats' => Inertia::defer(fn () => Stats::make())->once(),
'activity' => Inertia::merge(fn () => Activity::recent())->once(),
```

Globally shared once props:

```
Inertia::shareOnce('countries', fn () => Country::all())
    ->until(86400);
```

### Nested props

[](#nested-props)

V3 prop types work inside nested arrays and closures, and partial reload headers support dot notation:

```
return inertia('Dashboard', [
    'auth' => [
        'user' => request()->user(),
        'notifications' => Inertia::defer(fn () => Notification::all()),
        'invoices' => Inertia::optional(fn () => Invoice::all()),
    ],
]);
```

```
router.reload({ only: ['auth.notifications'] })
```

For reusable prop objects, implement `ProvidesInertiaProperties` to contribute multiple props or `ProvidesInertiaProperty` to resolve one contextual value. Both are resolved at any nesting depth and receive the current TinyMVC request.

### Infinite scroll

[](#infinite-scroll)

`scroll()` emits `scrollProps` and merge metadata and honors `X-Inertia-Infinite-Scroll-Merge-Intent`:

```
'posts' => Inertia::scroll($paginator),
```

TinyMVC's `Spark\Utils\Paginator` is detected automatically. For a custom paginator, provide metadata:

```
'posts' => Inertia::scroll(
    $result,
    wrapper: 'data',
    metadata: fn ($result) => [
        'pageName' => 'page',
        'previousPage' => $result['previous'],
        'nextPage' => $result['next'],
        'currentPage' => $result['current'],
    ],
),
```

Flash data
----------

[](#flash-data)

V3 flash data lives at `page.flash` and is not persisted in browser history:

```
Inertia::flash('message', 'User created.');
return inertia()->redirect('/users');

// Or:
return Inertia::flash([
    'message' => 'User created.',
    'userId' => $user->id,
])->back();
```

TinyMVC's conventional `info`, `success`, and `error` flash keys are also moved to `page.flash` automatically.

History
-------

[](#history)

```
return inertia()
    ->encryptHistory()
    ->render('Account/Settings', $props);

return inertia()
    ->clearHistory()
    ->render('Auth/Login');
```

`encryptHistory` and `clearHistory` are only included in the page object when true, as required by Inertia v3.

Redirects
---------

[](#redirects)

```
return inertia()->redirect('/users');
return inertia()->back();
return inertia()->location('https://example.com');
```

Redirects after `PUT`, `PATCH`, and `DELETE` become `303` responses. External Inertia redirects use `409` plus `X-Inertia-Location`; fragment redirects use the v3 `X-Inertia-Redirect` header.

To preserve the fragment from the original URL across a redirect:

```
return inertia()->preserveFragment()->redirect('/article/new-slug');
```

Asset versioning
----------------

[](#asset-versioning)

The adapter hashes `public/build/.vite/manifest.json` by default:

```
Inertia::setBuildDirectory('build');
```

You may provide a fixed or lazy version:

```
Inertia::version(config('app.deploy_version'));
Inertia::version(fn () => config('app.deploy_version'));
```

On a mismatched Inertia `GET`, the adapter returns `409` with the current URL in `X-Inertia-Location` before resolving page props.

Testing
-------

[](#testing)

```
composer test
```

License
-------

[](#license)

MIT

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance94

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 88.9% 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

Every ~51 days

Total

4

Last Release

27d ago

Major Versions

v1.0.2 → v2.0.02026-07-23

### Community

Maintainers

![](https://www.gravatar.com/avatar/f6904c684048421da96c056bc3b6dc0c1bbf58f847454a6b927bbc26da41ebe7?d=identicon)[dev.shahin](/maintainers/dev.shahin)

---

Top Contributors

[![shahinmoyshan](https://avatars.githubusercontent.com/u/128284645?v=4)](https://github.com/shahinmoyshan "shahinmoyshan (8 commits)")[![tinymvc](https://avatars.githubusercontent.com/u/177845414?v=4)](https://github.com/tinymvc "tinymvc (1 commits)")

### Embed Badge

![Health badge](/badges/tinymvc-inertia-php/health.svg)

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

###  Alternatives

[nineinchnick/edatatables

Grid widget for the Yii Framework, wrapper for the DataTables jQuery plugin

173.2k](/packages/nineinchnick-edatatables)[sergebezborodov/beanstalk-yii2

Beanstalk component for Yii Framework 2

201.2k](/packages/sergebezborodov-beanstalk-yii2)

PHPackages © 2026

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