Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

kurtobando's avatar

How to setup SSR Inertiajs + Vue3 + Ziggy + Vite ?

Hello community,

I have challenges with getting ZIggy routes work on my SSR setup, im getting;

TypeError: Cannot read properties of undefined (reading 'about')

Note; "about" is a name route in my web.php

So far; these are my config;

// vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import path from 'path';

export default defineConfig({
    build: {
        chunkSizeWarningLimit: 5000,
    },
    plugins: [
        laravel({
            input: ['resources/js/app.js'],
            ssr: ['resources/js/ssr.js'],
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    ssr: {
        noExternal: ['@inertiajs/server'],
    },
    resolve: {
        alias: {
            '@': path.resolve(__dirname, './resources/js'),
            ziggy: path.resolve('vendor/tightenco/ziggy/dist/index.es.js'),
        },
    },
});

// app.js
import '../css/app.css';
import 'toastify-js/src/toastify.css';
import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import route from 'ziggy';

InertiaProgress.init();

createInertiaApp({
    resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
    setup({ el, App, props, plugin }) {
        const app = createApp({ render: () => h(App, props) });

        app.config.globalProperties.$route = route;
        app.use(plugin);
        app.mount(el);
    },
});
// ssr.js
import '../css/app.css';
import { createSSRApp, h } from 'vue';
import { renderToString } from '@vue/server-renderer';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import createServer from '@inertiajs/server';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import route from 'ziggy';

createServer((page) =>
    createInertiaApp({
        page,
        render: renderToString,
        resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
        setup({ app, props, plugin }) {
            const ssr = createSSRApp({ render: () => h(app, props) });

            ssr.config.globalProperties.$route = route;
            ssr.use(plugin);

            return ssr;
        },
    })
);

Any suggestion on how to go about this?

0 likes
2 replies
kurtobando's avatar

Okay, it appears i got it working; here are the running config i found so far;

// ssr.js
import '../css/app.css';
import { createSSRApp, h } from 'vue';
import { renderToString } from '@vue/server-renderer';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import createServer from '@inertiajs/server';
import { ZiggyVue } from 'ziggyVue';
import { Ziggy } from './ziggy';

createServer((page) =>
    createInertiaApp({
        page,
        render: renderToString,
        resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
        setup({ app, props, plugin }) {
            const ssr = createSSRApp({ render: () => h(app, props) });

            ssr.use(ZiggyVue, Ziggy);
            ssr.use(plugin);

            return ssr;
        },
    })
);

// app.js
import '../css/app.css';
import 'toastify-js/src/toastify.css';
import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { ZiggyVue } from 'ziggyVue';

InertiaProgress.init();

createInertiaApp({
    resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
    setup({ el, App, props, plugin }) {
        const app = createApp({ render: () => h(App, props) });

        app.use(ZiggyVue);
        app.use(plugin);
        app.mount(el);
    },
});
// vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import path from 'path';

export default defineConfig({
    build: {
        chunkSizeWarningLimit: 5000,
    },
    plugins: [
        laravel({
            input: ['resources/js/app.js'],
            ssr: ['resources/js/ssr.js'],
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    ssr: {
        noExternal: ['@inertiajs/server'],
    },
    resolve: {
        alias: {
            '@': path.resolve(__dirname, './resources/js'),
            ziggy: path.resolve('vendor/tightenco/ziggy/dist/index.es.js'),
            ziggyVue: path.resolve('vendor/tightenco/ziggy/dist/vue.es.js'),
        },
    },
});

then php artisan ziggy:generate

then from your app.blade.php, keep the @routes for us to use route() in Vue components

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
    @inertiaHead
</head>
<body >
    @routes
    @inertia
    @vite('resources/js/app.js')
</body>
</html>

I am not sure if there are much easier approach on this case, however, happy to listen to community suggestions. Thank you

Reference:

https://inertiajs.com/server-side-rendering

https://laravel.com/docs/9.x/vite#ssr

https://github.com/tighten/ziggy#vue

2 likes

Please or to participate in this conversation.