⌘K

Show a Frame

Render a server-driven frame in your Android or iOS app.

A frame is an embeddable, server-driven UI unit rendered natively at runtime. Frames are not limited to full screens. You can embed one anywhere in your existing app:

Use caseExample
Full screenReplace an entire Composable or SwiftUI view with a frame
CardDrop a frame into a Column row or a SwiftUI HSack item
Dialog / AlertShow a frame inside a Dialog
Bottom sheetEmbed a frame in a bottomSheet
Section / BannerRender a frame as a partial section inside a larger screen

NativeblocksFrame is just a Composable / SwiftUI view. Place it anywhere you would place any other UI component. The route tells it which frame definition to fetch and render.


Scaffold

Before rendering any frame you can call getScaffold to fetch the scaffold model from the server. The scaffold returns registered frames. Use it to drive your initial navigation instead of hardcoding a route.

MainViewModel.kt
class MainViewModel : ViewModel() {

    fun loadScaffold() {
        viewModelScope.launch {
            NativeblocksManager.getInstance().getScaffold()
                .onSuccess { scaffold ->
                    scaffold.frames
                }
                .onFailure { Log.e("Nativeblocks", "scaffold failed", it) }
        }
    }
}
MainActivity.kt
class MainActivity : ComponentActivity() {

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

        val viewModel: MainViewModel by viewModels()

        setContent {
            MyAppTheme {
                LaunchedEffect(Unit) { viewModel.loadScaffold() }

                NativeblocksFrame(
                    route = viewModel.startRoute,
                    routeArguments = hashMapOf(),
                    loading = { NativeblocksLoading() },
                    error = { msg -> NativeblocksError(message = msg) }
                )
            }
        }
    }
}
MainActivity.kt
setContent {
    NativeblocksFrame(
        route = "/",
        routeArguments = hashMapOf(),
        loading = { NativeblocksLoading() },
        error = { message -> NativeblocksError(message = message) }
    )
}

Parameters

ParameterDescription
routeThe route key registered via the CLI (e.g. /home, /profile)
routeArgumentsRuntime values injected into the frame (user ID, locale, flags)
loadingUI shown while the frame is fetching
errorUI shown if the frame fails to load

Passing Route Arguments

Route arguments let you inject dynamic values into a frame at render time. They can be read at runtime to conditionally show blocks or populate data:

NativeblocksFrame(
    route = "/profile",
    routeArguments = hashMapOf(
        "userId" to "abc123",
        "tab" to "orders"
    ),
    loading = { NativeblocksLoading() },
    error = { message -> NativeblocksError(message = message) }
)

Full Example

A single-Activity app using Jetpack Compose Navigation to render different frames per destination.

MainActivity.kt
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Scaffold
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import io.nativeblocks.core.api.NativeblocksFrame
import io.nativeblocks.core.api.NativeblocksLoading
import io.nativeblocks.core.api.NativeblocksError

class MainActivity : ComponentActivity() {

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

        setContent {
            MyAppTheme {
                val navController = rememberNavController()

                Scaffold { padding ->
                    NavHost(
                        navController = navController,
                        startDestination = "home",
                        modifier = Modifier.padding(padding)
                    ) {
                        composable("home") {
                            NativeblocksFrame(
                                route = "/home",
                                routeArguments = hashMapOf(),
                                loading = { NativeblocksLoading() },
                                error = { msg -> NativeblocksError(message = msg) }
                            )
                        }

                        composable("profile/{userId}") { backStackEntry ->
                            val userId = backStackEntry.arguments?.getString("userId") ?: ""
                            NativeblocksFrame(
                                route = "/profile",
                                routeArguments = hashMapOf("userId" to userId),
                                loading = { NativeblocksLoading() },
                                error = { msg -> NativeblocksError(message = msg) }
                            )
                        }

                        composable("settings") {
                            NativeblocksFrame(
                                route = "/settings",
                                routeArguments = hashMapOf(),
                                loading = { NativeblocksLoading() },
                                error = { msg -> NativeblocksError(message = msg) }
                            )
                        }
                    }
                }
            }
        }
    }
}