Warning
The Optimization SDK Suite is pre-release (alpha). Breaking changes may be published at any time.
The Optimization Node SDK implements functionality specific to Node environments, based on the Optimization Core Library. This SDK is part of the Contentful Optimization SDK Suite.
Table of Contents
Install using an NPM-compatible package manager, pnpm for example:
pnpm install @contentful/optimization-nodeImport the Optimization class; both CJS and ESM module systems are supported, ESM preferred:
import ContentfulOptimization from '@contentful/optimization-node'Configure and initialize the Optimization Node SDK:
const optimization = new ContentfulOptimization({ clientId: 'abc123' })Reference implementations illustrate how the SDK may be used under common scenarios, as well as select less-common scenarios, with the most basic example solution possible.
- Node SSR Only: Example application that uses the Node SDK to render a personalized Web page
- Node SSR + Web Vanilla: Example application demonstrating simple profile synchronization between the Node and Web SDKs via cookie
| Option | Required? | Default | Description |
|---|---|---|---|
analytics |
No | See "Analytics Options" | Configuration specific to the Analytics/Insights API |
app |
No | undefined |
The application definition used to attribute events to a specific consumer app |
clientId |
Yes | N/A | The Optimization API key |
environment |
No | 'main' |
The environment identifier |
eventBuilder |
No | See "Event Builder Options" | Event builder configuration (channel/library metadata, etc.) |
fetchOptions |
No | See "Fetch Options" | Configuration for Fetch timeout and retry functionality |
logLevel |
No | 'error' |
Minimum log level for the default console sink |
personalization |
No | See "Personalization Options" | Configuration specific to the Personalization/Experience API |
| Option | Required? | Default | Description |
|---|---|---|---|
baseUrl |
No | 'https://ingest.insights.ninetailed.co/' |
Base URL for the Insights API |
Event builder options should only be supplied when building an SDK on top of the Optimization Node SDK or any of its descendent SDKs.
| Option | Required? | Default | Description |
|---|---|---|---|
channel |
No | 'server' |
The channel that identifies where events originate from (e.g. 'web', 'mobile') |
library |
No | { name: '@contentful/optimization-node', version: '0.0.0' } |
The client library metadata that is attached to all events |
Fetch options allow for configuration of a Fetch API-compatible fetch method and the retry/timeout
logic integrated into the Optimization API Client. Specify the fetchMethod when the host
application environment does not offer a fetch method that is compatible with the standard Fetch
API in its global scope.
| Option | Required? | Default | Description |
|---|---|---|---|
fetchMethod |
No | undefined |
Signature of a fetch method used by the API clients |
intervalTimeout |
No | 0 |
Delay (in milliseconds) between retry attempts |
onFailedAttempt |
No | undefined |
Callback invoked whenever a retry attempt fails |
onRequestTimeout |
No | undefined |
Callback invoked when a request exceeds the configured timeout |
requestTimeout |
No | 3000 |
Maximum time (in milliseconds) to wait for a response before aborting |
retries |
No | 1 |
Maximum number of retry attempts |
Configuration method signatures:
fetchMethod:(url: string | URL, init: RequestInit) => Promise<Response>onFailedAttemptandonRequestTimeout:(options: FetchMethodCallbackOptions) => void
| Option | Required? | Default | Description |
|---|---|---|---|
baseUrl |
No | 'https://experience.ninetailed.co/' |
Base URL for the Experience API |
enabledFeatures |
No | ['ip-enrichment', 'location'] |
Enabled features which the API may use for each request |
ip |
No | undefined |
IP address to override the API behavior for IP analysis |
locale |
No | 'en-US' (in API) |
Locale used to translate location.city and location.country |
plainText |
No | false |
Sends performance-critical endpoints in plain text |
preflight |
No | false |
Instructs the API to aggregate a new profile state but not store it |
Arguments marked with an asterisk (*) are always required.
Get the specified Custom Flag's value from the provided changes array.
Arguments:
name*: The name/key of the Custom Flagchanges: Changes array
Returns:
- The resolved value for the specified Custom Flag, or
undefinedif it cannot be found.
Behavior notes:
- Node SDK is stateless;
getFlag(...)does not auto-emittrackFlagView. - If full map resolution is needed for advanced use cases, use
optimization.flagsResolver.resolve(changes).
Note
If the changes argument is omitted, the method will return undefined.
Resolve a baseline Contentful entry to a personalized variant using the provided selected personalizations.
Type arguments:
S: Entry skeleton typeM: Chain modifiersL: Locale code
Arguments:
entry*: The entry to personalizeselectedPersonalizations: Selected personalizations
Returns:
- The resolved personalized entry variant, or the supplied baseline entry if baseline is the selected variant or a variant cannot be found.
Note
If the selectedPersonalizations argument is omitted, the method will return the baseline entry.
Resolve a "Merge Tag" to a value based on the provided profile. A "Merge Tag" is a special Rich Text fragment supported by Contentful that specifies a profile data member to be injected into the Rich Text when rendered.
Arguments:
embeddedNodeEntryTarget*: The merge tag entry node to resolveprofile: The user profile
Note
If the profile argument is omitted, the method will return the merge tag's fallback value.
Only the following methods may return an OptimizationData object:
identifypagescreentracktrackView(whenpayload.stickyistrue)
trackClick, trackHover, and trackFlagView return no data. When returned, OptimizationData
contains:
changes: Currently used for Custom FlagsselectedPersonalizations: Selected personalizations for the profileprofile: Profile associated with the evaluated events
Identify the current profile/visitor to associate traits with a profile.
Arguments:
payload*: Identify event builder arguments object, including an optionalprofileproperty with aPartialProfilevalue that requires only anid
Record a personalization page view.
Arguments:
payload*: Page view event builder arguments object, including an optionalprofileproperty with aPartialProfilevalue that requires only anid
Record a personalization screen view.
Arguments:
payload*: Screen view event builder arguments object, including an optionalprofileproperty with aPartialProfilevalue that requires only anid
Record a personalization custom track event.
Arguments:
payload*: Track event builder arguments object, including an optionalprofileproperty with aPartialProfilevalue that requires only anid
Record an analytics component view event. When the payload marks the component as "sticky", an
additional personalization component view is recorded. This method only returns OptimizationData
when the component is marked as "sticky".
Arguments:
payload*: Component view event builder arguments object, including an optionalprofileproperty with aPartialProfilevalue that requires only anid
Record an analytics component click event.
Returns:
void
Arguments:
payload*: Component click event builder arguments object
Record an analytics component hover event.
Returns:
void
Arguments:
payload*: Component hover event builder arguments object
Track a feature flag view via analytics. This is functionally the same as a non-sticky component view event.
Returns:
void
Arguments:
payload*: Component view event builder arguments object
Interceptors may be used to read and/or modify data flowing through the Core SDK.
event: Intercepts an event's data before it is queued and/or emittedstate: Intercepts state data retrieved from an Experience API call before updating the SDK's internal state
Example interceptor usage:
optimization.interceptors.event((event) => {
event.properties.timestamp = new Date().toISOString()
})Warning
Interceptors are intended to enable low-level interoperability and should be used with care.