Skip to content

Navigation

Navigating between screens is a core concept of building Hotwire Native apps. By default, all screens will be pushed onto the main navigation stack with animation. You can customize the navigation behavior by providing path configuration rules or manually routing in Swift or Kotlin.

Routing

Set context or presentation to a path configuration rule to apply the logic in the following table.

State Context Presentation Behavior
default default default Push on main stack (or)
Replace if visiting same page (or)
Pop then visit if previous screen is same URL
default default replace Replace screen on main stack
default modal default Present a modal with only this screen
default modal replace Present a modal with only this screen
modal default default Dismiss then Push on main stack
modal default replace Dismiss then Replace on main stack
modal modal default Push on the modal stack
modal modal replace Replace screen on modal stack
default (any) pop Pop screen off main stack
default (any) refresh Pop on main stack then
modal (any) pop Pop screen off modal stack (or)
Dismiss if one modal screen
modal (any) refresh Pop screen off modal stack then
Refresh last screen on modal stack
(or)
Dismiss if one modal screen then
Refresh last screen on main stack
(any) (any) clearAll Dismiss if modal screen then
Pop to root then
Refresh root screen on main stack
(any) (any) replaceRoot Dismiss if modal screen then
Pop to root then
Replace root screen on main stack
(any) (any) none Nothing

Server-Driven Routing in Rails

If you’re using Ruby on Rails, the turbo-rails gem provides the following additional routes. Use these to customize the behavior for Hotwire Native apps but falling back to redirecting elsewhere.

Add the following to your path configuration to apply the presentation logic.

{
"settings": {},
"rules": [
{
"patterns": ["/turbo_recede_historical_location_url"],
"properties": {"presentation": "pop"}
},
{
"patterns": ["/turbo_resume_historical_location_url"],
"properties": {"presentation": "none"}
},
{
"patterns": ["/turbo_refresh_historical_location_url"],
"properties": {"presentation": "refresh"}
}
]
}

Manual Navigation

Navigator can be used to navigate from a native screen to another native screen or back to a web context.

iOS

let rootURL = URL(string: "...")!
let navigator = Navigator()

// Visit a new page.
navigator.route(rootURL.appending(path: "foo"))

// Pop the top controller off the stack.
navigator.pop()

// Pop the entire stack of controllers.
navigator.clearAll()

Disable the animation via the optional animated parameter.

navigator.route(rootURL.appending(path: "foo"), animated: false)
navigator.pop(animated: false)
navigator.clearAll(animated: false)

Android

Inside of a HotwireActivity class:

val location = "https://..."
val navigator = delegate.currentNavigator

// Visit a new page.
navigator?.route("$location/foo")

// Pop the backstack to the previous destination.
navigator?.pop()

// Clear the navigation backstack to the start destination.
navigator?.clearAll()

Inside of a HotwireFragment class:

val location = "https://..."

// Visit a new page.
navigator.route("$location/foo")

// Pop the backstack to the previous destination.
navigator.pop()

// Clear the navigation backstack to the start destination.
navigator.clearAll()

Next: Path Configuration