> ## Documentation Index
> Fetch the complete documentation index at: https://developers.hubspot.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

---
id: 3fdd71a4-854e-4c18-8aa5-72f7a56f4d09
---

# PageRoutes

> Learn about the PageRoutes component for defining routes in your app.

export const ComponentProp = ({name, required, type, description, defaultValue, seeItems}) => {
  const renderSeeItems = () => {
    if (!seeItems || seeItems.length === 0) {
      return null;
    }
    if (seeItems.length === 1) {
      return <div className="component-prop-see-wrapper">
          <strong>See:</strong> {seeItems[0]}
        </div>;
    }
    return <div className="component-prop-see-wrapper">
        See:
        <ul>
          {seeItems.map((item, index) => <li key={index}>{item}</li>)}
        </ul>
      </div>;
  };
  return <tr>
      <td>
        <code>{name}</code>
        {required && <> <Tag type="error">Required</Tag></>}
      </td>
      <td>
        {type}
        {defaultValue && <div className="component-prop-default-value-wrapper">
            <strong>Default:</strong> {defaultValue}
          </div>}
      </td>
      <td>
        {description}
        {renderSeeItems()}
      </td>
    </tr>;
};

export const ComponentProps = ({children}) => {
  return <div className="component-props">
      <table>
        <thead>
          <tr>
            <th>Prop</th>
            <th>Type</th>
            <th>Description</th>
          </tr>
        </thead>
        <tbody>{children}</tbody>
      </table>
    </div>;
};

export const Tag = ({children, type = 'default', className = ''}) => {
  return <span className={`tag tag-${type} ${className}`.trim()}>
      {children}
    </span>;
};

The `PageRoutes` component and its sub-components are used to define routing for app pages. Use `createPageRouter` to wrap your route definitions, which returns a React component that handles routing.

```tsx theme={null}
import { createPageRouter, PageRoutes } from "@hubspot/ui-extensions/pages";

const PageRouter = createPageRouter(
  <PageRoutes>
    <PageRoutes.IndexRoute component={AppHomePage} />
    <PageRoutes.Route path="/docs" component={AppDocsPage} />
    <PageRoutes.Route path="/support" component={AppSupportPage} />
    <PageRoutes.AnyRoute component={AppNotFoundPage} />
  </PageRoutes>
);
```

## Basic example

Here's a complete example showing how to create multiple pages in your app with routing:

```tsx theme={null}
import React from "react";
import { Text, Heading, hubspot } from "@hubspot/ui-extensions";
import { createPageRouter, PageHeader, PageRoutes, PageLink, PageBreadcrumbs, PageTitle } from "@hubspot/ui-extensions/pages";

const AppHomePage = () => {
  return (
    <>
      <PageBreadcrumbs>
        <PageBreadcrumbs.Current>Home</PageBreadcrumbs.Current>
      </PageBreadcrumbs>
      <PageTitle>Home</PageTitle>

      <Text>This is the home page of your app.</Text>
      <PageLink to="/docs">View Documentation</PageLink>
    </>
  );
};

const AppDocsPage = () => {
  return (
    <>
      <PageBreadcrumbs>
        <PageBreadcrumbs.PageLink to="/">Home</PageBreadcrumbs.PageLink>
        <PageBreadcrumbs.Current>Documentation</PageBreadcrumbs.Current>
      </PageBreadcrumbs>
      <PageTitle>Documentation</PageTitle>

      <Text>Welcome to the documentation page!</Text>
      <PageLink to="/">Back to Home</PageLink>
    </>
  );
};

const AppNotFoundPage = () => {
  return (
    <>
      <PageBreadcrumbs>
        <PageBreadcrumbs.PageLink to="/">Home</PageBreadcrumbs.PageLink>
        <PageBreadcrumbs.Current>Not Found</PageBreadcrumbs.Current>
      </PageBreadcrumbs>
      <PageTitle>Page Not Found</PageTitle>

      <Text>The page you're looking for doesn't exist.</Text>
      <PageLink to="/">Go to Home</PageLink>
    </>
  );
};

const PageRouter = createPageRouter(
  <PageRoutes>
    <PageRoutes.IndexRoute component={AppHomePage} />
    <PageRoutes.Route path="/docs" component={AppDocsPage} />
    <PageRoutes.AnyRoute component={AppNotFoundPage} />
  </PageRoutes>
);

const AppPages = () => {
  return (
    <>
      <PageHeader>
        <PageHeader.PrimaryAction>
          <PageBreadcrumbs.PageLink to="/">Home</PageBreadcrumbs.PageLink>
        </PageHeader.PrimaryAction>
        <PageHeader.SecondaryActions>
          <PageBreadcrumbs.PageLink to="/docs">Documentation</PageBreadcrumbs.PageLink>
        </PageHeader.SecondaryActions>
      </PageHeader>

      <PageRouter />
    </>
  );
};

hubspot.extend<"pages">(() => <AppPages />);
```

