Integrating Scaleflex Asset Picker into SFMC
Integrating Scaleflex Asset Picker into SFMC CloudPages
Drop this into a CloudPage's HTML block (Content Builder → CloudPages → HTML Content Block). It loads the Asset Picker, opens it on button click, and writes the selected URL into a visible input (which can then be submitted via a form to a Data Extension).
HTML<!-- Container --> <button id="open-picker-btn" type="button">Choose Image</button> <input type="text" id="selected-image-url" name="ImageURL" readonly placeholder="No image selected" /> <img id="preview-img" style="max-width:200px; display:none;" /> <!-- Scaleflex Asset Picker assets --> <link rel="stylesheet" href="https://cdn.filerobot.com/asset-picker/latest/style.css"> <script src="https://cdn.filerobot.com/asset-picker/latest/index.js"></script> <script> var picker = null; function initPicker() { picker = new AssetPicker({ token: 'YOUR_SCALEFLEX_TOKEN', // from Scaleflex dashboard onSelect: function (assets) { if (!assets || !assets.length) return; var url = assets[0].cdnUrl || assets[0].url; document.getElementById('selected-image-url').value = url; var preview = document.getElementById('preview-img'); preview.src = url; preview.style.display = 'block'; picker.close(); }, onClose: function () { console.log('Asset picker closed'); } }); } document.getElementById('open-picker-btn').addEventListener('click', function () { if (!picker) initPicker(); picker.open(); }); </script>
Replace YOUR_SCALEFLEX_TOKEN with the real token/config from the Scaleflex dashboard, and confirm the exact CDN script URL and API (AssetPicker, onSelect payload shape) against the current docs — Scaleflex has shipped multiple SDK versions (legacy FilerobotFilePicker, newer @scaleflex/asset-picker), so the constructor name and callback signature can differ by version.
Progress:
- Step 1: Get Scaleflex credentials (token/company, container/folder scope) from client's Scaleflex dashboard
- Step 2: Confirm which SDK build to use (script tag vs npm module) — CloudPages only supports static HTML/JS, so use the CDN
<script>build, not an npm/bundler-based one - Step 3: Build the CloudPage HTML block with button + hidden/visible field + preview
- Step 4: Wire button click → open picker
- Step 5: Wire
onSelectcallback → write URL into input field, update preview - Step 6: Connect the input field to a form (AMPscript
RequestParameteror a<form>POST) so the URL gets saved to a Data Extension or passed along to the next page - Step 7: Test in an actual CloudPage (not just local HTML) — check CSP/iframe restrictions and cross-domain script loading behave inside SFMC's iframe-based CloudPage renderer
- Step 8: Handle edge cases: user cancels picker, no image selected, multiple selection disabled
To persist the picked URL when the CloudPage form submits:
HTML%%[ VAR @imageURL SET @imageURL = RequestParameter("ImageURL") IF NOT EMPTY(@imageURL) THEN InsertDE("YourDataExtensionName", "SubscriberKey,ImageURL", @subscriberKey, @imageURL) ENDIF ]%% <form method="post" action="%%=RequestParameter('PAGEURL')=%%"> <input type="text" id="selected-image-url" name="ImageURL" readonly /> <button id="open-picker-btn" type="button">Choose Image</button> <button type="submit">Save</button> </form>
The picker button stays type="button" (never submit) so opening the picker doesn't submit the form prematurely.
Example 1:
Input: User clicks "Choose Image" on a CloudPage.
Output: Scaleflex Asset Picker modal opens over the page; user browses/searches assets; clicks an image; modal closes; #selected-image-url input now contains https://cdn.scaleflex.it/your-container/path/image.jpg; preview <img> shows the thumbnail.
Example 2:
Input: User clicks "Choose Image" then clicks the picker's close/cancel button without selecting anything.
Output: onClose fires, no onSelect call happens, input field remains empty/unchanged, no error thrown.
- Lazy-init the picker instance (only construct it on first click) to avoid loading overhead on every CloudPage view.
- Use
cdnUrlover any signed/temporary URL field the asset object returns — you want the permanent public CDN link stored in the Data Extension. - Sanitize/validate the URL before saving (check it's
https://and matches your Scaleflex CDN domain) to avoid storing garbage if the picker API changes shape. - Namespace your JS (wrap in an IIFE or unique variable names) since CloudPages often stack multiple content blocks with their own scripts on one page.
- Test inside SFMC's actual rendering context, not just a local HTML file — CloudPages sandbox scripts differently (CSP headers, SFMC's own JS on the page) and third-party widget modals can clash with SFMC's own overlay/z-index stack.
- Pin the SDK version in the CDN URL (e.g.
/asset-picker/2.x/index.js) rather thanlatest, so a Scaleflex release doesn't silently break a live CloudPage.
- Assuming the callback is always called
onSelectwithassets[0].url— verify against current docs; some versions useonAssetsSelected, return a single object not an array, or nest the URL underdata.publicUrl. - Forgetting
type="button"on the trigger button inside a<form>— causes an accidental form submit/page reload instead of opening the picker. - Loading the picker script/styles multiple times if the CloudPage has multiple content blocks each including the
<script>tag — dedupe by loading it once in a shared header/footer block. - Relying on npm/webpack-based install instructions when the target is a CloudPage — CloudPages can't run a build step; only the CDN script-tag distribution works.
- Not handling z-index conflicts — SFMC's own CloudPage chrome or other modals can render above/below the Scaleflex modal; test and adjust CSS
z-indexif the picker appears hidden. - Storing a temporary/session-scoped URL instead of the permanent CDN URL, causing broken images later.