Connecting the Chat to Your Page#

Once the chat runs on your page, it can answer about the page that the reader is on, treat links to your site differently, take questions from your own buttons, open documents, and report what happens. For adding the chat, see the Add the Chat to Your Page page.

Answer about the Page the Reader Is On#

context tells the chat what the reader is looking at. The simplest option is to let the chat read the page itself, with context: 'auto' in initNeoSdk(), or on the element:

<neo-chat base-url="/api/chat" project-id="YOUR_PROJECT_ID" auth="anonymous" context="auto"></neo-chat>

With auto, each question carries the following:

  • The title of the page.

  • Its URL, without the query string or # part, which often carry tokens or search terms.

  • Its description and main text: the first of [data-neo-context], #main-content, main, [role=main], and article on the page that has text in it, else the whole page body.

The chat never reads navigation, headers, footers, forms, form fields, hidden content, text in the shadow root of another web component, or the chat itself. It does read text that is rendered but out of sight, such as visibility: hidden or off screen. To keep anything else out, mark it with data-neo-exclude:

<div class="account-balance" data-neo-exclude>CHF 12 400</div>

A page can opt out entirely with <meta name="neo-context" content="none">, or send only its title and URL with content="title". Any other value also sends nothing. To tune what is read, pass options instead of 'auto':

context: {
  root: '#main-content',
  exclude: ['.cookie-banner'],
  maxLength: 2000,
  url: 'path', // 'canonical' (the default), 'path' or 'full'
},

Or write the function yourself. The chat calls it for each question:

context: () => ({
  title: document.title,
  url: location.origin + location.pathname,
  text: document.querySelector('main')?.innerText ?? '',
}),

The page context goes out with the first question of a conversation, and again only when the reader has moved to another page, a route change in a single-page app included. It becomes part of the conversation stored on your Squirro instance. See the Where Conversations Are Kept section of the What Readers Share page.

Ask from Your Own Buttons#

sdk.ask(text) sends a question as if the reader had typed it. It resolves when that answer completes, and rejects if the answer fails or the reader stops it. While the chat waits for the reader to approve an action of the agent, it rejects immediately and sends nothing.

A closed floating chat opens first, as with sdk.open(). For example, to ask from a button:

document.getElementById('explain').addEventListener('click', () => {
  sdk.ask('Explain this page in three sentences').catch(() => {});
});

sdk.newConversation() starts a fresh conversation.

sdk is what initNeoSdk() or NeoSdk.mount() returned. On a script-tag page, it is also the sdk property of the <neo-chat> element, which is not set until the chat has started. So read it where you use it:

const chat = document.querySelector('neo-chat');
document.getElementById('explain').addEventListener('click', () => {
  chat.sdk?.ask('Explain this page in three sentences').catch(() => {});
});

Every method works as soon as the property is set, except newConversation, which works only after the neo-chat-ready event on the element. That event carries the handle in event.detail.sdk:

document.querySelector('neo-chat').addEventListener('neo-chat-ready', (event) => {
  event.detail.sdk.newConversation();
});

Open a Document from Your Page#

sdk.openDocument({ itemId }) shows a Squirro document in a full-page overlay in front of your page, and sdk.closeDocument() closes it. Readers open the same overlay by clicking a source in an answer. The optional fields are the following:

  • title, the accessible name of the overlay, announced when it opens.

  • pageNumber, 1-based, for a PDF.

  • highlightFragments, the text to highlight. With a pageNumber, every match is highlighted, but the viewer stays on that page.

For example, to open page 2 of a report from a button:

document.getElementById('open-report').addEventListener('click', () => {
  sdk.openDocument({ itemId: 'the-squirro-item-id', title: 'Q3 report', pageNumber: 2 });
});

The overlay covers the whole window, above the floating chat and the fixed header of your site, whatever z-index your layout uses. It closes on Escape or from its close button.

The document view is read-only. Open original in its header opens a PDF, a PNG, JPEG, GIF, or WebP image, or a plain text file in a new tab, and downloads any other file, so that a stored file cannot run a script on your site.

If you pass your own callbacks.onOpenSidePanel, it replaces that behavior: clicking a source calls your callback, and the overlay does not open. You can still call sdk.openDocument() from it.

PDF documents use the Nutrient viewer, which your proxy serves together with its license key, so the page needs no key. See the Serve the PDF Viewer section of the Set Up the Proxy page. Use one pdfViewer setting per page, because the viewer keeps the first one for the whole page.

Listen to What Happens#

events reports what the chat does, for analytics or for your own UI. The onConversationStarted, onQuestionSent, and onAnswerCompleted events carry the ID of the conversation, so leave it out of what you send to analytics. See the What Readers Share page.

For every event, see the Events section of the Configuration Reference page.

For example, to count completed answers and their sources:

events: {
  onAnswerCompleted: (event) => {
    if (event.reason === 'completed') {
      analytics.track('chat_answer', { sources: event.sources.length });
    }
  },
},