Skip to main content

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.

App pages support routing, allowing you to create multiple pages within your app that users can navigate between. This guide covers how to define routes, including route types, path parameters, nested routes, and how paths are normalized.

Route types

The PageRoutes component supports three types of routes to handle different navigation scenarios.

Index routes

The index route is your app’s home page, rendered when users navigate to the root URL of your app. Every app pages implementation should include an index route.
import { createPageRouter, PageRoutes } from "@hubspot/ui-extensions/pages";

const PageRouter = createPageRouter(
  <PageRoutes>
    <PageRoutes.IndexRoute component={HomePage} />
  </PageRoutes>
);
URL: https://app.hubspot.com/app/{HubID}/{appId} The index route is always accessed with an empty path or /. You don’t need to specify a path prop for index routes.

Named routes

Named routes define specific pages within your app. Each route has a unique path that users can navigate to.
<PageRoutes>
  <PageRoutes.IndexRoute component={HomePage} />
  <PageRoutes.Route path="/docs" component={DocsPage} />
  <PageRoutes.Route path="/support" component={SupportPage} />
  <PageRoutes.Route path="/analytics" component={AnalyticsPage} />
</PageRoutes>
Route paths are normalized automatically, so both "docs" and "/docs" will work. See path normalization for details.
URLs:
  • https://app.hubspot.com/app/{HubID}/{appId}/docs
  • https://app.hubspot.com/app/{HubID}/{appId}/support
  • https://app.hubspot.com/app/{HubID}/{appId}/analytics

AnyRoute component

The AnyRoute component defines a fallback route that renders when no other routes match. This is useful for displaying custom 404 pages or redirecting users.
<PageRoutes>
  <PageRoutes.IndexRoute component={HomePage} />
  <PageRoutes.Route path="/docs" component={DocsPage} />
  <PageRoutes.AnyRoute component={NotFoundPage} />
</PageRoutes>
The AnyRoute will render for any path that doesn’t match defined routes, such as /invalid-path or /does-not-exist.
It’s recommended to always include an AnyRoute to provide a better user experience when users navigate to undefined paths.

Wildcard routes (splat routes)

Wildcard routes, also known as “splat” routes, allow you to match any characters following a specific path prefix. If a route path ends with /*, it will match any characters following the /, including other / characters.
<PageRoutes>
  <PageRoutes.IndexRoute component={HomePage} />
  <PageRoutes.Route path="/files/*" component={FileBrowserPage} />
  <PageRoutes.Route path="/docs/*" component={DocsPage} />
</PageRoutes>
Example matches The table below provides examples of route patterns and sample URLs that will and won’t match:
Route PatternMatchesDoes Not Match
files/*/files/documents/report.pdf
/files/images/photo.jpg
/files/a/b/c/d.txt
/file/doc.pdf
/documents/file.txt
docs/*/docs/getting-started
/docs/api/endpoints
/docs/guides/advanced/routing
/doc/guide
/documentation/api

Accessing the wildcard value

The matched portion of the URL is available as params["*"]:
import { Heading, Text } from "@hubspot/ui-extensions";
import { usePageRoute, PageBreadcrumbs, PageTitle } from "@hubspot/ui-extensions/pages";

const FileBrowserPage = () => {
  const { params } = usePageRoute();
  const filePath = params["*"];

  // For URL: /files/documents/report.pdf
  // filePath = "documents/report.pdf"

  return (
    <>
      <PageBreadcrumbs>
        <PageBreadcrumbs.PageLink to="/">Home</PageBreadcrumbs.PageLink>
        <PageBreadcrumbs.PageLink to="/files">Files</PageBreadcrumbs.PageLink>
        <PageBreadcrumbs.Current>{filePath}</PageBreadcrumbs.Current>
      </PageBreadcrumbs>
      <PageTitle>File Browser</PageTitle>

      <Text>Current path: {filePath}</Text>
    </>
  );
};
You can destructure the * parameter by assigning it a more descriptive name:
const { params: { "*": filePath } } = usePageRoute();
// or
const { params: { "*": splat } } = usePageRoute();

Wildcard routes vs AnyRoute

While both match multiple paths, they serve different purposes: AnyRoute component:
  • Catches any unmatched path at that nesting level
  • Typically used for 404 pages or fallback routes
  • Does not provide the matched path as a parameter
Wildcard routes (path="prefix/*"):
  • Match a specific path pattern (e.g., /docs/* only matches paths starting with /docs/)
  • The matched portion is accessible as a parameter
  • Useful for file browsers, documentation sites, or any hierarchical content
<PageRoutes>
  <PageRoutes.IndexRoute component={HomePage} />
  <PageRoutes.Route path="/docs/*" component={DocsPage} />
  {/* Wildcard route matches /docs/anything */}

  <PageRoutes.AnyRoute component={NotFoundPage} />
  {/* AnyRoute catches everything else that doesn't match */}
