Shopify headless storefront guide
Purpose
This guide explains how a Shopify headless storefront should prepare a signed config payload, expose it to the Tern storefront module, and mount <tern-trade-in>.
This is the recommended integration path when the storefront can identify the shop and, optionally, the logged-in Shopify customer.
If you are not a Shopify merchant, use Non-Shopify Headless Storefront Integration Guide.
If you cannot use headless authentication at all, use Standalone Storefront Integration Guide.
Recommendation First
Use this guide when:
The storefront belongs to a Shopify shop.
You can generate merchant-signed bootstrap payloads on your backend.
You may need anonymous or logged-in customer bootstrap.
You want the recommended trust model for headless integrations.
Summary
The implementation has three steps:
Get the merchant shared secret from Tern.
Use that shared secret on your backend to sign the bootstrap request payload.
Expose
window.ternStorefrontConfigbefore mounting<tern-trade-in>.
Shared Secret
Before implementing the bootstrap call, obtain the merchant shared secret from the Tern admin interface for the relevant shop.
Implementation guidance:
Generate or copy the shared secret from the Tern admin interface.
Store the shared secret on your backend.
Do not expose the shared secret in browser code.
Use the shared secret only on the server when generating the HMAC signature.
Config Format
Expose window.ternStorefrontConfig with these fields:
shopDomainlocaleproofOptional
customerLogin
Browser config uses shopDomain. The storefront runtime converts that to the API field shop_domain before calling the bootstrap endpoint.
Optional customerLogin
Use customerLogin when you want to override where unauthenticated customers are redirected for login.
customerLogin supports:
path: the login path on the current origin (must start with/)redirectParam: query-string key used to return from login
If omitted, storefront uses:
path = /customer_authentication/loginredirectParam = checkout_url
Example:
Supported Bootstrap Flows
Merchant-Signed Anonymous Bootstrap
Use this when you want a signed storefront config without attaching a customer.
Merchant-Signed Logged-In Bootstrap
Use this when you want the storefront config to identify a logged-in customer.
How To Sign The Request
When using merchant_signed, your backend must sign the full canonical string shown below with HMAC-SHA256 using the merchant shared secret.
The result of that HMAC operation becomes proof.signature in window.ternStorefrontConfig.
Only these four values are part of the signature, joined in alphabetical key order:
emailidshop_domaintimestamp
Sign this exact canonical string:
Rules:
emailmust be lowercased and trimmed.shop_domainmust be the Shopify shop domain for the target store.idmust be the logged-in customer id, or0when the bootstrap is anonymous.timestampmust be a Unix timestamp in seconds.The signature must be lowercase hex.
Generate the signature on your backend, never in browser code.
Node.js Example: Anonymous Signing
Node.js Example: Logged-In Customer Signing
In the logged-in example:
The signed string includes the normalized email and Shopify customer id.
The
customerobject in the request must match the values used to build the signed canonical string.If these values do not match, Tern will reject the request.
For anonymous merchant-signed bootstrap, omit proof.customer entirely and sign with an empty email and id=0.
Bootstrap Response
After the storefront module initializes, it obtains a bootstrap response that includes:
tokenlocalega_measurement_idstorefront_version(1or2— see Bundle URL By Storefront Version)Optional
shopify_customer
Example response:
Browser Runtime And Mount
Your page must load the Tern storefront runtime before you try to mount <tern-trade-in>.
If you are using the built browser bundle, load it first:
Bundle URL By Storefront Version
The bundle URL depends on which storefront version the shop has been migrated to:
v1 (default):
https://prod.tern.eco/js/storefront/trn-nrc-umd.jsv2 (migrated shops):
https://prod.tern.eco/js/storefront/v2/trn-nrc-umd.js
Tern's own embedded Shopify integration switches this automatically server-side based on the shop's storefront_version. Third-party headless integrations that load the bundle directly must switch this URL themselves when the shop is migrated to v2. Confirm which version applies to your shop with Tern before changing the bundle URL.
Then define window.ternStorefrontConfig before mounting <tern-trade-in>. The storefront module uses that config to initialize the storefront session internally.
Example head
Example body
What The JavaScript Example Assumes
The JavaScript snippets in this guide are integration snippets, not complete standalone pages.
They assume:
Your page already includes the Tern storefront bundle, for example
https://prod.tern.eco/js/storefront/trn-nrc-umd.js(or thev2path for migrated shops — see Bundle URL By Storefront Version).Your page already contains a mount target such as
<div id="tern-storefront-root"></div>.The HMAC signature was generated on your backend before the browser set
window.ternStorefrontConfig.The browser can load the Tern storefront bundle successfully.
If you paste the snippet into a page without those prerequisites, it will not work on its own.
Implementation Checklist
Obtain the merchant shared secret from the Tern admin interface.
Store the shared secret on your backend.
Build and sign the canonical payload on the backend.
Expose
shopDomain,locale, andproofinwindow.ternStorefrontConfigbefore mounting the storefront.Optionally set
customerLogin.pathandcustomerLogin.redirectParamto control login redirect behavior.Load the storefront browser bundle, for example
https://prod.tern.eco/js/storefront/trn-nrc-umd.js(or thev2path for migrated shops — see Bundle URL By Storefront Version).Mount
<tern-trade-in>afterwindow.ternStorefrontConfigis defined.Let the storefront module initialize the storefront session from that config.
Use the returned
tokenfrom the bootstrap response as the storefront session token.
Last updated