We're importing two things from React Router: the <RouterProvider>
component and the createBrowserRouter()
function. The <RouterProvider>
component is the main entry point to our app while the createBrowserRouter()
function is what we use to configure our routes. We're passing the return value to our <RouterProvider>
instance via its .router
prop. We're also importing our routes and their loader functions.
We're passing an array of objects to the createBrowserRouter()
function. Each object represents a route. I prefer to use plain object literals, but you can alternatively use the createRoutesFromElements()
function to configure your routes in JSX.
Both routes wire up their loader functions and both render the <ErrorPage>
component if they encounter an error. The /
route renders the <Home>
component while the posts/:postId
route renders the <Post>
component. The :postId
part of the path is the dynamic segment which is accessible via the params.postId
property in the route's loader function.
Demo of client-side routing with React Router.
In today's post, we used React Router to enable client-side routing in our React app. This lets us use multiple pages even though we only have a single HTML file. This is known as a single-page app (SPA) and is useful for highly interactive web apps. While I think this approach is overused, I recommend Rich Harris' talk about transitional apps for a more optimistic view.
We've only scratched the surface of what React Router can do, so I recommend trying the official tutorial. React Router is actually part of Remix, a React framework I recommend for a more complete solution. Next.js is a popular alternative. Both tools support pre-rendering, meaning your app doesn't need to rely entirely on JavaScript in order to function. In other words, this is how we always used to build websites, and it results in a more stable experience.