Routing & navigation
Edit this pageSolid Router simplifies routing in Solid applications to help developers manage navigation and rendering by defining routes using JSX or objects passed via props.
Getting started
1. Install the router
This package is not included by default.
2. Setup the <Router>
component
Start your application by rendering the Router component. This component will match the URL to display the desired page.
3. Provide a root level layout
This layout will not update on page change and is the ideal place for top-level navigation and Context Providers.
4. Add routes
Each route is added to the Router
using the Route
component.
Here, you specify a path and a component to render once the user navigates to that path.
5. Create a CatchAll route (404 page)
A catchall route can be used for pages not found at any nested level of the router.
Using *
will retrieve the rest of the path.
Optionally, you can also add a parameter name.
6. Create links to your routes
The <A>
component provides navigation to an application's routes.
Alternatively, you can use the native anchor tag.
However, the <A>
component provides additional functionality including properties for CSS, inactiveClass
and activeClass
.
Lazy-loading route components
The lazy
function postpones the loading of a component until it is navigated to.
Dynamic routes
If a path is unknown ahead of time, you can treat part of the path as a flexible parameter.
The colon indicates that id
can be any string, and as long as the URL fits that pattern, the <User>
component will show.
You can then access that id
from within a route component with useParams
.
Note on animation/transitions:
Routes that share the same path will be treated as the same route.
If you want to force re-render, you can wrap your component in a keyed <Show>
:
Accessing parameters
In cases where you may need to access a dynamic route's parameters within your components, the useParams
primitive is available.
Once the parameters have been accessed using useParams
, they can be used within your component:
useParams
can be especially useful with other Solid primitives, such as createResource
and createSignal
, which can create dynamic behaviors based on the route parameters.
Every time the id
parameter changes in this example, the fetchUser
function is called to fetch the new user data.
Validating routes
Each path parameter can be validated using a MatchFilter
.
Instead of checking for the presence of a parameter, this allows for more complex routing descriptions:
In this example, the matchFilters
prop provides a way to validate the parent
, id
and withHtmlExtension
parameters against the filters defined in filters
.
If the validation fails, the route will not match.
In this example:
/users/mom/123/contact.html
will match,/users/dad/123/about.html
will match,/users/aunt/123/contact.html
will not match as:parent
is not 'mom' or 'dad',/users/mom/me/contact.html
will not match as:id
is not a number,/users/dad/123/contact
will not match as:withHtmlExtension
is missing.html
.
Optional parameters
Parameters can be specified as optional by adding a question mark to the end of the parameter name:
Wildcard routes
To match any descendent routes within a given path, you can use the wildcard token (*
).
This can be used to represent any value in that segment of the path.
To expose the wildcard portion to the component as a parameter, you can name it:
Wildcard tokens must be the last part of the path; foo/*any/bar
will not create any routes.
Multiple paths
The Routes
component also supports defining multiple paths using an array.
This allows avoids a route rerendering when switching between two or more locations that it matches:
Nested routes
Only leaf <Route>
nodes (the innermost <Route>
components) are given a route.
The following two route definitions both match the same URL /users/:id
and render the same component:
If you want to make the parent its own route, you have to specify it separately:
You can also take advantage of nesting by using props.children
passed to the route component.
The routes are still configured the same, however now their components will appear inside the parent component where the props.children
is declared.
Routes can also be nested indefinitely.
This example will only render the route /layer1/layer2
, which will be nested in 3 divs.
Load functions
With load functions, data fetching is started parallel to loading the route, so it can be used as soon as possible. The load function prevents this by being called once the Route is loaded, or eagerly if links are hovered.
As the only argument, the load function is passed an object that is used to access route information:
The load function is then passed in the <Route>
definition:
You can export load functions and data wrappers that correspond to routes from a dedicated [route].data.js
or [route].data.ts
file.
This pattern provides a way to import the data function without loading anything else.
loadUser
is passed an object which contains params
, location
and intent
.
Please note that while it is best practice to write these files as [id].data.js
, you can still write route.data.js
.
The value of a load function is passed to the page component when called at any time other than "preload". This means you can initialize the page, or use Data APIs.
To prevent a fetch from happening more than once, or to trigger a refetch, you can use the cache
function.
[id].jsx
contains the component that gets rendered.
When you wrap the function within createAsync
with the imported function, it will yield a signal once the anticipated promise resolves.
To learn more about routing your Solid applications, visit the Solid Router documentation.