navigation
@bedrock-core/navigation moves a player from one screen to another by key, and keeps a stack of where they have been.
@bedrock-core/navigation is in beta: the API can change between releases. Pin exact versions and read the changelog before upgrading.
The API for navigation WILL change, this a temp step while transitioning to hybrid screens from only runtime ones.
What is @bedrock-core/navigation?
A compiled screen is drawn from the resource pack by its title, and its shape is frozen at build. That rules out the navigator every React app has — a stack of components swapped inside one root — because there is no root to swap into.
What fits is a stack of keys. navigate('shop:catalog', player) shows that screen and puts the one the player was on behind them; back(player) returns to it.
The key is <addon>:<name>, and that is what makes this work across addons: a key for a screen nobody in this realm compiled still resolves, through the reference its owner replicated.
Install
- npm
- yarn
- pnpm
npm install @bedrock-core/navigation
yarn add @bedrock-core/navigation
pnpm add @bedrock-core/navigation
Peer dependency: @bedrock-core/ui-runtime, which an addon already has through @bedrock-core/ui.
Quick start
import { core } from '@bedrock-core/server';
import { navigate, provideReferences, screens } from '@bedrock-core/navigation';
import { uiReference } from '@bedrock-core/generated/ui';
import '@bedrock-core/generated/ui';
core.register({ manifest });
// Publish this addon's screens so other realms can show them, and resolve a key this
// bundle did not compile from whoever owns it. An addon that installs any of the apps
// gets both done by `uiOf(core)`; this is the bundle that mounts none.
screens(core).provide(uiReference());
provideReferences(key => screens(core).find(key));
export function openCatalog(player: Player): void {
navigate('shop:catalog', player);
}
Inside a screen, reach for the hook instead — the player is already in hand:
function Row(): JSX.Element {
const { navigate, back, canGoBack } = useNavigation();
return (
<Panel flexDirection={'row'} gap={4}>
<Button onPress={() => navigate('shop:catalog')}><Text>{'Catalog'}</Text></Button>
<Button visible={canGoBack} onPress={() => back()}><Text>{'Back'}</Text></Button>
</Panel>
);
}
What you get
A stack that survives a frozen layout — it holds keys, not trees. Going back means showing that screen again, drawn from its own initial state; the state of the screen being returned to went with its fibers.
Screens other addons can open — publish your static screens once and navigate('<you>:<screen>') works in any realm in the world, whether or not your script runs there. The client draws it from the pack it already holds.
A press that is data — <Link to> puts the destination on the element rather than in a closure, so the build can read where it leads and describe the screen to other addons.
Next steps
- Moving between screens —
navigate,back,replace,resetand what each does to the stack useNavigation— the same calls inside a screen, bound to its player- References — publishing your screens and resolving another addon's
- The realm —
uiOf(core): the show methods, the way back, and where each player is - Navigation in the ui docs — screen keys,
<Link>and static screens