An Inertia.js adapter for Yii2 framework, providing a seamless bridge between your Yii2 backend and modern JavaScript frontend frameworks (React, Vue, Svelte).
- 🚀 Simple API: Match the developer experience of
inertia-laravel - 📦 Shared Props: Share data across all Inertia responses
- 🔄 Partial Reloads: Support for partial page updates
- 🎯 Asset Versioning: Automatic version management for cache busting
- đź§Ş Well Tested: Comprehensive unit and integration tests
- 📚 Full Documentation: Complete usage examples and guides
Install via Composer:
composer require crenspire/yii2-inertiaIn your config/web.php, register the Inertia view renderer:
'view' => [
'renderers' => [
'inertia' => \Crenspire\Yii2Inertia\ViewRenderer::class,
],
],Create a root view template at views/layouts/inertia.php:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Inertia.js App</title>
<script type="module" crossorigin src="/dist/assets/index.js"></script>
<link rel="stylesheet" crossorigin href="/dist/assets/index.css">
</head>
<body>
<div id="app" data-page="<?= htmlspecialchars(json_encode($page), ENT_QUOTES, 'UTF-8') ?>"></div>
</body>
</html>use Crenspire\Yii2Inertia\Inertia;
class HomeController extends \yii\web\Controller
{
public function actionIndex()
{
return Inertia::render('Home', [
'title' => 'Welcome',
'user' => Yii::$app->user->identity,
]);
}
}Install Inertia.js and your frontend framework:
npm install @inertiajs/inertia @inertiajs/inertia-react react react-domCreate src/main.jsx:
import React from 'react';
import ReactDOM from 'react-dom/client';
import { createInertiaApp } from '@inertiajs/inertia-react';
import Home from './pages/Home';
createInertiaApp({
resolve: (name) => {
const pages = { Home };
return pages[name];
},
setup({ el, App, props }) {
ReactDOM.createRoot(el).render(<App {...props} />);
},
});Render an Inertia page:
return Inertia::render('Dashboard', [
'users' => User::find()->all(),
]);Share data with all Inertia responses:
// Single key-value
Inertia::share('appName', 'My App');
// Multiple values
Inertia::share([
'user' => Yii::$app->user->identity,
'flash' => Yii::$app->session->getFlash('message'),
]);
// Using closures
Inertia::share('timestamp', function () {
return time();
});Set or get the asset version:
// String version
Inertia::version('1.0.0');
// Callback version
Inertia::version(function () {
return filemtime(Yii::getAlias('@webroot/dist/manifest.json'));
});
// Get current version
$version = Inertia::version();Create an Inertia redirect response:
return Inertia::location('/dashboard');You can also use the global inertia() helper function:
return inertia('Home', ['title' => 'Welcome']);Inertia supports partial reloads for better performance. The client can request only specific props:
// Client sends: X-Inertia-Partial-Component: Dashboard
// Client sends: X-Inertia-Partial-Data: users,stats
// Only 'users' and 'stats' props will be returned (plus shared props)
return Inertia::render('Dashboard', [
'users' => $users,
'stats' => $stats,
'other' => $other, // This will be excluded
]);For POST/PUT/PATCH/DELETE requests, Inertia handles redirects automatically:
public function actionStore()
{
// ... save data
// For Inertia requests, returns 409 with X-Inertia-Location header
// For regular requests, returns 302 redirect
return Inertia::location('/dashboard');
}The Inertia::location() method automatically detects the request type:
- Inertia requests: Returns HTTP 409 with
X-Inertia-Locationheader - Regular requests: Returns HTTP 302 with
Locationheader
Inertia.js uses version checking to ensure the frontend and backend stay in sync. When the client's version doesn't match the server's version, a full page reload is triggered.
By default, the version is automatically detected from your manifest.json file:
// Automatically uses dist/manifest.json mtime if it exists
$version = Inertia::version();You can set a custom version:
// String version
Inertia::version('1.0.0');
// Callback version (evaluated on each request)
Inertia::version(function () {
return filemtime(Yii::getAlias('@webroot/dist/manifest.json'));
});When a client sends an X-Inertia-Version header that doesn't match the current version, the adapter automatically returns a location redirect (409 status) to trigger a full page reload. This ensures users always have the latest assets.
You can configure the root view path:
Inertia::setRootView('@app/views/custom-inertia.php');For shared props that should be available on every page, you can set them in your application bootstrap or a common controller:
// In config/bootstrap.php or a base controller
use Crenspire\Yii2Inertia\Inertia;
// Share user data
Inertia::share('user', function () {
return Yii::$app->user->identity;
});
// Share flash messages
Inertia::share('flash', function () {
return [
'success' => Yii::$app->session->getFlash('success'),
'error' => Yii::$app->session->getFlash('error'),
];
});If you're experiencing frequent full page reloads, check:
- Your version callback is returning a stable value
- The
manifest.jsonfile exists and is accessible - File permissions allow reading the manifest file
If redirects aren't working as expected:
- Ensure you're using
Inertia::location()instead of Yii'sredirect() - Check that the request has the
X-Inertiaheader for Inertia requests - Verify the response status code (409 for Inertia, 302 for regular)
If you get "Root view file not found" errors:
- Verify the path in
Inertia::setRootView()is correct - Check that the view file exists and is readable
- Ensure Yii aliases are properly configured
The repository includes a complete example application. To run it:
# Install dependencies
cd examples/basic
composer install
# Install frontend dependencies
cd vite
npm install
# Build frontend assets
npm run build
# Or run dev server
npm run dev
# Start PHP server
cd ../web
php -S localhost:8000Visit http://localhost:8000 in your browser.
Run the test suite:
composer install
vendor/bin/phpunit- PHP ^8.1
- Yii2 ~2.0.50
MIT License. See LICENSE file for details.
Please see CONTRIBUTING.md for details.
See CHANGELOG.md for a list of changes.