## createPageRouter

The `createPageRouter` function accepts JSX route definitions and returns a React component that handles routing. Call it at the module level with your `<PageRoutes>` tree:

```jsx theme={null}
import { createPageRouter, PageRoutes } from "@hubspot/ui-extensions/pages";

const PageRouter = createPageRouter(
  <PageRoutes>
    <PageRoutes.IndexRoute component={HomePage} />
    <PageRoutes.Route path="/about" component={AboutPage} />
  </PageRoutes>
);

function App() {
  return <PageRouter />;
}
```

### Parameters

| Parameter | Type        | Required | Description                                                 |
| --------- | ----------- | -------- | ----------------------------------------------------------- |
| `routes`  | `ReactNode` | Yes      | A `<PageRoutes>` JSX tree defining all routes for your app. |

### Returns

A React component (`PageRouter`) that you render in your app to activate routing.

## PageRoutes

The `PageRoutes` component is the container for route definitions. When used as the root element passed to `createPageRouter`, it defines the top-level routes. When nested inside another `<PageRoutes>`, it defines a group of sub-routes under a shared path prefix.

```jsx theme={null}
import { createPageRouter, PageRoutes } from "@hubspot/ui-extensions/pages";

const PageRouter = createPageRouter(
  <PageRoutes layoutComponent={AppLayout}>
    <PageRoutes.IndexRoute component={HomePage} />
    <PageRoutes.Route path="/about" component={AboutPage} />
  </PageRoutes>
);
```

### Props

