Skip to content
Routing in SwiftUI
Branch: master
Clone or download
Latest commit 0c2aa86 Aug 21, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
RouterPrototype.xcodeproj First commit. Aug 17, 2019
RouterPrototype First commit. Aug 17, 2019
.gitignore First commit. Aug 17, 2019
LICENSE Create LICENSE Aug 17, 2019
swiftui-router-demo.gif Better gif Aug 17, 2019

SwiftUI Router

Merely a proof of concept for now.

SwiftUI Swift Xcode MIT

Inspired by React Router, SwiftUI Router allows you to program (relatively) easy navigation in your app, much like a website. Without the hassle of NavigationView and NavigationLink. SwiftUI Router borrows the following objects from React Router: Link (named LinkButton), Redirect, Route, Router and Switch. Their behaviours should be similar to that of React Router.

Note: This project is very much a prototype/proof-of-concept. There are an unreasonable amount of kinks in the code and some basic features missing.


Router (entry)

Router {

The Router view initiates a routing environment. Wrap your entire app (or at least, the part that needs navigation) in a Router.


LinkButton(to: "/my/path") {
    Text("Go to next page")

Wrapper around a Button view to easily navigate to another path.


Redirect(to: "/notfound", replace: true)

When rendered, will redirect instantly to the given path. Set replace: true to prevent the redirect to be added to the history stack.


Route(path: "/home", exact: false) { props in

Will only render its children when the environment's path matches that of the Route. exact requires the environment path and route path to match exactly. If false, the route will also render if the environment path is e.g. "/home/and/anything/deeper".

A RouteDescription object is passed to the closure. This allows you to perform some additional logic. Note: This feature is unfinished and pretty much useless in its current state. ¯\_(ツ)_/¯


Switch {
    Route(path: "/list/details") { _ in 

    Route(path: "/list") { _ in 

    Route {

The Switch view will only render the first matching Route view. This will allow you to render fallback routes. Note: due to the @ViewBuilder limit, only 10 direct ancestor Routes are possible.


You can add a .animation() property to the Switch to animate the Route transitions.


@EnvironmentObject private var history: HistoryData

path: String

The current environment path. (Computed value)

go(to: String, replace: Bool = false)

Perform a navigation to a new path. Set replace to true to prevent the navigation from being added to the history stack.

goBack(count: Int = 1), goForward(count: Int = 1)

Go back or forward. count is clamped and will prevent from going out of bounds.

canGoBack: Bool, canGoForward: Bool

Returns whether you can go back or forward.


  • Allow for (optional) parameters in paths.
  • Fix history stack having some odd behaviour when returning to the root.
  • Limit the Switch view only to Route ancestors?
You can’t perform that action at this time.