</PageRoutes>
Use wildcard routes when you need to handle hierarchical paths (like file systems or documentation structures) and need access to the full path. Use AnyRoute for general 404 handling.

Nested routes

You can nest PageRoutes components within the route tree to create hierarchical page structures. Nest routes by adding a <PageRoutes> with a path prop as a child of the parent <PageRoutes>:
import React from "react";
import { Text, hubspot } from "@hubspot/ui-extensions";
import { createPageRouter, PageRoutes, PageLink, PageBreadcrumbs, PageTitle } from "@hubspot/ui-extensions/pages";

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

      <Text>Content for the Home page...</Text>
      <PageLink to="/support">Visit Support</PageLink>
    </>
  );
};

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

      <Text>Browse our support resources...</Text>
      <PageLink to="/support/contact-us">Contact Us</PageLink>
      <PageLink to="/support/faq">FAQ</PageLink>
    </>
  );
};

const ContactUsPage = () => {
  return (
    <>
      <PageBreadcrumbs>
        <PageBreadcrumbs.PageLink to="/">Home</PageBreadcrumbs.PageLink>
        <PageBreadcrumbs.PageLink to="/support">Support</PageBreadcrumbs.PageLink>
        <PageBreadcrumbs.Current>Contact Us</PageBreadcrumbs.Current>
      </PageBreadcrumbs>
      <PageTitle>Contact Us</PageTitle>

      <Text>Get in touch with our support team...</Text>
    </>
  );
};

const FAQPage = () => {
  return (
    <>
      <PageBreadcrumbs>
        <PageBreadcrumbs.PageLink to="/">Home</PageBreadcrumbs.PageLink>
        <PageBreadcrumbs.PageLink to="/support">Support</PageBreadcrumbs.PageLink>
        <PageBreadcrumbs.Current>FAQ</PageBreadcrumbs.Current>
      </PageBreadcrumbs>
      <PageTitle>FAQ</PageTitle>

      <Text>Find answers to common questions...</Text>
    </>
  );
};

const PageRouter = createPageRouter(
  <PageRoutes>
    <PageRoutes.IndexRoute component={HomePage} />
    <PageRoutes path="/support">
      <PageRoutes.IndexRoute component={SupportIndexPage} />
      <PageRoutes.Route path="/contact-us" component={ContactUsPage} />
      <PageRoutes.Route path="/faq" component={FAQPage} />
    </PageRoutes>
  </PageRoutes>
);

hubspot.extend<"pages">(() => <PageRouter />);
This creates the following URL structure:
  • / - Home page
  • /support - Support index page
  • /support/contact-us - Contact us page
  • /support/faq - FAQ page

Nested route behavior

When using nested routes:
  • A <PageRoutes> with a path prop defines a group of nested routes under that path
  • The nested IndexRoute renders when the path matches exactly the parent path (/support)
  • Named routes within the nested PageRoutes extend the parent path (/support/contact-us)
  • Each nested level can have its own AnyRoute for unmatched paths within that section

Nesting with path parameters

You can combine nested routes with path parameters to create hierarchical structures:
const PageRouter = createPageRouter(
  <PageRoutes>
    <PageRoutes.IndexRoute component={HomePage} />
    <PageRoutes path="/deals/:dealId">
      <PageRoutes.IndexRoute component={DealOverview} />
      <PageRoutes.Route path="/notes" component={DealNotes} />
      <PageRoutes.Route path="/notes/:noteId" component={NoteDetails} />
    </PageRoutes>
  </PageRoutes>
);
This creates routes like:
  • /deals/123 - Deal overview
  • /deals/123/notes - Deal notes list
  • /deals/123/notes/456 - Specific note details

Layout components

