Skip to main content

Installing Loyalty on Headless Instances

Overview​

For stores specifically running Shopify Hydrogen 2, please look here for further support.

This guide explains how to integrate Okendo Loyalty into your headless Shopify store. The implementation requires 2-3 code snippets depending on your needs.

Prerequisites:

  • Active Okendo Loyalty subscription
  • Headless Shopify storefront
  • Customer authentication implemented (via Customer Account API or Storefront API)

Quick Links:

Implementation Steps​

To implement Okendo Loyalty, you will need to render two or three snippets on your store:

1. Loyalty Settings Metafield​

Located in your Shop Metafields, under the okendo namespace and LoyaltySettings key, you will find a snippet containing 2 script tags (one for the loyalty widget settings, and one for the initialisation script).

Purpose: Loads the Loyalty App with your customized settings and displays the Floating Widget.

Implementation: Render the metafield content in the <head> section of your store pages.

<!-- Liquid example -->
{{ shop.metafields.okendo.LoyaltySettings }}
// GraphQL query example (for Hydrogen/Remix)
query metafields {
shop {
metafield(namespace: "okendo", key: "LoyaltySettings") {
value
}
}
}

The metafield contains 2 script tags:

  1. Widget settings configuration
  2. Initialization script

Result: The Floating Widget will appear automatically (unless disabled in Okendo Admin settings).

⚠️ Important: This must be rendered on every page where you want loyalty features to appear.

2. Customer Access Token Script Tag​

Purpose: Authenticates the customer to display personalized loyalty information.

Required for:

  • Logged-in customer experience
  • Points balance display
  • Rewards redemption
  • Member-specific content

Choose one implementation method based on your authentication approach:

When to use: Your store uses the Customer Account API for authentication (Shopify's newer authentication method).

Implementation:

<script type="application/json" id="oke-loyalty-customer-access-token">
{
"customerAccessToken": "YOUR_ACCESS_TOKEN_HERE"
}
</script>

Example (React/Hydrogen):

// In your root layout or auth context
export function LoyaltyAuth({ accessToken }: { accessToken: string }) {
return (
<script
type="application/json"
id="oke-loyalty-customer-access-token"
dangerouslySetInnerHTML={{
__html: JSON.stringify({ customerAccessToken: accessToken })
}}
/>
);
}

Where to get the token:

  • The access_token is obtained during your login flow from the Customer Account API
  • Typically stored in session/cookies after the OAuth redirect
  • Usually already available since it's required for Customer Account API requests

Token Lifecycle:

  • ✅ Must implement automatic token refresh when it expires
  • ✅ Remove or update the script tag when customer logs out
  • ✅ Check token expiry before rendering

💡 Tip: Most Hydrogen projects already manage this token in an auth context or session.

Option B: Storefront API (Legacy Authentication)​

When to use: Your store uses the Storefront API for authentication (older method).

Implementation:

<script
type="application/json"
id="oke-loyalty-storefront-customer-access-token"
>
{
"storefrontCustomerAccessToken": "CUSTOMER_ACCESS_TOKEN",
"storefrontAccessToken": "STOREFRONT_PUBLIC_TOKEN"
}
</script>

Example (React):

export function LoyaltyAuthStorefront({
customerToken,
storefrontToken
}: {
customerToken: string;
storefrontToken: string;
}) {
return (
<script
type="application/json"
id="oke-loyalty-storefront-customer-access-token"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
storefrontCustomerAccessToken: customerToken,
storefrontAccessToken: storefrontToken
})
}}
/>
);
}

Required Token #1: storefrontCustomerAccessToken

Source: Returned from the customerAccessTokenCreate mutation.

mutation {
customerAccessTokenCreate(
input: { email: "customer@example.com", password: "password" }
) {
customerAccessToken {
accessToken # ← Use this value
expiresAt
}
}
}

What you need: The accessToken string from the response.

Required Token #2: storefrontAccessToken

Source: Your Storefront API public access token.

Where to find it:

  1. Go to Shopify Admin → Sales channels
  2. Click on your headless storefront
  3. Navigate to Storefront API → Public access token
  4. Copy the token value

Environment variable: Usually stored as PUBLIC_STOREFRONT_API_TOKEN and used for your X-Shopify-Storefront-Access-Token header.

💡 Tip: You're likely already using this token for all Storefront API requests in your project.

3. Loyalty Landing Page / Other Widgets (Optional)​

Loyalty Page​

