Skip to content

Native capabilities and container choices ​

Try Fieldnotes, the integrated native example, to follow drawer, search, shared actions, guards and a modal result in one app.

Start with what your application needs to show, then choose the native owner. NativeScript supplies page headers and controls; the router supplies route identity, guards, results and coordination between native stacks. The application supplies content, business actions and persistence policy.

This page describes 0.1.0-rc.3, compared with the previous 0.1.0-rc.2 baseline. “Existing” below means already available in rc.2; “rc.3” identifies additions that require the new candidate or a local repository build. The package is still a release candidate, not a 1.0 stability promise. Detailed guides remain the API reference.

Find a capability ​

Examples below are repository paths. Follow the demo setup; build the package before running an opt-in example. The compatibility table records dependency baselines.

NeedOwner / availabilityPlatform boundaryGuide and runnable source
Native header and page buttonsCore ActionBar / ActionItem; existingUIKit navigation bar on iOS, native Toolbar on AndroidNative bars; Inbox.vue, normal demo
Collapsing large titleCore ActionBar iosLargeTitle; existingiOS with native scrolling content. Standard Android ActionBar has no equivalent collapsing Material app-bar policyNative bars; normal demo Inbox
Native page searchRouter useNativeSearch; existingiOS UISearchController; Android SearchView in the existing ActionBar title viewSearch ownership; normal demo Inbox
Item context actions and previewRouter menu integration, app callbacks; existingiOS native preview/menu; Android native popup with explicit open actionContext menus; MessagePreview.vue, normal demo Inbox
Shared header/menu/keyboard actionsRouter usePageActions / PageActionItem; rc.3Shared eligibility/busy/error handling across supported native surfaces; application still performs save/share/deletePage actions; actions-app.ts, --env.actionsTest
Keyboard commandsRouter registration and native key dispatch; existingPhysical keyboard/platform shortcut behavior differsKeyboard; navigation-commands.ts, normal demo
Drawer / persistent custom menuRouter RouterDrawerAndroid overlay existing; iOS overlay and adaptive/permanent presentation rc.3Drawer; adaptivedrawer-app.ts, --env.adaptivedrawerTest
Independent tab histories / iPad tab sidebarRouter RouterTabs with native hosts; existingUIKit tabs/sidebar on iOS 18+; Android Material bottom navigation/rail with documented Core fallbackTabs; App.vue, normal demo
Adaptive list/detailRouter RouterSplitView, separate native Frames; existingCross-platform, including optional Android fold geometrySplit; normal demo Inbox
UIKit-controlled split columnsRouter RouterUIKitSplitView; experimental, existingiOS 18+; owns the window root. Not a child of a drawer or tabsUIKit split; uikitsplit-app.ts, --env.uikitsplitTest
Native modal and typed resultRouter route presentation, native modal host; existingInner history is separate; sheet behavior/dependencies differModals; Compose.vue, normal demo
Zoom / shared elements / predictive BackUIKit/Core transitions and router coordination; existingiOS zoom needs 18+ and runtime API; Android progress needs 14+. No universal interactive controllerTransitions, ownership limits; Transitions.vue, Settings in normal demo
Navigation diagnosticsRouter opt-in collector/export; existing. Browser viewer rc.3Logical/native state and timings, not native heap/FPS or live time travelDiagnostics, viewer; Diagnostics.vue, Settings in normal demo
Multiple native windows / recreationOne router per native window; existingPublished dependency baseline and platform-specific session/task reconstruction testsWindows; windows-app.ts, --env.windowsTest

Flags run from demo, for example ns run ios --env.actionsTest or ns run android --env.actionsTest. iOS-only fixtures require iOS. Large titles, headers, search and menus do not require a new “Native Navigation Headers” subsystem.

Choose a container ​

ContainerWhat it ownsUse it when
RouterViewOne native Frame and its route stackYou need ordinary push/back navigation.
RouterTabs + RouterTabDestination selection and the Frames mounted in each tabDestinations should retain independent histories. sidebar changes UIKit's tab presentation; it does not create a generic drawer.
RouterDrawerA menu around already-mounted content; no route history of its ownYou need custom navigation content or an adaptive persistent menu. Its buttons choose whether to push, open a link or reset a stack.
RouterSplitViewA Frame-based list/detail arrangement and its adaptationOne logical flow should expand into panes. It can be drawer content or live inside a tab.
RouterUIKitSplitViewThe window's native UISplitViewController and columnsYou explicitly want UIKit column/root ownership and accept the experimental/platform limits.

A permanent drawer, UIKit's tab sidebar and UIKit split columns may all look like a sidebar. Their history and controller ownership differ; choose by that ownership, not appearance alone.

Compose a drawer with independent destinations ​

Keep the container and named Frames mounted. Adapt the drawer's presentation rather than switching entire keyed trees with v-if:

vue
<RouterDrawer ref="drawer" presentation="auto" :breakpoint="840">
  <template #drawer>
    <StackLayout>
      <Button text="Inbox" @tap="router.openLink('/')" />
      <Button text="Settings" @tap="router.openLink('/settings')" />
    </StackLayout>
  </template>
  <RouterTabs>
    <RouterTab name="inbox" title="Inbox">
      <RouterView name="inbox" />
    </RouterTab>
    <RouterTab name="settings" title="Settings">
      <RouterView name="settings" initial="/settings" />
    </RouterTab>
  </RouterTabs>
</RouterDrawer>

This fragment belongs in an app installed with a router. Configure links.frame to choose settings for /settings and inbox otherwise; the drawer guide and runnable drawer fixture provide the full setup. openLink selects the owning destination as well as its stack. A successful navigation closes an overlay drawer; a rejected guard leaves it open. Selecting a destination is not an implicit history reset.

Unsupported composition: <RouterDrawer><RouterUIKitSplitView /></RouterDrawer> asks two containers to own incompatible native roots. Use RouterSplitView inside the drawer, or make RouterUIKitSplitView the window root and design its columns there. Do not remount a RouterView to simulate a transition; doing so discards its native history and page identity.

State, focus and accessibility ​

A retained Page keeps its Vue state while another page covers it. usePageState opts small serializable state into restoration after process death; it does not preserve promises or native objects. Search query ownership belongs to the application, and search activation must target the current eligible page. Page actions also reject execution from a covered, inactive or disposed owner.

Use native buttons with clear accessibility labels for drawer destinations, keep a Menu/Back alternative to gestures, and declare focus targets with navigation focus. Honor Reduce Motion. Automated native hierarchy checks are not evidence of spoken VoiceOver/TalkBack focus. Each linked validation report states its limits.

Proposals are not shipped capabilities ​

The interactive-transition investigation proposes boundaries, not a new common API or a Jolt integration. The Core-owned Android preview requires an unreleased pinned candidate; Core 9.1.3 falls back. A collapsing Material Android app bar, live diagnostics transport and arbitrary custom-host gesture parity are not promised by this overview.

Released under the MIT License.