Use createNavigationConfig to define your application's route structure in a single location. This function accepts a callback that provides a defineRoute helper. You can define params for dynamic segments and search for query string parameters using a validation schema.
Tip: Enable experimental.typedRoutes in next.config.js for improved autocomplete experience.
// src/shared/navigation.ts
import { createNavigationConfig } from 'next-safe-navigation';
import { z } from 'zod';
export const { routes, useSafeParams, useSafeSearchParams } =
createNavigationConfig((defineRoute) => ({
home: defineRoute('/'),
customers: defineRoute('/customers', {
search: z
.object({
query: z.string().default(''),
page: z.coerce.number().default(1),
})
.default({ query: '', page: 1 }),
}),
invoice: defineRoute('/invoices/[invoiceId]', {
params: z.object({
invoiceId: z.string(),
}),
}),
shop: defineRoute('/support/[...tickets]', {
params: z.object({
tickets: z.array(z.string()),
}),
}),
shop: defineRoute('/shop/[[...slug]]', {
params: z.object({
// ⚠️ Remember to always set your optional catch-all segments
// as optional values, or add a default value to them
slug: z.array(z.string()).optional(),
}),
}),
}));