{"id":18264746,"url":"https://github.com/reactcomponentkit/router","last_synced_at":"2025-04-04T21:30:48.075Z","repository":{"id":53766957,"uuid":"343760011","full_name":"ReactComponentKit/Router","owner":"ReactComponentKit","description":"Router for SwiftUI","archived":false,"fork":false,"pushed_at":"2021-05-02T11:16:01.000Z","size":57,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-20T19:17:08.834Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ReactComponentKit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-02T12:03:26.000Z","updated_at":"2023-09-24T09:05:21.000Z","dependencies_parsed_at":"2022-09-14T03:23:04.641Z","dependency_job_id":null,"html_url":"https://github.com/ReactComponentKit/Router","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactComponentKit%2FRouter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactComponentKit%2FRouter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactComponentKit%2FRouter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ReactComponentKit%2FRouter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ReactComponentKit","download_url":"https://codeload.github.com/ReactComponentKit/Router/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247252018,"owners_count":20908610,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-05T11:15:48.767Z","updated_at":"2025-04-04T21:30:47.719Z","avatar_url":"https://github.com/ReactComponentKit.png","language":"Swift","readme":"# Router\n\nRouter for SwiftUI 🚀 Router uses UINavigationController behind scene so Router can be used only for iOS.😄\n\n## Example([Go to Code](https://github.com/ReactComponentKit/RouterExample))\n\n\u003ccenter\u003e\u003cimg src='https://github.com/ReactComponentKit/RouterExample/blob/main/example.gif?raw=true'\u003e\u003c/center\u003e\n\n## RouterRootView\n\nYou can define Router start position by using RouterRootView. If you call popToRoot(), you can back to the start position.\n\n```swift\nvar body: some Scene {\n    WindowGroup {\n        RouterRootView { router in\n            ContentView()        \n        }\n    }\n}\n```\n\nRouterRootView inject the router into the ViewBuilder.  you can route to any view with router.\n\n```swift\nvar body: some Scene {\n    WindowGroup {\n        RouterRootView { router in\n            Button(\"Go to SomeView\") {\n                router.route(\"myscheme://someview\", .push)\n            }\n        }\n    }\n}\n```\n\n## Define router path and map it to the View\n\n```swift\nvar body: some Scene {\n    WindowGroup {\n        RouterRootView { router in\n            Button(\"Go to SomeView\") {\n                router.route(\"myscheme://someview?i=10\u0026s=hello\", .push)\n            }\n        }\n        .path(\"myscheme://someview\") { data in\n            SomeView(number: data.i.flatMap { Int($0) } ?? 0, message: data.s ?? \"\")\n        }\n        .path(\"myscheme://detail\") { _ in \n            DetailView()\n        }\n    }\n}\n```\n\n## Route to the View\n\nThere are two ways for routing to the view. \n\n### Routing with path\n\n```swift\nButton(\"Route to the View\") {\n    router.route(\"myscheme://detail\", .sheet)\n}\n```\n\n### Routing with navigation methods\n\n```swift\nButton(\"Route to the View\") {\n    router.sheet(DetailView())\n}\n```\n\n## Pass bindings and Inject Environment things\n\nIf you want to pass binding or environment things, you should use builder method.\n\n```swift\nButton(\"router with binding\") {\n    router.builder()\n        .route(\"route://detail?a=123\u0026b=Hello\")\n        .presentation(mode: .sheet)\n        .binding(name: \"test\", $test)\n        .go {\n            $0.environment(\\.colorScheme, .light)\n        }\n}\n```\n\nYou can register path like below:\n\n```swift\nvar body: some Scene {\n    WindowGroup {\n        RouterRootView { router in\n            Button(\"Go to SomeView\") {\n                router.route(\"myscheme://someview?i=10\u0026s=hello\", .push)\n            }\n        }\n        .path(\"myscheme://detail\") { data in \n            DetailView(a: data.a.flatMap { Int($0) } ?? 0, b: data.b ?? \"\", test: data.bindings.test)\n        }\n    }\n}\n```\n\n## Navigation Methods\n\n- push()\n- sheet()\n- fullscreen()\n- overFullscreen()\n- replace()\n- popToRoot()\n\n\n## Presentation Mode with Route.route\n\n- .push\n- .sheet\n- .fullscreen\n- .overFullscreen\n- .replace\n\n## Dismiss Presented View\n\nYou can get `routerPresentationMode` with `@Environment(\\.routerPresentationMode) var routerPresentationMode`. You can dismiss or pop the view with routerPresentationMode like below:\n\n```swift\nButton(\"Dismiss\") {\n    routerPresentationMode.dismiss()\n}\n```\n\n## Get Router In Child View\n\nYou can get `router` with `@EnvironmentObject var router: Router`. You can route to the any view with it.\n\n```swift\nstruct DetailView: View {\n    @EnvironmentObject\n    var router: Router\n    @Environment(\\.routerPresentationMode)\n    var routerPresentationMode\n    \n    var a: Int\n    var b: String\n    \n    @Binding\n    var test: Bool\n    \n    var body: some View {\n        VStack {\n            VStack {\n                Text(\"a = \\(a)\")\n                Text(\"b = \\(b)\")\n                Toggle(isOn: $test) {\n                    Text(\"Test Toggle\")\n                }\n            }\n            Button(\"Dismiss\") {\n                routerPresentationMode.dismiss()\n            }\n            .onAppear {\n                print(routerPresentationMode.isPresented)\n            }\n            .onDisappear {\n                print(routerPresentationMode.isPresented)\n            }\n            \n            Button(\"Go to Three\") {\n                router.push {\n                    Text(\"Three\")\n                    Button(\"push again\") {\n                        router.push {\n                            Text(\"Hello World\")\n                            Button(\"Pop to Root\") {\n                                router.popToRoot()\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n```\n\n## SwitchCaseView and IfLetView\n\nFor choosing view by variable value or optional value, Router provides SwitchCaseView and IfLetView. You can use them like below:\n\n```swift\n@main\nstruct RouterExampleApp: App {\n    \n    @Default(.isFirstLaunch)\n    var isFirstLaunch\n    \n    var body: some Scene {\n        WindowGroup {\n            RouterRootView { router in\n                Switch(isFirstLaunch)\n                    .Case(true) { _ in\n                        OnboardingView()\n                    }\n                    .Case(false) { _ in\n                        ContentView()\n                    }\n                    .Else {\n                        EmptyView()\n                    }\n            }\n        }\n    }\n}\n```\n\nOr\n\n```swift\nvar body: some Scene {\n        WindowGroup {\n            RouterRootView { router in\n                Switch(isFirstLaunch)\n                    .Case(true) { _ in\n                        OnboardingView()\n                    }\n                    .Case(false) { _ in\n                        ContentView()\n                    }\n                    .Else {\n                        EmptyView()\n                    }\n            }\n            .path(\"myapp://color\") { data in\n                Switch(data.color)\n                    .Case(\"red\") { color in\n                        ColorView(color:  MyColor.from(string: color))\n                            .navigationBarHidden(true)\n                    }\n                    .Case(\"green\") { color in\n                        ColorView(color:  MyColor.from(string: color))\n                            .navigationBarHidden(true)\n                    }\n                    .Else {\n                        Text(\"OMG\")\n                    }\n            }\n        }\n}\n```\n\nOr\n\n```swift\nvar body: some Scene {\n        WindowGroup {\n            RouterRootView { router in\n                Switch(isFirstLaunch)\n                    .Case(true) { _ in\n                        OnboardingView()\n                    }\n                    .Case(false) { _ in\n                        ContentView()\n                    }\n                    .Else {\n                        EmptyView()\n                    }\n            }\n            .path(\"myapp://color\") { data in\n                If(data.color).Let { color in\n                    ColorView(color:  MyColor.from(string: color))\n                        .navigationBarHidden(true)\n                }\n            }\n        }\n}\n```\n\n## Integration\n\n###  Swift Package Manager\n\nYou can use The Swift Package Manager to install Router by adding the proper description to your Package.swift file:\n\n```swift\n// swift-tools-version:4.0\nimport PackageDescription\n\nlet package = Package(\n    name: \"YOUR_PROJECT_NAME\",\n    dependencies: [\n        .package(url: \"https://github.com/ReactComponentKit/Router.git\", from: \"0.0.1\"),\n    ]\n)\n```\n\n## MIT License\n\nMIT License\n\nCopyright (c) 2021 ReactComponentKit.Router\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactcomponentkit%2Frouter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freactcomponentkit%2Frouter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactcomponentkit%2Frouter/lists"}