๐Ÿงช Typed Routes

Stage: prototyping

Provides type safe way of building URLs within the application.

Installation

  1. update vite.config.ts
    // ...
    import { qwikTypes } from '@builder.io/qwik-labs/vite';
     
    export default defineConfig(() => {
      return {
        plugins: [
         // ...
         qwikTypes() // <== Add `qwikTypes()` to the list of plugins
        ],
        // ...
      };
    });
  2. Run build so that it generates ~/routes.gen.d.ts and ~/routes.config.tsx files.
  3. To create a typesafe link:
    import { AppLink } from '~/routes.config';
     
    export default component$(() => {
      // ...
      return (
        // ...
        <AppLink route="/your/[appParam]/link/" param:appParam={"some-value"}>
          Link text
        </AppLink>
      );
    });

Declarative Routing

This is a package originally created by Jack Herrington aka "The Blue Collar Coder" for type safe routing inside NextJS applications and has been adapted for use inside QwikCity

Installation

Setup

The initialization process will create some important files for you.

.src/declarativeRoutes

  • makeRoute.ts - Used for defining page routes
  • index.ts - Where all of your route files will be imported from.
  • hooks.ts - A file with two custom hooks useParams & useSearchParams used to access type safe route urls, params, and searchParams

Each of your route directories

  • routeInfo.ts - Where you name the route, and provide a zod schema for the params and search (search params)

Usage

Declare Route Details

/src/routes/pokemon/[pokemonId]/routeInfo.ts
import { z } from "zod";
 
export const Route = {
  name: "PokemonDetail",
  params: z.object({
    pokemonId: z.coerce.number(),
  }),
};

Inside Component

There are a few different ways you can use Declarative Routes inside your component.

  1. Use RouteName.Link
myComponent.tsx
import { PokemonDetail } from "~/declarativeRoutes";
 
export default component$(() => {
  // ...
  return (
    // ...
    <PokemonDetail.Link pokemonId={1}>Bulbasaur</PokemonDetail.Link>
  );
});
  1. Use the standard Link and use the RouteName as a function to return the path
myComponent.tsx
import { Link } from "@builder.io/qwik-city";
import { PokemonDetail } from "~/declarativeRoutes";
 
export default component$(() => {
  // ...
  return (
    // ...
    <Link href={PokemonDetail({ pokemonId: 1 })}>Bulbasaur</Link>
  );
});
  1. Use RouteName.ParamsLink
myComponent.tsx
import { PokemonDetail } from "~/declarativeRoutes";
 
export default component$(() => {
  // ...
  return (
    // ...
    <PokemonDetail.ParamsLink params={{ pokemonId: 1 }}>Bulbasaur</PokemonDetail.ParamsLink>
  );
});
  1. Get the params from a RouteName
myComponent.tsx
import { PokemonDetail } from "~/declarativeRoutes";
 
export default component$(() => {
  // Typescript will know the correct params and their types
  const { pokemonId } = useParams(PokemonDetail);
  // ...
  return (
    // ...
  );
});

Add or Change Routes

If you add a new route, or move an existing route, simply run

and this will rerun the process and update any changes needed

Contributors

Thanks to all the contributors who have helped make this documentation better!

  • mhevery
  • RumNCodeDev
bun install github:QwikDev/qwik-labs-build#main
npm install github:QwikDev/qwik-labs-build#main
pnpm install github:QwikDev/qwik-labs-build#main
yarn add github:QwikDev/qwik-labs-build#main
bunx declarative-routing init
npx declarative-routing init
pnpm dlx declarative-routing init
yarn dlx declarative-routing init
bunx declarative-routing build
npx declarative-routing build
pnpm dlx declarative-routing build
yarn dlx declarative-routing build