<ComponentProps autoGenerated componentName="PageRoutes">
  <ComponentProp name="children" required={true} type={<><code>ReactNode</code></>} description={<>Sets the content that will render inside the component. Should contain <code>PageRoutes.IndexRoute</code>, <code>PageRoutes.Route</code>, <code>PageRoutes.AnyRoute</code>, and/or nested <code>PageRoutes</code> components.</>} />

  <ComponentProp name="path" required={false} type={<><code>string</code></>} description={<>The path prefix for nested routes. Required when nesting <code>PageRoutes</code> inside another <code>PageRoutes</code>. Child routes will be scoped under this path.</>} />

  <ComponentProp name="layoutComponent" required={false} type={<><code>ComponentType&lt;&#123; children: ReactNode &#125;&gt;</code></>} description={<>A React component that wraps all child routes. Receives the matched page as <code>children</code>. Useful for shared navigation, sidebars, or other persistent UI.</>} />

  <ComponentProp name="testId" required={false} type={<><code>string</code></>} description={<>Used by <code>findByTestId()</code> to locate this component in tests.</>} seeItems={[<><a href="https://developers.hubspot.com/docs/apps/developer-platform/add-features/ui-extensibility/testing/reference#findbytestid">Testing utilities reference</a></>]} />
</ComponentProps>

## PageRoutes.IndexRoute

The `PageRoutes.IndexRoute` component defines the home page (index route) of your app or a nested section. This is the page that will be rendered when users navigate to the base URL of the enclosing `PageRoutes`.

```jsx theme={null}
<PageRoutes.IndexRoute component={AppHomePage} />
```

### Props

<ComponentProps autoGenerated componentName="PageRoutes.IndexRoute">
  <ComponentProp name="id" required={false} type={<><code>string</code></>} description={<>A stable identifier for this route. When the route matches, the <code>id</code> value is available as <code>routeId</code> from the <code>usePageRoute</code> hook. Useful for determining which route is active in layout components.</>} />

  <ComponentProp name="component" required={true} type={<><code>ComponentType</code></>} description={<>The React component to render when the index route matches. Pass the component reference, not a JSX element.</>} />

  <ComponentProp name="testId" required={false} type={<><code>string</code></>} description={<>Used by <code>findByTestId()</code> to locate this component in tests.</>} seeItems={[<><a href="https://developers.hubspot.com/docs/apps/developer-platform/add-features/ui-extensibility/testing/reference#findbytestid">Testing utilities reference</a></>]} />
</ComponentProps>

## PageRoutes.Route

The `PageRoutes.Route` component defines a named page route in your app. Users can navigate to these routes using the path specified in the `path` prop.

```jsx theme={null}
<PageRoutes.Route path="/docs" component={DocsPage} />
<PageRoutes.Route path="/settings" component={SettingsPage} />
```

### Props

<ComponentProps autoGenerated componentName="PageRoutes.Route">
  <ComponentProp name="id" required={false} type={<><code>string</code></>} description={<>A stable identifier for this route. When the route matches, the <code>id</code> value is available as <code>routeId</code> from the <code>usePageRoute</code> hook. Useful for determining which route is active in layout components.</>} />

  <ComponentProp name="path" required={true} type={<><code>string</code></>} description={<>The path for this route. Paths are automatically normalized, so both <code>"docs"</code> and <code>"/docs"</code> work equivalently.</>} />

  <ComponentProp name="component" required={true} type={<><code>ComponentType</code></>} description={<>The React component to render when this route matches. Pass the component reference, not a JSX element.</>} />

  <ComponentProp name="testId" required={false} type={<><code>string</code></>} description={<>Used by <code>findByTestId()</code> to locate this component in tests.</>} seeItems={[<><a href="https://developers.hubspot.com/docs/apps/developer-platform/add-features/ui-extensibility/testing/reference#findbytestid">Testing utilities reference</a></>]} />
</ComponentProps>

## PageRoutes.AnyRoute

The `PageRoutes.AnyRoute` component defines a catch-all route that will be rendered when no other routes match. This is useful for displaying a custom 404 or "page not found" message.

```jsx theme={null}
<PageRoutes.AnyRoute component={NotFoundPage} />
```

### Props

<ComponentProps autoGenerated componentName="PageRoutes.AnyRoute">
  <ComponentProp name="id" required={false} type={<><code>string</code></>} description={<>A stable identifier for this route. When the route matches, the <code>id</code> value is available as <code>routeId</code> from the <code>usePageRoute</code> hook. Useful for determining which route is active in layout components.</>} />

  <ComponentProp name="component" required={true} type={<><code>ComponentType</code></>} description={<>The React component to render when no other routes match. Pass the component reference, not a JSX element.</>} />

  <ComponentProp name="testId" required={false} type={<><code>string</code></>} description={<>Used by <code>findByTestId()</code> to locate this component in tests.</>} seeItems={[<><a href="https://developers.hubspot.com/docs/apps/developer-platform/add-features/ui-extensibility/testing/reference#findbytestid">Testing utilities reference</a></>]} />
</ComponentProps>

## Guidelines

* **DO:** use `createPageRouter` to define your routes and render the returned component.
* **DO:** use `PageRoutes.IndexRoute` to define your app's home page.
* **DO:** use meaningful path names that describe the page content (e.g., "/docs", "/settings", "/support").
* **DO:** include a `PageRoutes.AnyRoute` to handle unmatched routes gracefully.
* **DO:** use `layoutComponent` to share common UI across groups of routes.
* **DO:** assign an `id` to each route when you need to identify the active route in layout components.

## Related components

* [PageHeader](/apps/developer-platform/add-features/ui-extensions/ui-components/app-page-components/page-header)
* [PageLink](/apps/developer-platform/add-features/ui-extensions/ui-components/app-page-components/page-link)
* [PageBreadcrumbs](/apps/developer-platform/add-features/ui-extensions/ui-components/app-page-components/page-breadcrumbs)
* [PageTitle](/apps/developer-platform/add-features/ui-extensions/ui-components/app-page-components/page-title)

## Related guides

* [Create app pages](/apps/developer-platform/add-features/ui-extensions/extension-points/app-pages/create-app-pages)
* [Page routing guide](/apps/developer-platform/add-features/ui-extensions/extension-points/app-pages/page-routing)
* [Page linking guide](/apps/developer-platform/add-features/ui-extensions/extension-points/app-pages/page-linking)
* [App pages reference](/apps/developer-platform/add-features/ui-extensions/extension-points/app-pages/reference)
