Productlane
Productlane
  • Docs
  • Changelog
  • Feature requests
  • Support portal
    • Widget
    • Theme
    • Custom domain
    • SSO
    • Signatures
    • Custom data
    • Widget Content Security Policy (CSP)
Docs / Setup

Widget

Unified widget for your Live Chat, Help Center, and Changelog.
Widget

By going to Settings → Widget, you can easily add a widget to your site. It only takes a few lines of JavaScript to set up, providing you with a simple way to unify your support, Changelog, docs, and AI Chat for your customers. You can customize the widget's appearance to fit your site's design, listen to events & more.


Installation

  1. Embed & initialize
    Head to the widget settings page, where you'll find a copy/pastable snippet that looks like the snippet below. Or copy the code below and replace <your-widget-key /> with your workspace's widget key.

    <script>
      ;((w)=>{const P=(w.Productlane={queue:{}});["set","open","close","toggle","on","off","init"].forEach(m=>{P[m]=(n=>function(){P.queue[n]={args:arguments}})(m)})})(window);
      
      Productlane.init({
        widgetKey: "<your-widget-key />",
      })
    </script>
    <script 
      async 
      defer 
      crossorigin="anonymous" src="https://widget.productlane.com/latest.productlane-widget.min.js"
    ></script>
    
  2. That's it!
    While this is all you have to do, let's briefly unwrap what happens in the snippet.
    The first script sets up the global Productlane object used to communicate with the widget. It also initializes the widget via Productlane.init() with your corresponding widget key.
    The second script tag loads the widget from Productlane's CDN.


API

Widget key

The widgetKey is a unique identifier that links the snippet to your workspace's widget configuration. It is not a JSX element or selector — the angle-bracket notation (<your-widget-key />) in the snippet is just a placeholder to show you where to paste your actual key.

You can find your real widget key on your widget settings page. It looks like a short alphanumeric string (for example, wg_abc123). Copy it directly from that page and replace the placeholder.

Productlane.init({
  widgetKey: "wg_abc123", // paste your actual key here, without angle brackets
});

User

An object containing information about the current user for simple authentication. Will hide the email field in the contact form if provided.

Productlane.init({
  widgetKey: "<your-widget-key />",
  user: {
    email: "[email protected]",
  },
});

Authentication

To verify your users' identities and ensure conversations are securely linked to them, enable secure mode by passing a signed JWT (JSON Web Token) to the widget.

  1. Generate the Token

    You need to generate a JWT on your backend using a Signing Secret. You can find this secret in your Widget Settings.

    The token must be signed using the HS256 algorithm and include the user's email, an issued-at timestamp (iat), and an expiration timestamp (exp).

    The expiration timestamp can not exceed 1 hour. This does not affect the time your user is signed into the widget. After the user token is passed to the widget, it is exchanged for a session token. The session token is valid for 12 hours by default.

    Here is an example using Node.js and the jsonwebtoken library:

    const jwt = require('jsonwebtoken');
    
    const secret = "wg_sec_..."
    
    const payload = {
      email: user.email,
      iat: Math.floor(Date.now() / 1000),
      exp: Math.floor(Date.now() / 1000) + (15 * 60) // 15 minutes (recommended)
    };
    
    const userToken = jwt.sign(payload, secret, { algorithm: 'HS256' })
    
  2. Pass Token to Widget

    Once generated, pass the token to the widget using the userToken property. You can do this during initialization, or update it dynamically later.

    On Initialization:

    Productlane.init({
      widgetKey: "<your-widget-key />",
      userToken: "<user-token>"
    });
    

    Dynamically (e.g., after login):

    Productlane.set({
      userToken: "<user-token>"
    });
    

Sign Out

To sign the user out and unset the authentication token, use the signOut method:

Productlane.signOut();

Important Note on User Objects

The userToken provides secure authentication. If you subsequently set the simple user object (e.g., Productlane.set({ user: { email: ... } })), it will overwrite the authentication status and effectively sign the user out of the secure session. Ensure you use either userToken for authenticated users or user for simple identification, but avoid mixing them in the same session state.


