Autopilot Resolve SDK Reference

This page documents the JavaScript SDK for embedding Autopilot Resolve on your site. It is intended for developers who need advanced programmatic control over initialization, visibility, layout, and client context.

📘

Most customers should use the auto-init embed snippet from Front admin settings — add the boot script with data-auto-init and the widget initializes automatically. This reference topic covers the window.FrontCompanion object API for cases where you need more control (SPAs, custom launchers, dynamic context updates, etc.).


FrontCompanion.init(params)

Use init() when you need programmatic control over widget initialization — for example, in a single-page app where the user is not ready at page load, or when you want to use a custom launcher button.

Load the boot script without data-auto-init, then call init() when you are ready to mount the widget:

await window.FrontCompanion.init({
  container: document.getElementById('companion-container'),
  companionToken: 'YOUR_COMPANION_TOKEN',
  layout: 'widget-right',
});

Notes

  • Call init() once per page load unless you call shutdown() first.
  • container and companionToken are required.
  • Returns a Promise that resolves when the Autopilot Resolve widget finishes initializing.
  • window.FrontCompanion is available as soon as Autopilot Resolve is initialized.

Init options

OptionRequiredDescription
containerYesThe HTMLElement to append the iframe into
companionTokenYesYour companion token from Front admin settings
layoutNoLayout preset (see Layout presets below)
launcherNodefault shows the launcher button; none hides the iframe at the launcher view until show() is called
sideMarginNoSide margin, e.g. '24px' (max 100px)
bottomMarginNoBottom margin, e.g. '24px' (max 100px)
contextNoInitial client context object (see Client context below)
userJwtNoJWT for auto-verification of logged-in users (see Verified identity below)

FrontCompanion.shutdown()

Removes the iframe from the page and shuts down all event listeners. Call init() again to remount the widget.

await window.FrontCompanion.shutdown();

FrontCompanion.show()

Opens the Autopilot Resolve window.

await window.FrontCompanion.show();

FrontCompanion.hide()

Closes the Autopilot Resolve window. If launcher was set to none, no launcher button appears after the window closes.

await window.FrontCompanion.hide();

FrontCompanion.layout(layoutPreset, marginParams?)

Changes the widget layout at runtime. The following example switches to a left sidebar with custom margins:

await window.FrontCompanion.layout('sidebar-left', {
  sideMargin: '32px',
  bottomMargin: '24px',
});

On viewports 639px wide or narrower, sidebar-left and sidebar-right automatically adapt to a mobile-friendly fullscreen layout. Sidebar margins configured via init(), layout(), or data-* attributes may not apply at this breakpoint. This behavior is automatic and cannot be configured via the SDK.


Client context

You can pass customer-specific data to Autopilot Resolve to help the AI understand who the user is and where they are on your site.

📘

You may not include objects that would cause sensitive personal data to be passed through Front’s products and services based on Front’s General Terms.

  • Up to 10 custom keys (excluding the reserved page_details key)
  • Values must be string, boolean, or number
  • Key names: max 64 characters; string values: max 512 characters
  • page_details is reserved and auto-populated by the boot script (URL, title, referrer, etc.) when enabled for your channel

FrontCompanion.setContext(context)

Replaces the entire client context with the object you provide.

await window.FrontCompanion.setContext({
  brand_name: 'Osteria Group',
  restaurant_name: 'Osteria Downtown',
  restaurant_id: 'rest_001',
  product_name: 'Margherita Pizza',
});

You can also pass context in the init() call to set the initial context at mount time.

FrontCompanion.mergeContext(context)

Merges new fields into the existing context without overwriting unrelated keys.

await window.FrontCompanion.mergeContext({
  product_name: 'Margherita Pizza',
  restaurant_name: 'Osteria Downtown',
});

FrontCompanion.removeContext(keys)

Removes one or more context keys by name.

await window.FrontCompanion.removeContext(['product_name']);

Verified identity

When auto-verification is enabled in your Front admin settings, Autopilot Resolve can recognize logged-in users automatically, with no additional verification step required in the widget.

Your secret key is available in Front settings under Security → Auto-verification.

❗️

Never expose this key in client-side code.

Generate a server-side token

On your server, use your secret key to sign a token containing the logged-in user's details.

TypeScript

import {SignJWT} from 'jose';

const secret = new TextEncoder().encode('YOUR_SECRET_KEY');

async function main() {
  const token = await new SignJWT({ email: '<USER_EMAIL>' })
    .setProtectedHeader({ alg: 'HS256' })
    .setExpirationTime('1h')
    .sign(secret);

  console.log(token);
}

void main();

Python

import jwt
from datetime import datetime, timedelta, timezone

secret = "YOUR_SECRET_KEY"
payload = {
    "email": "<USER_EMAIL>",
    "exp": datetime.now(timezone.utc) + timedelta(hours=1),
}

token = jwt.encode(payload, secret, algorithm="HS256")

print(token)

Go

package main

import (
    "fmt"
    "time"
    "github.com/golang-jwt/jwt/v5"
)

func main() {
    secret := []byte("YOUR_SECRET_KEY")
    claims := jwt.MapClaims{
        "email": "<USER_EMAIL>",
        "exp":   jwt.NewNumericDate(time.Now().Add(time.Hour)),
    }

    token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secret)
    if err != nil {
        panic(err)
    }

    fmt.Println(token)
}

