Install the quote form

Add the quote form with the paste-in snippet, start it from your own code, or give it tokens from your own server.

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.

html
<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, call Subcontext.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:

html
<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:

html
<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:

Code
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.

Stuck, or something missing?

Get in touch and a person on the team will help.

Contact us