Skip to main content

AB Test - Experiment API client side

Depends on Experiment API to get AB Test configuration, calculation will be done on experiment team's server side when we call the API.

This hooks accept 2 props:

(
FetchExperimentConfigOptions: {
namespace: string;
fallbackVariant: string;
additionalInput?: Record<string, any>;
};
trackCondition?: () => boolean // This will send data to tvlk/events api
)

This hooks will return object with 3 items:

{
isLoading: boolean; // `true` only until the first variant is resolved (initial load)
isFetching: boolean; // `true` whenever a network request is in flight, including subsequent refetches
variant: string | null; // null return as init value
}

Flow

  • Experiment config will be cached in the browser cookie for 1 minute; Cookie TTL won't be extended
  • Experiment config will be fetched from API if not exists in cookie
  • Fallback variant will be used if API call failed or timeout

isLoading vs isFetching

  • isLoading is true only until the first variant is resolved (from cookie or API). Once a variant has been resolved, isLoading stays false for the lifetime of the hook — it will NOT flip back to true when the cookie expires and a background refetch happens. Use this for first-paint loaders so you don't trigger extra re-renders during background refreshes.
  • isFetching is true whenever a network request is in flight, including subsequent refetches after the first variant has been resolved. Use this when you need to reflect the actual fetching status (e.g. a subtle "refreshing" indicator).

Caution

  • When handling UI updates for experiment result availability (like showing loaders or conditionally rendering content), prefer relying on the variant value to determine readiness.

Example

import React, { useEffect, useState } from 'react';
import { Text } from 'react-native';
import { useExperimentConfigClient } from '@traveloka/core';

export default function Component(props) {
const experimentConfigOptions = {
namespace: 'namespace',
fallbackVariant: 'CONTROL',
additionalInput: { input: 1, input: '2' },
};
const { isLoading, isFetching, variant } = useExperimentConfigClient(
experimentConfigOptions,
() => experimentConfigOptions.namespace === 'namespace' // Example for conditional tracking to tvlk/events. If undefined, will send tracking by default
);

let content = <Text>This is control</Text>;

if (variant === 'variant1') {
content = <Text>This is variant 1</Text>;
}

return content;
}

Reference