Skip to main content
Computed Fields are a core feature of Embeddables, allowing you to calculate new values based on existing data. They take in inputs, from the User Data JSON object, and return an output. This output is then part of the User Data JSON object, and can be used elsewhere in the Embeddable. For example, it can be displayed in a text component, used in a condition, or even used as an input for another Computed Field. Computed Fields have access to the User Data JSON object, a series of helper functions like setUserData and triggerAction, and extra context about how the Computed Field was triggered.

How to create a Computed Field

1

Create a Computed Field

  • Go to the Logic sidebar and click on the Computed Fields tab.
  • Click + Add New Computed Field.
  • Give it a key to be used for the output value in the User Data JSON object, like full_name.
  • Hit Add.
2

Write your custom code

  • Computed Fields must start with a function called result().
  • You can write any custom JS code inside the result() function.
  • The first argument of result() is the User Data, and the other arguments are described here.
  • The code will execute on the frontend, in the main window environment, so has access to window functions and variables.
Computed Fields are executed client-side, in the main window environment.This means that they have access to the main window’s functions and variables, such as window.location, document, and localStorage.

Computed Field Options

Computed Fields have several configuration options that control how they behave:
Controls where and how the computed field result is stored:
  • Save to User Data (default): The result is saved to the User Data JSON object and persisted in cookies/localStorage
  • Do Not Save: The result is calculated but not saved to storage. It’s still available in the User Data during the session
  • Save to Cloud Only: The result is saved to the Embeddables database but not stored locally in cookies/localStorage
Specifies which User Data keys the computed field depends on. When any of these keys change, the computed field will have access to their values in the userData parameter.Example: If you add first_name and last_name as inputs, your computed field will receive these values:
function result(userData) {
  // userData.first_name and userData.last_name are available
  return `${userData.first_name} ${userData.last_name}`;
}
Specifies which User Data keys will trigger the computed field to re-run. This is useful when you want the field to recalculate only when specific values change, even if it depends on other inputs.Use case: You might have a computed field that uses many inputs but should only recalculate when a specific key changes (like recalculate_total).
When enabled, the computed field:
  • Receives the entire User Data object (excluding its own key to prevent circular references)
  • Re-runs whenever any User Data value changes
  • Useful for computed fields that need access to all data or should update frequently
Example:
function result(userData) {
  // All User Data keys are available
  // This will re-run whenever ANY User Data changes
  return Object.keys(userData).length;
}
When enabled, the computed field:
  • Receives the entire User Data object (excluding its own key)
  • Only re-runs when the keys specified in Inputs or Triggers change
  • Useful when you need access to all data but want to control when recalculation happens
Example:
function result(userData) {
  // All User Data keys are available
  // But this only re-runs when specified inputs/triggers change
  return userData.first_name + userData.last_name + userData.email;
}
Marks the computed field as asynchronous, allowing you to use await and promises inside the function.Example:
async function result(userData, helperFunctions) {
  const response = await fetch('https://api.example.com/data');
  const data = await response.json();
  return data.value;
}
Async computed fields are evaluated separately from synchronous ones. Sync fields are computed first for faster updates, then async fields are computed afterward.
Only available when Async is enabled. Adds a debounce delay (in milliseconds) before the computed field recalculates. This prevents excessive recalculations when inputs change rapidly.Use case: If a user is typing in an input field and you’re making an API call based on that input, you might set this to 500ms to wait until they stop typing.
When enabled, the computed field key will be set to "_loading" while the async computation is in progress. This allows you to show loading indicators in your UI.Example:
// In your computed field
async function result(userData) {
  const data = await fetch('https://api.example.com/data');
  return data.value;
}

// In your UI, you can check:
// if (userData.my_field === "_loading") { show loading spinner }
When enabled, the computed field’s value is added as a CSS class to the flow container element in the format: field-value-{key}-{value}Example: If your computed field key is user_type and it returns "premium", the class field-value-user_type-premium will be added to the flow container.Use case: This allows you to style your flow differently based on computed values using CSS:
.field-value-user_type-premium .pricing-section {
  background-color: gold;
}

Example Computed Fields

Full Name

Here’s an example of a Computed Field called full_name, that takes the user’s first and last name and concatenates them together.
// All Computed Fields must contain a function called result()
function result(userData, helperFunctions, triggerContext) {
  // Get the user's first and last name from the User Data JSON object,
  // and join them together with a space in the middle
  return `${userData.first_name} ${userData.last_name}`;
}

BMI

Here’s an example of a Computed Field called bmi, that takes the user’s weight and height and calculates their BMI.
// All Computed Fields must contain a function called result()
function result(userData, helperFunctions, triggerContext) {
  // Get the user's weight and height from the User Data JSON object
  // In this example, we're assuming the weight is in kilograms and the height is in centimeters
  const weight = userData.weight;
  const height = userData.height;
  const bmi = weight / (height * height);

  // Return the BMI value
  return bmi;
}

User is/is not over 18 - from a single date input

Here’s an example of a Computed Field called is_over_18, that takes the user’s date of birth and returns a boolean value indicating whether they are over 18.
// All Computed Fields must contain a function called result()
function result(userData, helperFunctions, triggerContext) {
  // Get the user's date of birth from the User Data JSON object
  // Assumes the date of birth is stored as a 'YYYY-MM-DD' string, e.g. '1990-01-01'
  const dob = userData.date_of_birth;

  // Calculate the date exactly 18 years ago
  const eighteenYearsAgo = new Date();
  eighteenYearsAgo.setFullYear(eighteenYearsAgo.getFullYear() - 18);

  // Return true if the user's date of birth is before 18 years ago, false otherwise
  return new Date(dob) < eighteenYearsAgo;
}

User is/is not over 18 - from three dropdowns

Here’s an example of a Computed Field called is_over_18, that takes the user’s date of birth, entered by the user into month, day and year dropdowns, and returns a boolean value indicating whether they are over 18.
// All Computed Fields must contain a function called result()
function result(userData, helperFunctions, triggerContext) {
  // Get the user's date of birth from the User Data JSON object
  const day = userData.dob_day;
  const month = userData.dob_month;
  const year = userData.dob_year;

  // Calculate the date of birth from the day, month and year
  const dob = new Date(year, month - 1, day);

  // Calculate the date exactly 18 years ago
  const eighteenYearsAgo = new Date();
  eighteenYearsAgo.setFullYear(eighteenYearsAgo.getFullYear() - 18);

  // Return true if the user's date of birth is before 18 years ago, false otherwise
  return dob < eighteenYearsAgo;
}

Learn more about Custom Code

Read more about writing Custom Code in Embeddables, including all the available arguments passed in to the function.