ExampleFeature Flags · Remote Config
A/B Testing
Split users between two variants of a feature using percentage rollouts and remote config to deliver different experiences.
Setup in the dashboard
Create two feature flags and two remote config keys:
Flag
checkout_v250% rolloutGroup A sees new checkoutConfig
checkout_cta_text"Buy Now"CTA for control groupConfig
checkout_v2_cta_text"Get Instant Access"CTA for variant groupFlutter implementation
lib/screens/checkout_screen.dartDart
class CheckoutScreen extends StatelessWidget {
const CheckoutScreen({super.key});
@override
Widget build(BuildContext context) {
// Check which variant this user is in
final isVariantB = Koolbase.flags['checkout_v2'] == true;
// Read the appropriate CTA text from remote config
final ctaText = isVariantB
? Koolbase.config.getString('checkout_v2_cta_text', fallback: 'Get Instant Access')
: Koolbase.config.getString('checkout_cta_text', fallback: 'Buy Now');
return Scaffold(
body: Column(
children: [
// Show different UI per variant
if (isVariantB)
const NewCheckoutFlow()
else
const LegacyCheckoutFlow(),
// Dynamic CTA button
ElevatedButton(
onPressed: () => _handleCheckout(isVariantB),
child: Text(ctaText),
),
],
),
);
}
void _handleCheckout(bool isVariantB) {
// Track which variant converted
// e.g. log to your analytics: { variant: isVariantB ? 'B' : 'A', action: 'checkout' }
}
}Deterministic assignment
Because bucketing is based on a hash of the device ID, a user is always in the same variant. They won't flip between A and B across sessions. This makes conversion tracking reliable.
Concluding the test
Once you have enough data to determine a winner:
Winner is variant B
Set checkout_v2 rollout to 100% in the dashboard — all users now see variant B
Winner is control
Set checkout_v2 rollout to 0% — all users revert to the control
Clean up
Remove the checkout_v2 flag check from code in the next release and delete the flag