Routing
Routing is possibly the most important concept to understand in SolidStart. Everything starts with your routes: the compiler, the initial request, and almost every user interaction afterward. In this section, you'll learn how to write basic routes, navigate between routes, and handle more complex/dynamic routing scenarios.
There are two categories of routes:
- UI routes, which define the user interfaces in your app
- API routes, which define data endpoints in your app
This section of the documentation will mainly focus on UI routes.
Creating pages
SolidStart uses file system-based routing. This means that the directory path of your route files will translate exactly to the route structure in your application.
Here are a few examples of files in our directory structure and how they would translate to application routes:
/src/routes/index.tsx
➜mysite.com
/src/routes/admin/index.tsx
➜mysite.com/admin
/src/routes/admin/edit-settings.tsx
➜mysite.com/admin/edit-settings
We put all our routes in the same top-level directory, src/routes
. This includes our pages, but also our API routes. For a route to be rendered as a page, it should default export a component. This component represents the content that will be rendered when users visit the page:
tsx
export default function Index() {return <div>Welcome to SolidStart!</div>;}
tsx
export default function Index() {return <div>Welcome to SolidStart!</div>;}
In this example, visiting mysite.com/ will render a <div>
with the text "Welcome to SolidStart!" inside it.
show mini demo of mysite.com with text
Under the hood, SolidStart traverses your routes
directory, collects all the routes, and makes them accessible using the <FileRoutes />
component. The <FileRoutes />
component only includes your page routes, and not your API routes. This component can be used instead of manually specifying routes inside the <Routes />
component in root.tsx
.
tsx
import { Html, Body, Routes, FileRoutes } from "solid-start";export default function Root() {return (<Html><Body><Routes><FileRoutes /></Routes></Body></Html>);}
tsx
import { Html, Body, Routes, FileRoutes } from "solid-start";export default function Root() {return (<Html><Body><Routes><FileRoutes /></Routes></Body></Html>);}
This means that all you have to do is create a route in your directory structure and SolidStart takes care of everything else needed to make that route available to visit in your application!
Navigating between pages
While the user can enter your app from any URL that your app serves, once they are using your app, you can provide them a user experience that is designed. You need a way for the user to travel between your pages. As with any website, you can use a
tags to add links between pages in your app. Nothing special! Lets look at an example,
Using links
The easiest way to add a link to another page in your app is to the use the anchor tag A
. Similar to what you would do in a plain HTML document, you can add a href
attribute to the A
tag and we will navigate to that route in SPA style.
tsx
export default function Index() {return (<div><A href="/about">About</A></div>);}
tsx
export default function Index() {return (<div><A href="/about">About</A></div>);}
If you use an a
tag, you have to use the absolute path to the route you want to navigate to. You might find it easier to specify the path to a route relative to the current route. There are also cases where you might want to know if the href
matches the current route for styling purposes. For these situations, we have the [A][A] component re-exported from @solidjs/router
.
You can specify class names to add to the A
tag when the current location matches the href
of the anchor using the activeClass
prop. Use the inactive
prop to add a class name to the a
tag if the current route does not match the href
of the anchor.
tsx
import { A } from "solid-start"export default function UsersLayout() {return (<div><Ahref="./projects"activeClass="active-link"inactiveClass="inactive-link">Projects</A>// renders this when the user is on /users/1/projects<a href="/users/1/projects" class="active-link">Projects</a>// and this when the user is on /users/1/tasks<a href="/users/1/projects" class="inactive-link">Projects</a></div>);}
tsx
import { A } from "solid-start"export default function UsersLayout() {return (<div><Ahref="./projects"activeClass="active-link"inactiveClass="inactive-link">Projects</A>// renders this when the user is on /users/1/projects<a href="/users/1/projects" class="active-link">Projects</a>// and this when the user is on /users/1/tasks<a href="/users/1/projects" class="inactive-link">Projects</a></div>);}
When the user clicks a button
There are cases where the link
tag is not right for your navigation needs. For example,
- You want to navigate after the user clicks a button, and we do some logic.
- You want to navigate after an async process completes
For these use cases we provide an imperative navigate
function that can be access using the useNavigate
helper
Redirecting
-
The primary way of redirecting from a route to another is to use the
<Navigate />
component in the JSX. For example, if you want to redirect to the home page, you can use the following code.- Server: When we get a request for this page, we will rend a
308 (Redirect)
response withLocation
header set to the home page. The browser will then do its normal redirect routine. This also helps crawlers to understand that the page should be redirected. - Client: When you navigate to this page from another page in the site, we will immediately navigate to the home page.
- Server: When we get a request for this page, we will rend a
tsx
export default function InactivePage() {return <Navigate to="/" />;}
tsx
export default function InactivePage() {return <Navigate to="/" />;}
- routeData, accessing parent route data
- Throwing in route data
- Search query params (not sure yet optimal API for this)
- Instructions for creating basic pages
- Nested routes (e.g.,
auth.tsx
vsauth/login.tsx
)- Talk about using route data function in parent route