I’m using SvelteKit and svelte-spa-router
.
My file structure looks like the following:
src/ ├─ assets/ ├─ lib/ │ ├─ Navbar.svelte │ ├─ Sidebar.svelte ├─ routes/ │ ├─ about/ │ │ ├─ index.svelte │ ├─ contact/ │ │ ├─ index.svelte │ ├─ products/ │ │ ├─ index.svelte │ ├─ Test.svelte │ ├─ index.svelte │ ├─ __layout.svelte ├─ app.css ├─ app.html
__layout.svelte:
(As per the example in the link above.)
<script> import Router from 'svelte-spa-router' import Navbar from "$lib/Navbar.svelte"; import Sidebar from "$lib/Sidebar.svelte"; import Home from './index.svelte' import About from './about/index.svelte' import Contact from './contact/index.svelte' import Products from './products/index.svelte' import Test from './Test.svelte'; const routes = { // Exact path '/': Home, '/about': About, '/contact': Contact, '/products': Products, '/test': Test } </script> <Navbar /> <Sidebar /> <Router {routes} /> <style> </style>
Error:
Error: Invalid component object at new RouteItem (Router.svelte:303:23) at Router.svelte:432:28 at Array.forEach (<anonymous>) at Router.svelte:431:31 at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at eval (/src/routes/__layout.svelte:62:85) at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122) at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26)
Console:
If I remove <Router {routes} />
and use <slot></slot>
, everything works fine.
The only thing I managed to find about this error was this GitHub source code of Router.svelte
(line #301
), but it didn’t help much.
I tried changing the names of the components like in the example, but the error was still thrown (I figured maybe the fact that they’re all called the same might be a bug, I don’t know…).
Manually navigating via localhost:3000/[path]
throws the error as well, including /test
path which is outside in the same path as the __layout.svelte
. The latter I mention because in the first link I provided the author said:
To display the router, in a Svelte component (usually App.svelte), first import the router component…
Usually from the examples I’ve seen, the structure you normally put in the App.svelte
goes in the __layout.svelte
and then the index.svelte
, which serves as the “Home”/”Landing” page, automatically goes in the <slot />
(and whatever other routes you might have) located in __layout.svelte
, by default.
Last but not least, dynamically importing them didn’t work either. See –> Edit 3
I understand a lot of the things I’ve tried probably have nothing to do with the problem, but the problem itself makes no sense to me. Like, why are the components getting passed as objects of a type the Router
doesn’t understand? Test.svelte
literally only has <h1>TEST COMPONENT</h1>
in it.
Edit:
Added the following code to my __layout.svelte
‘s <script></script>
section:
// Contains logging information used by tests let logbox = '' // Handles the "conditionsFailed" event dispatched by the router when a component can't be loaded because one of its pre-condition failed function conditionsFailed(event) { // eslint-disable-next-line no-console console.error('Caught event conditionsFailed', event.detail) logbox += 'conditionsFailed - ' + JSON.stringify(event.detail) + 'n' // Replace the route replace('/wild/conditions-failed') } // Handles the "routeLoaded" event dispatched by the router after a route has been successfully loaded function routeLoaded(event) { // eslint-disable-next-line no-console console.info('Caught event routeLoaded', event.detail) logbox += 'routeLoaded - ' + JSON.stringify(event.detail) + 'n' } // Handles the "routeLoading" event dispatched by the router whie a route is being loaded // If the route is dynamically imported, such as with the `import()` syntax, then there might be a delay before the route is loaded function routeLoading(event) { // eslint-disable-next-line no-console console.info('Caught event routeLoading', event.detail) logbox += 'routeLoading - ' + JSON.stringify(event.detail) + 'n' } // Handles event bubbling up from nested routes function routeEvent(event) { // eslint-disable-next-line no-console console.info('Caught event routeEvent', event.detail) logbox += 'routeEvent - ' + JSON.stringify(event.detail) + 'n' }
After which I put the following below it, as shown in this test example:
<Router {routes} on:conditionsFailed={conditionsFailed} on:routeLoaded={routeLoaded} on:routeLoading={routeLoading} on:routeEvent={routeEvent} />
None of these got called, there was only the red console message seen in the picture above.
Edit 2:
As suggested by Thomas Hennes, I replaced <Router {routes} />
with each component individually in my __layout.svelte
file, like so:
<script> import Router from 'svelte-spa-router' import Navbar from "$lib/Navbar.svelte"; import Sidebar from "$lib/Sidebar.svelte"; import Home from './index.svelte' import About from './about/index.svelte' import Contact from './contact/index.svelte' import Products from './products/index.svelte' import Test from './Test.svelte'; const routes = { // Exact path '/': Home, //'/about': About, //'/contact': Contact, //'/products': Products, //'/test': Test } </script> <Navbar /> <Sidebar /> <Routes {routes} /> <style> </style>
None of them worked.
Edit 3:
Funny thing, I noticed dynamically importing the routes crashes my local server. xD
const routes = { // Exact path '/': wrap({ asyncComponent: () => import('./index.svelte') }), '/about': wrap({ asyncComponent: () => import('./about/index.svelte') }), '/contact': wrap({ asyncComponent: () => import('./contact/.svelte') }), '/products': wrap({ asyncComponent: () => import('./products/.svelte') }), '/test': wrap({ asyncComponent: () => import('./Test.svelte') }), }
It doesn’t matter which one I import, if I only import one of them or all of them at the same time.
This is the console output of this adventure:
window is not defined ReferenceError: window is not defined at getLocation (Router.svelte:38:31) at start (Router.svelte:59:23) at Object.subscribe ([Path to project]/node_modules/svelte/store/index.js:51:20) at Router.svelte:493:36 at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at eval (/src/routes/__layout.svelte:112:85) at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122) at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26) history is not defined ReferenceError: history is not defined at Router.svelte:455:10 at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at eval (/src/routes/__layout.svelte:112:85) at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122) at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26) at render_response (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:561:28) at async respond_with_error (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:1148:10) at async respond$1 (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:1392:4) /node_modules/svelte-spa-router/Router.svelte:413 const match = routesList[i].match(newLoc.location); ^ TypeError: Cannot read properties of null (reading 'location') at eval (/node_modules/svelte-spa-router/Router.svelte:413:45) at Object.subscribe ([Path to project]/node_modules/svelte/store/index.js:53:9) at eval (/node_modules/svelte-spa-router/Router.svelte:406:29) at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at eval (/src/routes/__layout.svelte:112:85) at Object.$$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at eval (eval at instantiateModule ([Path to project]/node_modules/vite/dist/node/chunks/dep-fcec4469.js:67775:28), <anonymous>:55:122) at $$render ([Path to project]/node_modules/svelte/internal/index.js:1702:22) at Object.render ([Path to project]/node_modules/svelte/internal/index.js:1710:26) at render_response (file://[Path to project]/node_modules/@sveltejs/kit/dist/ssr.js:561:28)
Advertisement
Answer
svelte-spa-router
is designed as a routing solution for Svelte projects (which are client-side only). It is not meant to function in server-side rendered SvelteKit projects.
SvelteKit, which is a universal (CSR + SSR) framework, provides its own routing solution, which will work client-side and server-side.