⌘K

Core introduction

Nativeblocks is a tool for Android that helps you build your app’s screens from simple JSON files that come from your server. You don’t need to update the app for every small change in the UI — you control things from your backend instead.


What can Nativeblocks do?

  • Update UI from the backend: Change what your app looks like by sending new JSON. No need to re-release your app.
  • Pick how you load screens: You can use a cloud setup (everything from your server), or a community setup (you give it a set of frame URLs).
  • Add actions and events: Your screens can have buttons, input, and other interactions driven by your backend.
  • Works for small and big apps: Nativeblocks can be used for simple or very complex UI, and it helps keep your codebase tidy.

How does it work?

Here’s the usual flow:

  1. Initialization: Set up Nativeblocks in your app (your Application or Activity).
  2. Frame Registration: The system loads the list of screen frames from the backend or your configuration.
  3. Rendering: Your blocks, screens, and actions show up according to your JSON config.

Getting Started

Before you begin, make sure you have:

  • Kotlin 1.9.24 or later
  • Android API level 26 or higher

Add Nativeblocks to Your Project

Add this to your build.gradle file:

dependencies {
    implementation("io.nativeblocks:nativeblocks-android:1.7.1")
}

Set Up Nativeblocks

You need to initialize Nativeblocks before you use it, usually at the start of your app.

Cloud Edition

If you want Nativeblocks to fetch everything from your Nativeblocks cloud:

  • name (optional): Instance name for multi-instance support. Defaults to "default". Must contain only A–Z, a–z, 0–9, _ or -
  • API Url: Get it from your Nativeblocks studio after you create a new project.
  • API Key: Get it from your Nativeblocks studio after you create a new project.
  • DevelopmentMode: Set this to true if you want to see changes right away during development. Turn it off for production.
NativeblocksManager.initialize(
    applicationContext = this,
    edition = NativeblocksEdition.Cloud(
        endpoint = NATIVEBLOCKS_API_URL,
        apiKey = NATIVEBLOCKS_API_KEY,
        developmentMode = true
    )
)

Community Edition

If you want to give a load frame from your server:

NativeblocksManager.initialize(
    applicationContext = this,
    edition = NativeblocksEdition.Community(
        framesData = mapOf(
            "/login" to "https://api.example.com/login.json",
            "/profile" to "https://api.example.com/profile.json"
        )
    )
)

Multi-Instance Support

You can initialize multiple Nativeblocks instances with different names:

// Initialize first instance
NativeblocksManager.initialize(
    name = "main",
    applicationContext = this,
    edition = NativeblocksEdition.Cloud(...)
)

// Initialize second instance
NativeblocksManager.initialize(
    name = "secondary",
    applicationContext = this,
    edition = NativeblocksEdition.Cloud(...)
)

// Get specific instance
val mainManager = NativeblocksManager.getInstance("main")
val secondaryManager = NativeblocksManager.getInstance("secondary")

// Check if instance is initialized
if (NativeblocksManager.isInitialized("main")) {
    // Use the instance
}

Don't forget to clean up when your activity is destroyed:

override fun onDestroy() {
    super.onDestroy()
    NativeblocksManager.getInstance().destroy()
}

Wandkit Setup

Configure Wandkit(s) to extend Nativeblocks functionality:

NativeblocksManager.getInstance().wandKit(
    CustomWandkit1(),
    CustomWandkit2()
)

Show a Nativeblocks Frame

Once initialized, you can show your first Nativeblocks screen. For Jetpack Compose:

@Composable
fun ContentView() {
    NativeblocksFrame(
        frameRoute = "/",
        routeArguments = hashMapOf(),
        loading = { NativeblocksLoading() },
        error = { message -> NativeblocksError(message = message) }
    )
}

The core SDK itself does not have any integrations. All integrations need to be registered in the Nativeblocks integration marketplace and provided to the SDK.


Registering Custom Integrations

Nativeblocks lets you define and register your own custom pieces, like blocks, actions, and loggers:

Custom Block

Register your own block type:

NativeblocksManager.getInstance().provideBlock(
    blockType = "INTEGRATION_UNIQUE_KEY_TYPE",
    block = { props -> CustomBlockInstance(props) }
)

Fallback Block

Register a fallback block to handle missing or unrecognized block types:

NativeblocksManager.getInstance().provideFallbackBlock { keyType, key ->
    // Handle missing block - show placeholder or error UI
    Text("Block not found: $keyType ($key)")
}

Custom Action

To add your own action logic:

NativeblocksManager.getInstance().provideAction(
    actionType = "INTEGRATION_UNIQUE_KEY_TYPE",
    action = CustomActionInstance()
)

NativeblocksManager.getInstance().provideActionContractor(
    actionContractor = CustomActionContractorInstance()
)

Fallback Action

Register a fallback action to handle missing or unrecognized action types:

NativeblocksManager.getInstance().provideFallbackAction { keyType, name ->
    // Handle missing action - log or show error
    Log.w("Nativeblocks", "Action not found: $keyType ($name)")
}

Custom Logger

If you want to handle logging in your own way:

NativeblocksManager.getInstance().provideEventLogger(
    loggerType = "INTEGRATION_UNIQUE_KEY_TYPE",
    logger = CustomLoggerInstance()
)

Change Language

To set the language used in your screens:

NativeblocksManager.getInstance().setLocalization("EN")

Set global parameters for A/B testing

To set global parameters used to load a frame based on some conditions:

NativeblocksManager.getInstance().setGlobalParameters(
    "language" to "EN",
    "country" to "UAE",
    "currency" to "AED",
    "appVersionCode" to "45"
)

Experiment & Feature Flags

Get experiment or feature flag values with optional cache control:

// Use default cache (24 hours)
val showNewUI = NativeblocksManager.getInstance().getExperiment("show_new_ui", false)

// No cache - always fetch fresh
val criticalFlag = NativeblocksManager.getInstance().getExperiment("payment_enabled", false, 0L)

// Custom cache duration (10 minutes)
val theme = NativeblocksManager.getInstance().getExperiment("theme_color", "#FF0000", 10 * 60 * 1000L)

The getExperiment method supports:

  • STRING: String
  • NUMBER: Int, Float, Double, Long
  • BOOLEAN: Boolean
  • JSON: String (as raw JSON)

Scaffold API

Retrieve the scaffold model containing frame definitions:

NativeblocksManager.getInstance().getScaffold().onSuccess { scaffold ->
    // Access scaffold model with frames list
}

Frame Cache Management

Manage frame data synchronization and caching:

// Sync a specific frame from the server
NativeblocksManager.getInstance().syncFrame("/home")

// Clear a specific frame from cache
NativeblocksManager.getInstance().clearFrame("/home")

// Clear all frames from cache
NativeblocksManager.getInstance().clearAllFrames()

Custom Type Converter

If your JSON contains a special type (for example, a size or color), you can register a converter:

NativeblocksManager.getInstance().provideTypeConverter(
    type = Dp::class,
    converter = DpNativeType()
)