Before you start

✅ Set up a OneAuxilia application

✅ Add authentication and user management to your React app with OneAuxilia

You will learn the following:

  • Install react-router-dom

  • Create components for your routes

  • Create layouts

  • Wire layouts and routes up with createBrowserRouter

Add React Router to your OneAuxilia-powered React application

Learn how to add React Router to your application using React Router's new Data API router. This tutorial will cover configuring layouts and setting up protected routes.

1. Install react-router-dom

React Router's react-router-dom is a mature, battle tested routing package for React that gives you many options. As it is the most popular routing option, it will be used for this guide.

terminal
npm install react-router-dom

2. Create components for your routes

The exact routes you will need depends on your application. For this guide, you will create /, /contact, /dashboard, /sign-in, and sign-up routes. The /dashboard route will contain a default route (/dashbard/) and an invoices route (/dashboard/invoices). The first step will be creating basic components for these routes.

Use the tabs below to find the example components and recreate these files using the path from each tab.

src/routes/index.tsx
import { Link } from "react-router-dom";

export default function IndexPage() {
  return (
    <div>
      <h1>This is the index page</h1>
      <div>
        <ul>
          <li><Link to="/sign-up">Sign Up</Link></li>
          <li><Link to="/sign-in">Sign In</Link></li>
          <li><Link to="/contact">Contact</Link></li>
          <li><Link to="/dashboard">Dashboard</Link></li>
        </ul>
      </div>
    </div>
  )
}

3. Create layouts

You're going to create two layouts for your application. One will mount OneAuxiliaProvider and act as a top level layout. It will also be a place for a header, footer, and other standard elements for your application.

The second layout will be non-rendering and will protect everything in the /dashboard route. This avoids the need for per-page auth checks or for using OneAuxilia's control components.

src/layouts/root-layout.tsx
import { Link, Outlet, useNavigate } from 'react-router-dom'
import { OneAuxiliaProvider, SignedIn, SignedOut, UserButton } from '@oneauxilia/oneauxilia-react'

const PUBLISHABLE_KEY = import.meta.env.VITE_ONEAUXILIA_PUBLISHABLE_KEY

if (!PUBLISHABLE_KEY) {
  throw new Error("Missing Publishable Key")
}

export default function RootLayout() {
  const navigate = useNavigate();

  return (
    <OneAuxiliaProvider
      routerPush={(to) => navigate(to)}
      routerReplace={(to) => navigate(to, { replace: true })}
      publishableKey={PUBLISHABLE_KEY}
    >
      <header className="header">
        <div>
          <div>
            <p>OneAuxilia + React + React Router App</p>
          </div>
          <SignedIn>
            <UserButton />
          </SignedIn>
          <SignedOut>
            <Link to="/sign-in">Sign In</Link>
          </SignedOut>
        </div>
      </header>
      <main>
        <Outlet />
      </main>
    </OneAuxiliaProvider>
  )
}

Key Takeaways

The new root-layout.tsx has a simple header that includes the and a link to the /sign-in page instead of a . The rendering of these is controlled by the and control components. This is very similar to the Embed the and step from the React Quickstart.

Both the layouts contain an component from react-router-dom. This behaves similar to {children} in Next.js or more generic React components. You will take advantage of this component in the next step.

4. Wire layouts and routes up with createBrowserRouter

With all the routes and layouts you need created, you now need to wire up the layouts and the routes with the createBrowserRouter function from react-router-dom. This will use the Data API (aka Data Router) to configure your application.

You can start by removing src/App.tsx—the contents of that file were moved to src/layouts/root-layout.tsx.

In src/main.tsx, import RouterProvider and createBrowserRouter() from react-router-dom, as well as all of the default components from the layouts and routes you created. Replace the contents inside of <React.StrictMode /> with only . Lastly, you will build the router using createBrowserRouter().

src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import { RouterProvider, createBrowserRouter } from 'react-router-dom'

// Import the layouts
import RootLayout from './layouts/root-layout'
import DashboardLayout from './layouts/dashboard-layout'

// Import the components
import IndexPage from './routes'
import ContactPage from './routes/contact'
import SignInPage from './routes/sign-in'
import SignUpPage from './routes/sign-up'
import DashboardPage from './routes/dashboard'
import InvoicesPage from './routes/dashboard.invoices'

const router = createBrowserRouter([
  {
    element: <RootLayout />,
    children: [
      { path: "/", element: <IndexPage /> },
      { path: "/contact", element: <ContactPage /> },
      { path: "/sign-in/*", element: <SignInPage /> },
      { path: "/sign-up/*", element: <SignUpPage /> },
      {
        element: <DashboardLayout />,
        path: "dashboard",
        children: [
          { path: "/dashboard", element: <DashboardPage /> },
          { path: "/dashboard/invoices", element: <InvoicesPage /> }
        ]
      }
    ]
  }
])

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>,
)

Visit http://localhost:5173 and explore your app's pages.

Key Takeaways

  • The top most object in the router is the component, and everything else is a child. Any child route will be mounted where the component is inside the root layout. This wraps the entire application with and allows you to add a header, footer, sidebars and other pieces that will be available to the entire application.

  • Several routes are direct children of the root layout. These are all public routes. You can use control components like or check the userId from useAuth() if you want to make content protected.

  • The is child of the root layout, renders nothing, and has a check to see if the userId exists. This will confirm that a user is signed in. If the userId is not truthy, then the user will be redirected to the /sign-in route to sign-in. That protects all pages in the /dashboard route. All children of /dashboard will be mounted inside of the component in the dashboard layout.

Your application is setup with react-router-dom and ready for you to add more layouts and routes as needed! If you want to get started using a template from this guide, please clone the following repository and then checkout the integrate-react-router-dom-using-data-router-method branch.

Last updated