Frame
Frame entry point, platform factories, and lifecycle hooks in the Nativeblocks DSL.
A frame is a single function that returns a NativeblocksFrame. The CLI locates it by the fixed name frame(). One frame function per file.
Entry point
fun frame(): NativeblocksFrame = androidFrame(name = "name", route = "/route") {
// variables, lifecycle, rootBlock
}
The frame file extension is .kt (Kotlin), .tsx (TypeScript), or .swift (Swift). Never add an entry point (main, @main), the CLI injects its own runner at deploy time.
Platform factories
| Platform | Kotlin | TypeScript | Swift |
|---|---|---|---|
| Android | androidFrame(name, route, type) { } | androidFrame({ name, route, type }) | androidFrame(name:route:type:) { f in } |
| iOS | iosFrame(name, route, type) { } | iosFrame({ name, route, type }) | iosFrame(name:route:type:) { f in } |
name: PascalCase. For example:"ProductDetail","CheckoutFlow"route: kebab-case path. For example:"/product-detail","/order/{orderId}"type: optionalFrameType, defaults toFRAME. See Frame type.
The platform factory ties the frame to a platform, so its rootBlock and slots accept only that platform's blocks.
Frame type
A frame is presented as a full screen, a bottom sheet, or a dialog. The type parameter selects how the SDK renders it; it defaults to FRAME when omitted.
| Value | Renders as |
|---|---|
FRAME | A full-screen frame (default) |
BOTTOM_SHEET | A bottom sheet that slides up over the current screen |
DIALOG | A modal dialog centered over the current screen |
// Full screen (default)
androidFrame(name = "Home", route = "/home") { /* ... */ }
// Bottom sheet
androidFrame(name = "Filters", route = "/filters", type = FrameType.BOTTOM_SHEET) { /* ... */ }
// Dialog
androidFrame(name = "Confirm", route = "/confirm", type = FrameType.DIALOG) { /* ... */ }
Lifecycle hooks
onAppear runs when the frame mounts; onDisappear runs when it unmounts. Both are optional and take actions.
androidFrame(name = "Home", route = "/home") {
onAppear {
script { _, updateVariable, _ -> updateVariable(loadingVar, "true") }
}
onDisappear {
script { _, updateVariable, _ -> updateVariable(loadingVar, "false") }
}
rootBlock { /* ... */ }
}
Full example
package com.example.app.frames
import com.example.app.generated.shared.*
import com.example.app.generated.integration.android.Script.script
import com.example.app.generated.integration.android.nativeblocks.button.nativeblocksButton
import com.example.app.generated.integration.android.nativeblocks.column.NativeblocksColumn
import com.example.app.generated.integration.android.nativeblocks.column.nativeblocksColumn
import com.example.app.generated.integration.android.nativeblocks.image.NativeblocksImage
import com.example.app.generated.integration.android.nativeblocks.image.nativeblocksImage
import com.example.app.generated.integration.android.nativeblocks.spacer.nativeblocksSpacer
import com.example.app.generated.integration.android.nativeblocks.text.nativeblocksText
fun frame(): NativeblocksFrame = androidFrame(name = "Profile", route = "/profile") {
val avatarUrl by remember("https://example.com/avatar.jpg")
val username by remember("John Doe")
val bio by remember("Mobile engineer")
val isFollowing by remember(false)
val followLabel by remember("Follow")
onAppear {
script { _, updateVariable, _ ->
updateVariable(followLabel, "Follow")
}
}
rootBlock {
nativeblocksColumn(
blockKey = "main",
width = NativeblocksColumn.WidthOptions.Match,
height = NativeblocksColumn.HeightOptions.Match,
horizontalAlignment = NativeblocksColumn.HorizontalAlignmentOptions.Center,
content = {
nativeblocksSpacer(blockKey = "topSpacer")
nativeblocksImage(
blockKey = "avatar",
imageUrl = avatarUrl,
width = NativeblocksImage.WidthOptions.Wrap,
scaleType = NativeblocksImage.ScaleTypeOptions.Fit,
)
nativeblocksText(blockKey = "nameText", text = username, fontSize = "20")
nativeblocksText(blockKey = "bioText", text = bio, fontSize = "14")
nativeblocksSpacer(blockKey = "gap")
nativeblocksButton(
blockKey = "followButton",
label = followLabel,
onClick = {
script { getVariable, _, _ ->
"""
let f = ${getVariable(isFollowing)} !== "true";
updateVariable("${isFollowing.key}", String(f));
updateVariable("${followLabel.key}", f ? "Unfollow" : "Follow");
""".trimIndent()
}
},
)
nativeblocksSpacer(blockKey = "bottomSpacer")
},
)
}
}
Deploy
# Development
nativeblocks frame deploy --file src/profile-android.kt --watch
# Production
nativeblocks frame deploy --file src/profile-android.kt --tag v1.0.0
--tag marks the deployed frame as a named release version; --tag and --watch are mutually exclusive.