Laravel and Inertia with React and TypeScript
Tags: laravel, react, typescript
Published: 2020-09-11 14:03:33

- Create a fresh Laravel project.

```bash
laravel new inertia-typescript
```
## Back-End
- Let's setup back-end for Inertia.js by following instructions from [here](https://inertiajs.com/server-side-setup).
```bash
composer require inertiajs/inertia-laravel
```
- Create **Root** template at `resources/views/app.blade.php` with following contents:
```html
<!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>
```
- Create a route in `routes/web.php` 
```php
use Inertia\Inertia;

Route::get('home', function(){
  return Inertia::render('Home');
});
```
**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](https://inertiajs.com/client-side-setup).
- We'll start with bunch of installations:
```bash
npm install react react-dom @types/react
```
```bash
npm install @inertiajs/inertia @inertiajs/inertia-react
```
```bash
npm install --save-dev ts-loader typescript
```
- Initialize `typescript` by creating `tsconfig.json` file using below command:
```bash
tsc --init --jsx react
```
- Initialize our Inertia app like below inside `resources/js/app.js`:
```jsx
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
)
```
- Create our `Home` component at `resources/js/Pages/Home.tsx`
```jsx
import React from "react";

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

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

export default Home;
```
> Notice that I have `.tsx` extension instead of `.jsx`

- Change `mix.js` to `mix.ts` in `webpack.mix.js` file:
```javascript
mix.ts('resources/js/app.js', 'public/js')
    .postCss('resources/css/app.css', 'public/css', [
        //
    ]);
```
- 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.
```bassh
npm install --save-dev @babel/preset-react
```
- Create a `.babelrc` file at root of our project with following contents:
```json
{
  "presets": ["@babel/preset-react"]
}
```
- 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](https://github.com/awebartisan/laravel-inertia-react-typescript).

## Update
[Amitav Roy](https://twitter.com/amitavroy7) 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](https://github.com/awebartisan/laravel-inertia-react-typescript/commit/49be431db72a4350d79cc8aba37917a1acd77e8f)