You can paste in the snippet the dashboard gives you, or start the form from your own code. Which you can use depends on how the form gets its token.
Option 1: paste-in snippet (key only)#
Paste this where the form should appear. The dashboard gives it to you with your values already filled in.
<div data-subcontext-quote data-key="qfk_YOUR_KEY" data-product="YOUR_PRODUCT_SLUG" data-journey="YOUR_JOURNEY_SLUG"></div>
<script src="https://js.subcontext.com/quoteform-latest.js" defer></script>
When the script runs, it finds every element with data-subcontext-quote and
draws a form in it. It waits for the page to finish loading if it hasn't yet.
About the snippet:
- Single-page apps work. Placeholders added later (for example when the app changes view) are started as they appear. If a placeholder is removed, its form is removed too, and putting it back starts a fresh form.
- Each placeholder is started once. The script marks it with
data-subcontext-quote-booted="true". - If your code adds a placeholder first and sets its
data-*attributes after, callSubcontext.Quote.mountAll()once they're set. - Forms you start with
init()are never removed this way.
| Attribute | Goes on | Required | What it does |
|---|---|---|---|
data-subcontext-quote |
the placeholder | yes | Marks the element to draw a quote form in. |
data-key |
the placeholder | yes | The quote form's key (qfk_...). |
data-product |
the placeholder | yes | The product slug. Must be the quote form's product. |
data-journey |
the placeholder | yes | The journey slug. Must be the quote form's journey. |
data-presentation |
the placeholder | no | Another presentation of the journey. Leave it out for the default. |
data-primary-color |
the placeholder | no | This form's main colour, like #0f766e. |
data-accent-color |
the placeholder | no | This form's accent colour. |
data-font-family |
the placeholder | no | This form's font, like Figtree, system-ui, sans-serif. Load the font on your page yourself. |
data-remember-click-ids |
the placeholder | no | "true" or "false": whether ad click ids may be kept for a form on a later page. See Ad clicks across pages. |
data-base-url |
the <script> tag |
no | The Subcontext address. It defaults to https://subcontext.com, so you can leave it out. |
You can't set callbacks, prefill or other options with attributes. For those, start the form from your own code.
Option 2: from your own code#
With a key:
<div id="quote"></div>
<script src="https://js.subcontext.com/quoteform-latest.js"></script>
<script>
const widget = Subcontext.Quote.init({
container: '#quote',
key: 'qfk_YOUR_KEY',
productSlug: 'YOUR_PRODUCT_SLUG',
journeySlug: 'YOUR_JOURNEY_SLUG'
})
</script>
With your own server:
<div id="quote"></div>
<script src="https://js.subcontext.com/quoteform-latest.js"></script>
<script>
Subcontext.Quote.init({
container: '#quote',
productSlug: 'YOUR_PRODUCT_SLUG',
journeySlug: 'YOUR_JOURNEY_SLUG',
getToken: () =>
fetch('/subcontext-token').then((response) => {
if (!response.ok) throw new Error('Could not get a quote token (' + response.status + ')')
return response.json() // { access_token, expires_in }
})
})
</script>
apiBase is the Subcontext address. It is optional and defaults to
https://subcontext.com.
Your own token endpoint#
Your server asks Subcontext for a token with the API application's client id and secret (an OAuth "client credentials" request), then hands the page only the token. The secret never goes to the browser.
The request your server makes:
POST https://subcontext.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&scope=read write
&resource=https://subcontext.com/api/v1
Return { "access_token": "...", "expires_in": 7200 } to your page. Put this
endpoint on the same website as the page, so the browser needs no extra
cross-origin setup. token-server.mjs is a small
working example in Node (see the own-server example).
It answers GET (or POST) /subcontext-token, and keeps one token for all
visitors until it nearly runs out.
The form calls getToken again 30 seconds before the token runs out, and once
more if Subcontext ever answers "401 Unauthorized".
The access tokens guide covers this in full: setting up the API application, server-only and browser applications, caching the token, errors and fixes, and another working token server with an example page.