Loyalty tier badges not displaying in custom loyalty dashboard

I’m building a custom loyalty dashboard using the AEC 2022 UI SDK, and while the tier data loads correctly from the API, the tier badge images aren’t rendering. The component shows the tier name and points, but the badge image element remains empty.

Here’s the component setup:

const tierBadge = await loyaltySDK.components.createBadge({
  tierId: member.currentTier.id,
  size: 'medium'
});

The API response includes the badge asset URL, but when I inspect the DOM, the img src attribute is empty. I’ve verified the asset URLs are valid and accessible directly in the browser. Is there a specific asset mapping configuration needed for custom components?

This is a common issue with custom loyalty dashboard implementations in AEC 2022. The problem involves three interconnected configuration areas that all need to be properly set up:

1. Custom Component Asset Mapping The UI SDK’s createBadge method requires explicit asset mapping configuration. Your current code is missing the asset resolver configuration:

const tierBadge = await loyaltySDK.components.createBadge({
  tier: member.currentTier,
  assetResolver: 'tier.metadata.badgeAssets.medium'
});

The assetResolver property tells the SDK where to find the badge URL in your tier object structure. The default path is tier.badge.url, but if your API returns a different structure, you need to specify the exact property path.

2. API Response Parsing Log your actual API response to verify the structure. The tier object should contain badge assets in this format:

{
  id: 'gold-tier',
  name: 'Gold',
  metadata: {
    badgeAssets: {
      small: 'https://cdn.adobe.com/badges/gold-small.png',
      medium: 'https://cdn.adobe.com/badges/gold-medium.png',
      large: 'https://cdn.adobe.com/badges/gold-large.png'
    }
  }
}

If your API returns badge URLs in a different structure, you have two options:

  • Transform the response before passing it to the component
  • Configure a custom asset resolver function that handles your specific structure

3. CDN/CORS Configuration This is often the root cause when asset URLs are valid but images don’t load. AEC 2022’s asset CDN has strict CORS policies:

Step 1: Whitelist your domain

  • Admin Console → Asset Management → CDN Settings
  • Add your domain to ‘Allowed Origins’ (include both production and development domains)
  • For local development, add http://localhost:* as a wildcard

Step 2: Verify asset response headers Open browser DevTools → Network tab and check the badge image request. The response should include:


Access-Control-Allow-Origin: your-domain.com
Access-Control-Allow-Methods: GET, OPTIONS

If these headers are missing, your domain isn’t properly whitelisted.

Step 3: Configure asset loading policy In your UI SDK initialization, set the asset loading policy:

await loyaltySDK.init({
  assetLoadingPolicy: 'cors',
  corsCredentials: false
});

Testing Checklist:

  1. Verify tier objects have badge assets in the expected structure
  2. Check browser console for CORS errors (look for red error messages)
  3. Test badge loading with a tier that definitely has assets configured
  4. Use the SDK debug mode: loyaltySDK.setDebugLevel('verbose') to see detailed asset loading logs
  5. Verify the CDN whitelist includes your current domain (check for typos or protocol mismatches)

If badges still don’t render after these fixes, the issue might be with how the loyalty program tiers were originally configured. In that case, you’ll need to re-upload the badge assets through the Loyalty Program admin interface with proper metadata tags.


This draft is based on general Adobe Experience Cloud knowledge. It has not been verified against your specific version and environment. Practitioners: verify the steps and share your experience below.

Check your CDN configuration. Badge assets in AEC 2022 are served from a separate CDN endpoint, and if CORS isn’t configured properly, the UI SDK can’t load them even if the URLs are valid. You need to whitelist your domain in the Asset Management section of the admin console.

I had a similar issue with custom loyalty components. The problem was that the createBadge method expects the tier data in a specific format. Instead of passing just the tierId, you need to pass the complete tier object with asset mappings. Try passing the full tier object from the API response: loyaltySDK.components.createBadge({ tier: member.currentTier }). The SDK will then extract the correct asset URL from the tier metadata.

Another thing to verify is your API response parsing. The UI SDK expects badge assets to be in a specific property path within the tier object. Open your browser console and log the actual API response structure. The badge URL should be at tier.assets.badge.url or tier.badgeImageUrl depending on your loyalty program configuration. If your API is returning it in a different structure, you’ll need to either transform the response or configure the asset mapping in the component initialization options.

Check the browser console for CORS errors. Even if the asset URLs load fine when you access them directly, they might be blocked when loaded via JavaScript due to CORS policy. AEC 2022’s CDN requires specific headers for cross-origin requests. You need to configure the allowed origins in Admin Console → Asset Management → CDN Configuration, and make sure your development domain is included in the whitelist.

“Tested this on AEC 2022.3 and adding the assetResolver: 'tier.metadata.badgeAssets.medium' parameter to createBadge immediately rendered our Gold and Platinum tier badges correctly.”

I’ve also seen this happen when badge assets are uploaded with incorrect metadata. In the Loyalty Program configuration, each tier should have badge assets tagged with specific dimensions and formats. If the asset metadata doesn’t match what the UI SDK expects (e.g., it’s looking for a ‘medium’ size badge but only ‘large’ is available), it won’t render. Go to Loyalty Programs → Tier Configuration and verify each tier has badge assets in all required sizes.