Shared Helpers
Create a small helper module for the XM/XP DAM field shapes. The JSS examples import these types and functions so the rendering components can stay focused on a single field type.
These helpers are examples, not a required SDK or fixed implementation. Use them as a starting point and adapt the field types, parsing, rendering, and error handling to match your own frontend architecture.
src/lib/bynder-xm-xp-headless.ts
export type BynderAssetFile = {
name?: string;
url?: string;
width?: number;
height?: number;
};
export type BynderAsset = {
id?: string;
name?: string;
description?: string;
files?: BynderAssetFile[];
};
export type BynderAssetSelection = {
assets?: BynderAsset[];
file?: BynderAssetFile;
};
export function getFile(asset?: BynderAsset) {
return asset?.files?.[0];
}
export function getAssetAlt(asset?: BynderAsset) {
return asset?.description || asset?.name || '';
}
export function parseBynderXpField(rawValue?: string): BynderAssetSelection | null {
if (!rawValue) {
return null;
}
const cdataMatch = rawValue.match(/<!\[CDATA\[([\s\S]*?)\]\]>/);
const json = cdataMatch?.[1] || rawValue.replace(/<[^>]+>/g, '').trim();
if (!json) {
return null;
}
return JSON.parse(json) as BynderAssetSelection;
}
export function getSingleAsset(field?: { value?: string }) {
return parseBynderXpField(field?.value)?.assets?.[0];
}
export function getMultipleAssets(field?: { value?: string }) {
return parseBynderXpField(field?.value)?.assets || [];
}
export function getFieldFile(field?: { value?: string }) {
const selection = parseBynderXpField(field?.value);
return selection?.file || getFile(selection?.assets?.[0]);
}If your JSS application renders on the server and you want stricter XML handling, replace the parseBynderXpField XML extraction with your preferred server-safe XML parser. The important part is that XM/XP field values from Layout Service contain JSON inside an XML wrapper.