inertia-laravel
inertia-laravel copied to clipboard
"route is not defined" from SSR server
I'm not quite sure where to put this.
I just verified that its not just my app.
I installed a fresh Laravel project with Laravel Breeze using Vue with Inertia, Inertia SSR and TypeScript.
Then I added a console.log(route('profile')) in my Welcome.vue files <script setup> section. compiled everything with npm run build, started the ssr server with php artisan inertia:start-ssr, disabled JavaScript in my browser and reload the page.
The result is always the same:
Starting SSR server on port 13714...
Inertia SSR server started.
[Vue warn]: Unhandled error during execution of setup function
at <Welcome errors= {} auth= { user: null } ziggy= {
url: 'http://ziggy-test.test',
port: null,
defaults: [],
routes: {
'sanctum.csrf-cookie': { uri: 'sanctum/csrf-cookie', methods: [Array] },
dashboard: { uri: 'dashboard', methods: [Array] },
'profile.edit': { uri: 'profile', methods: [Array] },
'profile.update': { uri: 'profile', methods: [Array] },
'profile.destroy': { uri: 'profile', methods: [Array] },
register: { uri: 'register', methods: [Array] },
login: { uri: 'login', methods: [Array] },
'password.request': { uri: 'forgot-password', methods: [Array] },
'password.email': { uri: 'forgot-password', methods: [Array] },
'password.reset': {
uri: 'reset-password/{token}',
methods: [Array],
parameters: [Array]
},
'password.store': { uri: 'reset-password', methods: [Array] },
'verification.notice': { uri: 'verify-email', methods: [Array] },
'verification.verify': {
uri: 'verify-email/{id}/{hash}',
methods: [Array],
parameters: [Array]
},
'verification.send': { uri: 'email/verification-notification', methods: [Array] },
'password.confirm': { uri: 'confirm-password', methods: [Array] },
'password.update': { uri: 'password', methods: [Array] },
logout: { uri: 'logout', methods: [Array] },
'storage.local': {
uri: 'storage/{path}',
methods: [Array],
wheres: [Object],
parameters: [Array]
}
},
location: 'http://ziggy-test.test'
} ... >
at <Inertia initialPage= {
component: 'Welcome',
props: {
errors: {},
auth: { user: null },
ziggy: {
url: 'http://ziggy-test.test',
port: null,
defaults: [],
routes: [Object],
location: 'http://ziggy-test.test'
},
canLogin: true,
canRegister: true,
laravelVersion: '11.26.0',
phpVersion: '8.3.10'
},
url: '/',
version: 'ef7dfac2be4457af7cedae810f854f68'
} initialComponent= {
__name: 'Welcome',
__ssrInlineRender: true,
props: {
canLogin: { type: [Function: Boolean] },
canRegister: { type: [Function: Boolean] },
laravelVersion: {},
phpVersion: {}
},
setup: [Function (anonymous)],
inheritAttrs: false
} resolveComponent=fn<r> ... >
at <App>
ReferenceError: route is not defined
at setup (file:///Users/tii/projects/web/ziggy-test/bootstrap/ssr/assets/Welcome-BnVlHDQj.js:14:13)
at _sfc_main.setup (file:///Users/tii/projects/web/ziggy-test/bootstrap/ssr/assets/Welcome-BnVlHDQj.js:87:23)
at callWithErrorHandling (/Users/tii/projects/web/ziggy-test/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:200:19)
at setupStatefulComponent (/Users/tii/projects/web/ziggy-test/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:7783:25)
at setupComponent (/Users/tii/projects/web/ziggy-test/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:7744:36)
at renderComponentVNode (/Users/tii/projects/web/ziggy-test/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:645:15)
at renderVNode (/Users/tii/projects/web/ziggy-test/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:779:14)
at renderComponentSubTree (/Users/tii/projects/web/ziggy-test/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:730:7)
at renderComponentVNode (/Users/tii/projects/web/ziggy-test/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:664:12)
at renderVNode (/Users/tii/projects/web/ziggy-test/node_modules/@vue/server-renderer/dist/server-renderer.cjs.js:779:14)
It's always ReferenceError: route is not defined.
That's the problem I have in my application too. With JavaScript running from the browser: No problems at all. Everything works fine.
But without JavaScript, so it definitely comes from the SSR server: route is not defined.
I'm a litte overwhelmed with this... Someone any ideas?
I found a workaround by doing this in every component I need routes:
import {route as ziggyRoute} from "ziggy-js";
const route = inject<typeof ziggyRoute>("route")!;
Hi, I have this problem too. I use Inertia Laravel + Inertia/Svelte. Here's the issue I create in my repository: https://github.com/senkulabs/breeze-lite/issues/4. I don't setup any route in my Svelte components. I just use @route blade directive that I put in app.blade.php. That's it. I was thinking that this is more than enough. But, it turns out no.
+1, same issue, but with Jetstream.
I will try the workaround, but I think it's a bug. Probably will be fixed with Inertia 2.0? Hopefully!
+1, same issue, but with Jetstream.
I will try the workaround, but I think it's a bug. Probably will be fixed with Inertia 2.0? Hopefully!
I run into this myself with Jetstream as well, but only intermittently.
Hi, I have this problem too. I use Inertia Laravel + Inertia/Svelte. Here's the issue I create in my repository: senkulabs/breeze-lite#4. I don't setup any route in my Svelte components. I just use
@routeblade directive that I put inapp.blade.php. That's it. I was thinking that this is more than enough. But, it turns out no.
It turns out that I need to explicitly tell the vite the exact location of Ziggy's route in ssr.js or ssr.ts in order to solve this problem.
- import { route } from 'ziggy-js';
+ import { route } from '../../vendor/tightenco/ziggy';
I have the same issue with Laravel + inertia + vue
import {route as ziggyRoute} from "ziggy-js"; const route = inject<typeof ziggyRoute>("route")!;
I try this, but I got new error: TypeError: route is not a function
@TiiFuchs
+1 i have the same issues.... Route is not defined only in ssr
Having the same issue here
The same problem persists with the Laravel Vue Starter Kit
I found a workaround by doing this in every component I need routes:
import {route as ziggyRoute} from "ziggy-js"; const route = inject<typeof ziggyRoute>("route")!;
This workaround worked for me, not in every component but its appears the error occurs on one specific
to fix it, I have added this as a workaround on each component that uses route:
import {inject} from "vue";
const route = inject('route');
Is there any official fix to this? Any inertia app with SSR is just broken.
This was fixed in the Starter Kits with these PRs:
React
- https://github.com/laravel/react-starter-kit/pull/53
Vue
- https://github.com/laravel/vue-starter-kit/pull/74
- https://github.com/laravel/vue-starter-kit/pull/127
import { ZiggyVue } from 'ziggy-js';
createServer((page) =>
createInertiaApp({
// ...
setup: ({ App, props, plugin }) =>
createSSRApp({ render: () => h(App, props) })
.use(plugin)
.use(ZiggyVue, {
...page.props.ziggy,
location: new URL(page.props.ziggy.location),
}),
}),
);
The key here is to use Ziggy's Vue plugin in the main SSR JavaScript file.
Still have this issue.
import { createInertiaApp } from '@inertiajs/vue3';
import createServer from '@inertiajs/vue3/server';
import { renderToString } from 'vue/server-renderer';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { createSSRApp, DefineComponent, h } from 'vue';
import { ZiggyVue } from 'ziggy-js';
const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
createServer((page) =>
createInertiaApp({
page,
render: renderToString,
title: (title) => title ? `${title} - ${appName}` : appName,
resolve: resolvePage,
setup: ({ App, props, plugin }) =>
createSSRApp({ render: () => h(App, props) })
.use(plugin)
.use(ZiggyVue, {
...page.props.ziggy,
location: new URL(page.props.ziggy.location),
}),
}),
{ cluster: true },
);
function resolvePage(name: string) {
const pages = import.meta.glob<DefineComponent>('./pages/**/*.vue');
return resolvePageComponent<DefineComponent>(`./pages/${name}.vue`, pages);
}
tried on fresh laravel installation - same thing ReferenceError: route is not defined
@bunkdev-com did you find the solution? I also have the same issue
I ran into the same SSR problem. After digging into how Inertia + Ziggy + Vite SSR behave, I got it working, Sharing everything I had to adjust in case it helps others.
Setup
- Laravel 12.x (no starter kit)
- Inertia.js + React
- Ziggy for route() helper
- Vite (with an SSR build step)
Add build command
In package.json add SSR build command
"build-ssr": "vite build && vite build --ssr"
Fixing route is not defined in SSR
When running npm run build-ssr it was failing because of route undefined, SSR was not able to resolve route() function. So I had to add import { route } from 'ziggy-js'; to every react component where I call route function.
Also add an alias so Vite can resolve ziggy-js during both client and SSR builds:
// vite.config.js
import path from 'path';
export default {
resolve: {
alias: {
'ziggy-js': path.resolve('vendor/tightenco/ziggy'),
},
},
};
Generate the Ziggy routes file Run:
php artisan ziggy:generate
This creates resources/js/ziggy.js (critical: it contains the route definitions of the application which SSR build needs).
Configure SSR Follow Inertia’s SSR guide, Create your ssr.tsx (or ssr.js) entry. I saw, InertiaJS website updated some documentation, May be you are also using the old way of SSR, So make sure you used correct ssr.tsx file for your project
Fixing undefined route keys during SSR start up I was seeing during process startup:
TypeError: Cannot read properties of undefined (reading 'dashboard')
(Ziggy couldn’t resolve routes at SSR build time.)
To ensure the generated ziggy.js is present before vendor code executes, I prepended it to the vendor chunk with a Vite plugin:
// Inside vite.config.js
import { readFileSync } from 'fs';
function prependZiggyToVendor() {
return {
name: 'append-static-file-to-vendor',
enforce: 'post',
generateBundle(_, bundle) {
const staticPath = './resources/js/ziggy.js';
const vendorChunk = Object.values(bundle).find(
(item) => item.type === 'chunk' && item.name.includes('vendor')
);
if (vendorChunk) {
const extra = readFileSync(staticPath, 'utf8');
vendorChunk.code = `${extra}\n` + vendorChunk.code;
} else {
this.warn('vendor chunk not found; ensure manualChunks created it.');
}
},
};
}
export default {
// ...other config
plugins: [prependZiggyToVendor()],
};
This step is important because Vite builds apps for both SSR and the client. I noticed that once the build process was completed, it generated an extra files in the root directory of my app: /bootstrap/ssr, which contained the application for SSR.
Also, I added "resources/js/ziggy.js" file in the ts.config.js includes array, I'm not sure if its required or not as I was trying lot of things
After completing all of the above steps, I was able to see:
php artisan inertia:start-ssr
Starting SSR server on port 13714...
Inertia SSR server started.
However, I did not see the HTML generated on the server side using browser view source
Handling window / localStorage in SSR
After doing all of the above, the page still didn’t render properly on the server side because some components accessed window and localStorage native objects directly at render time, and these errors did not appear during the build process. When I accessed my application, I noticed in the console (where I had run the php artisan inertia:start-ssr command to start the background process) that it was throwing an "undefined window" error.
In your case you might be using some other native object which might not be available during the SSR. So you have to adjust your code to handle them.
Finally, after all of the above my home page rendered with the SSR. But I still had to fix other pages component which uses localStorage etc.