Laravel Inertia.js - Running SSR on a different port than 13714
Tags: laravel, inertiajs, php, ssr
Published: 2023-02-09 21:14:12

I am getting into [Inertia.js](https://inertiajs.com/) and so far love it for its simplicity and the huge advantages it brings for building a modern website on a modern stack driven by both frontend awesomeness with a Javascript framework of your choice and the power of Laravel and PHP in the backend.

One of my main concerns was whether Inertia would be a good solution in terms of SEO. Turns out: it is! 🎉 With its inbuilt SSR capabilities, it is a breeze to setup a completely server-side rendered, SEO friendly frontend that still profits from all the Inertia magic.

Setting SSR up is [well documented](https://inertiajs.com/server-side-rendering) and easy to do. When everything is setup, running

```shell
php artisan inertia:start-ssr
```

will start the SSR server and Laravel will give you plain HTML with all the client side features still working. But: it will always run the SSR server on port 13714 and I couldn't find any existing resource showing how to change that.

## Changing the default SSR port

There might me multiple reasons to change the port. Some examples:

* The port is already taken. This is not very likely when running only one website on a server (or locally), but as soon as you have two projects running, the runners would conflict each other.
* The port is forbidden. Some hosters will not allow you to assign any port outside of a given range.
* You don't like the number. Also unlikely, but maybe you are just not a fan of numbers starting with a 13.

Changing the port to something else takes two steps. You'll need to 
* reconfigure the SSR build to make the SSR server run on the desired port and
* change the Laravel runtime config so that the Laravel runtime talks to the SSR server on the correct port.

This is (as far as I know) not documented and I had to dive into the sourcecode for both the [inertia server runner](https://github.com/inertiajs/inertia/blob/master/packages/core/src/server.ts) and the [Laravel command to start the server](https://github.com/inertiajs/inertia-laravel/blob/master/src/Commands/StartSsr.php) to understand what is going on. Here we go.

## Changing the port for the SSR build

Step 1: Given that you have followed the SSR setup guide, when running

```shell
npm run build
```

the configuration is baked into the bundle that will be executed when starting the SSR server (you can find this bundle at `bootstrap/ssr/ssr.js`). By default, no port is passed in, so the default port is used.

In order to change what port will be used later, this has to be changed in your `resources/js/ssr.js` file. The port can be changed by passing it **as a second parameter to the `createServer` function**. So

```javascript
createServer(page =>
  createInertiaApp({
    page,
    render: renderToString,
    resolve: name => {
      const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
      return pages[`./Pages/${name}.vue`]
    },
    setup({ App, props, plugin }) {
      return createSSRApp({
        render: () => h(App, props),
      }).use(plugin)
    },
  }),
  8080
)
```

The change in regards to the defaults here is the **last line**. I'm passing in the port as a second parameter. With this setup, run `npm run build` again and the next time you run `php artisan inertia:start-ssr` you will see:

```shell
Starting SSR server on port 8080...
Inertia SSR server started.
```

Awesome. But: This change alone will not do. Laravel will still try to talk to the SSR server on port 13714. Let's change this.

## Changing the port for the Laravel backend

The laravel inertia adapter has a configuration file that is not published by default. If you didn't do this yet, run

```shell
php artisan vendor:publish --provider "Inertia\ServiceProvider"
```

This will publish a file named `inertia.php` to your `config` folder. Open this and voilà, there you can change the SSR server url that Laravel is talking to. Change the URL to

```php
'url' => 'http://127.0.0.1:8080',
```

and you are all set. 🚀

## Making the port easier to configure

Changing the port in two places seems a bit tedious, also this port should be depending on your environment. So let's make it an environment variable.

In your `config/inertia.php`, change this line

```php
'url' => 'http://127.0.0.1:8080',
```

to

```php
'url' => 'http://127.0.0.1:'.env('VITE_INERTIA_SSR_PORT', 13714),
```

And in your `ssr.js`, instead of hardcoding the port also inject the env variable.

```javascript
createServer(page =>
  createInertiaApp({
    // config here...
  }),
  process.env.VITE_INERTIA_SSR_PORT || 13714
)
```

With both changes in place, you can now add the `VITE_INERTIA_SSR_PORT` variable to your `.env` file and set it there.

```shell
VITE_INERTIA_SSR_PORT=8080
```

#### Notes

* Yes, the `VITE_` prefix for the env variable name is obligatory in order to make it available to the `ssr.js`.
* Keep in mind that the port for the SSR server is still baked into the build bundle when running `npm run build`. Just changing the env variable will not change the port the server is running on if you do not recreate the bundle.
* Yes, this should be documented somewhere. If you have the power to add it to the docs, do so.