Laravel and Inertia with React and TypeScript
Zubair Mohsin

Zubair Mohsin @zubairmohsin33

About: Full Stack Laravel Developer

Location:
Lahore, Pakistan
Joined:
Mar 4, 2019

Laravel and Inertia with React and TypeScript

Publish Date: Sep 11 '20
60 7
  • Create a fresh Laravel project.
laravel new inertia-typescript
Enter fullscreen mode Exit fullscreen mode

Back-End

  • Let's setup back-end for Inertia.js by following instructions from here.
composer require inertiajs/inertia-laravel
Enter fullscreen mode Exit fullscreen mode
  • Create Root template at resources/views/app.blade.php with following contents:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
    <link href="{{ mix('/css/app.css') }}" rel="stylesheet" />
    <script src="{{ mix('/js/app.js') }}" defer></script>
  </head>
  <body>
    @inertia
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode
  • Create a route in routes/web.php
use Inertia\Inertia;

Route::get('home', function(){
  return Inertia::render('Home');
});
Enter fullscreen mode Exit fullscreen mode

Note: We haven't yet created Home component specified inside render method.

Front-End

Let's set up our front-end by following instructions from here.

  • We'll start with bunch of installations:
npm install react react-dom @types/react
Enter fullscreen mode Exit fullscreen mode
npm install @inertiajs/inertia @inertiajs/inertia-react
Enter fullscreen mode Exit fullscreen mode
npm install --save-dev ts-loader typescript
Enter fullscreen mode Exit fullscreen mode
  • Initialize typescript by creating tsconfig.json file using below command:
tsc --init --jsx react
Enter fullscreen mode Exit fullscreen mode
  • Initialize our Inertia app like below inside resources/js/app.js:
import { InertiaApp } from '@inertiajs/inertia-react'
import React from 'react'
import { render } from 'react-dom'

const app = document.getElementById('app')

render(
  <InertiaApp
    initialPage={JSON.parse(app.dataset.page)}
    resolveComponent={name => import(`./Pages/${name}`).then(module => module.default)}
  />,
  app
)
Enter fullscreen mode Exit fullscreen mode
  • Create our Home component at resources/js/Pages/Home.tsx
import React from "react";

const Home = () => {
    let foo: string = "React";
    const bar: string = "TypeScript";

    return (
        <h1>
            Hello {foo} + {bar}
        </h1>
    );
};

export default Home;
Enter fullscreen mode Exit fullscreen mode

Notice that I have .tsx extension instead of .jsx

  • Change mix.js to mix.ts in webpack.mix.js file:
mix.ts('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]);
Enter fullscreen mode Exit fullscreen mode
  • Next, npm run dev

  • Read Update below 👇🏼

🔴 You will face an error here inside your resources/js/app.js file because we have written some JSX syntax to initialize our app but we haven't installed react-preset so that Babel can understand it.

  • Lets install @babel/preset-react as dev dependency.
npm install --save-dev @babel/preset-react
Enter fullscreen mode Exit fullscreen mode
  • Create a .babelrc file at root of our project with following contents:
{
  "presets": ["@babel/preset-react"]
}
Enter fullscreen mode Exit fullscreen mode
  • Run npm run dev again and you should be able to compile your assets now. Visit the /home route to verify that you are able to see the output in browser.

Disclaimer: This is not the definitive guide on setting up TypeScript with React for Laravel and Inertia. This is just how I am proceeding with this setup.

If you find any mistakes, or know a better approach please leave your feedback in comments below 🙏🏼

Demo source code can be found here.

Update

Amitav Roy mentioned on Twitter if we can completely ditch JavaScript and also be able to avoid @babel/preset-react step above. Turns out it can be done easily.
Commit from Demo repository that shows how it can be done: 49be431

Comments 7 total

  • Hasnat Babur
    Hasnat BaburSep 11, 2020

    Nice one. Thanks

  • Ronnie Isurina
    Ronnie IsurinaJan 20, 2021

    Nice, Thanks!

  • Dieu-Donne Nazzah
    Dieu-Donne NazzahJul 16, 2021

    Nice, Thanks. The only suggestion to add is since every thing is being bundled, all dependencies can actually be devDepencies

  • andyyou
    andyyouFeb 9, 2022

    I found that code split feature is not working after setup. Originally pages will divide to different js after building but now all in app.js

    • andyyou
      andyyouFeb 10, 2022

      I solve the problem. If you want to use Inertia.js with code split (dynamic imports) you should setup tsconfig.json

      {
        "module": "esnext",
        "moduleResolution": "node", 
      }
      
      Enter fullscreen mode Exit fullscreen mode

      Ref here: stackoverflow.com/questions/563757...

  • Sreekant Krishnan
    Sreekant KrishnanSep 6, 2022

    I'm getting 404 error. I know it has something to do with Laravel being on a sub-directory, but not able to figure out how to get a workaround. Can you please help?

  • Friday Joshua
    Friday JoshuaNov 9, 2024

    Thanks so much. I've been on this all night and finally got it right.
    I kind of mixed up the dependencies, my project is setup with vite but your example uses webpack.

Add comment