> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# Routing and Navigation

Plan: B2B Developer

Lesson 11 of 25 · 20 min

## Introduction

In a traditional web application, browsing to a new URL triggers a new HTTP request, and the server returns a full HTML page.

The Buyer Portal is a single-page React application, meaning that all functionality runs in the browser; this includes navigating from one Buyer Portal page to another. No full page reload is required when the user moves from "Orders" to "Invoices," only a re-rendering of appropriate page components. To support this, the app needs a **client-side routing solution** that:

* Maps URL changes (or in-app "go to page" actions) to a React component structure.
* Keeps the URL in sync so that browser navigation behavior and links still work.
* Avoids full HTTP requests for in-app navigation, for maximum performance.

---

## React Router

[**React Router**](https://reactrouter.com/) is one of the most popular, fully featured solutions for client-side routing. It keeps the UI in sync with the URL by matching the current location to a set of route definitions and rendering the corresponding components. Key concepts:

* **Routes:** A route matches a URL pattern with a top-level page component.
* **Initial Loading:** When a user initially browses to a URL, the router examines the client-side pattern and renders the right component structure.
* **Navigation:** React Router provides a programmatic way to navigate to different routes, triggering re-rendering without fetching a new page from the server.

React Router makes several styles of router available. [`HashRouter`](https://reactrouter.com/6.30.3/router-components/hash-router) is the router used by the Buyer Portal. With this router, the "hash" portion of a URL represents the Buyer Portal page:

```text showLineNumbers={false}
https://mystore.com/garden/#/orders
https://mystore.com/garden/#/invoice
```

Everything after the `#` in the URL is ignored by the server in full page requests, but is used in the browser to determine the current Buyer Portal page.

The router supports nesting routes, with parent routes representing earlier segments of the URL path (such as a top-level `/` route), and their components wrapping child routes. The following is a simple demonstration of an app implementing `HashRouter` for paths like the above:

```tsx showLineNumbers={false}
import { HashRouter, Routes, Route } from 'react-router-dom';

function App() {
  return (
    <HashRouter>
      <Routes>
        <Route path="/" element={<ExampleTopComponent />} />
          <Route path="/orders" element={<ExampleOrdersComponent />} />
          <Route path="/invoice" element={<ExampleInvoiceComponent />} />
        </Route>
      </Routes>
    </HashRouter>
  );
}
```

Note that in the full context of a BigCommerce storefront, the portion of the URL *before* the `#` does determine the server-side page that is initially rendered. (For example, a catalog page.) The URL path `/garden/#/orders` might indicate the shopper browsed to a Garden category page before opening the Buyer Portal, after which client-side routing takes over. The paths `/garden/#/orders` and `/kitchen/#/orders` will render different initial server-side pages, but the Buyer Portal content will be identical.

---

## React Router in the Buyer Portal

> **Info**
>
> All file paths referenced in these exercises are relative to `apps/storefront/src` in your Buyer Portal project.

The low-level details of the React Router implementation are taken care of by built-in layout in the Buyer Portal. To add or customize routes, it is typically only necessary to modify the portal's own configuration files. These source files are involved:

* `App.tsx`: Renders `<HashRouter>`
* `components/layout/B3RenderRouter.tsx`: Renders all `<Route>` components based on config
* `shared/routeList.ts` and `shared/routes/index.tsx`: The central routes configuration

You'll see more of the details in the exercise to come.

## Permissions

In the Buyer Portal, we need to be concerned not only with routing itself, but with a user's permissions to access a particular route.

There are two important concepts for company user authorization:

* Users have different **roles**. Built-in roles include Admin, Senior Buyer, and Junior Buyer. It's possible to create custom roles in your own store.
* A role has one or more **permissions**. Permissions represent the specific actions that a user can perform, including the ability to view certain content.

Part of a route's configuration includes both role-based and permission-based details about who can access the route. You'll be modifying details in `shared/routes/config.ts` in the next exercise.

## Navigating Between Pages

It's not appropriate to use typical `<a>` elements to navigate between pages in a single-page application. While a link to `/current-page/#/orders` will result in the correct content being rendered, the round trip to the server to render the new URL from scratch is unnecesssary.

Because the Buyer Portal is built on React Router, client-side navigation uses React Router's own [`useNavigate`](https://reactrouter.com/6.30.3/hooks/use-navigate) hook. The hook returns a function that accepts a Buyer Portal path:

```tsx showLineNumbers={false}
import { useNavigate } from 'react-router-dom';
import { HeadlessRoutes } from '@/constants';

function MyComponent() {
  const navigate = useNavigate();

  return (
    <Button onClick={() => navigate(HeadlessRoutes.COMPANY_ORDERS)}>
      All Orders
    </Button>
  );
}
```

Prefer the `HeadlessRoutes` constants over hand-written path strings where a constant exists. Paths can also be passed directly when they include a dynamic segment, such as `/orderDetail/${orderId}`.

> **Info**
>
> You'll also see a `setOpenPage` function passed as a prop to page components in the Buyer Portal codebase. Despite its name, this is the app shell's mechanism for **opening and closing** the portal UI — it accepts an `isOpen` value — rather than a navigation API. Use `useNavigate` to move between pages.

## Resources

* [**React Router**](https://reactrouter.com/)
* [`HashRouter`](https://reactrouter.com/6.30.3/router-components/hash-router)
* [`useNavigate`](https://reactrouter.com/6.30.3/hooks/use-navigate)