I've wrote lots about how to make a patch on that, and now, still not an npm module, but at least we have a repo:
https://github.com/webentlib/router
The idea is simple — just create universal [...path] folder and proxy everything through it via some urls.ts.
So, this allows to define routes like that:
urls.ts:
import type { Pattern, Layout, Error } from '/router/types';  // or from '/' in case you use root index.ts
export const error: Error = () => import('/src/error.svelte');
const layout: Layout = { page: () => import('/src/base.svelte'), error };
const layouts: Layout[] = [layout];  // for nested layouts — [layout, sublayout, ...]
export const patterns: Pattern[] = [
    {re: '',                     page: () => import('/src/home.svelte'),              layouts},
    {re: 'articles',             page: () => import('/src/articles/articles.svelte'), layouts},
    {re: 'article/(<id>[0-9]+)', page: () => import('/src/articles/article.svelte'),  layouts},
]
Sure, now all pages/components could be stored in any folder and have any name you want and need.
More of it, one can describe load inside <script module> right in page component like in good old Sapper:
article.svelte:
<script module>
export async function load({ fetch, slugs }) {
    const response = await fetch(`/api/articles/${slugs.id}/`);
    const article = await response.json();
    return { article }
}
</script>
Sure, load in separate .js/ts file also available by specifying js and a side params to execute on:
urls.ts:
import { Sides } from '/router/';  // SERVER | CLIENT | UNIVERSAL
{
    re: '',
    page: () => import('/src/home.svelte'),
    js: () => import('/src/home.js'),
    side: Sides.SERVER,
    layouts,
}
More of it, now, one can define page specific vars just in routes, like:
urls.ts:
{
    re: '',
    page: () => import('/src/home.svelte'),
    js: () => import('/src/home.js'),
    side: Sides.SERVER,
    layouts,
    layout: Layouts.DEFAULT,         // E.g: 'CUSTOM', 'CUSTOM'
    wrapper: Wrappers.NARROW,        // Can be used for css class for <main>
    title: 'Welcome to My project!', // Can be used for <title>
    h1: 'Welcome!',                  // Can be used for <h1>
    name: 'HOME',                    // 'id' of a route
    extras: [EXTRAS.GO_TOP],         // Any additions to use in layout,
}
So it can be used in base layout and page like that:
urls.ts:
export enum Layouts {
    DEFAULT = 'DEFAULT',
    CUSTOM = 'CUSTOM',
    BLANK = 'BLANK',
}
export enum Wrappers {
    WIDE = 'WIDE',
    DEFAULT = 'DEFAULT',
    NARROW = 'NARROW',
}
export enum Extras {
    GO_TOP = 'GO_TOP',
}
base.svelte:
<script>
    // ROUTER
    import { routeStore, Layouts, Wrappers, Extras } from '/';
    let title   = $derived($routeStore.title);
    let h1      = $derived($routeStore.h1);
    let path    = $derived($routeStore.url.pathname + $routeStore.url.search);
    let layout  = $derived($routeStore.layout);
    let wrapper = $derived($routeStore.wrapper);
    let extras  = $derived($routeStore.extras);
    // CUSTOM
    import { GoTop } from '/';
    import Header from '/src/Header.svelte';
    let { children } = $props();
</script>
<svelte:head>
    <title>{title || 'My Project'}</title>
</svelte:head>
{#if layout !== Layouts.BLANK}
    <Header/>
{/if}
{#key path}
    {#if layout === Layouts.DEFAULT}
        <main
            class='Wrapper'
            class:_Wide={wrapper === Wrappers.WIDE}
            class:_Default={wrapper === Wrappers.DEFAULT}
            class:_Narrow={wrapper === Wrappers.NARROW}
        >
            {#if h1}
                <div class="Heading">
                    <h1 class="Title">{h1}</h1>
                </div>
            {/if}
            {@render children?.()}
        </main>
    {:else}
        {@render children?.()}
    {/if}
{/key}
{#if extras?.length || extras.includes(Extras.GO_TOP)}
    <GoTop/>
{/if}
For installation, usage, etc — please follow:
https://github.com/webentlib/router
Thx for you attention.
If you like the idea, please tell — I'll think about packing that as an npm module.
    
Top comments (0)