Layout components let you wrap groups of routes with shared UI, such as navigation bars, sidebars, or other persistent elements. A layout component receives children as a prop and renders the matched route’s content within it.

Basic layout

Pass a layout component to <PageRoutes> using the layoutComponent prop:
import { ReactNode } from "react";
import { Text, Flex } from "@hubspot/ui-extensions";
import { createPageRouter, PageRoutes, PageLink, usePageRoute } from "@hubspot/ui-extensions/pages";

function AppLayout({ children }: { children: ReactNode }) {
  const { path } = usePageRoute();

  return (
    <Flex direction="column" gap="medium">
      <Flex direction="row" gap="small">
        <PageLink to="/">Home</PageLink>
        <PageLink to="/docs">Docs</PageLink>
        <PageLink to="/support">Support</PageLink>
      </Flex>
      {children}
    </Flex>
  );
}

const PageRouter = createPageRouter(
  <PageRoutes layoutComponent={AppLayout}>
    <PageRoutes.IndexRoute component={HomePage} />
    <PageRoutes.Route path="/docs" component={DocsPage} />
    <PageRoutes.Route path="/support" component={SupportPage} />
    <PageRoutes.AnyRoute component={NotFoundPage} />
  </PageRoutes>
);
The AppLayout component will wrap every page rendered by these routes. The matched page component is rendered in place of {children}.

Nested layouts

You can apply different layout components at different nesting levels. Nested <PageRoutes> can define their own layoutComponent, which will render inside the parent layout:
function CustomersLayout({ children }: { children: ReactNode }) {
  return (
    <Flex direction="column" gap="medium">
      <Heading>Customers</Heading>
      {children}
    </Flex>
  );
}

const PageRouter = createPageRouter(
  <PageRoutes layoutComponent={AppLayout}>
    <PageRoutes.IndexRoute component={HomePage} />
    <PageRoutes.Route path="/docs" component={DocsPage} />
    <PageRoutes path="/customers" layoutComponent={CustomersLayout}>
      <PageRoutes.IndexRoute component={ListCustomersPage} />
      <PageRoutes.Route path="/:customerId" component={ViewCustomerPage} />
    </PageRoutes>
    <PageRoutes.AnyRoute component={NotFoundPage} />
  </PageRoutes>
);
When a user navigates to /customers, the rendered output will be AppLayout > CustomersLayout > ListCustomersPage. Each layout wraps the content below it in the route tree.

Path parameters

Path parameters allow you to create dynamic routes that can capture values from the URL path. This is useful for pages that display specific items, such as viewing a particular contact, deal, or custom object record.

Defining routes with path parameters

To define a route with path parameters, use a colon (:) followed by the parameter name in the route path:
<PageRoutes>
  <PageRoutes.IndexRoute component={HomePage} />
  <PageRoutes.Route path="/view-contact/:contactId" component={ContactDetailsPage} />
  <PageRoutes.Route path="/deals/:dealId" component={DealDetailsPage} />
  <PageRoutes.Route path="/documents/:folderId/:documentId" component={DocumentPage} />
</PageRoutes>
You can include multiple path parameters in a single route, as shown in the documents/:folderId/:documentId example.

Understanding path parameters

Path parameters are placeholders in your route definitions that capture values from the URL. When a user navigates to a URL that matches the route pattern, the parameter values are extracted and made available to your component. Example route pattern: /view-contact/:contactId This pattern will match URLs like:
  • /view-contact/123 (contactId = “123”)
  • /view-contact/abc-def (contactId = “abc-def”)
  • /view-contact/contact-456 (contactId = “contact-456”)
But will not match:
  • /view-contact (missing contactId)
  • /view-contact/123/edit (additional path segment)

Multiple path parameters

When using multiple path parameters, each segment of the URL path can capture a different value:
// Route definition
<PageRoutes.Route path="/deals/:dealId/notes/:noteId" component={NotePage} />
This route pattern creates a hierarchical structure where:
  • /deals/456/notes/789 matches with dealId="456" and noteId="789"
  • The path segments between parameters (deals and notes) must match exactly
  • Both parameters are required for the route to match

