How can I get antd and inertia SSR working?

Updated: Feb 13, 2025

How can I get antd and inertia SSR working?

To get Ant Design (antd) and Inertia.js working together in Server-Side Rendering (SSR) mode, you'll need to follow several steps. Here's a detailed guide to help you achieve this:

  1. Install dependencies:

First, make sure you have the following dependencies installed in your project:

You can install them using npm or yarn:

# Using npm
npm install react react-dom antd inertia inertia-react

# Using yarn
yarn add react react-dom antd inertia inertia-react
  1. Configure Inertia.js:

Create a new file called inertia.js in the root of your project and configure it as follows:

import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import { createInertiaApp } from '@inertiajs/inertia-vue'
import { InertiaProgress } from '@inertiajs/progress'

Vue.use(VueRouter)

createInertiaApp({
  app: App,
  router: new VueRouter({
    // Your routes configuration here
  }),
  plugins: [InertiaProgress],
})

export const app = createInertiaApp()
  1. Configure antd:

Create a new file called antd.config.js in the root of your project and configure it as follows:

module.exports = {
  // global theme overrides
  theme: {
    'primary-color': '#1890ff',
  },

  // customize component configuration
  components: {},
}
  1. Configure Vue CLI:

If you're using Vue CLI, you need to configure it to use Inertia.js and antd.

Create a new file called vue.config.js in the root of your project and configure it as follows:

const { createInertiaApp } = require('@inertiajs/inertia-vue')
const { name as appName } = require('./package.json')

module.exports = {
  // ... other config options
  configureWebpack: {
    resolve: {
      alias: {
        '@': __dirname,
      },
    },
  },
  chainWebpack: config => {
    config.plugins.delete('preload')
    config.plugins.delete('prefetch')
  },
  css: {
    loaderOptions: {
      antd: {
        customizeTheme: ({ antD }) => ({
          'primary-color': '#1890ff',
        }),
        customizeVariableMap: variables => ({
          '--border-radius-base': '4px',
        }),
      },
    },
  },
  configure: function (config, { isServer }) {
    if (isServer) {
      config.externals = {
        vue: 'Vue',
        'vue-router': 'VueRouter',
        'ant-design-vue': 'antd',
      }
    }

    createInertiaApp(config)
  },
}
  1. Create a new Express server:

If you don't already have an Express server, create a new file called server.js in the root of your project and configure it as follows:

const express = require('express')
const { createBundleRenderer } = require('vue-server-renderer')
const path = require('path')
const fs = require('fs')
const App = require('./src/App.vue')

const app = express()
const bundleRenderer = createBundleRenderer(path.join(process.cwd(), 'dist'), {
  template: fs.readFileSync('./src/index.template.html', 'utf-8'),
})

app.get('*', async (req, res) => {
  const context = {}

  const app = new Vue({
    router: require('vue-router').createRouter({
      history: require('history').createMemoryHistory(req.url),
      routes: require('./routes').default,
    }),
  })

  await app.beforeCreate()
  await app.router.isReady()

  const matchedComponents = app.router.getMatchedComponents(req.url)
  const { App, router } = matchedComponents

  const renderer = bundleRenderer.createBundleRenderer(App, {
    router,
    store: app.$store,
  })

  const html = await renderer.renderToString(context, req)
  const precompiledChunks = [
    'vendors~main.js',
    'main.js',
    'antd.min.css',
  ]

  res.status(200).send(
    `<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>${appName}</title>
    <link rel="stylesheet" href="/antd.min.css">
    <style>${context.css.join('')}</style>
  </head>
  <body>
    <div id="app">${html}</div>
    <script src="/vendors~main.js"></script>
    <script src="/main.js"></script>
    <script>
      window.APP = ${JSON.stringify(app)}
      window.context = ${JSON.stringify(context)}
    </script>
    <script src="/manifest.json" crossorigin></script>
    ${precompiledChunks.map(chunk => `<script src="/${chunk}"></script>`).join('\n')}
  </body>
</html>`
  )
})

app.listen(3000, () => {
  console.log('Server listening on port 3000')
})
  1. Run the server:

Now you can run your server using the following command:

node server.js
  1. Build your project:

Finally, you can build your project using the following command:

npm run build

Your project should now be ready to use antd and Inertia.js together in SSR mode.