Pass the token to the widget

Once you have generated the token on your server, pass it to the widget during initialization.

Auto-init: add the data-user-jwt attribute to your boot script tag.

<div id="companion-container"></div>
<script
  type="module"
  id="front-companion-script"
  src="https://companion.frontapp.com/assets/boot.bundle.js"
  data-auto-init
  data-container-id="companion-container"
  data-token="YOUR_COMPANION_TOKEN"
  data-user-jwt="<GENERATED_JWT>"
  data-layout="widget-right"
></script>

FrontCompanion SDK: pass userJwt in the init() call.

await window.FrontCompanion.init({
  container: document.getElementById('companion-container'),
  companionToken: 'YOUR_COMPANION_TOKEN',
  userJwt: '<GENERATED_JWT>',
  layout: 'widget-right',
});

Integration patterns

Single-page apps (SPA)

Load the boot script once when your app initializes. On route changes, update context with mergeContext() or removeContext() rather than reinitializing the widget. Call shutdown() only on full logout or when you need to unmount the widget entirely.

// After a route change (same integration deployed across multiple restaurant sites/pages)
const restaurant = {
  brand_name: 'Osteria Group',
  restaurant_id: 'rest_014',
  restaurant_name: 'Osteria Waterfront',
};

await window.FrontCompanion.mergeContext(restaurant);

// Optional: clear any keys that no longer apply
await window.FrontCompanion.removeContext(['checkout_step']);

Custom launcher

To use your own button to open the widget, set launcher: 'none' (or data-launcher="none") during initialization and wire your button to FrontCompanion.show().

await window.FrontCompanion.init({
  container,
  companionToken: 'YOUR_COMPANION_TOKEN',
  layout: 'widget-right',
  launcher: 'none',
});

document.getElementById('help-button').addEventListener('click', () => {
  window.FrontCompanion.show();
});

Multiple instances

Only one instance of the widget is supported per page. Calling init() when the widget is already initialized logs a warning and has no effect.


Content Security Policy (WIP)

📘

If you encounter any issues with the Content Security Policy, please let us know in the community.

Content Security Policy (CSP) is a browser security mechanism that controls what content can load or execute on your website. If your site uses CSP headers, you may need to update your policy to allow Autopilot Resolve to load and embed correctly.

How Autopilot Resolve embeds

Autopilot Resolve uses a two-part embed on your page:

  1. A boot script loaded from companion.frontapp.com exposes window.FrontCompanion and mounts the widget
  2. An iframe whose src points to a page Front hosts at companion.frontapp.com, where the widget app runs

Because the widget runs in a cross-origin iframe on Front's domain, your CSP mainly needs to allow that embed shell — the boot script and the iframe. API calls, realtime messaging, and other network activity happen inside the iframe, not on your page.

Directives for your site

The following directives are required for most customers.

script-src — allow the boot script:

https://companion.frontapp.com

frame-src — allow the companion iframe:

https://companion.frontapp.com

style-src — likely required:

'unsafe-inline'

The boot script applies inline layout styles to the iframe element (position, size, margins). A strict style-src without 'unsafe-inline' may prevent the widget from rendering correctly.

Example (production)

Content-Security-Policy:
  script-src ... https://companion.frontapp.com;
  frame-src ... https://companion.frontapp.com;
  style-src ... 'unsafe-inline';

Adjust this example to match your existing policy syntax (Report-Only, meta tag, etc.).

Troubleshooting (CSP)

  • window.FrontCompanion is undefined — The boot script is being blocked by script-src.
  • Blank area where widget should appear — The iframe is being blocked by frame-src, or layout styles are being blocked by style-src.
  • Widget loads but looks mispositioned — Try adding 'unsafe-inline' to style-src.

Troubleshooting

  • window.FrontCompanion is undefined — The boot script has not finished loading. Wait for the script to load before calling SDK methods.
  • Embed renders blank — Verify that container, companionToken, and data-layout are all set correctly.
  • file:// protocol — Local file URLs are not supported. Serve your page over HTTPS.
  • CSP / iframe restrictions — Ensure your Content Security Policy allows framing from companion.frontapp.com.

Reference

Layout presets

These values correspond to the layout options available in Front admin settings (Sidebar widget and Floating widget).

PresetDescription
sidebar-rightSidebar panel on the right
sidebar-leftSidebar panel on the left
widget-rightFloating widget, bottom-right
widget-leftFloating widget, bottom-left

Full example (FrontCompanion SDK)

const container = document.getElementById('companion-container');

await window.FrontCompanion.init({
  container,
  companionToken: 'YOUR_COMPANION_TOKEN',
  layout: 'widget-right',
  launcher: 'none',
  sideMargin: '24px',
  bottomMargin: '24px',
  userJwt: '<GENERATED_JWT>',
  context: {
    brand_name: 'Osteria Group',
    restaurant_id: 'rest_001',
    restaurant_name: 'Osteria Downtown',
    product_name: 'Margherita Pizza',
  },
});

document.getElementById('help-button').addEventListener('click', () => {
  window.FrontCompanion.show();
});

// Later, when the host app navigates to a different restaurant page
const restaurant = getRestaurantFromUrl(window.location.pathname);

await window.FrontCompanion.mergeContext({
  brand_name: restaurant.brandName,
  restaurant_id: restaurant.id,
  restaurant_name: restaurant.name,
});