Help us improve
Share bugs, ideas, or general feedback.
From bynder
Embed the Bynder Universal Compact View (UCV) — the asset picker — into custom apps, Contentful field controls, Salesforce Lightning components, internal tools, and any other host application that needs a "let editors pick a Bynder asset" UX. Covers UCV configuration (theme, default filters, allowed asset types, derivative selection), the two auth modes (OAuth flow vs. token flow), event handling via postMessage, host-side state integration, and the cases where UCV beats an OOTB Marketplace connector. Use this skill when there's no Marketplace connector for the host system, when the OOTB connector exists but doesn't expose the configuration the editorial flow needs, or when building a bespoke editor where the asset picker is part of the differentiated UX.
npx claudepluginhub bpainter/composable-dxp-claude-marketplace --plugin bynderHow this skill is triggered — by the user, by Claude, or both
Slash command
/bynder:bynder-compact-viewThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill puts you in the role of an integration engineer who's wired UCV into half a dozen host systems and knows the patterns. Default posture: check the Marketplace first; if there's a working OOTB connector, use it. UCV is the answer when the connector doesn't exist or doesn't fit.
Guides technical evaluation of code review feedback: read fully, restate for understanding, verify against codebase, respond with reasoning or pushback before implementing.
Share bugs, ideas, or general feedback.
This skill puts you in the role of an integration engineer who's wired UCV into half a dozen host systems and knows the patterns. Default posture: check the Marketplace first; if there's a working OOTB connector, use it. UCV is the answer when the connector doesn't exist or doesn't fit.
UCV is Bynder's embeddable asset picker — an iframe that runs inside a host application, lets the user search/browse/filter Bynder assets, and returns selected assets (with metadata + derivative URLs) to the host via postMessage. Documented at https://developers.bynder.com/universal-compact-view.
Pair with bynder-marketplace-connectors (always check first), bynder-contentful-pairing (the most common UCV target), bynder-derivatives (which derivative the picker returns), bynder-permissions-workflow (token / scope strategy), and bynder-asset-model (default filters that pre-narrow the picker).
OAuth flow — editor authenticates inline. Best when:
Host loads UCV iframe
→ UCV detects no token
→ User clicks "log in to Bynder"
→ OAuth redirect dance (handled by UCV)
→ Token issued in iframe context
→ Picker renders
Token flow — backend mints a token, hands to UCV. Best when:
Host backend → Bynder token endpoint (Client Credentials or impersonation)
→ Backend passes token to host frontend
→ Frontend instantiates UCV with the token
→ Picker renders without auth UI
Slalom default: OAuth flow when integrating into editor-facing tools where the editor has a Bynder account. Token flow when integrating into non-editorial surfaces (dashboards, batch tools).
Install the package and instantiate:
import BynderCompactView from '@bynder/compact-view';
BynderCompactView.open({
language: 'en_US',
portal: { url: 'https://your-portal.bynder.com' },
mode: 'SingleSelect', // or 'MultiSelect'
assetTypes: ['image', 'video'],
defaultSearchTerm: '',
hideLimitedUseAssets: true,
selectedAssets: [],
onSuccess: (assets, additionalInfo) => {
// assets is an array of selected asset metadata
// additionalInfo has any extra context (e.g., the derivative selected)
handleSelection(assets);
},
onClose: () => {
cleanupModalUI();
},
});
The package handles the iframe lifecycle, the postMessage event handling, and the modal scaffolding. The host app provides the callbacks.
| Option | Use |
|---|---|
mode | SingleSelect for fields that take one asset; MultiSelect for galleries / batches |
assetTypes | Limit to relevant types — image-only field shouldn't show videos |
defaultSearchTerm | Pre-populate search (e.g., the entry's tags joined into a search term) |
hideLimitedUseAssets | True for editorial flows (don't show "internal-only" assets) |
selectedAssets | Pre-select for edit-existing flows |
theme | Light/dark + primary color match for visual integration |
language | Localize the picker UI |
For richer config — default metaproperty filters, derivative-set selection — pass via the assetFieldSelection and defaultMetapropertyOptions configuration on Bynder's portal side, then reference them in the embed config. The portal config + embed config interact; you usually need both.
The big decision: what URL flows back to the host?
| Mode | Returns | Use |
|---|---|---|
original | Original asset URL | Print, download, source-master flows |
| Specific derivative | One named derivative URL (e.g., web_hero_lg) | Most production CMS flows |
| All derivatives | An object of { name → URL } | When the host wants flexibility (e.g., responsive image components that pick at render time) |
Slalom default for CMS pairing: return the asset ID + the canonical derivative for the field, plus a small set of responsive variants. Don't return all derivatives by default — payload bloats and the host has to choose anyway.
UCV emits messages to the host via window.postMessage:
{
type: 'BYNDER_ASSET_SELECTED',
payload: {
assets: [
{
id: '...',
name: '...',
type: 'image',
thumbnails: { /* derivative urls */ },
property_AssetCategory: ['Marketing'],
// ... other property_* and system fields
}
],
additionalInfo: { /* derivative chosen, etc. */ }
}
}
The package abstracts this — you write onSuccess. But when something's wrong, debug at the postMessage level. Open dev tools, watch messages, see what UCV is actually emitting.
When the OOTB Contentful Bynder app doesn't quite fit (e.g., needs hard-coded brand filter, custom derivative-selection UI, validation), build a custom field control via the Contentful App SDK that wraps UCV:
// SingleAssetField.tsx
import { useFieldValue } from '@contentful/react-apps-toolkit';
import BynderCompactView from '@bynder/compact-view';
export function BynderSingleAssetField() {
const [value, setValue] = useFieldValue<BynderAssetReference>();
function openPicker() {
BynderCompactView.open({
mode: 'SingleSelect',
assetTypes: ['image'],
portal: { url: PORTAL_URL },
hideLimitedUseAssets: true,
defaultMetapropertyOptions: [BRAND_OPTION_ID, RIGHTS_CLEARED_OPTION_ID],
onSuccess: (assets) => {
const a = assets[0];
setValue({
assetId: a.id,
name: a.name,
derivatives: {
heroLg: a.thumbnails.web_hero_lg,
cardMd: a.thumbnails.web_card_md,
},
alt: a.description,
});
},
});
}
return (
<div>
{value ? <PreviewCard asset={value} onChange={openPicker} /> : <Button onClick={openPicker}>Pick asset</Button>}
</div>
);
}
The Contentful field stores a small JSON envelope (asset ID + the derivative URLs the front end actually needs + alt). Don't store the full Bynder asset object — it goes stale.
See bynder-contentful-pairing for the full pattern.
UCV runs in a Lightning Web Component via an iframe wrapper. Auth is usually token flow — Salesforce backend mints a token via Apex callout to Bynder's OAuth endpoint, passes to the LWC.
For React or Vue host apps without a published connector: same pattern as Contentful. Drop the package, configure, handle the callback, persist what you need.
The hard part of UCV is not the picker — it's keeping the host's stored asset reference in sync with the underlying Bynder asset.
Three strategies:
{ assetId, derivatives: {...}, version }. A bynder-webhooks-events receiver invalidates and re-fetches when asset.updated fires.{ assetId }. Front end fetches derivative URLs on render. Latency cost; freshness benefit.Slalom default: strategy 1. Webhook-driven invalidation gives you fresh-enough state without the per-render fetch cost.
UCV can be themed to match the host's brand:
BynderCompactView.open({
theme: {
colorButtonPrimary: '#7C3AED',
colorPrimary: '#1F2937',
fontFamily: 'Inter, -apple-system, sans-serif',
},
// ...
});
Match the host's primary brand color and font. The picker shouldn't look like a foreign body.
# Bynder UCV Embed Plan: [Host system]
## Why UCV (vs. OOTB)
[What the OOTB connector doesn't do; why custom is justified.]
## Auth mode
[OAuth flow | Token flow — and why.]
## Picker configuration
- Mode: [Single | Multi]
- Asset types: [image | video | document | ...]
- Default filters: [metaproperty options]
- Hide limited-use: [true | false]
- Theme: [primary, secondary, font]
## Derivative selection
[What URL(s) flow back to the host.]
## Host state shape
[The JSON envelope persisted in the host CMS / DB.]
## Sync strategy
[Strategy 1 / 2 / 3 from above; webhook events subscribed.]
## Permission posture
[Who can use the picker; what their token / OAuth scope grants.]
## Test plan
[Pick + persist + render; pick + update in Bynder + invalidate; pick + delete in Bynder + handle gracefully.]
hideLimitedUseAssets. Editors see assets they shouldn't legally use; rights problems waiting to happen.bynder-marketplace-connectors.bynder-contentful-pairing.bynder-webhooks-events.bynder-derivatives.bynder-asset-model.bynder-permissions-workflow.bynder-js-sdk.@bynder/compact-view../../references/marketplace-connectors.md../../references/api-surface.md../../references/bynder-foundations.md