Skip to main content

Moving between screens

Four calls, distinguished by what they leave behind the player.

Import​

import { back, canGoBack, currentKey, historyOf, navigate, replace, reset } from '@bedrock-core/navigation';

Signatures​

navigate(key: ScreenKey, player: Player, options?: NavigateOptions): boolean
replace(key: ScreenKey, player: Player, options?: Omit<NavigateOptions, 'replace'>): boolean
reset(key: ScreenKey, player: Player, options?: Omit<NavigateOptions, 'replace'>): boolean
back(player: Player, options?: Omit<NavigateOptions, 'replace'>): boolean
CallThe stack afterwards
navigateone deeper — the screen they were on is behind them
replaceexactly as deep as it was — a back from the target returns past this screen
resetempty — a back from the target has nowhere to go
backone shallower — the screen behind becomes the current one

Each returns whether a screen was shown. A false is a key nothing resolved: a screen that did not compile, an addon nobody in this realm is running, or a typo. It is warned about where it is decided, never thrown.

Options​

OptionTypeDefaultDescription
paramsRecord<string, unknown>—Props the target screen is rendered with
replacebooleanfalseShow the screen in place of the current one; replace() is this with the flag already set
debugbooleanfalseDiff every present against the snapshot the build recorded and warn on drift

params fill what the layout already reserved. A compiled screen's shape is frozen, so they can never add or drop a cell — a generic screen's labels and values, not its structure. A static screen is shown from its table and takes none.

Params that reach another realm, or a static screen's table, are written as JSON, so they must be plain data: strings, finite numbers, booleans, null, and arrays and objects of those. A realm drops params that are not, with a warning, and still opens the screen.

Which one to reach for​

navigate is the default: the player is going somewhere they will come back from.

replace is for screens that are peers, where none is the way back to another — the pages of a guide, the tabs of a set. A redirect is the other case.

reset is what a menu's root wants. Going back out of the first screen of a flow should end the flow, not walk into whatever the player was looking at before it.

back needs no key: the player's own stack decides.

Reading the stack​

historyOf(player: Player): readonly string[]
currentKey(player: Player): ScreenKey | undefined
canGoBack(player: Player): boolean

historyOf is the keys behind the player, oldest first. currentKey is the screen they are looking at. canGoBack is whether there is anything behind it — what a back control's visible wants.

Examples​

A flow whose first screen ends it​

export function openShop(player: Player): void {
reset('shop:home', player);
}

A back from shop:home now returns false, so the control that calls it can be hidden with canGoBack(player).

Pages that move sideways​

export function openPage(player: Player, pageId: string): void {
replace(`guide:${pageId}`, player);
}

The guide's index stays the thing a back returns to, however many pages deep the player reads.

Filling a generic screen​

navigate('shop:item', player, { params: { itemId: 'diamond', price: 64 } });

Notes​

Closing what a player is looking at from outside a screen is closeUi(player), from @bedrock-core/ui — it clears the stack as well. A screen closing itself is useExit().

A container screen has no key, so none of these can open one. A chest is entered by walking up to an entity.