Setup Laravel 9 project with ReactJS
Tags: webdev, laravel, react, inertiajs
Published: 2022-07-05 17:43:35

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](https://vitejs.dev), 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](https://dev.to/emokores256/integrate-reactjs-in-laravel-5aad), 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](https://laravel.com/docs/9.x/starter-kits#breeze-and-inertia).

**Pre-requisites:**

- Composer

- npm

## Setting up the backend
We can do this either using the Laravel installer or [use composer](https://laravel.com/docs/9.x/installation#installation-via-composer). We are going to use the Laravel installer. Type the following command in your terminal:

```
laravel new laravel-react

```
Let's get into our new project:

```
cd laravel-react
```

We are going to need [InertiaJS](http://inertiajs.com) 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
```

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

```
php artisan inertia:middleware
```

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:

```php
'web' => [
  // ...
  \App\Http\Middleware\HandleInertiaRequests::class,
],
```

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
```

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:

```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 inertia>{{ config('app.name', 'Laravel') }}</title>

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

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

```

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:

```php
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');
}
*/

```
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](https://nodejs.org/en/download). In your terminal, type the following command:

```
npm i @inertiajs/inertia @inertiajs/inertia-react jsconfig.json @inertiajs/progress
```
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
```
We also need the vite plugin for react:

```
npm add @vitejs/plugin-react
```

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`:

```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" });

```

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:

```js
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
    ],
});
```

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:

```jsx
export default function Welcome () {
    return (
        <>
            <div>Hello Inertia!</div>
        </>
    );
}
```
Then start your PHP server with the command:

```
php artisan serve
```
Then add a tab in your terminal and start the Vite dev server:

```
npm run dev
```

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](inertiajs.com/client-side-setup) and [server-side setup](inertiajs.com/server-side-setup).