⌘K

A/B Testing

Deliver different frame variants to different users using global parameters and Nativeblocks CLI targeting rules.

A/B testing in Nativeblocks works at the frame level. Via the CLI, you define multiple frame variants and set targeting conditions. The SDK sends global parameters with every frame request, and the server picks the right variant based on your rules. No code changes needed per test.


How it works

  1. Via the CLI, create two or more variants of a frame (e.g. /home-v1, /home-v2, or a single frame with conditional blocks)
  2. Set targeting conditions via the Studio (percentage split, user attributes, etc.)
  3. In your app, set global parameters that represent the current user's context
  4. The SDK sends those parameters on every frame request: the server picks the right variant

Set Global Parameters

Global parameters are key-value pairs attached to every frame request. Set them once after init and update them when the user's context changes.

NativeblocksManager.getInstance().setGlobalParameters(
    "country" to "US",
    "language" to "EN",
    "appVersionCode" to "45",
    "plan" to "pro",
    "isLoggedIn" to "true"
)

Targeting examples

GoalGlobal parameter to setServer condition
Show a promo banner only to US users"country": "US"country == "US"
Roll out a new checkout flow to 20%(none)Percentage split 20/80
Beta feature for paid users"plan": "pro"plan == "pro"
Version-gate a redesign"appVersionCode": "50"appVersionCode >= "50"
Language-specific onboarding"language": "DE"language == "DE"

Scenario examples

Country-based promo banner

Show a promotional home frame only to users in a specific country. All other users see the default frame. The targeting rule is configured entirely via the Studio.

App.kt
class App : Application() {

    override fun onCreate() {
        super.onCreate()

        NativeblocksManager.initialize(
            applicationContext = this,
            edition = NativeblocksEdition.Cloud(
                endpoint = BuildConfig.NATIVEBLOCKS_API_URL,
                apiKey = BuildConfig.NATIVEBLOCKS_API_KEY,
                developmentMode = BuildConfig.DEBUG
            )
        )

        NativeblocksManager.getInstance().setGlobalParameters(
            "country" to Locale.getDefault().country
        )
    }
}
HomeScreen.kt
@Composable
fun HomeScreen() {
    NativeblocksFrame(
        route = "/home",
        routeArguments = hashMapOf(),
        loading = { NativeblocksLoading() },
        error = { msg -> NativeblocksError(message = msg) }
    )
}

In the Studio, configure the condition country == "US" on the promo variant of /home. Users in the US receive the promo frame, everyone else receives the default.


Plan-based feature gate

Show a premium feature frame only to users on the pro plan. After a user upgrades, update the parameter and sync so they see the new content immediately.

AuthViewModel.kt
fun onLoginSuccess(user: User) {
    NativeblocksManager.getInstance().setGlobalParameters(
        "userId" to user.id,
        "plan" to user.plan,
        "isLoggedIn" to "true"
    )
    navController.navigate("home")
}

fun onPlanUpgraded(newPlan: String) {
    viewModelScope.launch {
        NativeblocksManager.getInstance().setGlobalParameters(
            "plan" to newPlan
        )
        NativeblocksManager.getInstance().syncFrame("/home")
        NativeblocksManager.getInstance().syncFrame("/dashboard")
    }
}
DashboardScreen.kt
@Composable
fun DashboardScreen() {
    NativeblocksFrame(
        route = "/dashboard",
        routeArguments = hashMapOf(),
        loading = { NativeblocksLoading() },
        error = { msg -> NativeblocksError(message = msg) }
    )
}

In the Studio, configure plan == "pro" on the premium dashboard variant. Free users see the standard variant automatically.


Version-gate a redesign

Roll out a new UI only to users on a minimum app version. Older versions keep the old design automatically.

App.kt
NativeblocksManager.getInstance().setGlobalParameters(
    "appVersionCode" to BuildConfig.VERSION_CODE.toString()
)
HomeScreen.kt
@Composable
fun HomeScreen() {
    NativeblocksFrame(
        route = "/home",
        routeArguments = hashMapOf(),
        loading = { NativeblocksLoading() },
        error = { msg -> NativeblocksError(message = msg) }
    )
}

In the Studio, configure appVersionCode >= "50" on the redesigned frame variant. Users on older builds see the previous design with no app update required on your side.


Update parameters at runtime

Parameters can be updated any time: after login, on settings change, etc. The next frame fetch uses the updated values.

// After user logs in
NativeblocksManager.getInstance().setGlobalParameters(
    "userId" to user.id,
    "plan" to user.plan,
    "isLoggedIn" to "true"
)

// Sync the home frame to pick up the new variant immediately
NativeblocksManager.getInstance().syncFrame("/home")

Preview Kit

PreviewKit is a QA and stakeholder tool that lets you override global parameters at runtime without touching code or CLI targeting rules. Shake the device to open a parameter form, adjust any value, and the frame re-fetches immediately to deliver the matching variant.

Important: PreviewKit only works with developmentMode = false (production mode) and the Cloud edition only.

Add the dependency

build.gradle
dependencies {
    implementation("io.nativeblocks:nativeblocks-wandkit-android:1.2.0")
}

Initialize

Register PreviewKit after SDK init instead of DevKit. Use it only in production or internal QA builds.

MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    NativeblocksManager.initialize(
        applicationContext = this,
        edition = NativeblocksEdition.Cloud(
            endpoint = BuildConfig.NATIVEBLOCKS_API_URL,
            apiKey = BuildConfig.NATIVEBLOCKS_API_KEY,
            developmentMode = false
        )
    )

    val previewKit = PreviewKit.Builder()
        .launchOnShake()
        .build()

    NativeblocksManager.getInstance().wandKit(previewKit)
}

How to use

  1. Install a production build on a real device
  2. Shake the device. The parameter form opens.
  3. Change any global parameter (e.g. set plan to pro)
  4. Confirm. The frame re-fetches using the overridden values and delivers the matching variant.

You can also launch the form manually from a hidden settings button or debug menu:

previewKit.launch()
Builder optionWhat it does
launchOnShake()Opens the parameter form when the device is shaken