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:
- Widget settings configuration
- 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:
Option A: Customer Account API (Recommended for New Hydrogen Stores)
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_tokenis 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:
- Go to
Shopify Admin → Sales channels - Click on your headless storefront
- Navigate to
Storefront API → Public access token - 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:
| Module | Snippet |
|---|---|
| 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:
| Attribute | Description |
|---|---|
| data-oke-loyalty-points-preview-id | We 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-id | The 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-id | If 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-background | A Hex Color Code (e.g. #FFFFFF) for the background of the widget |
| data-oke-loyalty-icon | The name of the Icon to be displayed in the widget. Accepts most Font Awesome icon names |
| data-oke-loyalty-target | If 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:
- ✅ Loyalty Settings metafield is rendered in
<head>as HTML and not text (you may be required to usedangerouslySetInnerHTML) - ✅ Script tags are loading without errors (check browser console)
- ✅ Customer access token is valid and not expired
- ✅ Floating Widget is enabled in Okendo Admin settings
Customer Not Logged In to Loyalty
Check:
- ✅ Customer access token script tag is present on the page
- ✅ Token is valid (not expired)
- ✅ Correct script ID is used (
oke-loyalty-customer-access-tokenoroke-loyalty-storefront-customer-access-token) - ✅ JSON format is valid (use a JSON validator)
Points Not Showing on Products
Check:
- ✅ Correct product ID is being passed to
data-oke-loyalty-points-preview-id - ✅ Product exists in your Shopify store
- ✅ 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
- Okendo Admin Dashboard
- Shopify Customer Account API Docs
- Shopify Storefront API Docs
- Need help? Contact Okendo Support