3. Replace src/main.luau
luastra/navigation · luastra/host · navigation.history · about 20 minutesone router owns every navigation outcome
The application pushes; the host moves Back; both end by rendering the same validated router.
When to use it
Replace the complete entry module. resolve reports rejected host requests; only history events restore router state, and only system_back events carry platform Back intents.
Focused example
--!strict
local Host = require("luastra/host")
local Navigation = require("luastra/navigation")
local UI = require("luastra/ui")
local routes = Navigation.compile {
{ name = "home", path = "/" },
{ name = "detail", path = "/detail" },
}
local router = Navigation.createRouter {
compiler = routes,
initial = { name = "home", params = {}, query = {} },
}
local App = require("luastra/app")
local Root = {}
local message = "At home"
local function location(): string
return "#" .. router.currentLocation()
end
function Root.restoreHistory(value: string): boolean
local result = router.restoreEncoded(value)
if result.success then message = "History restored" end
return result.success
end
function Root.render(): UI.Node
return UI.Screen {
id = "history-recipe",
UI.Text { id = "history/title", text = "Route: " .. router.current().name, variant = "title" },
UI.Text { id = "history/location", text = location(), role = "status" },
UI.Text { id = "history/message", text = message, role = "status" },
UI.Button { id = "history/open", text = "Open detail", onTap = "route.open" },
}
end
function Root.handle(action: string, target: string, value: string)
if action == "lifecycle" and target == "app" and value == "launch" then
Host.historyReplaceLocation(location(), router.encode())
elseif action == "route.open" and target == "history/open" then
local result = router.push { name = "detail", params = {}, query = {} }
if result.success and result.changed then
Host.historyPushLocation(location(), router.encode())
message = "Detail opened"
end
elseif action == "history" and target == "app" then
if not Root.restoreHistory(value) then message = "Rejected history state" end
elseif action == "system_back" and target == "app" then
local intent = tonumber(string.match(value, "^([1-9][0-9]*):[01]$"))
if intent ~= nil then
if router.canBack() then Host.systemBackHistory(intent)
else Host.systemBackExit(intent) end
end
end
end
function Root.resolve(
_id: number,
success: boolean,
_payload: string,
code: string,
diagnostic: string
)
if not success then
message = "History request failed: " .. code .. " — " .. diagnostic
end
end
function Root.snapshot()
return { name = router.current().name, location = location() }
end
return App.compose {
render = function(_outputs) return Root.render() end,
handle = Root.handle,
resolve = Root.resolve,
snapshot = Root.snapshot,
}