Flex Experience SDK
Add your own JavaScript to a published Flex experience. Name the components you designed in Flex, then find them from a script and drive them at runtime — play a video, swap headline copy, toggle a state, navigate pages, or respond to a click.
<script type="module">
import { connect } from '@ceros/flex-experience-sdk'
const experience = await connect()
experience.findByLocator('hero-video').media.play()
</script>
That is the whole shape of it: connect, find, drive.
What you can build
- Interactive widgets — calculators, configurators, quizzes, and scoreboards driven by real logic rather than authored interactions alone.
- Live content — countdowns, tickers, and price or inventory figures pulled from your own API and written into the text you designed.
- Personalisation — show, hide, or restyle sections based on a URL parameter, a cookie, or your own visitor data.
- Integrations — forward clicks and video milestones to your analytics stack, CRM, or consent tooling.
How it works
1. Name your components in Flex. Select an element and give it a locator
in the SDK Locators inspector — hero-video, say. That name is the contract
between the design and your code, so the element can be restyled or moved
without touching the script.
2. Connect from a module script. connect() waits until the experience has
loaded and is ready to script, then hands you a handle scoped to that
experience.
3. Find components and drive them.
const experience = await connect()
const cta = experience.findByLocator('cta').only()
cta.text.setText('Only 3 left')
cta.on('component.click', () => track('cta_clicked'))
The four things you work with
| Concept | What it is |
|---|---|
| Experience | The handle connect() gives you. Every lookup is scoped to this experience, and experience.pages navigates its pages. |
| ComponentSet | What every lookup returns: 0, 1, or many matches. A call on a set applies to every member. |
| Component | One component on the page — its identity, attributes, events, and capabilities. |
| Capability | A group of behaviours a component type carries: media on videos, text on text, states and visibility on both. |
Two rules save you most of the surprises:
- A lookup always returns a set, even when exactly one component matches.
Use
.only()or.first()when you want the single component. - Nothing throws over a miss. A locator that matches nothing, a capability a component doesn't have, or a state name that doesn't exist all do nothing and explain themselves in the browser console. Your page doesn't break because an element got renamed.
The SDK drives a published experience. There is nothing for it to attach to inside the Flex editor, so test your scripts on a published URL or a preview link.
What you can drive today
| Capability | On | What you get |
|---|---|---|
media | Videos | play(), pause() |
text | Text | setText(), getText() |
states | Any visible element | activate(), deactivate(), toggle(), list(), current() |
visibility | Any visible element | show(), hide(), isHidden() |
pages | The experience | list(), current(), goTo(), next(), previous() |
| Events | Any component | Clicks, hovers, state changes, and video play / seek / progress |
| Attributes | Any component | getAttribute() / setAttribute(), plus author data via getData |
| Store | Your own state | A key-value store with subscriptions and optional persistence |
Full detail in Capabilities. See Limits for what the SDK deliberately does not do.
Where to go next
| Page | What it covers |
|---|---|
| Quickstart | Name components, add your first script, and get it running end to end |
| Delivery modes | Standalone, Flex Inline, and Flex SSR — what changes in each |
| Locators | findByLocator, findByTag, findById, and how to scope a search |
| Component | Identity, attributes, author data, events, and the escape hatch to the DOM |
| ComponentSet | Working with many matches, and how calls fan out across them |
| Events | Subscribing, event types, bubbling, and unsubscribing |
| Capabilities | media, text, states, visibility, and pages in full |
| Store | Holding your own state, with optional localStorage persistence |
| Examples | Complete, copy-paste scripts — a countdown and a calculator |
| Troubleshooting | What the console messages mean, and fixes for the common problems |
| Limits | What the SDK doesn't do, and what a page reload resets |
The API at a glance
import {
connect, // (root?, { timeout? }) => Promise<Component> — start here
wrap, // (element) => Component — skip the readiness wait (tests)
SDK_VERSION, // the loaded bundle's version, e.g. '0.1.0'
createStore, // (initialValues, { persist? }) => Store
localStorageAdapter, // (key, opts?) — persists across reloads
sessionStorageAdapter, // (key, opts?) — persists for the tab only
} from '@ceros/flex-experience-sdk'
Lookups are methods on the handle (and on any component), not separate
imports — experience.findByLocator('hero'). See
Locators.
TypeScript types
The package also exports ConnectOptions, ComponentEvent, SdkEvent,
SdkEventType, Unsubscribe, ComponentSet, Broadcast, CapabilityName,
MediaCapability, TextCapability, StatesCapability, PagesCapability,
PageInfo, Store, StoreSubscriber, CreateStoreOptions, PersistAdapter,
and WebStorageAdapterOptions, alongside the Component class and
createComponentSet.
show(), hide(), and isHidden() work as documented, but the
VisibilityCapability type is not exported yet — don't import that one name
until it is.