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

nexxai's avatar
Level 37

Inertia SSR + React - `ReferenceError: route is not defined` only on some pages

Ok, I'm kind of stumped here and hoping someone can tell me something I don't know.

I can successfully build the SSR and run the SSR server with php artisan inertia:start-ssr and everything seems to work fine but on a few different pages, I get the following error message:

ReferenceError: route is not defined
    at ProfileDetails (file:///[PATH TO THE PROJECT FOLDER]/bootstrap/ssr/ssr.js:662:23)
    at renderWithHooks (/[PATH TO THE PROJECT FOLDER]/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:5662:16)
    at renderIndeterminateComponent (/[PATH TO THE PROJECT FOLDER]/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:5736:15)
    at renderElement (/[PATH TO THE PROJECT FOLDER]/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:5961:7)
    at renderNodeDestructiveImpl (/[PATH TO THE PROJECT FOLDER]/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6119:11)
    at renderNodeDestructive (/[PATH TO THE PROJECT FOLDER]/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6091:14)
    at renderContextProvider (/[PATH TO THE PROJECT FOLDER]/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:5935:3)
    at renderElement (/[PATH TO THE PROJECT FOLDER]/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6032:11)
    at renderNodeDestructiveImpl (/[PATH TO THE PROJECT FOLDER]/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6119:11)
    at renderNodeDestructive (/[PATH TO THE PROJECT FOLDER]/node_modules/react-dom/cjs/react-dom-server-legacy.node.development.js:6091:14)

This makes no sense to me because there is nothing different about the pages it errors out on than the ones it doesn't. The only thing I've seen people reference on various post is to do something like globally import the ziggy-js package as part of the createInertiaApp({}) bit, but very post I've found with instructions on how to do this references Vue, rather than React.

Does anyone know what I might be doing wrong here?

0 likes
4 replies
nexxai's avatar
nexxai
OP
Best Answer
Level 37

Well after some messing around, I was able to get this to work, after running bun install ziggy-js and using this as my ssr.jsx file and HandlesInertiaRequests.php file:

import { createInertiaApp } from "@inertiajs/react";
import createServer from "@inertiajs/react/server";
import ReactDOMServer from "react-dom/server";
import { route } from "ziggy-js";

const appName = import.meta.env.VITE_APP_NAME || "Laravel";

createServer((page) => {
    globalThis.Ziggy = page.props.ziggy;

    return createInertiaApp({
        title: (title) => `${title} - ${appName}`,
        page,
        render: ReactDOMServer.renderToString,
        resolve: (name) => {
            const pages = import.meta.glob("./Pages/**/*.jsx", { eager: true });
            return pages[`./Pages/${name}.jsx`];
        },
        setup: ({ App, props }) => {
            const Ziggy = {
                // Pull the Ziggy config off of the props.
                ...props.initialPage.props.ziggy,
                // Build the location, since there is
                // no window.location in Node.
                location: new URL(props.initialPage.props.ziggy.url),
            };

            global.route = (name, params, absolute, config = Ziggy) =>
                route(name, params, absolute, config);

            return <App {...props} />;
        },
        progress: {
            color: "#4B5563",
        },
    });
});
<?php

namespace App\Http\Middleware;

use Illuminate\Http\Request;
use Inertia\Middleware;
use Tighten\Ziggy\Ziggy;

class HandleInertiaRequests extends Middleware
{
    /**
     * The root template that is loaded on the first page visit.
     *
     * @var string
     */
    protected $rootView = 'app';

    /**
     * Determine the current asset version.
     */
    public function version(Request $request): ?string
    {
        return parent::version($request);
    }

    /**
     * Define the props that are shared by default.
     *
     * @return array<string, mixed>
     */
    public function share(Request $request): array
    {
        $ziggy = new Ziggy($group = null, $request->url());

        return array_merge(parent::share($request), [
            // Add in Ziggy routes for SSR
            'ziggy' => $ziggy->toArray(),
            'auth' => [
                'user' => $request->user(),
            ],
        ]);
    }
}
1 like
phil-hudson's avatar

@nexxai I've just been having the same issue - thanks so much for the fix.

It might be worth a follow up here too - Inertia JS github #1083 (cannot post the link as account is too young!)

thanks :)

Tii's avatar

@nexxai That does not seem to be the solution when using Vue.js:

error TS2304: Cannot find name 'global'.
global.route = (name, params, absolute, config = Ziggy) 

But my setup() method (that is auto-generated from laravel breeze with ssr enabled) looks like this:

        setup({ App, props, plugin }) {
            return createSSRApp({ render: () => h(App, props) })
                .use(plugin)
                .use(ZiggyVue, {
                    ...page.props.ziggy,
                    location: new URL(page.props.ziggy.location),
                });
        },

So it already changed since you had the problem, I guess.

nonetheless I still have this problem when running the php artisan inertia:start-ssr command and calling the page with disabled js... I always get the ReferenceError: route is not defined error.

saspegas's avatar

I made a definition for the menu in the Header.vue component as follows.

// ...
const menuLinks = [
    {
        to: route('blog.index'),
        label: "Blog",
    },
// ...
<Link :href="item.to"
// ...

In this way, there is no problem in the development environment, but after building with ssr, it gives a "route not defined" error. I solved this by giving string input to the route() method in the template. After my definition, it should look like this.

// ...
const menuLinks = [
    {
        to: 'blog.index',
        label: "Blog",
    },
// ...
<Link :href="route(item.to)"
// ...

Please or to participate in this conversation.