Describe the bug
I have a use case where I'm creating a Micro Frontend architecture and using your package as the router for both the host and the remote. I'm using Module Federation 2.0 runtime functions for dynamically loading the remote, and I have a DynamicRoute.svelte component setup and attached to several routes and the build system is rsbuild (webpack compatible).
Host example code:
// App.svelte
<script>
import { Router } from '@mateothegreat/svelte5-router';
const routes = $state([
{
name: 'Root',
path: '/',
hooks: {
pre: async () {
// goto /home
}
},
props> {},
},
{
name: 'Home',
path: '/home',
component: async () => import('./pages/Home.svelte'),
hooks: {},
props> {},
},
{
name: 'Documents',
path: '/documents',
component: async () => import('./pages/Documents.svelte'),
hooks: {},
props> {},
},
{
name: 'Svelte Remote',
path: '/svelte-remote',
component: async () => import('./pages/DynamicRoute.svelte'),
hooks: {},
props> {
name: 'svelte',
entry: 'http://localhost:3001/mf-manifest.json',
basePath: '/svelte'
},
},
]);
</script>
<main>
<a href="/home" use:route>Home</a>
<a href="/documents" use:route>Documents</a>
<a href="/svelte" use:route>Svelte</a>
<Router id="host-router" {routes} />
</main>
// DynamicRoute.svelte (psuedo code as close to real thing as possible)
<script>
let { name, entry } = $props();
let RemoteComponent = $state();
$effect(() => {
registerRemotes([ { name, entry }]);
loadRemote(`${name}/App`).then((mod) => RemoteComponent = mod.default).catch(e => {});
});
</script>
{#if RemoteComponent}
<RemoteComponent {basePath} />
{/if}
As you can see from above, I have a dynamic route of /svelte that will load the DynamicRoute component when the router catches the route changed to localhost:3000/svelte. I also have some anchors to each of the routes so I can navigate between each route.
In the Remote, I have a similar setup, but using the basePath in the router so that it knows it's only supposed to look at the routes past /svelte.
Remove example code:
// App.svelte
<script>
import { Router } from '@mateothegreat/svelte5-router';
let { basePath } = $props();
const routes = $state([
{
name: 'Root',
path: '/',
hooks: {
pre: async () {
// goto /overview
}
},
props> {},
},
{
name: 'Overview',
path: '/overview',
component: async () => import('./pages/Overview.svelte'),
hooks: {},
props> {},
},
{
name: 'Underview',
path: '/underview',
component: async () => import('./pages/Underview.svelte'),
hooks: {},
props> {},
},
},
]);
</script>
<main>
<!-- "basePath" prepended to the href because without it the /svelte/ part of the route gets swallowed -->
<a href="/svelte/overview" use:route>Overview</a>
<a href="/svelte/underview" use:route>Underview</a>
<Router id="host-router" {routes} {basePath} />
</main>
When navigating using the remote routes (Overview and Underview), since the route contains the /svelte path, the host router thinks it needs to update and re-renders the entire DynamicRoute component instead of letting the remote router (the nested router) handle the route change since its within /svelte/.
I'm not sure if the router or use:path isn't pre-pending the basePath given to the nested router like it should, but the problem enlies with having to put the basePath in the anchor tag's href, which triggers the top level router to re-run the DynamicRoute component.
To Reproduce
Steps to reproduce the behavior:
- Create a Host MFE app and a remote MFE app
- Install the latest svelte5-router package
- Set some routes in the host and the remote
- Connect remote to host (can copy the code above) to load the nested router and routes.
- Try to navigate sub routes in the remote once it's loaded
- console.log() in the $effect in the DynamicRoute component and notice that it runs every time the nested router navigates.
Expected behavior
A single console.log() to happen when navigating to the top level route in the host (the one that loads the remote, in my case the /svelte/ route) and then not happen again while the nested router navigates, until the top level route changes (i.e. /svelte/ to /someotherroute/).
Logs
If available please provide any available logs, screenshots, etc.
I don't have a full example on my personal computer yet, and I can't take screenshots from my work computer. I'll try to create a working example with screenshots on my personal computer soon and post here.
Additional context
Add any other context about the problem here.
Package Versions:
@mateothegreat/svelte5-router: 2.16.19
svelte: 5.45.5
@module-federation/enhanced: 0.21.6
@module-federation/rsbuild-plugin: 0.21.6
@rsbuild/core: 1.6.7
@rsbuild/plugin-svelte: 1.0.11
My hunch is that the issue is with the file src\lib\router.svelte, where the RenderableComponent is surrounded by a {#key route?.result?.path?.original} and the fact that the nested anchors need the basePath to route properly. Since the anchors try to push /svelte/overview for example, the route?result?.path?.original changes in the host router, and causes the RenderableComponent to re-render.
Describe the bug
I have a use case where I'm creating a Micro Frontend architecture and using your package as the router for both the host and the remote. I'm using Module Federation 2.0 runtime functions for dynamically loading the remote, and I have a DynamicRoute.svelte component setup and attached to several routes and the build system is rsbuild (webpack compatible).
Host example code:
As you can see from above, I have a dynamic route of
/sveltethat will load theDynamicRoutecomponent when the router catches the route changed tolocalhost:3000/svelte. I also have some anchors to each of the routes so I can navigate between each route.In the Remote, I have a similar setup, but using the basePath in the router so that it knows it's only supposed to look at the routes past
/svelte.Remove example code:
When navigating using the remote routes (Overview and Underview), since the route contains the /svelte path, the host router thinks it needs to update and re-renders the entire DynamicRoute component instead of letting the remote router (the nested router) handle the route change since its within /svelte/.
I'm not sure if the router or use:path isn't pre-pending the basePath given to the nested router like it should, but the problem enlies with having to put the basePath in the anchor tag's href, which triggers the top level router to re-run the DynamicRoute component.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
A single console.log() to happen when navigating to the top level route in the host (the one that loads the remote, in my case the /svelte/ route) and then not happen again while the nested router navigates, until the top level route changes (i.e. /svelte/ to /someotherroute/).
Logs
If available please provide any available logs, screenshots, etc.
I don't have a full example on my personal computer yet, and I can't take screenshots from my work computer. I'll try to create a working example with screenshots on my personal computer soon and post here.
Additional context
Add any other context about the problem here.
Package Versions:
@mateothegreat/svelte5-router: 2.16.19
svelte: 5.45.5
@module-federation/enhanced: 0.21.6
@module-federation/rsbuild-plugin: 0.21.6
@rsbuild/core: 1.6.7
@rsbuild/plugin-svelte: 1.0.11
My hunch is that the issue is with the file src\lib\router.svelte, where the RenderableComponent is surrounded by a {#key route?.result?.path?.original} and the fact that the nested anchors need the basePath to route properly. Since the anchors try to push
/svelte/overviewfor example, theroute?result?.path?.originalchanges in the host router, and causes the RenderableComponent to re-render.