svelte5-router

repository·main·Indexed 43 days ago

https://github.com/mateothegreat/svelte5-router

An SPA router for Svelte 5 supporting nested routing, async components, and flexible rendering via components or snippets. Features include regex path matching, navigation hooks for authentication or logging, and the use:route action for managing active states and preventing page reloads. Version 2.16.19.

Tokens
14.7K
Snippets
56
Records
75
Agent score
52%

What's inside svelte5-router

  1. Overview of svelte5-router features

    main

    The svelte5-router is a router built specifically for Svelte 5 that supports several advanced routing patterns:

    • Nested Routers: Divide your application into smaller, manageable sections using nested routing structures.
    • Flexible Rendering: Define routes using Svelte components, snippets, or a combination of both.
    • Advanced Path Matching: Use regex paths (e.g., /foo/(.*?)/bar) alongside named parameters.
    • Async Routes: Load components lazily using component: async () => import("./my-component.svelte").
    • Navigation Hooks: Add hooks to routes to intercept and control the navigation flow.
    • Automatic Styling: Includes built-in support for styling anchor tags automatically.
    • Developer Experience: Includes helper methods and debugging tools.
  2. Handle route errors with the `statuses` prop

    main

    The Router component accepts a statuses prop to define what should be rendered when a route returns a specific status code (e.g., a 404 Not Found).

    Currently, only the StatusCode.NotFound (404) is implemented. Other codes like 301, 302, 400, 401, 403, and 500 are planned for future support.

    <Router
      {routes}
      statuses={{
        [StatusCode.NotFound]: NotFound
      }} />
  3. How the Router Registry works

    main
    The registry is a global object used to store route instances and their associated routing configurations. It is managed internally by the library: when a <Router /> component is mounted, it registers itself in the registry; when it is unmounted, it unregisters itself. The registry updates dynamically as you navigate through your application or as <Router /> components are mounted and unmounted.
  4. Understand the routing hook lifecycle and execution order

    main

    The router executes hooks in a specific sequence based on their type (pre or post) and their scope (<Router/> or Route).

    1. <Router/> pre-hooks: Run before any route is attempted.
    2. Route pre-hooks: Run before a specific route is rendered.
    3. Route post-hooks: Run after a specific route is rendered.
    4. <Router/> post-hooks: Run after the route has been rendered.
    | Order | Event | Scope | Description |
    | ----- | ----- | ----------- | ------------------------------------------ |
    | 1. | `pre` | `<Router/>` | Always runs *before* a route is attempted. |
    | 2. | `pre` | `Route` | Runs *before* the route is rendered. |
    | 3. | `post` | `Route` | Runs *after* the route is rendered. |
    | 4. | `post` | `<Router/>` | Always runs *after* a route is rendered. |
  5. How the router works

    main

    The router operates through a specific lifecycle triggered by changes to the browser URL:

    1. Trigger: The router instance detects a change in the browser URL.
    2. Registration: The route is registered in the internal Router Registry.
    3. Evaluation: The router evaluates the current URL against defined route patterns to find a match.
    4. Resolution: The router resolves the matched route and renders the associated component or snippet.
  6. Use pattern matching and regex for paths

    main

    Routes can be defined using static paths or dynamic paths using regular expressions.

    Pattern Examples

    PatternDescription
    /The root path
    /fooA static path
    /foo/(.*?)A dynamic path
    /cool/(.*?)/(.*?)A dynamic path with two parameters
    (?<param1>.*)A dynamic path with a named parameter
    ^/users/(?<id>[a-z0-9]{25})(?:/(?<tab>.*))?$A dynamic path with a named parameter and optional tab

    When using named parameters (e.g., (?<id>...)), the values are accessible via $props() or the route prop.

  7. Extract Parameters from Paths

    main

    You can combine static path segments with regular expression patterns to extract data from the URL.

    Unnamed Parameters

    Use non-named capture groups (e.g., (.*?)) to match arbitrary segments of a path.

    Named Parameters

    Use named capture groups (e.g., (?<name>.*)) to extract specific values into named parameters.

    Order of operations:

    1. If arbitrary paths are used, the route must contain all of them.
    2. If parameters are used, the path must match the regex expression.
    3. If the <Router /> component has a statuses prop with 404 configured, this route will match and end evaluation if no other routes were found.
    // Unnamed Parameters
    const routes: RouteConfig[] = [
      {
        path: "/path/(.*?)/path/(.*?)",
        component: ComponentToRender 
      }
    ];
    
    // Named Parameters
    const routes: RouteConfig[] = [
      {
        path: "/path/(?<myParam>.*)/path/(?<myParam2>.*)",
        component: ComponentToRender 
      }
    ];
  8. Configure routes with RouteConfig

    main

    To set up routing, provide an array of RouteConfig objects to the <Router /> component. Each object defines a path and an associated component. If a path is omitted, the router treats that route as the default route for the root path (/).

    <script>
      import Router, { type RouteConfig } from "@mateothegreat/svelte5-router/router.svelte";
      import Home from "./Home.svelte";
      import About from "./About.svelte";
    
      const routes: RouteConfig[] = [
        {
          // Default route
          component: Home
        },
        {
          path: "/about",
          component: About
        }
      ];
    </script>
    
    <Router {routes} />
    <Router {routes} />
  9. Define a Default Route

    main

    A default route is matched when the path is empty or when no other routes match the current URL. You can define a default route in three ways:

    1. Omit the path property: The route becomes the default.
    2. Use an empty string: Set path: "".
    3. Use a forward slash: Set path: "/".

    Order of operations for matching:

    1. If the path is empty, the route matches; otherwise, evaluation continues.
    2. If no other route matches, the default route is matched.
    3. If the <Router /> component has a statuses prop with 404 configured, this route will match and end evaluation if no other routes were found.
    // Option 1: Omit path
    const routes: RouteConfig[] = [
      {
        component: ComponentToRender 
      }
    ];
    
    // Option 2: Empty string
    const routes: RouteConfig[] = [
      {
        path: "",
        component: ComponentToRender 
      }
    ];
    
    // Option 3: Forward slash
    const routes: RouteConfig[] = [
      {
        path: "/",
        component: ComponentToRender 
      }
    ];
  10. Enable the Debug Logger

    main

    To enable detailed logging for the router, you must configure the import.meta.env.SPA_ROUTER object in your vite.config.ts file. Setting logLevel to "debug" prevents the compiler from tree-shaking (removing) the debug log statements during the build process.

    It is also recommended to enable sourcemap: true in your build configuration if you intend to use a browser debugger alongside the logs.

    export default defineConfig({
      plugins: [svelte()],
      build: {
        sourcemap: true // Enable this to use a debugger!
      },
      define: {
        // Tell the router to log when we're in debug mode.
        'import.meta.env.SPA_ROUTER': {
          logLevel: "debug"
        },
      }
    });
  11. Define a Single Path Route

    main

    A single path route matches a specific URL path exactly.

    Order of operations:

    1. If the path matches exactly, the route is matched; otherwise, evaluation continues.
    2. If the <Router /> component has a statuses prop with 404 configured, this route will match and end evaluation if no other routes were found.
    const routes: RouteConfig[] = [
      {
        path: "/path",
        component: ComponentToRender 
      }
    ];