Instant Answers Widget

Maven offers an instant answers widgets that allow you to embed a Maven experience directly into your website.

To add the instant answers widget to your website, you need to add a small piece of javascript to your page. This javascript code will initialize the widget and connect it to your Maven instance.

Your personalized code snippet can be found on either the chat settings page or instant answers settings page within the Dashboard. You’ll need to copy and paste the code snippet into your website’s HTML to get started. More specific instructions for common sites are provided below.

Instant Answers Widget

The instant answers code snippet requires a slightly deeper integration. It needs to know which piece of the page to attach the widget to and also needs to know when the user question has been submitted and what the question was. This requires a bit more HTML knowledge.

Configuration Options

The Instant Answers widget supports several configuration options that can be customized:

OptionTypeRequiredDefaultDescription
organizationIdstringYes-Your organization ID
agentIdstringYes-Your agent ID
localestringNobrowser localeWidget locale
signedUserDatastringNo-A signed and encrypted authentication token
unsignedUserDataRecord<string, any>No-Arbitrary data to include for context
tagsstring[]No-Tags to add to the search (can be a single tag or list of tags)

Basic Configuration Example

1Maven.InstantAnswersWidget.init({
2 agentId: "your-agent-id",
3 organizationId: "your-organization-id",
4 locale: "en",
5 signedUserData: "your-signed-jwt-token", // Optional user authentication
6 unsignedUserData: {
7 sessionId: "user-session-123",
8 department: "support"
9 },
10 tags: ["help-center", "self-service"]
11});

Authentication

Signed User Authentication

Maven Instant Answers supports signed and encrypted user authentication, allowing you to securely authenticate users and pass additional context data (such as session IDs) that can be used by Maven Apps to make API calls on behalf of the user.

Requirements

  • A server-generated, signed and encrypted JWT containing user data
  • A shared symmetrical encryption key, provided in the Instant Answers app settings under Security (Encryption secret)
  • A shared public key for verifying signing, provided in the Instant Answers app settings under Security (JWT public key)

User Data Requirements

The user data object must include:

  • firstName - User’s first name
  • lastName - User’s last name
  • id - User’s unique identifier (UUID)
  • At least one of:
    • phoneNumber - User’s phone number
    • email - User’s email address
  • Additional fields (like sessionId) will be included and can be used by Maven Apps

Generating User Authentication Token

To protect the user data in transit, generate a signed JWT token containing user data and encrypt the token with ES256 and a 32-bit secret key. This token must be generated on the backend and passed into the instant answers widget via the signedUserData property.

Example Implementation (TypeScript)
1import { SignJWT, EncryptJWT } from 'jose';
2
3async function secureUserData(userData: Record<string, string> & {
4 id: string
5 firstName: string
6 lastName: string
7 sessionId?: string // Additional context data
8} & (
9 { email: string, phoneNumber?: string } |
10 { email?: string, phoneNumber: string }
11)) {
12 // 1. Sign the user data with your private key (ES256 algorithm)
13 const signedJWT = await new SignJWT(userData)
14 .setProtectedHeader({ alg: 'ES256' })
15 .setIssuedAt()
16 .setExpirationTime('1d')
17 .sign(yourPrivateKey);
18
19 // 2. Encrypt the signed JWT using your encryption secret
20 const encryptedJWT = await new EncryptJWT({ jwt: signedJWT })
21 .setProtectedHeader({ alg: 'dir', enc: 'A128CBC-HS256' })
22 .encrypt(base64url.decode(encryptionSecret));
23
24 return encryptedJWT;
25}

Using Signed User Data

Once you have generated the signed user data token, pass it to the widget during initialization:

1Maven.InstantAnswersWidget.init({
2 agentId: "your-agent-id",
3 organizationId: "your-organization-id",
4 signedUserData: await secureUserData({
5 id: "user-123",
6 firstName: "John",
7 lastName: "Doe",
8 email: "[email protected]",
9 sessionId: "session-abc-123" // Custom data for your app
10 })
11});

Make sure to configure the JWT public key and Encryption secret in your Instant Answers app settings under the Security section for authentication to work properly.

Setting up Zendesk help center

