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-initand the widget initializes automatically. This reference topic covers thewindow.FrontCompanionobject API for cases where you need more control (SPAs, custom launchers, dynamic context updates, etc.).
FrontCompanion.init(params)
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 callshutdown()first. containerandcompanionTokenare required.- Returns a
Promisethat resolves when the Autopilot Resolve widget finishes initializing. window.FrontCompanionis available as soon as Autopilot Resolve is initialized.
Init options
| Option | Required | Description |
|---|---|---|
container | Yes | The HTMLElement to append the iframe into |
companionToken | Yes | Your companion token from Front admin settings |
layout | No | Layout preset (see Layout presets below) |
launcher | No | default shows the launcher button; none hides the iframe at the launcher view until show() is called |
sideMargin | No | Side margin, e.g. '24px' (max 100px) |
bottomMargin | No | Bottom margin, e.g. '24px' (max 100px) |
context | No | Initial client context object (see Client context below) |
userJwt | No | JWT for auto-verification of logged-in users (see Verified identity below) |
FrontCompanion.shutdown()
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()
FrontCompanion.show()Opens the Autopilot Resolve window.
await window.FrontCompanion.show();FrontCompanion.hide()
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?)
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_detailskey) - Values must be
string,boolean, ornumber - Key names: max 64 characters; string values: max 512 characters
page_detailsis reserved and auto-populated by the boot script (URL, title, referrer, etc.) when enabled for your channel
FrontCompanion.setContext(context)
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)
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)
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:
- A boot script loaded from
companion.frontapp.comexposeswindow.FrontCompanionand mounts the widget - An iframe whose
srcpoints to a page Front hosts atcompanion.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.FrontCompanionis undefined — The boot script is being blocked byscript-src.- Blank area where widget should appear — The iframe is being blocked by
frame-src, or layout styles are being blocked bystyle-src. - Widget loads but looks mispositioned — Try adding
'unsafe-inline'tostyle-src.
Troubleshooting
window.FrontCompanionis 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, anddata-layoutare 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).
| Preset | Description |
|---|---|
sidebar-right | Sidebar panel on the right |
sidebar-left | Sidebar panel on the left |
widget-right | Floating widget, bottom-right |
widget-left | Floating 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,
});