How to Use Inertia.js with Laravel: A Simple Guide for Beginners
Imagine building a super-fast website that feels like a mobile app, but you don't need to learn complicated APIs or extra tools! That's exactly what Inertia.js helps you do. In this guide, we'll learn how to connect Laravel (the backend) with React, Vue, or Svelte (the frontend) using Inertia.js. Even if you're just starting out in web development, this tutorial will make everything clear and simple!

What is Inertia.js? (Explained Simply)
Think of Inertia.js as a bridge between your Laravel backend and your React/Vue frontend. Normally, when you want to build a modern website with Laravel and React, you'd need to:
- Create a separate API (like a restaurant menu that lists all available dishes)
- Write extra code to send data back and forth
- Handle authentication twice (once in Laravel, once in React)
With Inertia.js, you don't need any of that! It lets you build modern websites using Laravel for routing and controllers (like you normally would), but renders your pages using React, Vue, or Svelte components. It's like having the best of both worlds! 🎉
🎯 Real-Life Example:
Imagine you're building a school website. With Inertia.js, your Laravel backend handles everything (student login, fetching grades, saving homework), and your React frontend makes it look beautiful and interactive—all without building a separate API!
Why Should You Use Inertia.js?
Here are the awesome benefits of using Inertia.js:
✅ No API Needed
You don't have to create RESTful or GraphQL APIs. Inertia handles communication for you!
⚡ Super Fast
Pages load instantly because only the data changes, not the whole page.
🔒 One Authentication System
Use Laravel's built-in authentication. No need to duplicate login logic in React.
📱 SPA Feel
Your website feels like a mobile app with smooth page transitions.
What You Need Before Starting
Before we begin, make sure you have these installed on your computer:
- PHP 8.2+ (Laravel's language)
- Composer (PHP package manager - like a app store for PHP tools)
- Node.js & NPM (JavaScript package manager - for React/Vue)
- MySQL or any database (to store your data)
- A code editor like VS Code
Don't worry if you don't understand everything yet. Just make sure these are installed!
Step 1: Create a New Laravel Project
First, let's create a fresh Laravel project. Open your terminal (command prompt) and type this command:
composer create-project laravel/laravel inertia-appThis creates a folder called inertia-app with all Laravel files inside. Think of it like creating a new folder for your school project! 📁
Now, go into that folder:
cd inertia-appStep 2: Install Inertia.js in Laravel (Server-Side)
Now we need to add Inertia.js to our Laravel project. Run this command:
composer require inertiajs/inertia-laravelWhat does this do? This command installs the Inertia package for Laravel. It's like adding a special tool to your toolbox that helps Laravel talk to React or Vue.
Create the Root Template
Inertia needs one main HTML file that will load your React/Vue components. Let's create it! Go to resources/views folder and create a file called app.blade.php:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My Inertia App</title>
<!-- Load our CSS and JavaScript files -->
@vite(['resources/css/app.css', 'resources/js/app.jsx'])
@inertiaHead
</head>
<body>
@inertia
</body>
</html>Think of this like: This is your website's main container. The @inertia part is like a magic box where all your React/Vue pages will appear!
Set Up Inertia Middleware
Middleware is like a security guard that checks things before they enter your website. Let's publish Inertia's middleware:
php artisan inertia:middlewareNow open bootstrap/app.php and add the middleware to the web group:
use App\Http\Middleware\HandleInertiaRequests;
return Application::configure(basePath: dirname(__DIR__))
->withRouting(
web: __DIR__.'/../routes/web.php',
commands: __DIR__.'/../routes/console.php',
health: '/up',
)
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [
HandleInertiaRequests::class,
]);
})
->withExceptions(function (Exceptions $exceptions) {
//
})->create();Step 3: Install Inertia.js for React (Client-Side)
Now let's add Inertia to the React side! We'll use React in this example, but you can also use Vue or Svelte.
npm install @inertiajs/react react react-domWhat's happening? This installs React and the Inertia React adapter. It's like downloading apps on your phone—these are the tools React needs to work with Inertia!
Install Vite Plugin
Vite is a tool that bundles your JavaScript code. We need the Inertia plugin for it:
npm install @vitejs/plugin-reactConfigure Vite
Open vite.config.js and update it:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [
laravel({
input: ['resources/css/app.css', 'resources/js/app.jsx'],
refresh: true,
}),
react(),
],
});Step 4: Set Up Your React Application
Now let's create the main React file that will connect everything together. Go to resources/js and rename app.js to app.jsx, then replace its content with:
import { createRoot } from 'react-dom/client';
import { createInertiaApp } from '@inertiajs/react';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
createInertiaApp({
// This tells Inertia where to find your React page components
resolve: (name) =>
resolvePageComponent(
`./Pages/${name}.jsx`,
import.meta.glob('./Pages/**/*.jsx')
),
// This sets up your app
setup({ el, App, props }) {
createRoot(el).render(<App {...props} />);
},
});Simple explanation: This code tells React: "Hey, when someone visits a page, look in the Pages folder for the matching component and show it!"
Step 5: Create Your First React Page Component
Let's create a simple homepage! Create a new folder: resources/js/Pages, then inside it, create Home.jsx:
import React from 'react';
import { Head, Link } from '@inertiajs/react';
export default function Home({ message, userName }) {
return (
<>
<Head title="Welcome to Inertia.js" />
<div className="min-h-screen bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center">
<div className="bg-white rounded-lg shadow-2xl p-8 max-w-md">
<h1 className="text-4xl font-bold text-gray-800 mb-4">
🎉 {message}
</h1>
<p className="text-xl text-gray-600 mb-6">
Hello, <strong>{userName}</strong>! Welcome to your first Inertia.js app!
</p>
<Link
href="/about"
className="bg-blue-500 text-white px-6 py-3 rounded-lg hover:bg-blue-600 transition"
>
Go to About Page →
</Link>
</div>
</div>
</>
);
}What's special here? Notice how we receive message and userName as props? These come directly from Laravel! Also, the Link component makes navigation super smooth without page reloads.
Step 6: Create Laravel Routes and Controllers
Now let's tell Laravel: "When someone visits the homepage, show them the Home component." Open routes/web.php:
<?php
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
// Home page route
Route::get('/', function () {
return Inertia::render('Home', [
'message' => 'Welcome to Inertia.js!',
'userName' => 'Student',
]);
});
// About page route
Route::get('/about', function () {
return Inertia::render('About', [
'title' => 'About Us',
'description' => 'This is a simple Inertia.js application built with Laravel and React!',
]);
});See what happened? Inertia::render('Home', [...]) tells Laravel: "Render the Home.jsx component and send this data to it." No API needed! 🚀
Create the About Page
Let's create resources/js/Pages/About.jsx:
import React from 'react';
import { Head, Link } from '@inertiajs/react';
export default function About({ title, description }) {
return (
<>
<Head title={title} />
<div className="min-h-screen bg-gradient-to-br from-green-500 to-teal-600 flex items-center justify-center">
<div className="bg-white rounded-lg shadow-2xl p-8 max-w-md">
<h1 className="text-3xl font-bold text-gray-800 mb-4">
{title}
</h1>
<p className="text-lg text-gray-600 mb-6">
{description}
</p>
<Link
href="/"
className="bg-green-500 text-white px-6 py-3 rounded-lg hover:bg-green-600 transition"
>
← Back to Home
</Link>
</div>
</div>
</>
);
}Step 7: Run Your Application
Time to see your app in action! Open two terminal windows:
Terminal 1: Start Laravel Server
php artisan serveThis runs your Laravel backend at http://localhost:8000
Terminal 2: Start Vite Dev Server
npm run devThis watches your React files and automatically updates when you make changes. It's like having a helper that rebuilds your code instantly!
🎊 Congratulations!
Open your browser and visit http://localhost:8000. You should see your beautiful homepage! Try clicking the "About" link—notice how the page changes smoothly without reloading? That's Inertia.js magic! ✨
Step 8: Working with Forms in Inertia.js
Let's learn how to submit forms! Inertia makes this super easy. Create a new page resources/js/Pages/Contact.jsx:
import React from 'react';
import { Head, useForm } from '@inertiajs/react';
export default function Contact() {
// useForm hook manages form state for us
const { data, setData, post, processing, errors } = useForm({
name: '',
email: '',
message: '',
});
const handleSubmit = (e) => {
e.preventDefault();
// This sends data to Laravel without page reload!
post('/contact');
};
return (
<>
<Head title="Contact Us" />
<div className="min-h-screen bg-gray-100 py-12 px-4">
<div className="max-w-md mx-auto bg-white rounded-lg shadow-md p-8">
<h1 className="text-3xl font-bold mb-6">Contact Us</h1>
<form onSubmit={handleSubmit}>
<div className="mb-4">
<label className="block text-gray-700 mb-2">Name:</label>
<input
type="text"
value={data.name}
onChange={e => setData('name', e.target.value)}
className="w-full border border-gray-300 rounded px-4 py-2"
/>
{errors.name && (
<p className="text-red-500 text-sm mt-1">{errors.name}</p>
)}
</div>
<div className="mb-4">
<label className="block text-gray-700 mb-2">Email:</label>
<input
type="email"
value={data.email}
onChange={e => setData('email', e.target.value)}
className="w-full border border-gray-300 rounded px-4 py-2"
/>
{errors.email && (
<p className="text-red-500 text-sm mt-1">{errors.email}</p>
)}
</div>
<div className="mb-6">
<label className="block text-gray-700 mb-2">Message:</label>
<textarea
value={data.message}
onChange={e => setData('message', e.target.value)}
className="w-full border border-gray-300 rounded px-4 py-2"
rows="4"
/>
{errors.message && (
<p className="text-red-500 text-sm mt-1">{errors.message}</p>
)}
</div>
<button
type="submit"
disabled={processing}
className="w-full bg-blue-500 text-white py-3 rounded hover:bg-blue-600 transition disabled:bg-gray-400"
>
{processing ? 'Sending...' : 'Send Message'}
</button>
</form>
</div>
</div>
</>
);
}Now add the route in routes/web.php:
Route::get('/contact', function () {
return Inertia::render('Contact');
});
Route::post('/contact', function (Request $request) {
// Validate the form data
$validated = $request->validate([
'name' => 'required|min:3',
'email' => 'required|email',
'message' => 'required|min:10',
]);
// In real app, save to database or send email
// For now, just redirect back with success message
return redirect()->back()->with('success', 'Message sent successfully!');
});What's cool here? The useForm hook handles everything: form state, submission, loading states, and even displays Laravel's validation errors automatically!
Step 9: Share Data Across All Pages
Sometimes you want to show the same data on every page (like the logged-in user's name). Open app/Http/Middleware/HandleInertiaRequests.php:
public function share(Request $request): array
{
return [
...parent::share($request),
// This data is available on ALL pages!
'auth' => [
'user' => $request->user() ? [
'name' => $request->user()->name,
'email' => $request->user()->email,
] : null,
],
// Flash messages (success/error notifications)
'flash' => [
'success' => $request->session()->get('success'),
'error' => $request->session()->get('error'),
],
];
}Now in ANY React component, you can access this shared data using the usePage hook:
import { usePage } from '@inertiajs/react';
export default function MyComponent() {
const { auth, flash } = usePage().props;
return (
<div>
{auth.user && <p>Welcome, {auth.user.name}!</p>}
{flash.success && <div className="alert">{flash.success}</div>}
</div>
);
}Step 10: Create a Reusable Layout
Most websites have a common header and footer. Let's create a layout component! Create resources/js/Layouts/MainLayout.jsx:
import React from 'react';
import { Link, usePage } from '@inertiajs/react';
export default function MainLayout({ children }) {
const { auth } = usePage().props;
return (
<div className="min-h-screen bg-gray-50">
{/* Header/Navigation */}
<nav className="bg-white shadow-md">
<div className="max-w-7xl mx-auto px-4 py-4 flex justify-between items-center">
<Link href="/" className="text-2xl font-bold text-blue-600">
MyApp
</Link>
<div className="space-x-4">
<Link href="/" className="text-gray-700 hover:text-blue-600">
Home
</Link>
<Link href="/about" className="text-gray-700 hover:text-blue-600">
About
</Link>
<Link href="/contact" className="text-gray-700 hover:text-blue-600">
Contact
</Link>
</div>
<div>
{auth.user ? (
<span className="text-gray-700">
Hello, {auth.user.name}
</span>
) : (
<Link href="/login" className="bg-blue-500 text-white px-4 py-2 rounded">
Login
</Link>
)}
</div>
</div>
</nav>
{/* Main Content */}
<main className="max-w-7xl mx-auto py-8 px-4">
{children}
</main>
{/* Footer */}
<footer className="bg-gray-800 text-white py-6 mt-12">
<div className="max-w-7xl mx-auto px-4 text-center">
<p>© 2025 MyApp. Built with Laravel & Inertia.js</p>
</div>
</footer>
</div>
);
}Now wrap your pages with this layout:
import MainLayout from '@/Layouts/MainLayout';
export default function Home({ message, userName }) {
return (
<MainLayout>
<div className="bg-white rounded-lg shadow-md p-8">
<h1 className="text-4xl font-bold">{message}</h1>
<p>Hello, {userName}!</p>
</div>
</MainLayout>
);
}Advanced Features (Optional)
1. Prefetching Links
Make your app even faster by loading page data before the user clicks:
<Link href="/about" prefetch="hover">
About Us
</Link>2. Partial Reloads
Only reload specific parts of your data:
import { router } from '@inertiajs/react';
// Only reload 'posts' data, keep everything else the same
router.reload({ only: ['posts'] });3. Progress Indicator
Show a loading bar when navigating between pages. Add this to resources/js/app.jsx:
import { router } from '@inertiajs/react';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
router.on('start', () => NProgress.start());
router.on('finish', () => NProgress.done());Don't forget to install nprogress:
npm install nprogressCommon Problems and Solutions
❌ Problem: "Vite manifest not found"
Solution: Make sure you ran npm run dev in a separate terminal. Both Laravel server AND Vite must be running during development.
❌ Problem: Page not found
Solution: Check that your component name matches the route. If your route says Inertia::render('Home'), your file must be Pages/Home.jsx.
❌ Problem: Data not showing up
Solution: Make sure you're passing data from Laravel correctly and receiving it as props in React. Check the browser console for errors.
❌ Problem: Forms not submitting
Solution: Check that your route matches (GET for displaying form, POST for submitting). Also verify you're using post('/route') in your form, not get().
Best Practices for Using Inertia.js
✅ DO:
- • Use shared data for common information
- • Create reusable layout components
- • Validate forms on the server (Laravel)
- • Use Inertia's form helper for easy submission
- • Keep components organized in folders
❌ DON'T:
- • Don't create separate APIs for Inertia
- • Don't use window.location for navigation
- • Don't mix Inertia routes with API routes
- • Don't forget CSRF protection for forms
- • Don't skip validation on the backend
Conclusion: You Did It! 🎉
Congratulations! You've just learned how to build modern web applications using Inertia.js with Laravel and React. Let's recap what you've learned:
- ✅ What Inertia.js is and why it's awesome
- ✅ How to install and configure Inertia.js in Laravel
- ✅ How to create React page components
- ✅ How to pass data from Laravel to React
- ✅ How to handle forms and validation
- ✅ How to share data across all pages
- ✅ How to create reusable layouts
Remember: Inertia.js is like a bridge that connects your Laravel backend with your React frontend. You don't need to build APIs, and you can use Laravel for everything you're already familiar with!
🚀 Next Steps:
- • Try building a simple blog or todo app
- • Explore Inertia.js official documentation at inertiajs.com
- • Learn about authentication with Laravel Breeze + Inertia
- • Experiment with Vue or Svelte instead of React
- • Join the Inertia.js community on Discord
Keep practicing, keep building, and most importantly—have fun! If you found this guide helpful, share it with your friends who are learning web development. Happy coding! 💻✨
Frequently Asked Questions
Helpful Resources
📚 Inertia.js Documentation
Official docs with detailed guides and examples
📖 Laravel Documentation
Complete Laravel framework documentation
⚛️ React Documentation
Learn React fundamentals and advanced concepts
💻 GitHub Repository
Explore Inertia.js source code and examples
Related Articles You May Like
- Top Coding Tips: Clean Code, Boost Productivity, Master Practices
Best Practices • Intermediate
- The Ultimate Guide to Code Debugging: Techniques, Tools & Tips
Debugging • Intermediate
- Laravel API Example: Creating Efficient Endpoints
Laravel • Advanced
- Laravel Tips and Tricks: Hidden Features Most Developers Miss
Laravel • Advanced
- How to Debug Laravel SQL Queries in API Requests: A Developer's Guide
Laravel • Intermediate
- Setting Up Gmail SMTP in Laravel: A Comprehensive Guide
Laravel • Intermediate