Register components
Experiences SDK is currently available in alpha. APIs are unstable and subject to change.
The SDK renders an experience with your own components. You register each one under the ID it has in Contentful, in a configuration object that you pass to fetchExperience and to the renderer.
Create the configuration
The configuration has two registries and an optional token resolver:
components: Components, keyed by component ID.experienceTemplates: Coded experience templates, keyed by experience template ID. Optional.resolveToken: Resolves design tokens to values. See Style components. Optional.
React
Svelte
Angular
Keep the configuration in one file. Your components stay plain framework components with no SDK imports, so they work in Storybook, in tests, and in other apps. The configuration is the only place that knows about Contentful.
Choose registry keys
The registry key is the last segment of the component’s URN in Contentful. For crn:contentful:::experience:spaces/$self/environments/$self/components/Button, the key is Button. Experience template keys come from the experience template node’s URN the same way.
To find the IDs an experience uses, render it with debug mode on. Each unregistered component renders a box that names its ID. See Errors and debugging.
A component registered under an ID never satisfies an experience template with the same ID: each registry only resolves its own node type.
Register a component
Register a bare component for the common case. Use defineComponent when the component needs default props or data loaded before rendering:
defineComponent<Props> narrows defaults, resolveData, and component to your component’s prop type. It returns the configuration unchanged.
Load data with resolveData
resolveData runs once per fetch, inside fetchExperience or resolveExperience, before the experience renders. Its return value is merged into the component’s props. It receives:
content: The node’s content properties, as delivered.design: The node’s design properties, as raw design values ({ type, value }).experience: The render context:debugand themetadatapassed tofetchExperience.
The SDK runs every resolveData function in parallel, so a slow one doesn’t block the others. A function that throws or rejects is reported as a diagnostic, and that component renders without the resolved data.
resolveData doesn’t run again when the page re-renders or on client-side navigation. To load new data, fetch the experience again.
Merge order
A component’s props are merged in this order, last wins:
defaultsfromdefineComponent- Design properties, with design tokens resolved
- Content properties
- The output of
resolveData - Slots
A content value always wins over a default or a design value with the same name. A default only applies when the experience doesn’t supply that property.
Render slots
Each slot arrives as a prop named after the slot, holding one entry per child node. children is the conventional name for the default slot but isn’t special: a component with a header slot receives a header prop.
React
Svelte
Angular
A slot is a ReactNode[]. Render the array directly, or map over it to wrap or reorder children:
Register experience templates
A coded experience template renders the page around an experience’s content. Register it in experienceTemplates, with a bare component or defineExperienceTemplate, which takes the same fields as defineComponent. Its slots arrive as props, like a component’s: a template with a content slot receives a content prop.
An experience whose template was composed in the Contentful editor has no template node: its components render at the root.
Read the raw node payload
Components receive merged props. To read a node’s original payload, call the component payload accessor from inside the component:
The accessor is useContentfulComponent() in React, getContentfulComponent() in Svelte, and injectContentfulComponent() in Angular. The experience template equivalents are useContentfulExperienceTemplate(), getContentfulExperienceTemplate(), and injectContentfulExperienceTemplate(). Outside a node of that kind, React returns null and Svelte returns undefined. Angular’s accessors return a Signal, whose value is undefined outside a node.
Use the payload for a generic wrapper that branches by component ID, for analytics keyed by node ID, or for custom design handling.