Zendesk provides instructions for customizing your help center theme. Follow those instructions to edit your theme.

For the chat widget you want to add your code snippet to script.js.

For the instant answers widget:

  1. Goto “search_results.hbs”
  2. Find
    {{#if results}}
    <ul class="search-results-list">
    And replace with:
    <div id="maven-instant-answers-container" style="margin-bottom: 5px"></div>
    {{#if results}}
    <ul class="search-results-list">
  3. Add the following to the end of the file and remember to replace the API KEY with your Maven API key found within the code snippet on the Instant Answers Settings page.
    <script src="https://instant-answers.onmaven.app/js/widget.js" async></script>
    <script>
    // This code loads the Maven widget when the page is first opened
    addEventListener("load", function () {
    Maven.InstantAnswersWidget.init({
    agentId: "REPLACE THIS WITH YOUR AGENT", // defaults to support
    organizationId: "REPLACE THIS WITH YOUR ORG",
    locale: "en",
    signedUserData: "your-signed-jwt-token", // Optional: for authenticated users
    unsignedUserData: {
    page: "zendesk-help-center",
    source: "search"
    }
    });
    // If there is an HTML element on the page with the ID 'query'
    if (document.getElementById('query') !== null) {
    // Get the user question from the value of that element
    var text = document.getElementById('query').value;
    if (text) {
    console.log("Loading Maven with the question: " + text);
    Maven.InstantAnswersWidget.search({
    query: document.getElementById('query').value,
    selector: '#maven-instant-answers-container'
    });
    } else {
    console.log("No query found. Not loading Maven.");
    }
    } else {
    console.log("No HTML element found with the ID query. Not loading Maven.");
    }
    });
    </script>

If Maven does not render after adding this snippet, check the browser logs to see if either the query HTML element is missing or doesn’t have a value.

If you see those type of logs:

  • Your Zendesk instance may be putting the user question in another HTML element - if so change query in the above snippet to the ID of the HTML element that the user question does appear in
  • Or the question may only be in the page url, and not in the HTML at all. In this case, try replacing the above var text line with var text = new URLSearchParams(window.location.search).get("query");. (Note: you may also need to comment out the if statement that checks for the presence of the query element: document.getElementById('query') !== null)

Setting up Salesforce Digital Experience

The Maven Instant Answers widget can be added to a help center built on the Salesforce Content Management System (CMS). To allow a page hosted in the CMS to access Maven AGI, you will likely need to confirm or change a few security settings.

Trusted URLs for data access

First you must ensure that Salesforce can load data from Maven AGI. In the Salesforce setup navigation, search for “Trusted URLs”. In the Trusted URLs page, add entries for https://instant-answers.onmaven.app.

Trusted Scripts

Next the CMS must be allowed to load scripts from Maven AGI. In Experience Builder for your site, open the settings and navigate to Security & Privacy. Change “Content Security Policy (CSP)” to Relaxed, then add https://instant-answers.onmaven.app to the “Trusted Sites for Scripts” list.

Add the Maven Script

In Settings for your site in Experience Builder, navigate to “Advanced” and press the “Edit Head Markup” button. In the editor, add the following snippet

1<script src="https://instant-answers.onmaven.app/js/widget.js" async></script>
2<script>
3 // This code loads the Maven widget when the page is first opened
4 addEventListener("load", function () {
5 Maven.InstantAnswersWidget.init({
6 agentId: "REPLACE THIS WITH YOUR AGENT", // defaults to support
7 organizationId: "REPLACE THIS WITH YOUR ORG",
8 locale: "en",
9 signedUserData: "your-signed-jwt-token", // Optional: for authenticated users
10 unsignedUserData: {
11 page: "salesforce-help-center",
12 source: "search"
13 }
14 });
15 }
16</script>

Add the results container

In experience builder, add a “HTML Editor” component on the page where you would like the search results. Add the following markup:

1<div id="maven-instant-answers-container"></div>

Add a search button, or hook the search button

To invoke search and start returning results from Maven, make the following Javascript call in a new button or when an existing search button is pressed

1Maven.InstantAnswersWidget.search({
2 query: text,
3 selector: '#maven-instant-answers-container'
4});

Setting up HubSpot Knowledge Base

HubSpot Knowledge Base requires JavaScript injection through the Header HTML settings to embed the Maven Instant Answers widget.

Access Header HTML Settings

  1. In HubSpot, navigate to ServicesKnowledge BaseSettings (cog icon)
  2. Click on ContentPages
  3. Select the knowledge base where you want to add Instant Answers
  4. Click Template to access template settings
  5. Locate the Header HTML section

Add Integration Code

Copy and paste the following code into the Header HTML section:

1<!-- Load Maven AGI Instant Answers Script -->
2<script src="https://instant-answers.onmaven.app/js/widget.js" async></script>
3
4<script>
5(function () {
6
7 const MAVEN_CONFIG = {
8 organizationId: "YOUR_ORG_ID", // Replace with your organization ID
9 agentId: "YOUR_AGENT_ID" // Replace with your agent ID
10 };
11
12 // Check if current page is a search page
13 function isSearchPage() {
14 const { pathname, search } = window.location;
15 return pathname.toLowerCase().includes("search") || /[?&](q|term|query)=/.test(search);
16 }
17
18 // Extract search query from URL
19 function getSearchQuery() {
20 const params = new URLSearchParams(window.location.search);
21 return params.get("q") || params.get("term") || params.get("query") || "";
22 }
23
24 // Create and insert widget into page
25 function insertMavenWidget() {
26
27 // Parent container to insert the widget in. This must exist in your knowledge base
28 const searchContainer =
29 document.querySelector(".hs-search-results") ||
30 document.querySelector("[class*='search']") ||
31 document.querySelector("main") ||
32 document.body;
33
34 if (!searchContainer) {
35 console.warn("[Maven] No container found");
36 return;
37 }
38
39 const wrapper = document.createElement("div");
40 wrapper.id = "maven-instant-answers-search";
41 searchContainer.insertBefore(wrapper, searchContainer.firstChild);
42
43 // Wait for DOM to fully update before initializing
44 setTimeout(initializeMaven, 100);
45 }
46
47 // Initialize Maven widget and perform search
48 function initializeMaven() {
49 let attempts = 0;
50 const maxAttempts = 30; // 3 seconds
51
52 const checkMaven = setInterval(() => {
53 attempts++;
54
55 if (typeof Maven !== "undefined" && Maven.InstantAnswersWidget) {
56 clearInterval(checkMaven);
57
58 try {
59 Maven.InstantAnswersWidget.init(MAVEN_CONFIG);
60
61 const query = getSearchQuery();
62 if (query) {
63 Maven.InstantAnswersWidget.search({
64 query: query,
65 selector: "#maven-instant-answers-search"
66 });
67 }
68 } catch (error) {
69 console.error("[Maven] Error:", error);
70 }
71 }
72
73 if (attempts >= maxAttempts) {
74 clearInterval(checkMaven);
75 console.warn("[Maven] Maven API not found");
76 }
77 }, 100);
78 }
79
80 // Setup on page load
81 function setup() {
82 if (isSearchPage()) {
83 // Wait for page to stabilize before inserting widget
84 setTimeout(insertMavenWidget, 500);
85 }
86 }
87
88 // Run setup when DOM is ready
89 if (document.readyState === "loading") {
90 document.addEventListener("DOMContentLoaded", setup);
91 } else {
92 setup();
93 }
94
95})();
96</script>

Configure Credentials

Update the MAVEN_CONFIG object with your credentials:

1const MAVEN_CONFIG = {
2 organizationId: "your-org-id", // Your Maven organization ID
3 agentId: "your-agent-id" // Your Maven agent ID
4};

Customize Container Selector (Optional)

The script automatically finds where to inject the widget using fallback selectors. If the widget doesn’t appear in the right location, you can customize the searchContainer variable in the integration code to match your knowledge base structure.

The widget is inserted as the first child of the selected container. If you need it in a different position, modify the insertBefore line in the insertMavenWidget() function.

Still not working?

In general, if the instant answers widget renders but seems to load forever, this most likely means that Maven is being sent an empty question. Generally this means the user question needs to be pulled from a different HTML element on the page, or, it might be only in the page url. Reach out and we can help you fix this!

Contact us on Discord for technical support.