Best practices for path parameters

  • Use descriptive parameter names: Choose names that clearly indicate what the parameter represents (e.g., :contactId, :dealId, not :id)
  • Keep parameter counts reasonable: While you can have multiple path parameters, too many can make URLs hard to read
  • Validate parameter values: Always validate path parameter values before using them (e.g., check if an ID exists)
  • Use path parameters for resource IDs: Path parameters work well for resource identifiers that define what page you’re viewing
  • Use query parameters for optional state: Use query parameters for filtering, sorting, or view state that doesn’t change what resource you’re viewing
  • Use wildcards for hierarchical paths: When you need to match multiple nested segments and preserve the full path (e.g., file systems, documentation), use wildcard routes instead of multiple path parameters

Accessing route information

Use the usePageRoute hook to access the current page path, route ID, and all parameters (both path parameters and query parameters) in your page components. The hook returns an object with path, routeId, and params.

Basic usage

import { Text } from "@hubspot/ui-extensions";
import { usePageRoute, PageBreadcrumbs, PageTitle } from "@hubspot/ui-extensions/pages";

const DocsPage = () => {
  const { path, params } = usePageRoute();
  const { section, topic } = params;

  return (
    <>
      <PageBreadcrumbs>
        <PageBreadcrumbs.PageLink to="/">Home</PageBreadcrumbs.PageLink>
        <PageBreadcrumbs.Current>Documentation</PageBreadcrumbs.Current>
      </PageBreadcrumbs>
      <PageTitle>Documentation</PageTitle>

      <Text>Current path: {path}</Text>
      {section && <Text>Section: {section}</Text>}
      {topic && <Text>Topic: {topic}</Text>}
    </>
  );
};
When a user visits https://app.hubspot.com/app/{HubID}/{appId}/docs?section=api&topic=authentication, the hook will return:
  • path: "/docs"
  • params.section: "api"
  • params.topic: "authentication"

Accessing path parameters

Path parameters are included in params alongside query parameters - the usePageRoute hook returns all parameters regardless of their source:
// Route definition: <PageRoutes.Route path="/view-contact/:contactId" component={ContactPage} />

const ContactDetailsPage = () => {
  const { params } = usePageRoute();
  const { contactId, tab } = params;

  // contactId comes from the path: /view-contact/123
  // tab comes from query string: ?tab=activity

  return (
    <>
      <PageBreadcrumbs>
        <PageBreadcrumbs.PageLink to="/">Home</PageBreadcrumbs.PageLink>
        <PageBreadcrumbs.PageLink to="/contacts">Contacts</PageBreadcrumbs.PageLink>
        <PageBreadcrumbs.Current>Contact {contactId}</PageBreadcrumbs.Current>
      </PageBreadcrumbs>
      <PageTitle>Contact {contactId}</PageTitle>

      <Text>Contact ID: {contactId}</Text>
      {tab && <Text>Active tab: {tab}</Text>}
    </>
  );
};
When a user visits /view-contact/123?tab=activity:
  • contactId: "123" (from path)
  • tab: "activity" (from query string)

Accessing wildcard parameters

Wildcard values are accessed through the params["*"] property:
import { usePageRoute } from "@hubspot/ui-extensions/pages";

const FileBrowserPage = () => {
  const { params } = usePageRoute();
  const wildcardValue = params["*"];

  // For URL: /files/documents/2024/report.pdf
  // wildcardValue = "documents/2024/report.pdf"

  return (
    <>
      <Heading>File Browser</Heading>
      <Text>Path: {wildcardValue}</Text>
    </>
  );
};
You can destructure the * parameter by assigning it a more descriptive name:
const { params: { "*": filePath } } = usePageRoute();
// or
const { params: { "*": splat } } = usePageRoute();
When a user visits /files/documents/2024/report.pdf with a route defined as path="/files/*":
  • params["*"]: "documents/2024/report.pdf"
Like all page parameters, wildcard values are strings. Remember to validate and sanitize the wildcard value before using it, especially if using it to access files or resources.

Route IDs

Each route can be assigned a stable id prop that uniquely identifies it. When a route matches, its id is available as routeId from the usePageRoute hook. This is particularly useful in layout components where you need to determine which route is currently active without relying on path matching.
Route IDs must be unique within your collection of routes. Having multiple routes with the same id will result in an error.

Defining route IDs

