🧪 Typed Routes
Stage: prototyping
Provides type safe way of building URLs within the application.
Installation
pnpm install github:QwikDev/qwik-labs-build#main
npm install github:QwikDev/qwik-labs-build#main
yarn add github:QwikDev/qwik-labs-build#main
bun install github:QwikDev/qwik-labs-build#main
- 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 ], // ... }; });
- Run build so that it generates
~/routes.gen.d.ts
and~/routes.config.tsx
files. - 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
pnpm dlx declarative-routing init
npx declarative-routing init
yarn dlx declarative-routing init
bunx declarative-routing init
Setup
The initialization process will create some important files for you.
.src/declarativeRoutes
makeRoute.ts
- Used for defining page routesindex.ts
- Where all of your route files will be imported from.hooks.ts
- A file with two custom hooksuseParams
&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 theparams
andsearch
(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.
- Use RouteName.Link
myComponent.tsx
import { PokemonDetail } from "~/declarativeRoutes";
export default component$(() => {
// ...
return (
// ...
<PokemonDetail.Link pokemonId={1}>Bulbasaur</PokemonDetail.Link>
);
});
- 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>
);
});
- Use RouteName.ParamsLink
myComponent.tsx
import { PokemonDetail } from "~/declarativeRoutes";
export default component$(() => {
// ...
return (
// ...
<PokemonDetail.ParamsLink params={{ pokemonId: 1 }}>Bulbasaur</PokemonDetail.ParamsLink>
);
});
- 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
pnpm dlx declarative-routing build
npx declarative-routing build
yarn dlx declarative-routing build
bunx declarative-routing build
and this will rerun the process and update any changes needed