Automatic Portal Sign-In

When a user is authenticated in the widget via JWT, they are automatically signed into the portal when clicking any link that opens it. For example the roadmap, changelog, docs, or requests. This works like single sign-on (SSO): no separate login is required on the portal side.

How It Works

  1. The user authenticates in the widget using a userToken (JWT).

  2. When they click a link to the portal (e.g., to view a roadmap item or help article), the widget requests a short-lived, one-time authorization code.

  3. The portal exchanges this code for a session, automatically signing the user in.

Requirements

To use this feature, both Identity Verification and Portal Auth must be enabled in your Widget Settings.


Widget Dynamic Context

The widget supports dynamic context passing, which helps the AI Chat provide more relevant and page-specific answers to your users. By setting context information about the current page or feature your user is viewing, the AI can tailor its responses accordingly.

Setting Context

Use the setContext method to pass contextual information to the widget. Context is provided as an object with string key-value pairs.

Productlane.setContext({
  page: "dashboard",
  feature: "analytics",
  plan: "pro"
});

Common use cases:

  • Page tracking: Let the AI know which page the user is currently on

  • Feature context: Indicate which feature or section the user is interacting with

  • User attributes: Pass relevant user information like their plan type or role

  • Product state: Provide context about what the user is viewing or editing

Getting Current Context

You can retrieve the currently set context at any time:

const currentContext = Productlane.getContext();
console.log(currentContext); // { page: "dashboard", feature: "analytics" }

Clearing Context

To remove all context information:

Productlane.clearContext();

How Context Enhances AI Chat

When a user asks a question in the AI Chat, the context you've set is automatically included with their message. This allows the AI to:

  • Prioritize information relevant to the current page or feature

  • Provide more specific and actionable answers

  • Reference documentation or help articles related to what the user is currently doing

For example, if a user is on your "Analytics Dashboard" page and asks "How do I export this data?", the AI will know they're referring to analytics data specifically, not data from other parts of your application.


Positioning

To control where the widget appears on your site, use the position option. These settings let you choose which side of the screen the widget button appears on and which direction the widget opens.

  • position ("left", "right" or "center"):
    Sets the default side of the screen where the widget button is placed. The widget panel will open in the opposite direction relative to the button and remain close to it, or appear centered if position is set to "center".
    For example, position: "right" places the button on the right edge of the screen, and the widget opens toward the left.

Here is an example of widget positioning:

Productlane.init({
  widgetKey: "<your-widget-key />",
  position: "left",
});

Offset

To fine-tune the widget's distance from the edges of the screen, use the offset option. This allows you to add custom spacing from the bottom, left, or right edges.

Productlane.init({
  widgetKey: "<your-widget-key />",
  offset: {
    bottom: "20px",
    right: "20px",
  },
});

Offset Properties

Property

Type

Description

bottom

string

Distance from the bottom edge (e.g., "20px", "2rem")

left

string

Distance from the left edge (e.g., "20px", "2rem")

right

string

Distance from the right edge (e.g., "20px", "2rem")

All properties are optional. Use left or right depending on your position setting. For example, if your widget is positioned on the left, use left and bottom to adjust its placement:

Productlane.init({
  widgetKey: "<your-widget-key />",
  position: "left",
  offset: {
    bottom: "80px",
    left: "16px",
  },
});

Custom trigger button

By default, the widget renders its own floating icon button. If you want to use your own button or link to open the widget, you can hide the default icon and call the JavaScript API directly.

Icon size

Changing the size of the built-in widget icon is not currently supported. If you need a differently sized or styled trigger, use a custom trigger button instead (see below).

Using a custom trigger

  1. In Settings → Widget, set the icon style to None. This hides the default floating button so your own element becomes the only trigger.

  2. Call Productlane.open() or Productlane.toggle() from your own button's click handler.

Plain HTML example:

<button onclick="Productlane.open()">Open support</button>

React / JSX example:

<button onClick={() => Productlane.toggle()}>Open support</button>

Open a specific view directly:

