- While your WebView has history, back runs
history.back()inside your miniapp. Your router oruseHistoryStatehook sees thepopstateand shows the previous screen. - When the history is empty, back minimizes your miniapp. The UI WebView unmounts, but your background layer keeps running with its session. When the user reopens the miniapp, the UI starts again on its first screen with empty history. Keep anything that must survive in the background layer and send it to the UI when it reopens.
useState, MemoryRouter, createMemoryRouter, or wouter’s memoryLocation) never creates a history entry, so back skips past it and minimizes the whole miniapp. Anything the user should be able to go back from must push a history entry.
Pages: a router in hash mode
For page-level navigation, use your router’s hash mode. Each navigation becomes a real history entry, and hash URLs keep working when the host reloads your bundle from disk.Tabs, dialogs, and screens: useHistoryState
For UI state that is not a route, such as tabs, dialogs, sheets, pickers, or a multi-step screen, use useHistoryState from @mentra/miniapp/ui. It works like useState, except that the phone’s back gesture undoes each change.
Rules for keys and values:
keynames the value inside the history entry. Use a different key for each piece of state on the page. Two components that pass the same key share one value.- Values are stored in
history.state, so they must survive structured clone: strings, numbers, booleans,null, and plain objects and arrays. For a dialog about one item, store the item’s id rather than an object with methods. - The value belongs to the current history entry. A component that remounts, or a page that reloads, reads it back. Minimizing the miniapp discards it along with the WebView.
useHistoryState and a hash router can live in the same app. A route change starts a fresh entry, so hook values fall back to their initial values on the new page and come back when the user returns.
Check it on a phone
- Open a nested page or dialog, then swipe back. You land on its parent.
- Open a dialog, close it with its own button, then swipe back. The dialog does not reopen.
- From the first screen, swipe back. The miniapp minimizes.
Next steps
The UI layer
The
mentra bridge, hooks, and components.Safe areas & layout
Keep content clear of the capsule menu.