To display the Loyalty Page Widget on one of your store pages (e.g. a dedicated loyalty page) all you need to do is render the snippet below:

<div data-oke-loyalty-embedded-widget=""></div>

When the app initialisation script runs, it will detect this div and render the Loyalty Page widget there.

Other valid snippets for rendering individual modules from the Loyalty Page Widget are listed below:

ModuleSnippet
Member Profile<div data-oke-loyalty-profile=""></div>
Redeem Rewards<div data-oke-loyalty-redeem=""></div>
Earn Rewards<div data-oke-loyalty-earn=""></div>
VIP Tiers<div data-oke-loyalty-vip-tiers=""></div>
Achievements<div data-oke-loyalty-achievements=""></div>
Refer A Friend<div data-oke-loyalty-refer-friends=""></div>
FAQ<div data-oke-loyalty-faq=""></div>

Cart Banner Widget​

Display a banner showing points information at the top of your Cart page or cart drawer.

Use cases:

  • Cart page header
  • Cart drawer header
  • Checkout flow

Implementation:

<div data-oke-loyalty-banner-widget=""></div>

Points Preview Widget​

We also offer a Points Preview widget for products, which can help inform customers how many points they will receive upon purchasing a specific product (usually displayed under the price on the Product Display Page, but also works on product carousels, etc).

This div also accepts other data attributes which will help it identify the correct product, and can also be used to help style it for different use cases on different pages:

AttributeDescription
data-oke-loyalty-points-preview-idWe will use this Product ID to calculate the reward. If not supplied then we will try to find it elsewhere on the page.
data-oke-loyalty-variant-idThe Variant ID of the product for the calculation. If not supplied then we will try to find it elsewhere on the page or else use the default for the product.
data-oke-loyalty-selling-plan-idIf you offer subscription options for the product then you can use this to tell us which one is currently selected. If not supplied then we will try to find it elsewhere on the page or else use the default for the product.
data-oke-loyalty-backgroundA Hex Color Code (e.g. #FFFFFF) for the background of the widget
data-oke-loyalty-iconThe name of the Icon to be displayed in the widget. Accepts most Font Awesome icon names
data-oke-loyalty-targetIf you are using this widget in the cart, please set this to "cart". If you are using this widget in a cart drawer, please set this to "cart-drawer". This is purely for analytics purposes.

As a simple example, your snippet may look something like this:

<div
data-oke-loyalty-points-preview=""
data-oke-loyalty-points-preview-id="8234567890123"
></div>

Complete example with optional attributes:

<div
data-oke-loyalty-points-preview=""
data-oke-loyalty-points-preview-id="8234567890123"
data-oke-loyalty-variant-id="45678901234567"
data-oke-loyalty-background="#F5F5F5"
data-oke-loyalty-icon="gift"
data-oke-loyalty-target="product"
></div>

Troubleshooting​

Widget Not Appearing​

Check:

  1. ✅ Loyalty Settings metafield is rendered in <head> as HTML and not text (you may be required to use dangerouslySetInnerHTML)
  2. ✅ Script tags are loading without errors (check browser console)
  3. ✅ Customer access token is valid and not expired
  4. ✅ Floating Widget is enabled in Okendo Admin settings

Customer Not Logged In to Loyalty​

Check:

  1. ✅ Customer access token script tag is present on the page
  2. ✅ Token is valid (not expired)
  3. ✅ Correct script ID is used (oke-loyalty-customer-access-token or oke-loyalty-storefront-customer-access-token)
  4. ✅ JSON format is valid (use a JSON validator)

Points Not Showing on Products​

Check:

  1. ✅ Correct product ID is being passed to data-oke-loyalty-points-preview-id
  2. ✅ Product exists in your Shopify store
  3. ✅ Points earning rules are configured in Okendo Admin

Console Errors​

Common errors and solutions:

  • "Cannot find metafield": Ensure Loyalty is enabled in Okendo Admin
  • "Invalid token": Check token format and expiry
  • "Widget initialization failed": Verify settings script is loaded and formatted correctly

Testing Checklist​

Before going live, verify:

  • Floating Widget appears on all pages
  • Customer can log in to loyalty widget when authenticated
  • Points balance displays correctly for logged-in customers
  • Products show points preview on product pages
  • Loyalty page displays all modules correctly
  • Cart banner shows points information
  • Widget styling matches your brand
  • All widgets work on mobile devices
  • Token refresh works correctly when token expires

Additional Resources​