Skip to content

Server-side Rendering (SSR)

Server-side rendering pre-renders your JavaScript pages on the server, allowing your visitors to receive fully rendered HTML when they visit your application. Since fully rendered HTML is served by your application, it's also easier for search engines to index your site.

NOTE

Server-side rendering uses Node.js to render your pages in a background process; therefore, Node must be available on your server for server-side rendering to function properly.

Install dependencies

First, install the additional dependencies required for server-side rendering. This is only necessary for the Vue adapters, so you can skip this step if you're using React or Svelte.

shell
npm install @vue/server-renderer

Add server entry-point

Next, we'll create a app/frontend/ssr/ssr.js file within the Rails project that will serve as the SSR entry point.

This file is going to look very similar to your regular inertia initialization file, except it's not going to run in the browser, but rather in Node.js. Here's a complete example.

js
import { createInertiaApp } from '@inertiajs/vue3'
import createServer from '@inertiajs/vue3/server'
import { renderToString } from '@vue/server-renderer'
import { createSSRApp, h } from 'vue'

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)
    },
  }),
)

When creating this file, be sure to add anything that's missing from your regular initialization file that makes sense to run in SSR mode, such as plugins or custom mixins.

Setup Vite Ruby

Next, we need to update our Vite configuration to build our new ssr.js file. We can do this by adding a ssrBuildEnabled property to Ruby Vite plugin configuration in the config/vite.json file.

json
  "production": {
    "ssrBuildEnabled": true
  }

NOTE

For more available properties see the Ruby Vite documentation.

Enable SSR in the Inertia's Rails adapter

ruby
InertiaRails.configure do |config|
  config.ssr_enabled = ViteRuby.config.ssr_build_enabled
end

Now you can build your server-side bundle.

shell
bin/vite build --ssr

Running the SSR server

Now that you have built both your client-side and server-side bundles, you should be able run the Node-based Inertia SSR server using the following command.

shell
bin/vite ssr

With the server running, you should be able to access your app within the browser with server-side rendering enabled. In fact, you should be able to disable JavaScript entirely and still navigate around your application.

Client side hydration

Since your website is now being server-side rendered, you can instruct your client to "hydrate" the static markup and make it interactive instead of re-rendering all the HTML that we just generated.

To enable client-side hydration, update your initialization file:

js
// frontend/entrypoints/inertia.js
import { createApp, h } from 'vue'
import { createSSRApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'

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

Deployment

When deploying your SSR enabled app to production, you'll need to build both the client-side (application.js) and server-side bundles (ssr.js), and then run the SSR server as a background process.