// Opens straight to the AI Chat view
Productlane.open("AICHAT");

// Opens straight to the feedback form
Productlane.open("FEEDBACK");

Make sure to call Productlane.open() or Productlane.toggle() only after the widget has loaded. Wrap the call inside a Productlane.on("loaded", ...) handler if you need to invoke it programmatically on page load rather than on a click event.


Changelog notifications

If you want to prevent the changelog notification popup from appearing and instead have the widget display as usual, you can use the disableChangelogNotification option. This can be useful, for example, when you want to hide the popup for selected users.

Productlane.init({
  widgetKey: "<your-widget-key />",
  disableChangelogNotification: true,
});

When set to true, the changelog popup will not appear, and the widget will behave normally. Setting it to false (or omitting it) will keep the default behavior where changelog popups are shown when new changelogs were published.


Branding

To remove the Productlane branding from your widget, go to Settings → Widget and turn off the "Show branding" toggle.


Custom links

Custom links open in a new tab by default. To run your own logic instead, return false from your customLinkClicked handler and the widget will skip opening the URL. You can also leave the URL field blank in Widget Settings to render a link that only fires the event.

Productlane.on("customLinkClicked", (link) => {
  if (link.title === "Start tour") {
    startProductTour()
    return false
  }
})

The link object has the shape { title?: string; url?: string }. When no URL is configured, link.url is undefined.


Widget methods

Once the widget is initialized, you can use these methods to interact with it.

  • Productlane.open(view?: "INDEX" | "CHANGELOG" | "DOCS" | "FEEDBACK" | "AICHAT" | "LIVE_CHAT")
    Opens the Productlane widget. By default, it opens the last active view, but you can optionally specify a view to open directly:

    • "INDEX" - opens the main index view with all navigation links.

    • "CHANGELOG" - opens the latest changelog.

    • "DOCS" - opens the documentation navigation menu. (Use Productlane.openDocs() method to open a specific article.)

    • "FEEDBACK" - opens the contact form where users can leave feedback, report bugs, or ask questions.

    The view argument is case-insensitive, so "changelog", "Changelog", and "CHANGELOG" all work the same.

  • Productlane.close() Closes the widget.

  • Productlane.toggle() Toggles between opening and closing the widget.

  • Productlane.disable() Disables the widget across the entire page.

  • Productlane.enable() Enables the widget.

  • Productlane.openDocs(documentUrlName | documentId) To open a specific article. You can pass either:

    • documentUrlName - the URL path of the article, like "get-started/quickstart"

    • documentId - the internal ID of the document

  • Productlane.set() For setting certain widget properties. Equal to the settings object in Productlane.init().

Productlane.init({
  widgetKey: "<your-widget-key />",
});

Productlane.on("loaded", () => {
  Productlane.set({
    user: {
      email: "[email protected]",
    },
  });
});

Make sure to call any methods after the widget is initialized, e.g. like so: Productlane.on('loaded', () => {/* Your code here */}).


Widget events

You can listen to the following events:

  • Productlane.on("loaded", () => {}) Fires when the widget is fully loaded. Make sure to call any methods in the callback of this event.

  • Productlane.on("opened", () => {}) Fires after the widget is opened.

  • Productlane.off("opened", () => {}) Removes event listener for opened event.

  • Productlane.on("closed", () => {}) Fires after the widget is closed.

  • Productlane.off("closed", () => {}) Removes event listener for closed event.

  • Productlane.on("toggled", () => {}) Fires after the widget is toggled.

  • Productlane.off("toggled", () => {}) Removes event listener for toggled.

  • Productlane.on("customLinkClicked", (link) => {})

  • Productlane.on("openDocsPage", ({id, title, urlName}) => {}) Fires when a docs article is opened.

Productlane.on("customLinkClicked", (link) => {
  console.log(link); // { "title": "Docs", "url": "productlane.com/docs" }
});

Productlane.off("customLinkClicked", () => {}) Removes the event listener for the customLinkClicked event.

PrevShortcuts
NextTheme
Was this helpful?