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

# Navigate Component

> Direct users to specific pages on your website

## Overview

The **Navigate** component lets your agent send users to a specific page on your website — pricing, a product, checkout, docs, or any path.

<Card title="WebChat / Lua Pop only" icon="globe">
  This component only works in the website chat widget (Lua Pop) and requires an `onNavigate` handler in your widget config.
</Card>

## Format

```
::: navigate
![navigate](/pathname?param1=value1&param2=value2)
:::
```

* `pathname` — a relative page path (e.g. `/pricing`, `/products/laptop`, `/checkout`)
* `?param=value` — optional query parameters

<Warning>
  Navigate **renders nothing in the chat** — no button or link. When the message arrives, the widget strips the block and immediately calls your `onNavigate` handler, so navigation happens automatically. Always include a line of context before the block so the jump isn't a surprise.
</Warning>

## How it works

<Steps>
  <Step title="Agent includes a navigate block">
    ```
    Our pricing starts at $300/month. Here's the full breakdown:

    ::: navigate
    ![navigate](/pricing?channel=web)
    :::
    ```
  </Step>

  <Step title="Widget calls your onNavigate handler">
    ```javascript theme={null}
    onNavigate("/pricing", { query: { channel: "web" } });
    ```
  </Step>

  <Step title="Your code performs the navigation">
    Route the user using your framework (see below).
  </Step>
</Steps>

## Configure the onNavigate handler

Navigation only works if you pass an `onNavigate` handler to the widget. It receives the `pathname` and an options object with the parsed `query` params.

```javascript theme={null}
window.LuaPop.init({
  agentId: "your-agent-id",
  onNavigate: (pathname, options) => {
    // pathname: "/pricing"
    // options.query: { channel: "web" }
    const params = new URLSearchParams(options.query).toString();
    window.location.href = params ? `${pathname}?${params}` : pathname;
  }
});
```

Using a router? Swap the last line for your framework:

```javascript theme={null}
// React Router
navigate({ pathname, search: new URLSearchParams(options.query).toString() });

// Next.js
router.push({ pathname, query: options.query });

// Vue Router
router.push({ path: pathname, query: options.query });
```

## Query parameters

Pass data to the destination page through the URL:

```
::: navigate
![navigate](/products/laptop?source=chat&campaign=spring)
:::
```

```javascript theme={null}
onNavigate("/products/laptop", {
  query: { source: "chat", campaign: "spring" }
});
```

Common uses: attribution (`?source=chat`), pre-filling forms (`?product=123`), campaigns (`?promo=SAVE10`), or opening a specific tab/filter (`?tab=specs`).

## Tell your agent to use it

Components are never used automatically — instruct the agent in its **persona** or a **skill context**:

```yaml theme={null}
persona: |
  You are a shopping assistant for TechStore.

  After describing a product, send the user to its page:

  ::: navigate
  ![navigate](/products/PRODUCT_SLUG?source=chat)
  :::

  For pricing questions, send them to pricing:

  ::: navigate
  ![navigate](/pricing?channel=chat)
  :::

  Always add source=chat for tracking.
```

## Best practices

<AccordionGroup>
  <Accordion title="Add context before the block">
    Because navigation is automatic, precede the block with a sentence about where the user is going (e.g. "Here's the full pricing breakdown:") so the jump feels intentional.
  </Accordion>

  <Accordion title="Use relative paths">
    Prefer `/pricing` or `/products/123` over absolute URLs like `https://yoursite.com/pricing` — relative paths route correctly through `onNavigate`.
  </Accordion>

  <Accordion title="Include tracking parameters">
    Add `?source=chat` (or similar) so you can measure how much traffic and conversion comes from the agent.
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Nothing happens">
    Make sure an `onNavigate` handler is passed to `window.LuaPop.init()`. Without it the block is stripped but no navigation occurs. Check the console for errors and confirm the pathname is relative.
  </Accordion>

  <Accordion title="Query parameters missing">
    Use a single `?` and join params with `&`: `/page?a=1&b=2` (not `/page?a=1?b=2`).
  </Accordion>

  <Accordion title="Agent never navigates">
    The agent only uses the component if you instruct it in the persona or skill context with the exact format shown above.
  </Accordion>
</AccordionGroup>

## Next steps

<CardGroup cols={2}>
  <Card title="Widget Configuration" icon="cog" href="/chat-widget/configuration">
    Set up the onNavigate handler
  </Card>

  <Card title="Widget Events" icon="bolt" href="/chat-widget/events">
    All widget callbacks and events
  </Card>

  <Card title="Response Formatting" icon="list" href="/formatting/introduction">
    Explore the other components
  </Card>
</CardGroup>
