sveltekit-gen-routes Svelte Themes

Sveltekit Gen Routes

A vite plugin to generate route helpers for sveltekit.

@fehnomenal/sveltekit-gen-routes

This vite plugin generates route helpers for sveltekit routes.

Getting started

Choose the one for your package manager.

npm install -D 'github:fehnomenal/sveltekit-gen-routes#semver:v4.1.6'
yarn install -D 'github:fehnomenal/sveltekit-gen-routes#semver:v4.1.6'
pnpm install -D 'github:fehnomenal/sveltekit-gen-routes#semver:v4.1.6'
bun add -D 'github:fehnomenal/sveltekit-gen-routes#v4.1.6'

Import and include the plugin in your vite.config.ts:

import { sveltekitRoutes } from '@fehnomenal/sveltekit-gen-routes';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [
    sveltekit(),
    sveltekitRoutes(),
  ],
});

Run pnpm dev and a new module (by default $routes) will be available containing constants and functions for all of your page routes, server endpoints and form actions:

import { PAGE__ROOT, PAGE_blog_post } from '$routes';

console.log(PAGE__ROOT);
// Output without base path: '/'

console.log(PAGE_blog_post(123));
// Output without base path: '/blog/123'

What?

On each build and during development a declaration file (by default src/$routes.d.ts) will be generated containing constants and functions for each of your page routes, server endpoints and form actions. The names are derived from the route id prefixed with the type (PAGE, SERVER or ACTION) and potentially suffixed with the endpoint method or action name.

Additionally a PAGE__ROOT constant is generated for the root route.

Routes without path (or query) parameters are simple string constants. To allow setting query parameters a second function (suffixed with _query) is generated that takes the query parameters as the only argument and returns a string with the query string appended.

Routes with a single path (or query) parameter will become a function with one argument for the parameter and an optional second argument for arbitrary query parameters.

Routes with more than one path (or query) parameter will become a function taking an object of parameter names to values as the first argument and optionally arbitrary query as the second argument.

For example for the following route structure:

src/params
└── int.ts
src/routes
├── (home)
│  └── +page.svelte
├── api
│  └── health
│     └── +server.ts       <-- GET handler
├── blog
│  └── [category_slug]
│     ├── +page.svelte
│     └── [post_id=int]
│        └── +page.svelte
└── contact
   ├── +page.server.ts     <-- submit_form action
   └── +page.svelte

This module declaration is generated:

declare module '$routes' {
  type Base = typeof import('$app/paths').base;

  type Param_int = Parameters<typeof import('./params/int.js').match>[0];

  type QueryParams = URLSearchParams | Record<string, string | undefined> | [string, string | undefined][];

  export const PAGE__ROOT: `${Base}/`;
  export const PAGE__ROOT_query: (
    queryParams: QueryParams,
  ) => `${Base}/${string}`;

  export const PAGE_blog_category_slug = (
    category_slug: string | number,
    queryParams?: QueryParams,
  ) => `${Base}/blog/${string | number}${string}`;

  export const PAGE_blog_category_slug_post_id_int = (
    params: {
      category_slug: string | number,
      post_id: Param_int,
    },
    queryParams?: QueryParams,
  ) => `${Base}/blog/${string | number}/${Param_int}${string}`;

  export const PAGE_contact: `${Base}/contact`;
  export const PAGE_contact_query: (
    queryParams: QueryParams,
  ) => `${Base}/contact${string}`;

  export const PAGE_home: `${Base}/`;
  export const PAGE_home_query: (
    queryParams: QueryParams,
  ) => `${Base}/${string}`;

  export const SERVER_api_health_GET: `${Base}/api/health`;
  export const SERVER_api_health_GET_query: (
    queryParams: QueryParams,
  ) => `${Base}/api/health${string}`;

  export const ACTION_contact_submit_form: `${Base}/contact?/submit_form`;
  export const ACTION_contact_submit_form_query: (
    queryParams: QueryParams,
  ) => `${Base}/contact?/submit_form${string}`;
}

Configuration

The sveltekitRoutes function takes an object for configuration. Here you can change the name of the module (also changes the name of the generated file), the paths of your application and the output directory:

  /**
   * Module to import routes from.
   * @default '$routes'
   */
  moduleName?: string;
  /**
   * Path to your routes folder.
   * @default './src/routes'
   */
  routesDir?: string;
  /**
   * Path to your params folder.
   * @default './src/params'
   */
  paramMatchersDir?: string;
  /**
   * Folder to place the generated file(s) in.
   * @default './src'
   */
  outputDir?: string;
  /**
   * Always create a route `PAGE__ROOT` even when no files `src/routes/+page.svelte` or `src/routes/+page.(js|ts)` are present.
   * @default true
   */
  forceRootRoute?: boolean;

You can define explicit query parameters for each route:

    sveltekitRoutes({
      SERVERS: {
        api_health_GET: {
          explicitQueryParams: {
            module: { type: 'string', required: true },
          },
        },
      },
    }),

This removes the generated constant (as the route has parameters now) and changes the function:

  export const SERVER_api_health_GET = (
    module: string,
    queryParams?: QueryParams,
  ) => `${Base}/api/health${string}`;

You can even get typesafety inside the configuration object:

+import type { ROUTES } from '$routes';
 import { sveltekitRoutes } from '@fehnomenal/sveltekit-gen-routes';
 import { sveltekit } from '@sveltejs/kit/vite';
 import { defineConfig } from 'vite';

 export default defineConfig({
   plugins: [
     sveltekit(),
-    sveltekitRoutes(),
+    sveltekitRoutes<ROUTES>({
+      SERVERS: {
+        api_health_GET: {
+          explicitQueryParams: {
+            module: { type: 'string' },
+          },
+        },
+      }
+    }),
   ],
 });

Development and publishing

Dev

> bun i
> # optionally on a new branch
> git switch -c ...
> # work work work
> bun changeset
> git add ...
> git commit
> # optionally push branch for automated tests
> git push

Publish

> bun version
> # update readme
> git add ...
> git commit -m "bump version to v..."
> bun run publish
> git push
> git push --tags

Top categories

Loading Svelte Themes