DEV Community

Cover image for Setup Laravel 9 project with ReactJS
Emokor Steven
Emokor Steven

Posted on

Setup Laravel 9 project with ReactJS

Ever since Laravel 9, a lot of new features and improvements have been included in Laravel. Furthermore, developer experience has been improved, especially with the introduction of Vite, a frontend asset bundler. Laravel was previously using webpack for years, and it did a very good job. Integrating React into Laravel 9 has changed a bit with Vite as the new frontend asset bundler. I wrote a previous article on how to integrate ReactJS into Laravel, but it works for Laravel 8.x and before, or anyone who is using webpack to compile the frontend. In this tutorial, we'll be covering how to do this with Laravel 9.

This tutorial is going to walk us through integrating ReactJS into Laravel from scratch. You could do this too using a starter kit.

Pre-requisites:

  • Composer

  • npm

Setting up the backend

We can do this either using the Laravel installer or use composer. We are going to use the Laravel installer. Type the following command in your terminal:

laravel new laravel-react

Enter fullscreen mode Exit fullscreen mode

Let's get into our new project:

cd laravel-react
Enter fullscreen mode Exit fullscreen mode

We are going to need InertiaJS to help us contain these two stacks in one project. We're installing it using composer. Think of inertia as the glue to stick our frontend stack to our backend stack. In your terminal, type:

composer require inertia/inertia-laravel
Enter fullscreen mode Exit fullscreen mode

We now need a middleware that gives inertia the power in our project. In our terminal, type:

php artisan inertia:middleware
Enter fullscreen mode Exit fullscreen mode

Head to the app/Http/ directory, then in the Kernel.php file, add the follwing line in the $middlewareGroups[] array, add this line in the web[] array:

'web' => [
  // ...
  \App\Http\Middleware\HandleInertiaRequests::class,
],
Enter fullscreen mode Exit fullscreen mode

We then need our routes to be recognized in the frontend, since we're not using blade, but javascript to render our frontend. So, we need a special package called ziggy that handles that for us. We are installing it via composer:

composer require tightenco/ziggy
Enter fullscreen mode Exit fullscreen mode

Now, in the resources/views/ directory, let's create a new blade file app.blade.php which will be our entry-point for our application's UI, since it's a SPA (single-page application) that we're going to be creating. Type the following script:


<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title inertia>{{ config('app.name', 'Laravel') }}</title>

        <!-- Scripts -->
        @routes
        @viteReactRefresh
        @vite('resources/js/app.jsx')
        @inertiaHead
    </head>

    <body>
        @inertia
    </body>
</html>

Enter fullscreen mode Exit fullscreen mode

Notice the @vite() and @viteReactRefresh. These are telling our Laravel app that Vite is compiling our assets (CSS and JS files), and that we're going to be using JSX for our frontend. Note that we do not call the css file from the app.blade.php. But if you want to, you can just add the line @vite('resources/css/app.css'). Ideally, this should be in the resources/js/app.jsx file that we will create later in this tutorial.

Finally, let's create our route for our welcome page. Head to the routes/ directory and in the web.php, let's add the following line to make Laravel aware of the route to our welcome page:

Route::get('/', function () {
   return inertia('Welcome');
}

// other option (must add use Inertia\Inertia after namespace declaration at the top):

/*
Route::get('/', function () {
   return Inertia::render('Welcome');
}
*/

Enter fullscreen mode Exit fullscreen mode

Note the other option commented out! Either one of them will work perfectly.

Setting up the frontend

We are using npm to install our frontend dependencies. The npm must be installed on your machine. Look at the NodeJS documentation. In your terminal, type the following command:

npm i @inertiajs/inertia @inertiajs/inertia-react jsconfig.json @inertiajs/progress
Enter fullscreen mode Exit fullscreen mode

The above command will install inertia frontend dependencies, inertia progress bar for page loading and the jsconfig.json file that identifies our project that relies on javascript to render the frontend.

There's one sensitive issue. We have not yet installed react-dom. Inertia uses reactjs v17.0.2 as per the time of publishing this article. In order not to encounter errors, we need to specify the version of react-dom that will be compatible with our version of reactjs already installed:

npm i react-dom@17.0.2
Enter fullscreen mode Exit fullscreen mode

We also need the vite plugin for react:

npm add @vitejs/plugin-react
Enter fullscreen mode Exit fullscreen mode

Head to the resources/js/ directory, in the app.js file, add the following script below the import "./bootstrap" line, then rename the file to app.jsx:

import "../css/app.css";

import React from "react";
import { render } from "react-dom";
import { createInertiaApp } from "@inertiajs/inertia-react";
import { InertiaProgress } from "@inertiajs/progress";
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";

const appName =
    window.document.getElementsByTagName("title")[0]?.innerText || "Laravel";

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) =>
        resolvePageComponent(
            `./Pages/${name}.jsx`,
            import.meta.glob("./Pages/**/*.jsx")
        ),
    setup({ el, App, props }) {
        return render(<App {...props} />, el);
    },
});

// you can specify any color of choice
InertiaProgress.init({ color: "#4B5563" });

Enter fullscreen mode Exit fullscreen mode

Almost there! We need to tell Vite that we are using react, and specify our entry-point file. Laravel already installed for us a vite.config.js file. Let's head there, modify and add the following lines:

import { defineConfig } from "vite";
import laravel from "laravel-vite-plugin";
import react from "@vitejs/plugin-react"; //this line

export default defineConfig({
    plugins: [
        laravel({
            input: "resources/js/app.jsx", //this line
        }),
        react(), //this line
    ],
});
Enter fullscreen mode Exit fullscreen mode

Finally, let's create our welcome page. Let's create a new folder Pages and add a Welcome.jsx file in our resources/js/ directory:

export default function Welcome () {
    return (
        <>
            <div>Hello Inertia!</div>
        </>
    );
}
Enter fullscreen mode Exit fullscreen mode

Then start your PHP server with the command:

php artisan serve
Enter fullscreen mode Exit fullscreen mode

Then add a tab in your terminal and start the Vite dev server:

npm run dev
Enter fullscreen mode Exit fullscreen mode

Done!

Conclusion

And that's pretty much it! It's a few more steps compared to the previous way of doing it. But, Vite is much better and provides a better developer experience. You can visit the Inertia documentation that explains more on the client-side setup and server-side setup.

Discussion (0)