Skip to main content

Pre-Fetching Context Data

Every time you call createContext(), the SDK makes a round-trip to the ABsmartly collector to fetch experiment data. In many situations you can avoid that round-trip by reusing data you've already fetched. That's what createContextWith() is for -- it creates a context from data you provide, so the context is ready immediately with no network request.

This is supported across all ABsmartly SDKs.

Why pre-fetch?

There are two common reasons to pre-fetch context data:

Avoiding flickering on the client. When you create a context client-side, the round-trip to the collector means your UI doesn't know which variant to show until the response comes back. The result is either a loading state or a flash of the wrong content. If you fetch the data on the server and pass it to the client, the context is ready on the first render.

Reducing latency on the server. If your server handles many requests for the same set of experiments, you can fetch the context data once and cache it (in memory, Redis, or wherever makes sense for your setup). Subsequent requests can create contexts from the cached data instead of making a round-trip to the collector each time.

How it works

  1. Create a context normally with createContext() and wait for it to be ready
  2. Extract the experiment data with context.data()
  3. Store or transfer that data however you like
  4. Create new contexts with createContextWith(), passing in the stored data

A context created with createContextWith() is ready immediately. It has the same behaviour as a normal context - it tracks exposures, records goals, and publishes events. The only difference is that it skips the initial fetch.

const sdk = new absmartly.SDK(sdkOptions);

// Fetch once
const context = sdk.createContext(contextOptions);
await context.ready();
const data = context.data();

// Reuse the data to create new contexts instantly
const newContext = sdk.createContextWith(contextOptions, data);

Use case: server-side caching

On a high-traffic server, you might not want every request to make its own round-trip to the collector. Instead, you can fetch the context data on a schedule (or on first request) and cache it.

let cachedData = null;

async function refreshCache() {
const sdk = new absmartly.SDK(sdkOptions);
// Any unit works here - we're fetching experiment definitions, not
// computing assignments. Each context created with createContextWith()
// computes its own assignments locally.
const context = sdk.createContext({ units: { user_id: "cache-warm" } });
await context.ready();
cachedData = context.data();
}

function handleRequest(userId) {
const sdk = new absmartly.SDK(sdkOptions);
const context = sdk.createContextWith({ units: { user_id: userId } }, cachedData);
// context is ready immediately, no round-trip
const variant = context.treatment("experiment_name");
}

The cached data contains experiment definitions, not user assignments. Assignments are computed locally by the SDK based on the user's units, so it's safe to share the same cached data across all users.

Use case: server to client (avoiding flicker)

In a server-rendered app, you can fetch the context data during the server render and pass it to the client. This is the most common way to eliminate flickering.

Next.js example

pages/index.tsx
import ABSmartly, { SDK } from "@absmartly/react-sdk";

const sdkOptions = {
endpoint: "https://your-company.absmartly.io/v1",
apiKey: "YOUR-API-KEY",
application: "website",
environment: process.env.NODE_ENV,
};

export const getServerSideProps: GetServerSideProps = async () => {
const serverSDK = new SDK(sdkOptions);

const contextOptions = {
units: {
user_id: "user-123",
anonymous_id: "anon-456",
},
};

const context = serverSDK.createContext(contextOptions);
await context.ready();

return {
props: {
contextData: context.data(),
contextOptions,
sdkOptions,
},
};
};

export default function Home({ contextData, contextOptions, sdkOptions }) {
const clientSDK = new SDK(sdkOptions);
const context = clientSDK.createContextWith(contextOptions, contextData);

return (
<ABSmartly context={context}>
{/* Your page content */}
</ABSmartly>
);
}

The server fetches the experiment data during getServerSideProps, serialises it as a prop, and the client creates the context instantly with createContextWith(). The user sees the correct variant on the very first paint.