December 3, 2025
Ken Suzuki
Technology

Modern SPA Development Environment Setup Guide with Laravel Sail, Inertia.js, and React

A comprehensive guide to building modern SPAs efficiently with React and TypeScript while leveraging Laravel's strengths through Inertia.js. Learn how to set up the latest development environment from scratch using Docker-based Laravel Sail, with detailed step-by-step commands.

LaravelReactInertia.jsTypeScriptSail
Modern SPA Development Environment Setup Guide with Laravel Sail, Inertia.js, and React

Introduction

Laravel is a powerful PHP framework, but by combining it with modern JavaScript frameworks like React or Vue.js, you can efficiently build richer single-page applications (SPAs). Inertia.js is particularly excellent as it allows you to leverage server-side routing and controllers while building the frontend with modern components.

In this article, we'll walk through setting up a Laravel + Inertia.js + React + TypeScript development environment from scratch using Laravel Sail (Docker-based local development environment), with detailed command explanations.

Target Audience

  • Those with basic Laravel knowledge
  • Those interested in React development
  • Those considering building SPAs with Laravel

1. Creating a Laravel Project

First, let's create a new Laravel project using Composer. We'll name our project new-project.

composer create-project laravel/laravel new-project

Once creation is complete, navigate to the project directory.

cd new-project

2. Setting up Laravel Sail

Next, let's set up Laravel Sail, a Docker-based development environment. This allows you to easily use services like MySQL and Redis without cluttering your local machine.

php artisan sail:install

Once installation is complete, start Sail to launch the Docker containers.

./vendor/bin/sail up

Add the -d option to run in the background.

From this point forward, commands like php artisan, composer, and npm should be executed with ./vendor/bin/sail prefix. Otherwise, you might run into issues when local environment versions differ from Docker container versions.

3. Setting up Inertia.js (Server-side)

Install the Inertia.js adapter for Laravel.

./vendor/bin/sail composer require inertiajs/inertia-laravel

Next, generate middleware to handle Inertia.js requests.

./vendor/bin/sail artisan inertia:middleware

Register the generated app/Http/Middleware/HandleInertiaRequests.php middleware.

For Laravel 10 and later versions (including Laravel 12), it's common practice to register middleware in bootstrap/app.php.

In bootstrap/app.php, add HandleInertiaRequests to the web middleware group within the withMiddleware method.

use App\Http\Middleware\HandleInertiaRequests;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    // ...
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->web(append: [
            HandleInertiaRequests::class,
        ]);
    })
    // ...

4. Setting up Inertia.js (Client-side)

Introduce Inertia.js to the frontend and integrate it with React.

Installing Dependencies

Install the Inertia.js React adapter, along with React and ReactDOM using NPM.

./vendor/bin/sail npm install @inertiajs/react react react-dom

Initializing the Inertia Application

Create/edit the resources/js/app.tsx (or app.jsx) file as follows to initialize the Inertia application. Here, we're using createRoot from React 18 and later.

import './bootstrap'; // Import Laravel's bootstrap file if needed
import React from 'react';
import { createRoot } from 'react-dom/client';
import { createInertiaApp } from '@inertiajs/react';

createInertiaApp({
  // Define how pages are resolved. Using import.meta.glob to
  // automatically load React components from resources/js/Pages directory.
  resolve: name => {
    const pages = import.meta.glob('./Pages/**/*.tsx', { eager: true });
    // If using .jsx, change both the above and below to .jsx
    return pages[`./Pages/${name}.tsx`];
  },
  setup({ el, App, props }) {
    // Mount the application using React 18's createRoot
    createRoot(el).render(<App {...props} />);
  },
  // Optional: Progress bar settings for page transitions
  progress: {
    color: '#29d',
  },
});

If the resources/js/Pages directory doesn't exist, create it. This is where page components will be placed.

Creating the Root Template

Use Laravel's Blade template as the root for the Inertia application. Create resources/views/app.blade.php (or any filename) and write as follows.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel Inertia React App</title>
        @viteReactRefresh
        @vite(['resources/js/app.tsx', 'resources/css/app.css'])
        @inertiaHead
    </head>
    <body class="font-sans antialiased">
        @inertia
    </body>
</html>

Key points:

  • @viteReactRefresh and @vite are necessary for compiling and loading frontend assets using Vite.
  • @inertiaHead is used for Inertia to inject necessary meta tags and other elements into <head>.
  • The @inertia directive renders the root element (equivalent to <div id="app"></div>) where the Inertia application will be mounted.

5. Introducing TypeScript

For more robust development, let's introduce TypeScript.

./vendor/bin/sail npm install -D typescript @types/react @types/react-dom

Generate the TypeScript configuration file tsconfig.json. Setting the jsx option to react enables handling of TSX (TypeScript + JSX) files.

./vendor/bin/sail npx tsc --init --jsx react

6. Creating Routes

Set up which frontend component a specified address points to as routes in Laravel's web routing routes/web.php.

use Inertia\Inertia;

Route::get('/', function () {
    return Inertia::render('Home'); // Setting to reference Home.tsx when '/' is specified in the address bar
});

7. Creating Frontend Components

As the first Inertia.js component, create Home.tsx in the resources/js/Pages folder.

import React from 'react';

export default function Home() {
  return <h1>Laravel Sail + Inertia + React + TS Environment Setup Complete!</h1>;
}

Summary

With these steps, you now have the foundation for a modern development environment using Inertia.js, React, and TypeScript on Laravel Sail.

I'd like to explore these topics in more detail in future articles.

Happy Hacking!

Modern SPA Development Environment Setup Guide with Laravel Sail, Inertia.js, and React | Shirokuma.online