> ## 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: d4e2b2bb-c8f2-408f-8a12-335900120f78
---

# Page linking and navigation

> Learn how to navigate between pages and pass data in app pages.

Once you've defined routes in your app, you'll need to navigate between them. This guide covers the different methods for linking to pages and passing parameters when navigating.

For information on how to access parameters in your page components, see the [accessing route information](/apps/developer-platform/add-features/ui-extensions/extension-points/app-pages/page-routing#accessing-route-information) section in the routing guide.

## Navigation methods

There are three primary ways to navigate between pages in your app.

### Using the PageLink component

The `PageLink` component is the primary way to create clickable links to other pages within your app.

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

// Link to home page
<PageLink to="/">Home</PageLink>

// Link to a named page
<PageLink to="/docs">Documentation</PageLink>

// Link with query parameters
<PageLink to="/docs" params={{ section: "getting-started" }}>
  Getting Started
</PageLink>
```

The `PageLink` component supports the following props:

* `to` (string): The path to navigate to (e.g., `"/"`, `"/docs"`)
* `params` (object): Query parameters to include in the URL

For more details on the PageLink component, see the [PageLink component reference](/apps/developer-platform/add-features/ui-extensions/ui-components/app-page-components/page-link).

<Note>
  The `Link` component from `@hubspot/ui-extensions` should only be used for external URLs. Use `PageLink` for navigating between pages within your app.
</Note>

### Using PageHeader actions

Page header actions support linking to app pages using `PageLink` components:

```tsx theme={null}
import { Link } from "@hubspot/ui-extensions";
import { PageHeader } from "@hubspot/ui-extensions/pages";

<PageHeader>
  <PageHeader.PrimaryAction>
    <PageHeader.PageLink to="/">Home</PageHeader.PageLink>
  </PageHeader.PrimaryAction>
  <PageHeader.SecondaryActions>
    <PageHeader.PageLink to="/docs">Documentation</PageHeader.PageLink>
    <PageHeader.PageLink to="/analytics" params={{ view: "dashboard" }}>
      Analytics Dashboard
    </PageHeader.PageLink>
    <PageHeader.Link href="https://example.com">External Link</PageHeader.Link>
  </PageHeader.SecondaryActions>
</PageHeader>
```

<Note>
  `PageHeader.PrimaryAction` and `PageHeader.SecondaryActions` can only contain `PageHeader.PageLink` (for internal pages) or `PageHeader.Link` (for external URLs) components.
</Note>

For more details on PageHeader components, see the [PageHeader component reference](/apps/developer-platform/add-features/ui-extensions/ui-components/app-page-components/page-header).

### Programmatic navigation

You can navigate programmatically using the `navigateToPage` action from the extension context:

```tsx theme={null}
import { Button, hubspot, useExtensionActions } from "@hubspot/ui-extensions";

const MyComponent = () => {
  const { navigateToPage } = useExtensionActions();
  
  const handleClick = () => {
    navigateToPage({
      to: '/docs',
      params: { section: 'api' }
    });
  };
  
  return <Button onClick={handleClick}>Go to API Docs</Button>;
};
```

The `navigateToPage` function accepts an options object with:

* `to` (string, required): The path to navigate to
* `params` (object, optional): Query parameters to include

## Linking with path parameters

When your routes include path parameters (e.g., `/view-contact/:contactId`), you can pass parameter values through the `params` object. The routing system will automatically substitute matching parameter names into the URL path.

### Basic path parameter linking

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

// Route definition: <PageRoutes.Route path="/view-contact/:contactId" component={ContactPage} />

// Link to a specific contact
<PageLink 
  to="/view-contact/:contactId"
  params={{ contactId: "123" }}
>
  View Contact
</PageLink>
```

**Generated URL:** `https://app.hubspot.com/app/{HubID}/{appId}/view-contact/123`

The `contactId` parameter matches the `:contactId` path parameter, so it gets substituted into the path.

### Mixing path and query parameters

When you provide multiple parameters, the routing system intelligently separates them:

```tsx theme={null}
<PageLink 
  to="/view-contact/:contactId"
  params={{ 
    contactId: "123",           // Matches :contactId - goes into path
    tab: "activity"             // No match - goes into query string
  }}
>
  Contact Activity
</PageLink>
```

**Generated URL:** `https://app.hubspot.com/app/{HubID}/{appId}/view-contact/123?tab=activity`

### Multiple path parameters

You can link to routes with multiple path parameters by including all matching parameters:

```tsx theme={null}
// Route definition: 
// <PageRoutes.Route path="/deals/:dealId/notes/:noteId" component={NotePage} />

<PageLink 
  to="/deals/:dealId/notes/:noteId"
  params={{ 
    dealId: "456",                    // Matches :dealId
    noteId: "789",                    // Matches :noteId
    highlightSection: "comments"      // Goes to query string
  }}
>
  View Note
</PageLink>
```

**Generated URL:** `https://app.hubspot.com/app/{HubID}/{appId}/deals/456/notes/789?highlightSection=comments`

### How parameter substitution works

The routing system follows these rules when generating URLs:

1. **Matching parameters go into the path**: If a parameter name matches a path parameter placeholder (e.g., `contactId` matches `:contactId`), it replaces that placeholder in the URL.

2. **Non-matching parameters become query parameters**: Any parameters that don't match path parameter names are added to the query string.

3. **Parameter order doesn't matter**: The system will correctly match parameters regardless of the order they appear in the `params` object.

### Programmatic navigation with path parameters

The same substitution rules apply when using `navigateToPage`:

```tsx theme={null}
const { navigateToPage } = useExtensionActions();

const viewContact = (contactId, initialTab) => {
  navigateToPage({
    to: '/view-contact/:contactId',
    params: { 
      contactId: contactId,    // Goes into path
      tab: initialTab          // Goes into query string
    }
  });
};

// Usage
viewContact("12345", "overview");
// Navigates to: /view-contact/12345?tab=overview
```

<Note>
  For details on how to access parameters in your page components using `usePageRoute`, including parameter limitations and best practices, see the [Accessing route information](/apps/developer-platform/add-features/ui-extensions/extension-points/app-pages/page-routing#accessing-route-information) section in the routing guide.
</Note>

## See also

* [Page routing](/apps/developer-platform/add-features/ui-extensions/extension-points/app-pages/page-routing)
* [PageLink component reference](/apps/developer-platform/add-features/ui-extensions/ui-components/app-page-components/page-link)
* [PageRoutes component reference](/apps/developer-platform/add-features/ui-extensions/ui-components/app-page-components/page-routes)
* [PageHeader component reference](/apps/developer-platform/add-features/ui-extensions/ui-components/app-page-components/page-header)
* [Link component reference](/apps/developer-platform/add-features/ui-extensions/ui-components/standard-components/link)
* [App pages reference](/apps/developer-platform/add-features/ui-extensions/extension-points/app-pages/reference)