Add an id prop to any route component:
const PageRouter = createPageRouter(
  <PageRoutes>
    <PageRoutes.IndexRoute id="home" component={HomePage} />
    <PageRoutes.Route id="support" path="/support" component={SupportPage} />
    <PageRoutes.AnyRoute id="not-found" component={NotFoundPage} />
  </PageRoutes>
);

Accessing the route ID

Use the routeId property from the usePageRoute hook:
import { usePageRoute } from "@hubspot/ui-extensions/pages";

const MyComponent = () => {
  const { routeId } = usePageRoute();
  // routeId is "home", "support", "not-found", etc.
};

Using route IDs in layout components

Route IDs are especially useful in layout components where you need to render different breadcrumbs, titles, or other shared UI based on the active route. Unlike path-based matching, route IDs remain stable even if route paths change, and they work reliably with dynamic path parameters.
import { ReactNode } from "react";
import { Text, Flex } from "@hubspot/ui-extensions";
import { createPageRouter, PageRoutes, PageLink, PageBreadcrumbs, PageTitle, usePageRoute } from "@hubspot/ui-extensions/pages";

const BREADCRUMBS: Record<string, ReactNode> = {
  home: <Text>Home</Text>,
  support: (
    <>
      <PageLink to="/">Home</PageLink>
      <Text>Support</Text>
    </>
  ),
  "not-found": (
    <>
      <PageLink to="/">Home</PageLink>
      <Text>Not Found</Text>
    </>
  ),
};

const TITLES: Record<string, string> = {
  home: "Home",
  support: "Support",
  "not-found": "Page Not Found",
};

function AppLayout({ children }: { children: ReactNode }) {
  const { routeId } = usePageRoute();

  return (
    <Flex direction="column" gap="medium">
      <PageBreadcrumbs>{BREADCRUMBS[routeId]}</PageBreadcrumbs>
      <PageTitle>{TITLES[routeId]}</PageTitle>
      {children}
    </Flex>
  );
}

const PageRouter = createPageRouter(
  <PageRoutes layoutComponent={AppLayout}>
    <PageRoutes.IndexRoute id="home" component={HomePage} />
    <PageRoutes.Route id="support" path="/support" component={SupportPage} />
    <PageRoutes.AnyRoute id="not-found" component={NotFoundPage} />
  </PageRoutes>
);
Route IDs provide a more robust way to identify the active route compared to path matching. They don’t break when paths are renamed and work naturally with routes that contain dynamic path parameters.

Parameter limitations

All page parameters are treated as strings. If you pass numbers, booleans, or other types, they will be converted to strings.
Understanding parameter limitations helps you avoid common issues when working with app pages.

All values are strings

Parameters are always received as strings, regardless of the type you pass.
// Passing parameters
navigateToPage({
  to: '/analytics',
  params: {
    count: 42,           // Will be "42"
    enabled: true,       // Will be "true"
    userId: "12345"      // Will be "12345"
  }
});

// Receiving parameters
const { params } = usePageRoute();
const { count, enabled, userId } = params;
// count is "42" (string, not number)
// enabled is "true" (string, not boolean)
// userId is "12345" (string)

// You'll need to convert them if needed
const countNumber = parseInt(count, 10);
const enabledBoolean = enabled === "true";
Always validate and convert parameter values before using them. Check for null, undefined, or invalid formats to handle cases where parameters are missing or malformed.

No complex objects

You cannot pass objects, arrays, or other complex data structures as parameters. Only simple string values are supported.
// ❌ NOT supported
navigateToPage({
  to: '/page',
  params: {
    user: { name: "John", age: 30 },  // Objects not supported
    items: [1, 2, 3]                   // Arrays not supported
  }
});

// ✅ Supported - use JSON.stringify and parse if needed
navigateToPage({
  to: '/page',
  params: {
    user: JSON.stringify({ name: "John", age: 30 })
  }
});

// Then parse it when accessing
const { params } = usePageRoute();
const userData = params.user ? JSON.parse(params.user) : null;
When using JSON.stringify for complex data, be mindful of URL length limits. Very large objects will create excessively long URLs.

URL length limits

Query parameters are part of the URL, which has practical length limits:
  • Browsers: Most browsers support URLs up to 2,000-8,000 characters
  • Best practice: Keep URLs under 2,000 characters for maximum compatibility
  • Recommendation: Use parameters for IDs and simple state, not for large data payloads
