Troubleshooting

Fix the most common Joy Loyalty issues on Hydrogen and Weaverse storefronts — token errors, Content Security Policy blocks, caching and empty blocks.

Common issues

What you seeCauseFix
/api/joy-token returns 500 missing_envA Joy environment variable is missing.Add JOY_API_URL, JOY_SHOP_DOMAIN and JOY_API_SECRET to .env and to each Oxygen environment (Preview and Production are separate).
Logged-in customers get 401 exchange_failed, or the token request repeatsJOY_API_SECRET is wrong, was revoked, or is the REST Secret key instead of the Headless secret — or JOY_SHOP_DOMAIN isn't your myshopify domain.Copy the current secret from Joy admin > Settings > Manage keys > Headless secret, and use your-store.myshopify.com. Check the secret first.
Logged-in customers get 401 customer_unresolvedHydrogen couldn't read the customer's ID or email from the Customer Account API.Check your Customer Account API login setup.
/api/joy-token returns 502 exchange_failed; Joy API requests in the network tab return 403 with PLAN_NOT_ELIGIBLEYour store isn't on the Ultimate plan.Upgrade to the Ultimate plan in Joy admin.
Joy API requests return 429 with RATE_LIMITED (or /api/joy-token returns 502 exchange_failed under load)Too many requests in a short time.Wait and retry. Make sure your code doesn't call /api/joy-token or the Joy API in a loop.
One customer gets 502 exchange_failed while others workThe customer is excluded from your loyalty program (EXCLUDED).Expected — excluded customers can't sign in to Joy. Remove the exclusion in Joy admin if this is a mistake.
/api/joy-token returns 502 upstream_unreachableJOY_API_URL is wrong or unreachable.Use https://api.joy.so/app/api/v1/headless, including the path.
Widget stuck on a loading skeleton, or "[joy] failed to load the widget core" in the consoleThe widget code is blocked by script-src, JOY_WIDGET_ASSET_URL points somewhere that doesn't respond, or you are on @joy-loyalty/hydrogen 0.2.0 without JOY_WIDGET_ASSET_URL (its default static.joy.so doesn't serve the widget).Merge the Joy CSP directives. Upgrade to @joy-loyalty/hydrogen 0.2.1 or later and unset JOY_WIDGET_ASSET_URL — or, on 0.2.0, set JOY_WIDGET_ASSET_URL=https://api.joy.so.
Images or icons missing; CSP errors for img-src or font-srcOnly some Joy CSP lists were merged.Merge all five joyCspDirectives lists and keep cdn.shopify.com in imgSrc.
Hydrogen analytics or consent errorThe checkout domain isn't set.Set PUBLIC_CHECKOUT_DOMAIN, or fall back to your store domain.
Build error: cannot resolve dompurifyYour package manager doesn't hoist dependencies (pnpm, Yarn PnP).Run npm i dompurify (or your package manager's equivalent).
Logged-in customer sees the guest widgetA cached guest page was served.Follow the full-page cache rules in Deploy and verify.
Joy texts in the wrong languagelocale isn't passed, or isn't lowercase.Pass storefront.i18n.language.toLowerCase().
Redeemed coupon shows a code but isn't appliedCart wiring is incomplete.Pass both cartFetcher and cartRevalidate, and a locale-aware cartRoute. See Loyalty widget.
Two launchers on the pageBoth <JoyWidget/> and the Weaverse launcher block are used.Keep one. See Weaverse blocks.
Loyalty Page or Weaverse block is emptyThe store is on Loyalty Page V1, or Joy variables are missing.Switch to Loyalty Page V2 in Joy admin and check the environment variables.
Old Weaverse Joy blocks disappeared after updatingVersion 0.2.0 replaced them with the Loyalty Page block.Add the Joy — Loyalty Page block and pick the section you need.

Using an AI coding agent? Ask it: "Use the joy-headless-install skill to diagnose my Joy Loyalty integration. Symptom: <what you see>." See Install with an AI agent.

Still stuck?

Contact us through the in-app chat with your storefront URL, the symptom, and a screenshot of the browser console and network tab — we are happy to help.