[{"data":1,"prerenderedAt":36},["ShallowReactive",2],{"4563324":3},{"type_of":4,"id":5,"title":6,"description":7,"readable_publish_date":8,"slug":9,"path":10,"url":11,"comments_count":12,"public_reactions_count":12,"collection_id":13,"published_timestamp":14,"language":15,"subforem_id":16,"ai_disclosure_level":17,"ai_disclosure_label":18,"positive_reactions_count":12,"cover_image":19,"social_image":20,"canonical_url":11,"created_at":14,"edited_at":13,"crossposted_at":13,"published_at":14,"last_comment_at":14,"reading_time_minutes":21,"tag_list":22,"tags":23,"body_html":28,"body_markdown":29,"user":30},"article",4563324,"Dev.to — Laravel with React or Vue through Inertia","Laravel with React or Vue through Inertia   If you've spent time with Laravel and wondered...","Sep 3","devto-laravel-with-react-or-vue-through-inertia-nj0","/mumbai_web_designer/devto-laravel-with-react-or-vue-through-inertia-nj0","https://dev.to/mumbai_web_designer/devto-laravel-with-react-or-vue-through-inertia-nj0",0,null,"2026-09-03T08:00:46Z","en",1,"not_disclosed","Not Disclosed","https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn7b0vwc5f5f9segg4ifi.jpg","https://media2.dev.to/dynamic/image/width=1200,height=627,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn7b0vwc5f5f9segg4ifi.jpg",6,"laravel, react, tutorial, vue",[24,25,26,27],"laravel","react","tutorial","vue","\u003Ch1>\n  \u003Ca name=\"laravel-with-react-or-vue-through-inertia\" href=\"#laravel-with-react-or-vue-through-inertia\">\n  \u003C/a>\n  Laravel with React or Vue through Inertia\n\u003C/h1>\n\n\u003Cp>If you've spent time with Laravel and wondered how to use React or Vue without abandoning the monolith, Inertia.js is the answer. It bridges the gap between a server-driven Laravel backend and a client-rendered component frontend — no separate API, no JSON contract negotiation, no duplicated routing layer.\u003C/p>\n\n\u003Cp>This article focuses on the practical setup: how Inertia actually works, how to scaffold it with React or Vue, and where it makes sense compared to going full-SPA or staying with Blade.\u003C/p>\n\n\n\u003Chr>\n\n\u003Ch2>\n  \u003Ca name=\"prerequisites-and-versions\" href=\"#prerequisites-and-versions\">\n  \u003C/a>\n  Prerequisites and Versions\n\u003C/h2>\n\n\u003Cp>Before starting, confirm your stack:\u003C/p>\n\n\u003Cul>\n\u003Cli>\n\u003Cstrong>Laravel 11 or 12\u003C/strong> — required for the Inertia Laravel adapter v3\u003C/li>\n\u003Cli>\n\u003Cstrong>Inertia.js v3.0.0\u003C/strong> (stable since March 25, 2026) — current default\u003C/li>\n\u003Cli>\n\u003Cstrong>Inertia.js v2.x\u003C/strong> — still supported; official Laravel starter kits ship with v2\u003C/li>\n\u003Cli>\n\u003Cstrong>React 19\u003C/strong> or \u003Cstrong>Vue 3\u003C/strong> — both work with Inertia v2 and v3\u003C/li>\n\u003Cli>\n\u003Cstrong>Node.js 20+\u003C/strong> and \u003Cstrong>Vite\u003C/strong> for the frontend build pipeline\u003C/li>\n\u003Cli>\n\u003Cstrong>Composer\u003C/strong> and \u003Cstrong>pnpm\u003C/strong> (or npm)\u003C/li>\n\u003C/ul>\n\n\u003Cp>If you are on Laravel 10, you are capped at Inertia adapter v2. The v3 adapter requires Laravel 11 minimum.\u003C/p>\n\n\n\u003Chr>\n\n\u003Ch2>\n  \u003Ca name=\"how-inertiajs-works-the-mental-model\" href=\"#how-inertiajs-works-the-mental-model\">\n  \u003C/a>\n  How Inertia.js Works (The Mental Model)\n\u003C/h2>\n\n\u003Cp>Inertia is not a UI framework. It is a protocol adapter that sits between Laravel controllers and React/Vue components.\u003C/p>\n\n\u003Cp>On a full-page load, Laravel renders an HTML shell with a single \u003Ccode>&lt;div id=\"app\"&gt;\u003C/code> that contains a JSON payload in a \u003Ccode>data-page\u003C/code> attribute. Inertia's client-side adapter bootstraps React or Vue, reads that payload, and renders the correct page component.\u003C/p>\n\n\u003Cp>On subsequent navigations, clicking an \u003Ccode>&lt;Link&gt;\u003C/code> component triggers a fetch request with an \u003Ccode>X-Inertia: true\u003C/code> header. Laravel detects this header and returns only JSON — the component name and its props — instead of a full HTML page. The client swaps the component without a full browser reload.\u003C/p>\n\n\u003Cp>The result: your Laravel routes, controllers, and auth middleware work exactly as they always did. Your frontend developers get full React or Vue components with props typed exactly as the controller passes them.\u003C/p>\n\n\n\u003Chr>\n\n\u003Ch2>\n  \u003Ca name=\"scaffolding-a-new-project\" href=\"#scaffolding-a-new-project\">\n  \u003C/a>\n  Scaffolding a New Project\n\u003C/h2>\n\n\u003Ch3>\n  \u003Ca name=\"option-a-official-laravel-starter-kit-fastest\" href=\"#option-a-official-laravel-starter-kit-fastest\">\n  \u003C/a>\n  Option A — Official Laravel Starter Kit (Fastest)\n\u003C/h3>\n\n\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight shell\">\u003Ccode>\u003Cspan class=\"c\"># React 19 + Inertia 2 + Tailwind 4 + shadcn/ui\u003C/span>\nlaravel new my-app \u003Cspan class=\"nt\">--react\u003C/span>\n\n\u003Cspan class=\"c\"># Vue 3 + Inertia 2 + Tailwind 4\u003C/span>\nlaravel new my-app \u003Cspan class=\"nt\">--vue\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Cp>Note: as of mid-2026, the official starter kits ship with Inertia \u003Cstrong>v2\u003C/strong>, not v3. Inertia v3 must be manually upgraded after scaffolding if needed.\u003C/p>\n\n\u003Ch3>\n  \u003Ca name=\"option-b-breeze-with-inertia-stack\" href=\"#option-b-breeze-with-inertia-stack\">\n  \u003C/a>\n  Option B — Breeze with Inertia Stack\n\u003C/h3>\n\n\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight shell\">\u003Ccode>composer require laravel/breeze \u003Cspan class=\"nt\">--dev\u003C/span>\nphp artisan breeze:install react\n\u003Cspan class=\"c\"># or\u003C/span>\nphp artisan breeze:install vue\n\nnpm \u003Cspan class=\"nb\">install\n\u003C/span>npm run dev\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Cp>Breeze installs authentication scaffolding (login, register, password reset) wired through Inertia pages. It's a solid starting point for applications that need auth out of the box.\u003C/p>\n\n\u003Ch3>\n  \u003Ca name=\"option-c-manual-inertia-install\" href=\"#option-c-manual-inertia-install\">\n  \u003C/a>\n  Option C — Manual Inertia Install\n\u003C/h3>\n\n\u003Cp>For projects where you need fine-grained control:\u003Cbr>\n\u003C/p>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight shell\">\u003Ccode>\u003Cspan class=\"c\"># Server side\u003C/span>\ncomposer require inertiajs/inertia-laravel\n\n\u003Cspan class=\"c\"># Publish middleware\u003C/span>\nphp artisan inertia:middleware\n\u003Cspan class=\"c\"># Register HandleInertiaRequests in bootstrap/app.php\u003C/span>\n\n\u003Cspan class=\"c\"># Client side — React\u003C/span>\nnpm \u003Cspan class=\"nb\">install\u003C/span> @inertiajs/react react react-dom\n\n\u003Cspan class=\"c\"># Or Vue\u003C/span>\nnpm \u003Cspan class=\"nb\">install\u003C/span> @inertiajs/vue3 vue\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Cp>\u003Cstrong>Root template\u003C/strong> (\u003Ccode>resources/views/app.blade.php\u003C/code>):\u003Cbr>\n\u003C/p>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight html\">\u003Ccode>\u003Cspan class=\"cp\">&lt;!DOCTYPE html&gt;\u003C/span>\n\u003Cspan class=\"nt\">&lt;html&gt;\u003C/span>\n\u003Cspan class=\"nt\">&lt;head&gt;\u003C/span>\n    @viteReactRefresh {{-- React only --}}\n    @vite(['resources/js/app.jsx', 'resources/css/app.css'])\n    @inertiaHead\n\u003Cspan class=\"nt\">&lt;/head&gt;\u003C/span>\n\u003Cspan class=\"nt\">&lt;body&gt;\u003C/span>\n    @inertia\n\u003Cspan class=\"nt\">&lt;/body&gt;\u003C/span>\n\u003Cspan class=\"nt\">&lt;/html&gt;\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Cp>\u003Cstrong>React entrypoint\u003C/strong> (\u003Ccode>resources/js/app.jsx\u003C/code>):\u003Cbr>\n\u003C/p>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight jsx\">\u003Ccode>\u003Cspan class=\"k\">import\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"nx\">createInertiaApp\u003C/span> \u003Cspan class=\"p\">}\u003C/span> \u003Cspan class=\"k\">from\u003C/span> \u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"s1\">@inertiajs/react\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"p\">;\u003C/span>\n\u003Cspan class=\"k\">import\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"nx\">createRoot\u003C/span> \u003Cspan class=\"p\">}\u003C/span> \u003Cspan class=\"k\">from\u003C/span> \u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"s1\">react-dom/client\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"p\">;\u003C/span>\n\n\u003Cspan class=\"nf\">createInertiaApp\u003C/span>\u003Cspan class=\"p\">({\u003C/span>\n    \u003Cspan class=\"na\">resolve\u003C/span>\u003Cspan class=\"p\">:\u003C/span> \u003Cspan class=\"nx\">name\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"p\">{\u003C/span>\n        \u003Cspan class=\"kd\">const\u003C/span> \u003Cspan class=\"nx\">pages\u003C/span> \u003Cspan class=\"o\">=\u003C/span> \u003Cspan class=\"k\">import\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">meta\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nf\">glob\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"s1\">./Pages/**/*.jsx\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"na\">eager\u003C/span>\u003Cspan class=\"p\">:\u003C/span> \u003Cspan class=\"kc\">true\u003C/span> \u003Cspan class=\"p\">});\u003C/span>\n        \u003Cspan class=\"k\">return\u003C/span> \u003Cspan class=\"nx\">pages\u003C/span>\u003Cspan class=\"p\">[\u003C/span>\u003Cspan class=\"s2\">`./Pages/\u003C/span>\u003Cspan class=\"p\">${\u003C/span>\u003Cspan class=\"nx\">name\u003C/span>\u003Cspan class=\"p\">}\u003C/span>\u003Cspan class=\"s2\">.jsx`\u003C/span>\u003Cspan class=\"p\">];\u003C/span>\n    \u003Cspan class=\"p\">},\u003C/span>\n    \u003Cspan class=\"nf\">setup\u003C/span>\u003Cspan class=\"p\">({\u003C/span> \u003Cspan class=\"nx\">el\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"nx\">App\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"nx\">props\u003C/span> \u003Cspan class=\"p\">})\u003C/span> \u003Cspan class=\"p\">{\u003C/span>\n        \u003Cspan class=\"nf\">createRoot\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"nx\">el\u003C/span>\u003Cspan class=\"p\">).\u003C/span>\u003Cspan class=\"nf\">render\u003C/span>\u003Cspan class=\"p\">(&lt;\u003C/span>\u003Cspan class=\"nc\">App\u003C/span> \u003Cspan class=\"si\">{\u003C/span>\u003Cspan class=\"p\">...\u003C/span>\u003Cspan class=\"nx\">props\u003C/span>\u003Cspan class=\"si\">}\u003C/span> \u003Cspan class=\"p\">/&gt;);\u003C/span>\n    \u003Cspan class=\"p\">},\u003C/span>\n\u003Cspan class=\"p\">});\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Cp>\u003Cstrong>Vue entrypoint\u003C/strong> (\u003Ccode>resources/js/app.js\u003C/code>):\u003Cbr>\n\u003C/p>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight javascript\">\u003Ccode>\u003Cspan class=\"k\">import\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"nx\">createApp\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"nx\">h\u003C/span> \u003Cspan class=\"p\">}\u003C/span> \u003Cspan class=\"k\">from\u003C/span> \u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"s1\">vue\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"p\">;\u003C/span>\n\u003Cspan class=\"k\">import\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"nx\">createInertiaApp\u003C/span> \u003Cspan class=\"p\">}\u003C/span> \u003Cspan class=\"k\">from\u003C/span> \u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"s1\">@inertiajs/vue3\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"p\">;\u003C/span>\n\n\u003Cspan class=\"nf\">createInertiaApp\u003C/span>\u003Cspan class=\"p\">({\u003C/span>\n    \u003Cspan class=\"na\">resolve\u003C/span>\u003Cspan class=\"p\">:\u003C/span> \u003Cspan class=\"nx\">name\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"p\">{\u003C/span>\n        \u003Cspan class=\"kd\">const\u003C/span> \u003Cspan class=\"nx\">pages\u003C/span> \u003Cspan class=\"o\">=\u003C/span> \u003Cspan class=\"k\">import\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">meta\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nf\">glob\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"s1\">./Pages/**/*.vue\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"na\">eager\u003C/span>\u003Cspan class=\"p\">:\u003C/span> \u003Cspan class=\"kc\">true\u003C/span> \u003Cspan class=\"p\">});\u003C/span>\n        \u003Cspan class=\"k\">return\u003C/span> \u003Cspan class=\"nx\">pages\u003C/span>\u003Cspan class=\"p\">[\u003C/span>\u003Cspan class=\"s2\">`./Pages/\u003C/span>\u003Cspan class=\"p\">${\u003C/span>\u003Cspan class=\"nx\">name\u003C/span>\u003Cspan class=\"p\">}\u003C/span>\u003Cspan class=\"s2\">.vue`\u003C/span>\u003Cspan class=\"p\">];\u003C/span>\n    \u003Cspan class=\"p\">},\u003C/span>\n    \u003Cspan class=\"nf\">setup\u003C/span>\u003Cspan class=\"p\">({\u003C/span> \u003Cspan class=\"nx\">el\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"nx\">App\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"nx\">props\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"nx\">plugin\u003C/span> \u003Cspan class=\"p\">})\u003C/span> \u003Cspan class=\"p\">{\u003C/span>\n        \u003Cspan class=\"nf\">createApp\u003C/span>\u003Cspan class=\"p\">({\u003C/span> \u003Cspan class=\"na\">render\u003C/span>\u003Cspan class=\"p\">:\u003C/span> \u003Cspan class=\"p\">()\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"nf\">h\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"nx\">App\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"nx\">props\u003C/span>\u003Cspan class=\"p\">)\u003C/span> \u003Cspan class=\"p\">})\u003C/span>\n            \u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nf\">use\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"nx\">plugin\u003C/span>\u003Cspan class=\"p\">)\u003C/span>\n            \u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nf\">mount\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"nx\">el\u003C/span>\u003Cspan class=\"p\">);\u003C/span>\n    \u003Cspan class=\"p\">},\u003C/span>\n\u003Cspan class=\"p\">});\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\n\u003Chr>\n\n\u003Ch2>\n  \u003Ca name=\"writing-controllers-and-page-components\" href=\"#writing-controllers-and-page-components\">\n  \u003C/a>\n  Writing Controllers and Page Components\n\u003C/h2>\n\n\u003Cp>A Laravel controller renders an Inertia page the same way it would render a Blade view — with one method call:\u003Cbr>\n\u003C/p>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight php\">\u003Ccode>\u003Cspan class=\"kn\">use\u003C/span> \u003Cspan class=\"nc\">Inertia\\Inertia\u003C/span>\u003Cspan class=\"p\">;\u003C/span>\n\n\u003Cspan class=\"kd\">class\u003C/span> \u003Cspan class=\"nc\">ProductController\u003C/span> \u003Cspan class=\"kd\">extends\u003C/span> \u003Cspan class=\"nc\">Controller\u003C/span>\n\u003Cspan class=\"p\">{\u003C/span>\n    \u003Cspan class=\"k\">public\u003C/span> \u003Cspan class=\"k\">function\u003C/span> \u003Cspan class=\"n\">index\u003C/span>\u003Cspan class=\"p\">()\u003C/span>\n    \u003Cspan class=\"p\">{\u003C/span>\n        \u003Cspan class=\"k\">return\u003C/span> \u003Cspan class=\"nc\">Inertia\u003C/span>\u003Cspan class=\"o\">::\u003C/span>\u003Cspan class=\"nf\">render\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"s1\">'Products/Index'\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"p\">[\u003C/span>\n            \u003Cspan class=\"s1\">'products'\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"nc\">Product\u003C/span>\u003Cspan class=\"o\">::\u003C/span>\u003Cspan class=\"nf\">latest\u003C/span>\u003Cspan class=\"p\">()\u003C/span>\u003Cspan class=\"o\">-&gt;\u003C/span>\u003Cspan class=\"nf\">paginate\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"mi\">20\u003C/span>\u003Cspan class=\"p\">),\u003C/span>\n        \u003Cspan class=\"p\">]);\u003C/span>\n    \u003Cspan class=\"p\">}\u003C/span>\n\n    \u003Cspan class=\"k\">public\u003C/span> \u003Cspan class=\"k\">function\u003C/span> \u003Cspan class=\"n\">show\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"kt\">Product\u003C/span> \u003Cspan class=\"nv\">$product\u003C/span>\u003Cspan class=\"p\">)\u003C/span>\n    \u003Cspan class=\"p\">{\u003C/span>\n        \u003Cspan class=\"k\">return\u003C/span> \u003Cspan class=\"nc\">Inertia\u003C/span>\u003Cspan class=\"o\">::\u003C/span>\u003Cspan class=\"nf\">render\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"s1\">'Products/Show'\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"p\">[\u003C/span>\n            \u003Cspan class=\"s1\">'product'\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"nv\">$product\u003C/span>\u003Cspan class=\"o\">-&gt;\u003C/span>\u003Cspan class=\"nf\">load\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"s1\">'reviews'\u003C/span>\u003Cspan class=\"p\">),\u003C/span>\n        \u003Cspan class=\"p\">]);\u003C/span>\n    \u003Cspan class=\"p\">}\u003C/span>\n\u003Cspan class=\"p\">}\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Cp>The matching React page component at \u003Ccode>resources/js/Pages/Products/Index.jsx\u003C/code>:\u003Cbr>\n\u003C/p>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight jsx\">\u003Ccode>\u003Cspan class=\"k\">export\u003C/span> \u003Cspan class=\"k\">default\u003C/span> \u003Cspan class=\"kd\">function\u003C/span> \u003Cspan class=\"nf\">Index\u003C/span>\u003Cspan class=\"p\">({\u003C/span> \u003Cspan class=\"nx\">products\u003C/span> \u003Cspan class=\"p\">})\u003C/span> \u003Cspan class=\"p\">{\u003C/span>\n    \u003Cspan class=\"k\">return \u003C/span>\u003Cspan class=\"p\">(\u003C/span>\n        \u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nt\">div\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\n            \u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nt\">h1\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>Products\u003Cspan class=\"p\">&lt;/\u003C/span>\u003Cspan class=\"nt\">h1\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\n            \u003Cspan class=\"si\">{\u003C/span>\u003Cspan class=\"nx\">products\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">data\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nf\">map\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"nx\">product\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"p\">(\u003C/span>\n                \u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nt\">div\u003C/span> \u003Cspan class=\"na\">key\u003C/span>\u003Cspan class=\"p\">=\u003C/span>\u003Cspan class=\"si\">{\u003C/span>\u003Cspan class=\"nx\">product\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">id\u003C/span>\u003Cspan class=\"si\">}\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\u003Cspan class=\"si\">{\u003C/span>\u003Cspan class=\"nx\">product\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">name\u003C/span>\u003Cspan class=\"si\">}\u003C/span>\u003Cspan class=\"p\">&lt;/\u003C/span>\u003Cspan class=\"nt\">div\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\n            \u003Cspan class=\"p\">))\u003C/span>\u003Cspan class=\"si\">}\u003C/span>\n        \u003Cspan class=\"p\">&lt;/\u003C/span>\u003Cspan class=\"nt\">div\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\n    \u003Cspan class=\"p\">);\u003C/span>\n\u003Cspan class=\"p\">}\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Cp>Props flow one way: controller → component. There is no need to define API endpoints, serializers, or fetch logic for standard page loads.\u003C/p>\n\n\n\u003Chr>\n\n\u003Ch2>\n  \u003Ca name=\"inertia-v2-features-worth-using\" href=\"#inertia-v2-features-worth-using\">\n  \u003C/a>\n  Inertia v2 Features Worth Using\n\u003C/h2>\n\n\u003Ch3>\n  \u003Ca name=\"deferred-props\" href=\"#deferred-props\">\n  \u003C/a>\n  Deferred Props\n\u003C/h3>\n\n\u003Cp>For data that is expensive to compute and not needed for the initial render:\u003Cbr>\n\u003C/p>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight php\">\u003Ccode>\u003Cspan class=\"c1\">// Controller\u003C/span>\n\u003Cspan class=\"k\">return\u003C/span> \u003Cspan class=\"nc\">Inertia\u003C/span>\u003Cspan class=\"o\">::\u003C/span>\u003Cspan class=\"nf\">render\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"s1\">'Dashboard'\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"p\">[\u003C/span>\n    \u003Cspan class=\"s1\">'user'\u003C/span>     \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"nv\">$user\u003C/span>\u003Cspan class=\"p\">,\u003C/span>\n    \u003Cspan class=\"s1\">'stats'\u003C/span>    \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"nc\">Inertia\u003C/span>\u003Cspan class=\"o\">::\u003C/span>\u003Cspan class=\"nf\">defer\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"k\">fn\u003C/span> \u003Cspan class=\"p\">()\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"nv\">$this\u003C/span>\u003Cspan class=\"o\">-&gt;\u003C/span>\u003Cspan class=\"nf\">getStats\u003C/span>\u003Cspan class=\"p\">()),\u003C/span>\n    \u003Cspan class=\"s1\">'activity'\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"nc\">Inertia\u003C/span>\u003Cspan class=\"o\">::\u003C/span>\u003Cspan class=\"nf\">defer\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"k\">fn\u003C/span> \u003Cspan class=\"p\">()\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"nv\">$this\u003C/span>\u003Cspan class=\"o\">-&gt;\u003C/span>\u003Cspan class=\"nf\">getActivity\u003C/span>\u003Cspan class=\"p\">(),\u003C/span> \u003Cspan class=\"s1\">'secondary'\u003C/span>\u003Cspan class=\"p\">),\u003C/span>\n\u003Cspan class=\"p\">]);\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight jsx\">\u003Ccode>\u003Cspan class=\"c1\">// React component\u003C/span>\n\u003Cspan class=\"k\">import\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"nx\">Deferred\u003C/span> \u003Cspan class=\"p\">}\u003C/span> \u003Cspan class=\"k\">from\u003C/span> \u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"s1\">@inertiajs/react\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"p\">;\u003C/span>\n\n\u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nc\">Deferred\u003C/span> \u003Cspan class=\"na\">data\u003C/span>\u003Cspan class=\"p\">=\u003C/span>\u003Cspan class=\"s\">\"stats\"\u003C/span> \u003Cspan class=\"na\">fallback\u003C/span>\u003Cspan class=\"p\">=\u003C/span>\u003Cspan class=\"si\">{\u003C/span>\u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nt\">p\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>Loading stats...\u003Cspan class=\"p\">&lt;/\u003C/span>\u003Cspan class=\"nt\">p\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\u003Cspan class=\"si\">}\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\n    \u003Cspan class=\"si\">{\u003C/span>\u003Cspan class=\"p\">({\u003C/span> \u003Cspan class=\"nx\">stats\u003C/span> \u003Cspan class=\"p\">})\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nc\">StatsChart\u003C/span> \u003Cspan class=\"na\">data\u003C/span>\u003Cspan class=\"p\">=\u003C/span>\u003Cspan class=\"si\">{\u003C/span>\u003Cspan class=\"nx\">stats\u003C/span>\u003Cspan class=\"si\">}\u003C/span> \u003Cspan class=\"p\">/&gt;\u003C/span>\u003Cspan class=\"si\">}\u003C/span>\n\u003Cspan class=\"p\">&lt;/\u003C/span>\u003Cspan class=\"nc\">Deferred\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Cp>\u003Ccode>stats\u003C/code> loads in a second request after the page renders. Props in the same group string (\u003Ccode>'secondary'\u003C/code>) are fetched in a single batched request.\u003C/p>\n\n\u003Ch3>\n  \u003Ca name=\"prefetching\" href=\"#prefetching\">\n  \u003C/a>\n  Prefetching\n\u003C/h3>\n\n\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight jsx\">\u003Ccode>\u003Cspan class=\"k\">import\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"nx\">Link\u003C/span> \u003Cspan class=\"p\">}\u003C/span> \u003Cspan class=\"k\">from\u003C/span> \u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"s1\">@inertiajs/react\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"p\">;\u003C/span>\n\n\u003Cspan class=\"c1\">// Prefetch after 75ms hover\u003C/span>\n\u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nc\">Link\u003C/span> \u003Cspan class=\"na\">href\u003C/span>\u003Cspan class=\"p\">=\u003C/span>\u003Cspan class=\"s\">\"/users\"\u003C/span> \u003Cspan class=\"na\">prefetch\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>Users\u003Cspan class=\"p\">&lt;/\u003C/span>\u003Cspan class=\"nc\">Link\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\n\n\u003Cspan class=\"c1\">// Prefetch on mount (useful for near-certain navigations)\u003C/span>\n\u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nc\">Link\u003C/span> \u003Cspan class=\"na\">href\u003C/span>\u003Cspan class=\"p\">=\u003C/span>\u003Cspan class=\"s\">\"/dashboard\"\u003C/span> \u003Cspan class=\"na\">prefetch\u003C/span>\u003Cspan class=\"p\">=\u003C/span>\u003Cspan class=\"s\">\"mount\"\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>Dashboard\u003Cspan class=\"p\">&lt;/\u003C/span>\u003Cspan class=\"nc\">Link\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\n\u003Chr>\n\n\u003Ch2>\n  \u003Ca name=\"inertia-v3-additions\" href=\"#inertia-v3-additions\">\n  \u003C/a>\n  Inertia v3 Additions\n\u003C/h2>\n\n\u003Ch3>\n  \u003Ca name=\"no-more-axios\" href=\"#no-more-axios\">\n  \u003C/a>\n  No More Axios\n\u003C/h3>\n\n\u003Cp>Inertia v3 ships its own built-in XHR client. Axios is no longer a required dependency, saving approximately 15 KB gzipped from your bundle. If you rely on Axios interceptors for token refresh or request logging, add Axios back as a peer dependency — but most projects do not need it.\u003C/p>\n\n\u003Ch3>\n  \u003Ca name=\"usehttp-for-nonnavigation-requests\" href=\"#usehttp-for-nonnavigation-requests\">\n  \u003C/a>\n  useHttp for Non-Navigation Requests\n\u003C/h3>\n\n\u003Cp>Inertia v3 introduces \u003Ccode>useHttp\u003C/code> for HTTP calls that should not trigger page navigation:\u003Cbr>\n\u003C/p>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight jsx\">\u003Ccode>\u003Cspan class=\"k\">import\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"nx\">useHttp\u003C/span> \u003Cspan class=\"p\">}\u003C/span> \u003Cspan class=\"k\">from\u003C/span> \u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"s1\">@inertiajs/react\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"p\">;\u003C/span>\n\n\u003Cspan class=\"kd\">function\u003C/span> \u003Cspan class=\"nf\">SubscribeForm\u003C/span>\u003Cspan class=\"p\">()\u003C/span> \u003Cspan class=\"p\">{\u003C/span>\n    \u003Cspan class=\"kd\">const\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"nx\">post\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"nx\">processing\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"nx\">errors\u003C/span> \u003Cspan class=\"p\">}\u003C/span> \u003Cspan class=\"o\">=\u003C/span> \u003Cspan class=\"nf\">useHttp\u003C/span>\u003Cspan class=\"p\">();\u003C/span>\n\n    \u003Cspan class=\"kd\">const\u003C/span> \u003Cspan class=\"nx\">submit\u003C/span> \u003Cspan class=\"o\">=\u003C/span> \u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"nx\">e\u003C/span>\u003Cspan class=\"p\">)\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"p\">{\u003C/span>\n        \u003Cspan class=\"nx\">e\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nf\">preventDefault\u003C/span>\u003Cspan class=\"p\">();\u003C/span>\n        \u003Cspan class=\"nf\">post\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"s1\">/subscribe\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"na\">email\u003C/span>\u003Cspan class=\"p\">:\u003C/span> \u003Cspan class=\"nx\">e\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">target\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">email\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">value\u003C/span> \u003Cspan class=\"p\">});\u003C/span>\n    \u003Cspan class=\"p\">};\u003C/span>\n\n    \u003Cspan class=\"k\">return \u003C/span>\u003Cspan class=\"p\">(\u003C/span>\n        \u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nt\">form\u003C/span> \u003Cspan class=\"na\">onSubmit\u003C/span>\u003Cspan class=\"p\">=\u003C/span>\u003Cspan class=\"si\">{\u003C/span>\u003Cspan class=\"nx\">submit\u003C/span>\u003Cspan class=\"si\">}\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\n            \u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nt\">input\u003C/span> \u003Cspan class=\"na\">name\u003C/span>\u003Cspan class=\"p\">=\u003C/span>\u003Cspan class=\"s\">\"email\"\u003C/span> \u003Cspan class=\"na\">type\u003C/span>\u003Cspan class=\"p\">=\u003C/span>\u003Cspan class=\"s\">\"email\"\u003C/span> \u003Cspan class=\"p\">/&gt;\u003C/span>\n            \u003Cspan class=\"si\">{\u003C/span>\u003Cspan class=\"nx\">errors\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">email\u003C/span> \u003Cspan class=\"o\">&amp;&amp;\u003C/span> \u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nt\">p\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\u003Cspan class=\"si\">{\u003C/span>\u003Cspan class=\"nx\">errors\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">email\u003C/span>\u003Cspan class=\"si\">}\u003C/span>\u003Cspan class=\"p\">&lt;/\u003C/span>\u003Cspan class=\"nt\">p\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\u003Cspan class=\"si\">}\u003C/span>\n            \u003Cspan class=\"p\">&lt;\u003C/span>\u003Cspan class=\"nt\">button\u003C/span> \u003Cspan class=\"na\">disabled\u003C/span>\u003Cspan class=\"p\">=\u003C/span>\u003Cspan class=\"si\">{\u003C/span>\u003Cspan class=\"nx\">processing\u003C/span>\u003Cspan class=\"si\">}\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>Subscribe\u003Cspan class=\"p\">&lt;/\u003C/span>\u003Cspan class=\"nt\">button\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\n        \u003Cspan class=\"p\">&lt;/\u003C/span>\u003Cspan class=\"nt\">form\u003C/span>\u003Cspan class=\"p\">&gt;\u003C/span>\n    \u003Cspan class=\"p\">);\u003C/span>\n\u003Cspan class=\"p\">}\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Ch3>\n  \u003Ca name=\"optimistic-updates\" href=\"#optimistic-updates\">\n  \u003C/a>\n  Optimistic Updates\n\u003C/h3>\n\n\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight jsx\">\u003Ccode>\u003Cspan class=\"k\">import\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"nx\">router\u003C/span> \u003Cspan class=\"p\">}\u003C/span> \u003Cspan class=\"k\">from\u003C/span> \u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"s1\">@inertiajs/react\u003C/span>\u003Cspan class=\"dl\">'\u003C/span>\u003Cspan class=\"p\">;\u003C/span>\n\n\u003Cspan class=\"kd\">function\u003C/span> \u003Cspan class=\"nf\">toggleTodo\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"nx\">id\u003C/span>\u003Cspan class=\"p\">)\u003C/span> \u003Cspan class=\"p\">{\u003C/span>\n    \u003Cspan class=\"nx\">router\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nf\">patch\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"s2\">`/todos/\u003C/span>\u003Cspan class=\"p\">${\u003C/span>\u003Cspan class=\"nx\">id\u003C/span>\u003Cspan class=\"p\">}\u003C/span>\u003Cspan class=\"s2\">`\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"na\">completed\u003C/span>\u003Cspan class=\"p\">:\u003C/span> \u003Cspan class=\"kc\">true\u003C/span> \u003Cspan class=\"p\">},\u003C/span> \u003Cspan class=\"p\">{\u003C/span>\n        \u003Cspan class=\"na\">optimistic\u003C/span>\u003Cspan class=\"p\">:\u003C/span> \u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"nx\">page\u003C/span>\u003Cspan class=\"p\">)\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"p\">{\u003C/span>\n            \u003Cspan class=\"nx\">page\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">props\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">todos\u003C/span> \u003Cspan class=\"o\">=\u003C/span> \u003Cspan class=\"nx\">page\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">props\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">todos\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nf\">map\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"nx\">t\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span>\n                \u003Cspan class=\"nx\">t\u003C/span>\u003Cspan class=\"p\">.\u003C/span>\u003Cspan class=\"nx\">id\u003C/span> \u003Cspan class=\"o\">===\u003C/span> \u003Cspan class=\"nx\">id\u003C/span> \u003Cspan class=\"p\">?\u003C/span> \u003Cspan class=\"p\">{\u003C/span> \u003Cspan class=\"p\">...\u003C/span>\u003Cspan class=\"nx\">t\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"na\">completed\u003C/span>\u003Cspan class=\"p\">:\u003C/span> \u003Cspan class=\"kc\">true\u003C/span> \u003Cspan class=\"p\">}\u003C/span> \u003Cspan class=\"p\">:\u003C/span> \u003Cspan class=\"nx\">t\u003C/span>\n            \u003Cspan class=\"p\">);\u003C/span>\n        \u003Cspan class=\"p\">},\u003C/span>\n    \u003Cspan class=\"p\">});\u003C/span>\n    \u003Cspan class=\"c1\">// If the server returns a non-2xx response, the optimistic change is automatically rolled back\u003C/span>\n\u003Cspan class=\"p\">}\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Ch3>\n  \u003Ca name=\"esmonly-output\" href=\"#esmonly-output\">\n  \u003C/a>\n  ESM-Only Output\n\u003C/h3>\n\n\u003Cp>Inertia v3 packages are ESM only. CommonJS \u003Ccode>require('@inertiajs/react')\u003C/code> will break. Ensure your Vite config does not force CJS output.\u003C/p>\n\n\n\u003Chr>\n\n\u003Ch2>\n  \u003Ca name=\"csrf-and-auth\" href=\"#csrf-and-auth\">\n  \u003C/a>\n  CSRF and Auth\n\u003C/h2>\n\n\u003Cp>Inertia handles CSRF transparently when used with Laravel. The \u003Ccode>HandleInertiaRequests\u003C/code> middleware automatically shares the CSRF token, and Inertia's client attaches it to every request. You do not need to manually include \u003Ccode>_token\u003C/code> in form submissions.\u003C/p>\n\n\u003Cp>A token mismatch produces a \u003Ccode>419\u003C/code> response. Common cause: the session has expired between page load and form submission. Handle this in the Inertia response handler by redirecting to a re-login page.\u003C/p>\n\n\n\u003Chr>\n\n\u003Ch2>\n  \u003Ca name=\"common-mistakes\" href=\"#common-mistakes\">\n  \u003C/a>\n  Common Mistakes\n\u003C/h2>\n\n\u003Cp>\u003Cstrong>Passing Eloquent models with too many fields.\u003C/strong> Every prop you pass is serialized to JSON and embedded in the page. Use API resources or \u003Ccode>-&gt;only()\u003C/code> to limit what leaves the server:\u003Cbr>\n\u003C/p>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight php\">\u003Ccode>\u003Cspan class=\"c1\">// Avoid\u003C/span>\n\u003Cspan class=\"s1\">'product'\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"nv\">$product\u003C/span>\u003Cspan class=\"p\">,\u003C/span>\n\n\u003Cspan class=\"c1\">// Prefer\u003C/span>\n\u003Cspan class=\"s1\">'product'\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"nv\">$product\u003C/span>\u003Cspan class=\"o\">-&gt;\u003C/span>\u003Cspan class=\"nf\">only\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"s1\">'id'\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"s1\">'name'\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"s1\">'price'\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"s1\">'slug'\u003C/span>\u003Cspan class=\"p\">),\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Cp>\u003Cstrong>Choosing Inertia for CRUD-heavy admin panels without React/Vue expertise.\u003C/strong> Inertia adds a JavaScript build step, component structure, and client-side state management overhead. If your team is PHP-native and the UI is primarily forms and tables, Livewire 4 will ship faster with less complexity.\u003C/p>\n\n\u003Cp>\u003Cstrong>Forgetting that Inertia v3 requires Laravel 11.\u003C/strong> Upgrading the npm packages without checking the server adapter version will break the app silently.\u003C/p>\n\n\u003Cp>\u003Cstrong>Using \u003Ccode>router.visit()\u003C/code> for everything.\u003C/strong> Inertia's \u003Ccode>router.visit()\u003C/code> triggers a full Inertia page visit including scroll reset and component remount. For in-page data mutations (toggle, delete, update), use \u003Ccode>router.patch()\u003C/code>, \u003Ccode>router.put()\u003C/code>, or \u003Ccode>router.delete()\u003C/code> — these preserve the current page component and merge updated props.\u003C/p>\n\n\u003Cp>\u003Cstrong>No shared data caching.\u003C/strong> The \u003Ccode>HandleInertiaRequests\u003C/code> middleware \u003Ccode>share()\u003C/code> method runs on every request. Avoid expensive queries there. Cache shared data (authenticated user, permissions, navigation items) in the session or a short-lived cache.\u003C/p>\n\n\n\u003Chr>\n\n\u003Ch2>\n  \u003Ca name=\"when-inertia-makes-sense-and-when-it-does-not\" href=\"#when-inertia-makes-sense-and-when-it-does-not\">\n  \u003C/a>\n  When Inertia Makes Sense (and When It Does Not)\n\u003C/h2>\n\n\u003Cdiv class=\"table-wrapper-paragraph\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Use Inertia when\u003C/th>\n\u003Cth>Prefer Livewire when\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Your team knows React or Vue\u003C/td>\n\u003Ctd>Your team is primarily PHP\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>You need complex client-side state\u003C/td>\n\u003Ctd>The UI is mostly forms and lists\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>You want the full npm ecosystem\u003C/td>\n\u003Ctd>You want minimal JS tooling\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>You have rich data visualizations\u003C/td>\n\u003Ctd>You are building an admin panel\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>You need SSR for public pages\u003C/td>\n\u003Ctd>Server-round-trip latency is acceptable\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\u003C/div>\n\n\u003Cp>Inertia is the \"modern monolith\" pattern: you keep Laravel's routing, auth, and data layer, but your frontend developers work in React or Vue with full HMR, TypeScript support, and component tooling — without maintaining a separate SPA deployment.\u003C/p>\n\n\n\u003Chr>\n\n\u003Ch2>\n  \u003Ca name=\"verifying-the-setup\" href=\"#verifying-the-setup\">\n  \u003C/a>\n  Verifying the Setup\n\u003C/h2>\n\n\u003Cp>After scaffolding, confirm Inertia is wiring correctly:\u003Cbr>\n\u003C/p>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight shell\">\u003Ccode>\u003Cspan class=\"c\"># Run the Laravel dev server\u003C/span>\nphp artisan serve\n\n\u003Cspan class=\"c\"># In a second terminal, run Vite\u003C/span>\nnpm run dev\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\u003Cp>Open the browser DevTools Network tab. Navigate between pages using \u003Ccode>&lt;Link&gt;\u003C/code> components. Subsequent navigations should show XHR requests returning \u003Ccode>application/json\u003C/code> with a \u003Ccode>X-Inertia: true\u003C/code> response header — not full HTML. If you see full HTML on every navigation, the \u003Ccode>HandleInertiaRequests\u003C/code> middleware is not registered.\u003C/p>\n\n\u003Cp>For automated testing, use Inertia's test helpers:\u003Cbr>\n\u003C/p>\n\n\u003Cdiv class=\"highlight js-code-highlight\">\n\u003Cpre class=\"highlight php\">\u003Ccode>\u003Cspan class=\"kn\">use\u003C/span> \u003Cspan class=\"nc\">Inertia\\Testing\\AssertableInertia\u003C/span> \u003Cspan class=\"k\">as\u003C/span> \u003Cspan class=\"nc\">Assert\u003C/span>\u003Cspan class=\"p\">;\u003C/span>\n\n\u003Cspan class=\"nf\">test\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"s1\">'products index renders correctly'\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"k\">function\u003C/span> \u003Cspan class=\"p\">()\u003C/span> \u003Cspan class=\"p\">{\u003C/span>\n    \u003Cspan class=\"nv\">$this\u003C/span>\u003Cspan class=\"o\">-&gt;\u003C/span>\u003Cspan class=\"nf\">get\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"s1\">'/products'\u003C/span>\u003Cspan class=\"p\">)\u003C/span>\n        \u003Cspan class=\"o\">-&gt;\u003C/span>\u003Cspan class=\"nf\">assertInertia\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"k\">fn\u003C/span> \u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"kt\">Assert\u003C/span> \u003Cspan class=\"nv\">$page\u003C/span>\u003Cspan class=\"p\">)\u003C/span> \u003Cspan class=\"o\">=&gt;\u003C/span> \u003Cspan class=\"nv\">$page\u003C/span>\n            \u003Cspan class=\"o\">-&gt;\u003C/span>\u003Cspan class=\"nf\">component\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"s1\">'Products/Index'\u003C/span>\u003Cspan class=\"p\">)\u003C/span>\n            \u003Cspan class=\"o\">-&gt;\u003C/span>\u003Cspan class=\"nf\">has\u003C/span>\u003Cspan class=\"p\">(\u003C/span>\u003Cspan class=\"s1\">'products.data'\u003C/span>\u003Cspan class=\"p\">,\u003C/span> \u003Cspan class=\"mi\">20\u003C/span>\u003Cspan class=\"p\">)\u003C/span>\n        \u003Cspan class=\"p\">);\u003C/span>\n\u003Cspan class=\"p\">});\u003C/span>\n\u003C/code>\u003C/pre>\n\u003Cdiv class=\"highlight__panel js-actions-panel\">\n\u003Cdiv class=\"highlight__panel-action js-fullscreen-code-action\">\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\">\u003Ctitle>Enter fullscreen mode\u003C/title>\n    \u003Cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\">\u003C/path>\n\u003C/svg>\n\n    \u003Csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\">\u003Ctitle>Exit fullscreen mode\u003C/title>\n    \u003Cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\">\u003C/path>\n\u003C/svg>\n\n\u003C/div>\n\u003C/div>\n\u003C/div>\n\n\n\n\n\u003Chr>\n\n\u003Cp>If you need Laravel development in Mumbai, \u003Ca href=\"https://mumbaiwebdesigner.com/services/laravel-development-mumbai\" target=\"_blank\" rel=\"noopener noreferrer\">Mumbai Web Designer\u003C/a> builds production-grade Laravel applications.\u003C/p>\n\n","# Laravel with React or Vue through Inertia\n\nIf you've spent time with Laravel and wondered how to use React or Vue without abandoning the monolith, Inertia.js is the answer. It bridges the gap between a server-driven Laravel backend and a client-rendered component frontend — no separate API, no JSON contract negotiation, no duplicated routing layer.\n\nThis article focuses on the practical setup: how Inertia actually works, how to scaffold it with React or Vue, and where it makes sense compared to going full-SPA or staying with Blade.\n\n---\n\n## Prerequisites and Versions\n\nBefore starting, confirm your stack:\n\n- **Laravel 11 or 12** — required for the Inertia Laravel adapter v3\n- **Inertia.js v3.0.0** (stable since March 25, 2026) — current default\n- **Inertia.js v2.x** — still supported; official Laravel starter kits ship with v2\n- **React 19** or **Vue 3** — both work with Inertia v2 and v3\n- **Node.js 20+** and **Vite** for the frontend build pipeline\n- **Composer** and **pnpm** (or npm)\n\nIf you are on Laravel 10, you are capped at Inertia adapter v2. The v3 adapter requires Laravel 11 minimum.\n\n---\n\n## How Inertia.js Works (The Mental Model)\n\nInertia is not a UI framework. It is a protocol adapter that sits between Laravel controllers and React/Vue components.\n\nOn a full-page load, Laravel renders an HTML shell with a single `\u003Cdiv id=\"app\">` that contains a JSON payload in a `data-page` attribute. Inertia's client-side adapter bootstraps React or Vue, reads that payload, and renders the correct page component.\n\nOn subsequent navigations, clicking an `\u003CLink>` component triggers a fetch request with an `X-Inertia: true` header. Laravel detects this header and returns only JSON — the component name and its props — instead of a full HTML page. The client swaps the component without a full browser reload.\n\nThe result: your Laravel routes, controllers, and auth middleware work exactly as they always did. Your frontend developers get full React or Vue components with props typed exactly as the controller passes them.\n\n---\n\n## Scaffolding a New Project\n\n### Option A — Official Laravel Starter Kit (Fastest)\n\n```bash\n# React 19 + Inertia 2 + Tailwind 4 + shadcn/ui\nlaravel new my-app --react\n\n# Vue 3 + Inertia 2 + Tailwind 4\nlaravel new my-app --vue\n```\n\nNote: as of mid-2026, the official starter kits ship with Inertia **v2**, not v3. Inertia v3 must be manually upgraded after scaffolding if needed.\n\n### Option B — Breeze with Inertia Stack\n\n```bash\ncomposer require laravel/breeze --dev\nphp artisan breeze:install react\n# or\nphp artisan breeze:install vue\n\nnpm install\nnpm run dev\n```\n\nBreeze installs authentication scaffolding (login, register, password reset) wired through Inertia pages. It's a solid starting point for applications that need auth out of the box.\n\n### Option C — Manual Inertia Install\n\nFor projects where you need fine-grained control:\n\n```bash\n# Server side\ncomposer require inertiajs/inertia-laravel\n\n# Publish middleware\nphp artisan inertia:middleware\n# Register HandleInertiaRequests in bootstrap/app.php\n\n# Client side — React\nnpm install @inertiajs/react react react-dom\n\n# Or Vue\nnpm install @inertiajs/vue3 vue\n```\n\n**Root template** (`resources/views/app.blade.php`):\n\n```html\n\u003C!DOCTYPE html>\n\u003Chtml>\n\u003Chead>\n    @viteReactRefresh {{-- React only --}}\n    @vite(['resources/js/app.jsx', 'resources/css/app.css'])\n    @inertiaHead\n\u003C/head>\n\u003Cbody>\n    @inertia\n\u003C/body>\n\u003C/html>\n```\n\n**React entrypoint** (`resources/js/app.jsx`):\n\n```jsx\nimport { createInertiaApp } from '@inertiajs/react';\nimport { createRoot } from 'react-dom/client';\n\ncreateInertiaApp({\n    resolve: name => {\n        const pages = import.meta.glob('./Pages/**/*.jsx', { eager: true });\n        return pages[`./Pages/${name}.jsx`];\n    },\n    setup({ el, App, props }) {\n        createRoot(el).render(\u003CApp {...props} />);\n    },\n});\n```\n\n**Vue entrypoint** (`resources/js/app.js`):\n\n```js\nimport { createApp, h } from 'vue';\nimport { createInertiaApp } from '@inertiajs/vue3';\n\ncreateInertiaApp({\n    resolve: name => {\n        const pages = import.meta.glob('./Pages/**/*.vue', { eager: true });\n        return pages[`./Pages/${name}.vue`];\n    },\n    setup({ el, App, props, plugin }) {\n        createApp({ render: () => h(App, props) })\n            .use(plugin)\n            .mount(el);\n    },\n});\n```\n\n---\n\n## Writing Controllers and Page Components\n\nA Laravel controller renders an Inertia page the same way it would render a Blade view — with one method call:\n\n```php\nuse Inertia\\Inertia;\n\nclass ProductController extends Controller\n{\n    public function index()\n    {\n        return Inertia::render('Products/Index', [\n            'products' => Product::latest()->paginate(20),\n        ]);\n    }\n\n    public function show(Product $product)\n    {\n        return Inertia::render('Products/Show', [\n            'product' => $product->load('reviews'),\n        ]);\n    }\n}\n```\n\nThe matching React page component at `resources/js/Pages/Products/Index.jsx`:\n\n```jsx\nexport default function Index({ products }) {\n    return (\n        \u003Cdiv>\n            \u003Ch1>Products\u003C/h1>\n            {products.data.map(product => (\n                \u003Cdiv key={product.id}>{product.name}\u003C/div>\n            ))}\n        \u003C/div>\n    );\n}\n```\n\nProps flow one way: controller → component. There is no need to define API endpoints, serializers, or fetch logic for standard page loads.\n\n---\n\n## Inertia v2 Features Worth Using\n\n### Deferred Props\n\nFor data that is expensive to compute and not needed for the initial render:\n\n```php\n// Controller\nreturn Inertia::render('Dashboard', [\n    'user'     => $user,\n    'stats'    => Inertia::defer(fn () => $this->getStats()),\n    'activity' => Inertia::defer(fn () => $this->getActivity(), 'secondary'),\n]);\n```\n\n```jsx\n// React component\nimport { Deferred } from '@inertiajs/react';\n\n\u003CDeferred data=\"stats\" fallback={\u003Cp>Loading stats...\u003C/p>}>\n    {({ stats }) => \u003CStatsChart data={stats} />}\n\u003C/Deferred>\n```\n\n`stats` loads in a second request after the page renders. Props in the same group string (`'secondary'`) are fetched in a single batched request.\n\n### Prefetching\n\n```jsx\nimport { Link } from '@inertiajs/react';\n\n// Prefetch after 75ms hover\n\u003CLink href=\"/users\" prefetch>Users\u003C/Link>\n\n// Prefetch on mount (useful for near-certain navigations)\n\u003CLink href=\"/dashboard\" prefetch=\"mount\">Dashboard\u003C/Link>\n```\n\n---\n\n## Inertia v3 Additions\n\n### No More Axios\n\nInertia v3 ships its own built-in XHR client. Axios is no longer a required dependency, saving approximately 15 KB gzipped from your bundle. If you rely on Axios interceptors for token refresh or request logging, add Axios back as a peer dependency — but most projects do not need it.\n\n### useHttp for Non-Navigation Requests\n\nInertia v3 introduces `useHttp` for HTTP calls that should not trigger page navigation:\n\n```jsx\nimport { useHttp } from '@inertiajs/react';\n\nfunction SubscribeForm() {\n    const { post, processing, errors } = useHttp();\n\n    const submit = (e) => {\n        e.preventDefault();\n        post('/subscribe', { email: e.target.email.value });\n    };\n\n    return (\n        \u003Cform onSubmit={submit}>\n            \u003Cinput name=\"email\" type=\"email\" />\n            {errors.email && \u003Cp>{errors.email}\u003C/p>}\n            \u003Cbutton disabled={processing}>Subscribe\u003C/button>\n        \u003C/form>\n    );\n}\n```\n\n### Optimistic Updates\n\n```jsx\nimport { router } from '@inertiajs/react';\n\nfunction toggleTodo(id) {\n    router.patch(`/todos/${id}`, { completed: true }, {\n        optimistic: (page) => {\n            page.props.todos = page.props.todos.map(t =>\n                t.id === id ? { ...t, completed: true } : t\n            );\n        },\n    });\n    // If the server returns a non-2xx response, the optimistic change is automatically rolled back\n}\n```\n\n### ESM-Only Output\n\nInertia v3 packages are ESM only. CommonJS `require('@inertiajs/react')` will break. Ensure your Vite config does not force CJS output.\n\n---\n\n## CSRF and Auth\n\nInertia handles CSRF transparently when used with Laravel. The `HandleInertiaRequests` middleware automatically shares the CSRF token, and Inertia's client attaches it to every request. You do not need to manually include `_token` in form submissions.\n\nA token mismatch produces a `419` response. Common cause: the session has expired between page load and form submission. Handle this in the Inertia response handler by redirecting to a re-login page.\n\n---\n\n## Common Mistakes\n\n**Passing Eloquent models with too many fields.** Every prop you pass is serialized to JSON and embedded in the page. Use API resources or `->only()` to limit what leaves the server:\n\n```php\n// Avoid\n'product' => $product,\n\n// Prefer\n'product' => $product->only('id', 'name', 'price', 'slug'),\n```\n\n**Choosing Inertia for CRUD-heavy admin panels without React/Vue expertise.** Inertia adds a JavaScript build step, component structure, and client-side state management overhead. If your team is PHP-native and the UI is primarily forms and tables, Livewire 4 will ship faster with less complexity.\n\n**Forgetting that Inertia v3 requires Laravel 11.** Upgrading the npm packages without checking the server adapter version will break the app silently.\n\n**Using `router.visit()` for everything.** Inertia's `router.visit()` triggers a full Inertia page visit including scroll reset and component remount. For in-page data mutations (toggle, delete, update), use `router.patch()`, `router.put()`, or `router.delete()` — these preserve the current page component and merge updated props.\n\n**No shared data caching.** The `HandleInertiaRequests` middleware `share()` method runs on every request. Avoid expensive queries there. Cache shared data (authenticated user, permissions, navigation items) in the session or a short-lived cache.\n\n---\n\n## When Inertia Makes Sense (and When It Does Not)\n\n| Use Inertia when | Prefer Livewire when |\n|---|---|\n| Your team knows React or Vue | Your team is primarily PHP |\n| You need complex client-side state | The UI is mostly forms and lists |\n| You want the full npm ecosystem | You want minimal JS tooling |\n| You have rich data visualizations | You are building an admin panel |\n| You need SSR for public pages | Server-round-trip latency is acceptable |\n\nInertia is the \"modern monolith\" pattern: you keep Laravel's routing, auth, and data layer, but your frontend developers work in React or Vue with full HMR, TypeScript support, and component tooling — without maintaining a separate SPA deployment.\n\n---\n\n## Verifying the Setup\n\nAfter scaffolding, confirm Inertia is wiring correctly:\n\n```bash\n# Run the Laravel dev server\nphp artisan serve\n\n# In a second terminal, run Vite\nnpm run dev\n```\n\nOpen the browser DevTools Network tab. Navigate between pages using `\u003CLink>` components. Subsequent navigations should show XHR requests returning `application/json` with a `X-Inertia: true` response header — not full HTML. If you see full HTML on every navigation, the `HandleInertiaRequests` middleware is not registered.\n\nFor automated testing, use Inertia's test helpers:\n\n```php\nuse Inertia\\Testing\\AssertableInertia as Assert;\n\ntest('products index renders correctly', function () {\n    $this->get('/products')\n        ->assertInertia(fn (Assert $page) => $page\n            ->component('Products/Index')\n            ->has('products.data', 20)\n        );\n});\n```\n\n---\n\nIf you need Laravel development in Mumbai, [Mumbai Web Designer](https://mumbaiwebdesigner.com/services/laravel-development-mumbai) builds production-grade Laravel applications.",{"name":31,"username":32,"twitter_username":13,"github_username":13,"user_id":33,"website_url":13,"profile_image":34,"profile_image_90":35},"Sumeet Shroff","mumbai_web_designer",3983179,"https://media2.dev.to/dynamic/image/width=640,height=640,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3983179%2F2edf10ed-7d57-4ac5-987f-d8afa268d641.png","https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3983179%2F2edf10ed-7d57-4ac5-987f-d8afa268d641.png",1788921586549]