If you need to pass large amounts of data:
  1. Store the data on your backend
  2. Pass only an ID through a URL parameter
  3. Fetch the full data using the ID when the page loads
// ❌ Bad - passing large data through URL
navigateToPage({
  to: '/report',
  params: {
    data: JSON.stringify(hugeDataObject)  // Too large!
  }
});

// ✅ Good - pass ID and fetch data
navigateToPage({
  to: '/report',
  params: {
    reportId: "report-123"  // Small ID
  }
});

// In the report page, fetch the full data
const ReportPage = () => {
  const { params } = usePageRoute();
  // Fetch report data using the ID
  const reportData = useFetchReport(params.reportId);
  // ...
};

Path normalization

When navigating to pages or defining routes, the routing system automatically normalizes paths to ensure consistent behavior. Understanding these normalization rules can help you avoid unexpected routing issues.

Normalization rules

The following transformations are applied to paths:
  1. Leading slashes are added: If a path doesn’t start with /, one is automatically added.
    • "foo""/foo"
    • "docs""/docs"
  2. Trailing slashes are removed: Paths should not end with a slash, and any trailing slashes are automatically removed.
    • "foo/""/foo"
    • "docs/""/docs"
    • "support/contact/""/support/contact"
  3. Multiple consecutive slashes are collapsed: Any sequence of multiple slashes is reduced to a single slash.
    • "foo//bar""/foo/bar"
    • "docs///api""/docs/api"
    • "//support""/support"
  4. Empty paths are treated as root: An empty string or single slash both represent the home page.
    • """/"
    • "/""/"

Examples

Here are some examples of how different path formats are normalized:
Input PathNormalized Path
"docs""/docs"
"/docs""/docs"
"docs/""/docs"
"/docs/""/docs"
"support/faq""/support/faq"
"support//faq""/support/faq"
"//docs///api//""/docs/api"
"""/"
"/""/"

Practical implications

Because of path normalization:
  • You can use either format in route definitions: Both path="docs" and path="/docs" will work the same way after normalization.
// Both are equivalent after normalization
<PageRoutes.Route path="docs" component={DocsPage} />
<PageRoutes.Route path="/docs" component={DocsPage} />
  • Navigation calls are forgiving: When navigating to pages, you don’t need to worry about exact path formatting. See the Page linking and navigation guide for more details.
  • Consistency in comparisons: When comparing paths using usePageRoute(), always compare against normalized paths.
import { usePageRoute } from "@hubspot/ui-extensions/pages";

const MyComponent = () => {
  const { path } = usePageRoute();

  // path is always normalized, so compare with normalized format
  if (path === "/docs") {
    // This will match /docs, docs/, /docs/, etc.
  }

  return <Text>Current page: {path}</Text>;
};
While path normalization is forgiving, it’s best practice to use consistent path formatting throughout your code.

Getting the current page path

Use the usePageRoute hook to get the current page path. This is useful for determining which page is currently active, which can help with navigation highlighting and conditional rendering.
import { usePageRoute, PageLink } from "@hubspot/ui-extensions/pages";

const Navigation = () => {
  const { path } = usePageRoute();
  // For home page: "/"
  // For /docs: "/docs"
  // For /support/faq: "/support/faq"

  return (
    <Flex gap="medium">
      <Text variant={path === "/" ? "strong" : "default"}>
        <PageLink to="/">Home</PageLink>
      </Text>
      <Text variant={path === "/docs" ? "strong" : "default"}>
        <PageLink to="/docs">Docs</PageLink>
      </Text>
      <Text variant={path === "/support" ? "strong" : "default"}>
        <PageLink to="/support">Support</PageLink>
      </Text>
    </Flex>
  );
};
The path value returned by usePageRoute is always the normalized path, so you can reliably compare it against expected values.

Common use cases

Highlighting active navigation items:
const { path } = usePageRoute();
const isActive = path === "/docs";
Identifying the active route in layout components:
const { routeId } = usePageRoute();
const showSidebar = routeId === "dashboard" || routeId === "analytics";
Conditional rendering based on current page:
const { path } = usePageRoute();
const showBreadcrumbs = path.includes("/support/");
Analytics and tracking:
const { path } = usePageRoute();
useEffect(() => {
  trackPageView(path);
}, [path]);
Last modified on April 17, 2026