# Add page tools to your site

> Working code for the script tag, npm, React and the <web-ai-chat> element, and tools that change per page.

Pick the method that matches how you installed the widget. A tool you register is offered by every chat widget on the page.

## Script tag (Quick install)

Put one line before the widget's script so you can call `HelpAI` before it has loaded, then register your tools. The deployment's **Install** tab has a short example in its **Let the AI agent act on your page** card, ready to copy.

```html
<script>
  window.HelpAI = window.HelpAI || function () { (HelpAI.q = HelpAI.q || []).push(arguments); };

  HelpAI('registerTool', {
    name: 'read_cart',
    description: "Read what's in the visitor's cart. Use it whenever they ask about their cart.",
    execute: () => getCart(), // your own code
  });
</script>
<script
  src="https://cdn.help.ai/sdk/js/elements/1.12.0/elements.js"
  data-public-key="YOUR_PUBLIC_KEY"
  data-ai-agent-deployment-id="YOUR_DEPLOYMENT_ID"
  defer
></script>
```

The first line holds your calls until the widget loads. After it has loaded, `HelpAI.registerTool(tool)` works too.

### Pass the tools when the widget starts

Leave the attributes off the script tag and start the widget with `init`, passing the `tools` it offers:

```html
<script src="https://cdn.help.ai/sdk/js/elements/1.12.0/elements.js" defer></script>
<script>
  window.HelpAI = window.HelpAI || function () { (HelpAI.q = HelpAI.q || []).push(arguments); };

  HelpAI('init', {
    publicKey: 'YOUR_PUBLIC_KEY',
    aiAgentDeploymentId: 'YOUR_DEPLOYMENT_ID',
    tools: [readCart, openBooking],
  });
</script>
```

## npm

```bash
npm install @helpai/elements
```

```js
import { init } from '@helpai/elements';

const chat = init({
  publicKey: 'YOUR_PUBLIC_KEY',
  aiAgentDeploymentId: 'YOUR_DEPLOYMENT_ID',
  tools: [readCart],
});

chat.registerTool(openBooking);
```

`tools` belongs to that widget; `registerTool` adds a tool for every widget on the page. `chat.update({ tools })` replaces the `tools` list later.

## React

```jsx
import { HelpAI, useHelpAITool } from '@helpai/elements/react';

export function App() {
  return (
    <>
      <HelpAI publicKey='YOUR_PUBLIC_KEY' aiAgentDeploymentId='YOUR_DEPLOYMENT_ID' />
      <Routes />
    </>
  );
}

function ProductPage({ product }) {
  useHelpAITool({
    name: 'add_to_cart',
    description: `Add ${product.name} to the visitor's cart. Use it when they want to buy it.`,
    inputSchema: {
      type: 'object',
      properties: { quantity: { type: 'integer', minimum: 1 } },
    },
    execute: ({ quantity = 1 }) => cart.add(product.id, quantity),
  });

  return <ProductDetails product={product} />;
}
```

`useHelpAITool` offers the tool while the component is on the screen and removes it when the component goes, so each page of your app offers its own tools. `execute` always runs the latest version from your component, and React's development double-mount still leaves one tool. For tools that apply everywhere you can also pass `<HelpAI tools={[...]} />`.

## Other frameworks and the `<web-ai-chat>` element

```html
<script type="module" src="https://cdn.help.ai/sdk/js/elements/1.12.0/elements-web-component.esm.js"></script>

<web-ai-chat public-key="YOUR_PUBLIC_KEY" ai-agent-deployment-id="YOUR_DEPLOYMENT_ID"></web-ai-chat>

<script type="module">
  const chat = document.querySelector('web-ai-chat');
  chat.registerTool(readCart);
  // Or set the whole list for this widget:
  chat.tools = [readCart, openBooking];
</script>
```

`tools` is a property, not an attribute, because functions can't be attributes. In Vue, bind it with `:tools="tools"`; in Svelte, `tools={tools}`.

## Remove a tool

Pass an `AbortSignal` when you register, and abort it to take the tool away. The next message no longer offers it.

```js
const controller = new AbortController();
HelpAI.registerTool(addToCart, { signal: controller.signal });

// Later, when the tool no longer applies:
controller.abort();
```

## Tools that change per page

In a single-page app, register a page's tools when the page shows and remove them when it goes. The widget reads your tools again each time the visitor sends a message, and again when the agent calls one, so there's nothing else to keep in sync.

```js
// With your router: called when the visitor opens a product page.
function onProductPage(product) {
  const page = new AbortController();
  HelpAI.registerTool(addToCartFor(product), { signal: page.signal });
  return () => page.abort(); // called when they leave the page
}
```

In React, `useHelpAITool` does this for you. If the agent calls a tool after the visitor left its page, it learns the page doesn't offer it right now and tells the visitor.

## A tool that leaves the page

If a tool navigates to another page, return first and navigate after, so the result reaches the agent:

```js
execute({ path }) {
  setTimeout(() => location.assign(path), 0);
  return { navigating: path };
},
```

The widget sends results in a way that survives the page unloading.
