web/versioned_docs/version-0.23/advanced/routing.md
Wasp uses React Router under the hood. Route paths support all the standard patterns described below.
Use :paramName in a route path to match any value in that segment. Access the matched value in your page component with the useParams hook from react-router.
route PhotoRoute { path: "/photo/:photoId", to: PhotoPage }
page PhotoPage {
component: import { PhotoPage } from "@src/PhotoPage"
}
import { useParams } from 'react-router'
export function PhotoPage() {
const { photoId } = useParams<'photoId'>()
return <div>Viewing photo {photoId}</div>
}
Read more in the React Router docs on dynamic segments.
Append ? to a path segment to make it optional. The route will match whether or not the segment is present.
route PhotoRoute { path: "/photo/:photoId/edit?", to: PhotoPage }
page PhotoPage {
component: import { PhotoPage } from "@src/PhotoPage"
}
import { useParams, useLocation } from 'react-router'
export function PhotoPage() {
const { photoId } = useParams<'photoId'>()
const { pathname } = useLocation()
const isEditing = pathname.endsWith('/edit')
return <div>{isEditing ? 'Editing' : 'Viewing'} photo {photoId}</div>
}
Read more in the React Router docs on optional segments.
Use /* at the end of a route path to match any remaining path segments. Access the matched portion with the '*' param.
route FilesRoute { path: "/files/*", to: FilesPage }
page FilesPage {
component: import { FilesPage } from "@src/FilesPage"
}
import { useParams } from 'react-router'
export function FilesPage() {
const { '*': filePath } = useParams()
// Visiting /files/docs/report.txt → filePath = "docs/report.txt"
return <div>File: {filePath}</div>
}
Read more in the React Router docs on splats.
By default, Wasp lazy-loads all page routes using React Router's lazy property. This means each page's code is only downloaded when the user navigates to it, resulting in smaller initial bundle sizes. This is especially useful for apps with many routes.
If you need a specific route to be eagerly loaded (included in the main bundle), you can set lazy: false on the route declaration:
// This route's page will be included in the initial bundle
route DashboardRoute { path: "/dashboard", to: DashboardPage, lazy: false }
:::note Most apps won't need to change this. Disabling lazy loading is useful when you want to avoid the brief loading delay for a page that users navigate to very frequently, at the cost of a larger initial download. :::
You can prerender specific routes at build time by setting prerender: true. This generates static HTML that is served immediately, giving faster load times and better SEO.
route LandingRoute { path: "/", to: LandingPage, prerender: true }
Prerendering works on static paths only and cannot be used with authRequired pages. See the Prerendering page for the full documentation.