Precomputed Assignments
Overview
Precomputed assignments is an execution mode that allows you to receive assignments for all flags for a given user.
The computation happens with a remote call to an Eppo Edge Function which is globally distributed to be as close to the user as possible. Availability is backed by Eppo's CDN.
This mode is best suited for applications that require a smaller response payload, more predictable latency, and removal of private targeting rules over the public internet.
The new SDK methods are available in Eppo's Javascript SDK version 3.8.2
and above.
Advantages
- Private and secure handling of targeting rules.
- High availability and low latency due to globally distribution with the CDN.
Prerequisites
On client initialization, you must have the subject key and all subject attributes available.
Assignment logging
Using the non-precomputed Eppo client, flag evaluation and assignments both occur together in the client.
When using the precomputed Eppo client, flag evaluation occurs up front during initialization and assignments occur afterwards.
In both case, assignment events are only logged by the provided logging callback when get*Assignment
is invoked.
Initialize precomputed client
import * as EppoSdk from "@eppo/js-client-sdk";
// Define logAssignment so that it logs events
const assignmentLogger: IAssignmentLogger = {
logAssignment(assignment) {
console.log(assignment);
}
};
// Initialize the client
const client = await EppoSdk.precomputedInit({
apiKey: 'YOUR_SDK_KEY',
assignmentLogger: assignmentLogger,
subjectKey: 'test-subject',
subjectAttributes: { attr1: 'value1' },
});
Perform evaluation
After the precomputed Eppo client is initialized, the client instance can be accessed anywhere in your application.
get*Assignment
looks up the precomputed assignment and returns it immediately, or returns the default value if the precomputed assignment is missing.
const client = EppoSdk.getPrecomputedInstance();
const variant = client.getStringAssignment(flagKey, 'default-value');
Offline (Bootstrapped) Precomputed Assignments
Overview
The Eppo Node Server SDK can be used to generate precomputed assignments on the server to bootstrap the client-side SDK using offlinePrecomputedInit
. This approach allows you to initialize the client without making remote calls from the browser.
These SDK methods are available in Eppo's JavaScript Client SDK version 3.9.4
and above.
Initialize offline (bootstrapped) precomputed client
First, generate the precomputed configuration on your backend using Eppo's Node Server SDK:
import * as EppoSDK from '@eppo/node-server-sdk';
await EppoSdk.init({
apiKey: 'YOUR_SDK_KEY',
assignmentLogger: { logAssignment() {} }, // we will log in the client, not here
})
const precomputedConfiguration = await EppoSDK.getInstance()
.getPrecomputedConfiguration(subjectKey, subjectAttributes);
Then, pass this configuration to your client-side application and initialize the SDK:
import * as EppoSdk from "@eppo/js-client-sdk";
const client = EppoSdk.offlinePrecomputedInit({
precomputedConfiguration, // JSON string from server-side getPrecomputedConfiguration
assignmentLogger: assignmentLogger,
});
Notice that offline (bootstrapped) initialization does not require an SDK key nor subject information; everything needed for making assignments is provided in the precomputed configuration.
Example of how using offlinePrecomputedInit
in a Next.js application
// page.tsx or similar server-side rendered component
import * as EppoSDK from '@eppo/node-server-sdk';
export default async function Page() {
await EppoSDK.init({
apiKey: process.env.NEXT_PUBLIC_EPPO_SDK_KEY as string,
assignmentLogger: { logAssignment() {} },
});
const precomputedConfiguration = await EppoSDK.getInstance().getPrecomputedConfiguration('<SUBJECT-KEY>', <SUBJECT-ATTRIBUTES>);
return (
<ClientSideComponent precomputedConfiguration={precomputedConfiguration} />
);
}
And then in your component to be rendered client side, as designated by the 'use client'
directive at the top of the file, you can use the offlinePrecomputedInit
method to initialize the SDK.
'use client';
import * as EppoSDK from '@eppo/js-client-sdk';
const assignmentLogger: EppoSDK.IAssignmentLogger = {
logAssignment(assignment) {
console.log(assignment);
}
};
export function ClientSideComponent({
precomputedConfiguration,
}: {
precomputedConfiguration: string;
}) {
EppoSDK.offlinePrecomputedInit({
precomputedConfiguration: configuration,
assignmentLogger: assignmentLogger,
});
const assignment = EppoSDK.getPrecomputedInstance().getStringAssignment('<FLAG-KEY>', '<DEFAULT-VALUE>');
// render the component with the assignment
}
Other ways to serve the precomputed configuration from the server
- Script Tags with Window Object
<script>
window.__EPPO_CONFIG__ = JSON.stringify({
precomputedConfiguration: /* configuration from server */
});
</script>
- Data Attributes
<div id="eppo-config" data-configuration="<encoded-configuration-here>"></div>
<script>
const config = document.getElementById('eppo-config').dataset.configuration;
// Use the config...
</script>
- Cookies
// Server-side
res.cookie('eppo-config', JSON.stringify(precomputedConfiguration));
// Client-side
const config = document.cookie
.split('; ')
.find(row => row.startsWith('eppo-config='))
?.split('=')[1];
- Meta Tags
<meta name="eppo-config" content="<encoded-configuration-here>" />
<script>
const config = document.querySelector('meta[name="eppo-config"]').content;
// Use the config...
</script>
The best approach depends on your application's architecture and security requirements, e.g.
- Script tags with window objects are simple but will expose the configuration globally
- Cookies may be constrainted by session durations and size limits
Perform evaluation
Evaluations are the same as the precomputedInit
method.