- Hotwire Native provides an answer to all of these drawbacks with its web-first approach. The framework enables you to build your screens once, in HTML and CSS, and reuse them across every platform. If you already have a Hotwire web app, you can use the screens you've already built!
-
-
-
- It unlocks bug fixes and new features without having to go through app store review. And you have full access to underlying iOS and Android SDKs and APIs as soon as they are released.
-
-
-
- Small teams can build highly functional, beautiful, and sustainable mobile apps. All without the headache and rigmarole of traditional native development.
-
-
-
- Hotwire Native is a high-level native framework, available for iOS and Android, that provides you with all the tools you need to leverage your web app and build great mobile apps. It wraps a web view within a native shell and renders HTML from your server. Native navigation and transition animations between screens work automatically out-of-the-box.
-
diff --git a/_source/ios/01_getting_started.md b/_source/ios/01_getting_started.md
deleted file mode 100644
index af3d131..0000000
--- a/_source/ios/01_getting_started.md
+++ /dev/null
@@ -1,69 +0,0 @@
----
-permalink: /ios/getting-started.html
-order: 01
-title: "Getting Started"
-description: "How to create a new Hotwire Native app on iOS."
----
-
-# Getting Started
-
-Follow these steps to create a minimal Hotwire Native application on iOS with support for basic back/forward navigation and error handling.
-
-## New Project
-
-First, download and install [Xcode 15+](https://developer.apple.com/xcode/).
-
-Open Xcode and create a new iOS app via File → New → Project... and choose the default iOS "App" template.
-
-
-
-In the project creation dialog, enter a product name, then select “Swift” under “Language”, and “Storyboard” under “Interface” and click Next.
-
-
-
-Select where to save the project and click Create.
-
-
-
-## Integrate Hotwire Native
-
-Next, add the Hotwire Native package via File → Add Packages Dependencies... and enter `https://github.com/hotwired/hotwire-native-ios` in the search field.
-Make sure the “Dependency Rule“ is set to “Branch“ pointing to main and your project is correctly set under “Add to Project“ and click Add Package.
-
-
-
-Once the package has been downloaded, select your app name under “Add to Target“ and click Add Package.
-
-
-
-Finally, open `SceneDelegate` and replace the entire file with this code:
-
-```swift
-import HotwireNative
-import UIKit
-
-let rootURL = URL(string: "https://hotwire-native-demo.dev")!
-
-class SceneDelegate: UIResponder, UIWindowSceneDelegate {
- var window: UIWindow?
-
- private let navigator = Navigator()
-
- func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
- window?.rootViewController = navigator.rootViewController
- navigator.route(rootURL)
- }
-}
-```
-
-## Run!
-
-Click Product → Run to launch the app in the simulator. You should see the following screen in the simulator.
-
-
-
-This example only touches on the core requirements of creating a `Navigator` and routing the root URL. Feel free to change the URL used for the initial visit to point to your web app.
-
-And note that we are pointing to a demo application server that expects a bit more native functionality. Some of the links, like native controls, won't work out of the box. Check out the [Hotwire Native iOS demo app](https://github.com/hotwired/hotwire-native-ios/tree/main/Demo) for examples on how to add bridge components, native screens, and more.
diff --git a/_source/ios/02_path_configuration.md b/_source/ios/02_path_configuration.md
deleted file mode 100644
index 5f43d75..0000000
--- a/_source/ios/02_path_configuration.md
+++ /dev/null
@@ -1,88 +0,0 @@
----
-permalink: /ios/path-configuration.html
-order: 02
-title: "Path Configuration"
-description: "Customize iOS app behavior via the path configuration."
----
-
-# Path Configuration
-
-Building on the [overview of path configuration](/overview/path-configuration), here's an example for an iOS app.
-
-```json
-{
- "settings": {},
- "rules": [
- {
- "patterns": [
- ".*"
- ],
- "properties": {
- "context": "default",
- "pull_to_refresh_enabled": true
- }
- },
- {
- "patterns": [
- "/new$"
- ],
- "properties": {
- "context": "modal",
- "pull_to_refresh_enabled": false
- }
- }
- ]
-}
-```
-
-This configuration does two things:
-
-1. Sets *all* URL path patterns with pull-to-refresh enabled.
-1. Overrides URL path patterns *ending* in `/new` to be presented as a modal with pull-to-refresh disabled. It is helpful to disable pull-to-refresh in modals so it doesn't interfere with the dismiss gesture or clear form data that a user may have entered.
-
-## Sources
-
-Path configuration has an array of `sources`. You can configure the source to be a locally bundled file, a remote file available from your server, or both. We recommend always including a bundled version even when loading remotely, so it will be available in case your app is offline.
-
-```swift
-let localPathConfigURL = Bundle.main.url(forResource: "path-configuration", withExtension: "json")!
-let remotePathConfigURL = URL(string: "https://example.com/configurations/ios_v1.json")!
-
-let pathConfiguration = PathConfiguration(sources: [
- .file(localPathConfigURL),
- .server(remotePathConfigURL)
-])
-
-let navigator = Navigator(pathConfiguration: pathConfiguration)
-```
-
-`PathConfiguration` will always load locally available configurations first. When providing both a bundled file and a server location, load order is as follows:
-
-1. The bundled file
-2. The cached server file (if a successful download has previously occurred)
-3. The downloaded server file
-
-Providing a bundled file and a server location will cause the path configuration to immediately load from the bundled version and – if it exists – a cached version of the server file. Then it will begin downloading the server file. Once the server file is successfully downloaded, it is loaded and cached for further use.
-
-## Query String Matching
-
-By default, path patterns match against the path component *and* query string of the URL.
-
-To ensure the order of query string parameters don't affect matching, a wildcard `.*` before and after the match is recommended, like so:
-
-```
-{
- "patterns": [".*\\?.*foo=bar.*"],
- "properties": {
- "foo": "bar"
- }
-}
-```
-
-Disable query string matching via:
-
-```swift
-Hotwire.config.pathConfiguration.matchQueryStrings = false
-```
-
-The [path configuration reference](/reference/path-configuration) provides more information including all the behavior Hotwire Native provides out of the box.
diff --git a/_source/ios/03_bridge_components.md b/_source/ios/03_bridge_components.md
deleted file mode 100644
index 31b3726..0000000
--- a/_source/ios/03_bridge_components.md
+++ /dev/null
@@ -1,122 +0,0 @@
----
-permalink: /ios/bridge-components.html
-order: 03
-title: "Bridge Components"
-description: "Bridge the gap with native bridge components driven by the web on iOS."
----
-
-# Bridge Components
-
-Hotwire Native abstracts the integration with its corresponding web bridge (formerly [Strada](https://dev.37signals.com/announcing-strada/)), making it even faster to get started. This assumes you've already installed the [Hotwire Native Bridge javaScript package](/reference/bridge-installation) on your server.
-
-Let's walk through how to create a new component on iOS.
-
-The component will add a native bar button item to the right side of the navigation bar. Tapping it will "click" the associated link in the HTML.
-
-
-
-Components are made of three parts: the HTML markup, a `BridgeComponent` [Stimulus](https://stimulus.hotwired.dev) controller, and the native code. The HTML configures Stimulus which passes messages to Swift.
-
-## Stimulus Controller
-
-On your server, add the data attributes needed to wire up the Stimulus controller.
-
-```html
-
- View profile
-
-```
-
-Then, create a new JavaScript `BridgeComponent` controller with the following.
-
-```javascript
-import { BridgeComponent } from "@hotwired/hotwire-native-bridge"
-
-export default class extends BridgeComponent {
- static component = "button"
-
- connect() {
- super.connect()
-
- const element = this.bridgeElement
- const title = element.bridgeAttribute("title")
- this.send("connect", {title}, () => {
- this.element.click()
- })
- }
-}
-```
-
-This component identifies itself as `"button"` via the static `component` property. It will pass all messages to a native bridge component identified with the same name.
-
-When `data-controller="button"` is found in the DOM then `connect()` is fired. This function calls `send()` which passes the `title` of the button in JSON to its native bridge component counterpart.
-
-The third parameter of send, the callback block, is executed when the bridge component replies back to the message, which is explained below. Here, the button is clicked.
-
-## Swift Component
-
-In Xcode, create a new Swift file with the following.
-
-```swift
-import HotwireNative
-import UIKit
-
-final class ButtonComponent: BridgeComponent {
- override class var name: String { "button" }
-
- override func onReceive(message: Message) {
- guard let viewController else { return }
- addButton(via: message, to: viewController)
- }
-
- private var viewController: UIViewController? {
- delegate.destination as? UIViewController
- }
-
- private func addButton(via message: Message, to viewController: UIViewController) {
- guard let data: MessageData = message.data() else { return }
-
- let action = UIAction { [unowned self] _ in
- self.reply(to: "connect")
- }
- let item = UIBarButtonItem(title: data.title, primaryAction: action)
- viewController.navigationItem.rightBarButtonItem = item
- }
-}
-
-private extension ButtonComponent {
- struct MessageData: Decodable {
- let title: String
- }
-}
-```
-
-First, the component identifies itself as `"button"` via `name` to match the Stimulus controller.
-
-`onReceive(message:)` is called when a message is received from Stimulus. Here, the `{title}` object is unpacked to add a native button to the right side of the screen. When it's tapped, the `UIAction` is fired, replying to the message and calling the callback block, clicking the button.
-
-Finally, register the component. If you followed the [getting started steps](/ios/getting-started) then this will go in `SceneDelegate.swift` before routing your first URL.
-
-```swift
-Hotwire.registerBridgeComponents([
- ButtonComponent.self
-])
-```
-
-## Add CSS to Hide Bridged Elements
-
-We've now set up `"button"` components in the web and native apps. Whenever a native app supports the `"button"` component, it'll receive a message from the web component and display its native button.
-
-There's one final piece to finish. We want to hide the web button when a native button is being displayed in the native app. It's easy to write scoped css that is only applied if:
-- A particular version of the native app supports the `"button"` component
-- A particular element in your app is connected to a `"button"` component
-
-```css
-[data-bridge-components~="button"]
-[data-controller~="button"] {
- display: none;
-}
-```
diff --git a/_source/ios/04_native_screens.md b/_source/ios/04_native_screens.md
deleted file mode 100644
index 809cb20..0000000
--- a/_source/ios/04_native_screens.md
+++ /dev/null
@@ -1,90 +0,0 @@
----
-permalink: /ios/native-screens.html
-order: 04
-title: "Native Screens"
-description: "Integrate fully native Swift screens in your Hotiwre Native app."
----
-
-# Native Screens
-
-If you need to go fully native, we've got you covered: it's easy to integrate native screens to Hotwire Native's navigation flow. Even though you may be tempted to get a reference to Hotwire Native's navigation controller and push/present yourself, we strongly advice against it. It's better to leverage the power of Hotwire Native's [Path Configuration](/ios/path-configuration), even for native screens.
-
-First, conform your controller to `PathConfigurationIdentifiable` and provide a matching `pathConfigurationIdentifier`. This identifier is used so you can easily identify that a native view controller was requested after a link interception.
-
-```swift
-class NumbersViewController: UITableViewController, PathConfigurationIdentifiable {
- static var pathConfigurationIdentifier: String { "numbers" }
-
- init(url: URL) {
- self.url = url
- }
-
- // ...
-}
-```
-
-Next, match a URL path pattern and set the `view_controller` property. This path configuration routes all URLs ending in `/numbers`.
-
-```json
-{
- "settings": {},
- "rules": [
- {
- "patterns": [
- "/numbers$"
- ],
- "properties": {
- "view_controller": "numbers"
- }
- }
- ]
-}
-```
-
-When a link is intercepted by Hotwire Native, it will go through its usual process of matching the link's URL path to all rules in the app's Path Configuration. When it matches the above rule, it will create a `VisitProposal` and will set this `view_controller` property to `"numbers"`.
-
-You can inspect this property when `handle(proposal:)` is called on `Navigator`'s delegate and create your own view controller there. That's it! Hotwire Native will handle presentation (push/replace and animations) as if it were a web view controller.
-
-```swift
-class SceneDelegate: UIResponder {
- private lazy var navigator = Navigator(delegate: self)
-
- // ...
-}
-
-extension SceneDelegate: NavigatorDelegate {
- func handle(proposal: VisitProposal) -> ProposalResult {
- switch proposal.viewController {
- case NumbersViewController.pathConfigurationIdentifier:
- let numbersViewController = NumbersViewController(url: proposal.url)
- return .acceptCustom(numbersViewController)
- default:
- return .accept
- }
- }
-}
-```
-
-## Progressive Rollout
-
-In a purely native app, if a new screen presented an issue you'd be unable to react immediately. The usual process would be to rush out bug fixes and hope for a quick review. If the bug was severe or your team needed more time to fix a critical issue, you'd have to rollback to a previous app version and submit that to the App Store, probably with an expedited review.
-
-Since even native screens are routed through Hotwire Native, the Path Configuration is a powerful ally when it comes to rolling out your native screens. If you were to find a critical issue with your native screen, you could easily update your remote Path Configuration and either point to your web-content so users don't lose functionality, or immediately disable the screen altogether – no app review required for these measures.
-
-Simply remove the `"view_controller"` property and Hotwire Native will stop using your native screen, instead presenting a web view controller which loads `"/numbers"`: a web page you fully control.
-
-```json
-{
- "settings": {},
- "rules": [
- {
- "patterns": [
- "/numbers$"
- ],
- "properties": { }
- }
- ]
-}
-```
-
-Check out the [demo app](https://github.com/hotwired/hotwire-native-ios/tree/main/Demo) to see how everything is wired up and for more complex examples.
diff --git a/_source/ios/05_configuration.md b/_source/ios/05_configuration.md
deleted file mode 100644
index a4a8657..0000000
--- a/_source/ios/05_configuration.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-permalink: /ios/configuration.html
-order: 05
-title: "Configuration"
-description: "How to customize a Hotwire Native iOS app."
----
-
-# Configuration
-
-`HotwireConfig` provides a few options to customize your Hotwire Native iOS app. We recommend making all configuration changes *before* instantiating a `Navigator`, ideally in `AppDelegate` or `SceneDelegate`.
-
-Append the following options to `Hotwire.config` to change the global configuration. For example, to enable debug logging call:
-
-```swift
-Hotwire.config.debugLoggingEnabled = true
-```
-
-## General
-
-* `debugLoggingEnabled` - Enable or disable debug logging for Turbo visits and bridge elements connecting, disconnecting, receiving/sending messages, and more.
-* `userAgent` - Override to set a custom user agent for your app's requests. Make sure to include "Hotwire Native" or "Turbo Native" to use `turbo_native_app?` on your Rails server.
-* `showDoneButtonOnModals` - When enabled, adds a `UIBarButtonItem` of type `.done` to the left navigation bar button item on screens presented modally.
-* `backButtonDisplayMode` - Sets the back button display mode of `HotwireWebViewController`.
-
-## Turbo
-
-* `defaultViewController` - The view controller used in `Navigator` for web requests. Must be a `VisitableViewController` or subclass.
-* `defaultNavigationController` - The navigation controller used in `Navigator` for the main and modal stacks. Must be a `UINavigationController` or subclass.
-* `makeCustomWebView` - Optionally customize the web views used by each Turbo Session. Ensure you return a new instance each time.
-
-## Path Configuration
-
-* `pathConfiguration.matchQueryStrings` - Enable to match the query string when applying rules in addition to the path.
-
-## Bridge
-
-* `jsonEncoder` - Set a custom JSON encoder when parsing bridge payloads. The custom encoder can be useful when you need to apply specific encoding strategies, like snake case vs. camel case.
-* `jsonDecoder` - Set a custom JSON decoder when parsing bridge payloads. The custom decoder can be useful when you need to apply specific decoding strategies, like snake case vs. camel case.
diff --git a/_source/ios/06_reference.md b/_source/ios/06_reference.md
deleted file mode 100644
index 8dee061..0000000
--- a/_source/ios/06_reference.md
+++ /dev/null
@@ -1,78 +0,0 @@
----
-permalink: /ios/reference.html
-order: 06
-title: "Reference"
-description: "An reference guide to the Hotwire Native iOS library."
----
-
-# Reference
-
-There are a few main types in Hotwire Native iOS, most notably `Navigator` and `Visitable`.
-
-## Navigator
-
-The `Navigator` is the central coordinator in a Hotwire Native iOS application. Each `Navigator` manages the stack of screens via a `UINavigationController` with a single, shared `WKWebView` instance. It lets your app choose how to handle link taps, present view controllers, and deal with errors.
-
-### Creating a `Navigator`
-
-Create with no parameters to use the default configuration:
-
-```swift
-let navigator = Navigator()
-```
-
-Provide optional [path configuration](path-configuration) to configure settings and path rules:
-
-```swift
-let navigator = Navigator(pathConfiguration: pathConfiguration)
-```
-
-Provide an optional [delegate](#navigatordelegate) to configure how different URLs, errors, and external links are handled:
-
-```swift
-let navigator = Navigator(delegate: delegate)
-
-extension SceneController: NavigatorDelgate {
- // ...
-}
-```
-
-Customize the underlying `WKWebView` and configuration with a block. For example, to use a custom `WKProcessPool` to share cookies from web views outside of Hotwire Native:
-
-```swift
-Hotwire.config.makeCustomWebView = { config in
- config.processPool = processPool
- return WKWebView(frame: .zero, configuration: config)
-}
-```
-
-## `NavigatorDelegate`
-
-The delegate is an optional interface you can implement to customize behavior of the `Navigator`.
-
-### Handling Proposals
-
-Hotwire Native iOS calls the `handle(proposal:)` method before every visit, such as when you tap a Turbo-enabled link or call `Turbo.visit(...)` in your web application. Implement this function to choose how to handle the specified URL and action. This is called a *proposal* since your application is not required to complete the visit.
-
-Return one of the following three `ProposalResult` cases:
-* `accept`: Proposals are accepted and a new [`HotwireWebViewController`](#hotwirewebviewcontroller) is displayed.
-* `acceptCustom(UIViewController)`: Provide a custom view controller to be displayed.
-* `reject`: No changes to navigation occur, the visit is effectively cancelled.
-
-### Handling External URLs
-
-Implement `handle(externalURL:)` to customize the behavior when an external URL is visited. URLs are considered "external" if they do not match the same domain as the first visited link. By default, this will present a [`SFSafariViewController`](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) modally.
-
-### Handling Errors
-
-Network errors and responses with HTTP status codes outside of the 200 range are considered errors. By default a native screen with the error's localized description and a Retry button is presented.
-
-Customize this behavior by implementing `visitableDidFailRequest(_:error:retryHandler:)`. Call `retryHandler()` to attempt the network request again.
-
-## `HotwireWebViewController`
-
-A `HotwireWebViewController` is a `UIViewController` that can be visited by a `Navigator`. Each view controller provides a `VisitableView` instance, which acts as a container for the shared `WKWebView`. The `VisitableView` optionally has a pull-to-refresh control and an activity indicator. It also automatically displays a screenshot of its contents when the web view moves to another `VisitableView`.
-
-Most applications will probably need want to subclass `HotwireWebViewController` to customize its layout or add additional views. If your application’s design prevents you from subclassing `HotwireWebViewController`, you can implement the `Visitable` and `BridgeDestination` protocols yourself.
-
-Note: Custom `Visitable` view controllers must notify their delegate of their `viewWillAppear` and `viewDidAppear` methods through the `VisitableDelegate`'s `visitableViewWillAppear` and `visitableViewDidAppear` methods. The `Navigator` uses these hooks to know when it should move the `WKWebView` from one `VisitableView` to another.
diff --git a/_source/ios/ios.json b/_source/ios/ios.json
deleted file mode 100644
index f5ed3e2..0000000
--- a/_source/ios/ios.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "tags": [
- "ios"
- ],
- "layout": "docs.html",
- "section_title": "iOS"
-}
diff --git a/_source/overview/01_how_it_works.md b/_source/overview/01_how_it_works.md
deleted file mode 100644
index c9e0f86..0000000
--- a/_source/overview/01_how_it_works.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-permalink: /overview/how-it-works.html
-order: 01
-title: "How it Works"
-description: "How Hotwire Native renders web content in a native app."
----
-
-# How it works
-
-Hotwire Native displays whatever HTML and CSS your server renders within a native shell and will react to intercepted link taps. This makes your mobile web content feel at home on Android and iOS by using standard, platform-specific navigation and animations.
-
-
-
-Hotwire Native intercepts link taps and passes control off to a native adapter. This adapter makes sure the experience is seamless: it screenshots the current page before pushing (or presenting) new screens on the native stack with a default, platform-specific animation. It will then request the web content for this new screen and render it via the web view.
-
-If the user navigates "back" to a previous screen Hotwire Native will use cached screenshots, and because we are using native navigation controls, interactive pop gestures work exactly as expected. Even the most tech-savvy users will have a hard time believing it's not a fully native app!
-
-Yet, the core of Hotwire Native is still a web browser which makes adding new screens as straightforward as building new pages in your web app. Your Android and iOS clients see updates as soon as you deploy. All without new submissions to the app stores.
-
-Hotwire Native's web-first approach means upgrading to native isn’t an all-or-nothing decision. You are free to choose specific screens or even specific *components* to write natively in Swift or Kotlin when you’re ready. It truly is progressive enhancement.
diff --git a/_source/overview/02_basic_navigation.md b/_source/overview/02_basic_navigation.md
deleted file mode 100644
index 5a66c23..0000000
--- a/_source/overview/02_basic_navigation.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-permalink: /overview/basic-navigation.html
-order: 02
-title: "Basic Navigation"
-description: "How to navigate between pages in Hotwire Native."
----
-
-# Basic Navigation
-
-Being a web-first framework means Hotwire Native adapts to your web content and how users navigate between screens: via links. Like the web, every page can link to another. Hotwire Native intercepts link taps and hands them over to its native counterpart which presents them natively – with platform-specific animations.
-
-When a user taps on a link, here's what's happening:
-
-1. A new screen is pushed onto the navigation stack with a native animation.
-1. A spinner appears indicating the page is loading.
-1. The page contents render inside the web view.
-
-
-
-## Replacing Screens
-
-By default, every tapped link _pushes_ a new screen onto the native stack. Hotwire Native uses platform-specific animations and native components so interactions feel smooth. To users, it feels like a native app because it _is_ a native app!
-
-The framework also applies a few sane defaults. Navigating to the _current_ page's URL path (again) will _replace_ the screen on the stack. You can also manually trigger a _replace_ action by adding `data-turbo-action="replace"` to links and forms. This will cause the visited page to replace the current screen (not push a new one) and load the new contents.
-
-## Caching
-
- Navigating to the _previous_ page's URL path will _pop_ the screen off the stack back to the previous screen. This animation uses a cached screenshot further blending the gap to native screens. On iOS, the interactive pop gesture - dragging your finger from the far left of the screen - is also supported and feels great.
-
-## External Links
-
-Note that if the URL of a tapped link is _not_ on the same domain as the current page it is considered _external_. External links are not routed through Hotwire Native. They instead open via an in-app web browser. iOS uses an [`SFSafariViewController`](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller) and Android uses [Custom Tabs](https://developer.chrome.com/docs/android/custom-tabs).
-
-## Advanced Navigation
-
-Hotwire Native supports a bunch of other navigation patterns like popping the entire stack and manually refreshing the current page. But individually decorating each link would create a maintenance nightmare.
-
-So we've abstracted these _rules_ into something called the [Path Configuration](/overview/path-configuration).
diff --git a/_source/overview/03_path_configuration.md b/_source/overview/03_path_configuration.md
deleted file mode 100644
index 2041ea1..0000000
--- a/_source/overview/03_path_configuration.md
+++ /dev/null
@@ -1,59 +0,0 @@
----
-permalink: /overview/path-configuration.html
-order: 03
-title: "Path Configuration"
-description: "Customize app behavior remotely via the path configuration."
----
-
-# Path Configuration
-
-Advanced navigation in Hotwire Native apps can be configured via a JSON file called the *path configuration*. The *path configuration* is broken down into two top-level objects: `settings` and `rules`. An empty path configuration requires both keys, as follows:
-
-```json
-{
- "settings": {},
- "rules": []
-}
-```
-
-`settings` contains app-level configuration items. These settings can be read when the *path configuration* is first loaded; common use cases include feature-flags or custom app information that you want to control remotely.
-
-`rules` contains entries that define navigation within the Hotwire app. Each entry contains regex patterns used to identify URLs and then apply the specified behavior on navigation. In the following example, all URLs that match regex `/new$` will open up in a modal screen instead of being pushed onto the default navigation stack.
-
-```json
-{
- "settings": {
- "feature_flags": [
- {
- "name": "new_onboarding_flow",
- "enabled": true
- }
- ]
- },
- "rules": [
- {
- "patterns": [
- "/new$"
- ],
- "properties": {
- "context": "modal"
- }
- },
- ]
-}
-```
-
-It's recommended that the *path configuration* file exists both locally (bundled with your app's binary) and remotely (on your server). The local *path configuration* ensures a smooth initial launch, while the remote *path configuration* unlocks a powerful perk: you can change the app's behavior from your server without needing to publish a new app update.
-
-## Versioning
-
-It is recommended to version your path configuration file names and use a unique resource for each OS platform, like so:
-
-* `/configurations/ios_v1.json`
-* `/configurations/android_v1.json`
-
-This allows forward and backward compatibility with new app versions that you release. If you make breaking changes in a new version of your app, point to `*_v2.json` for the new build. Keep old versions available on your server so older clients can continue to work properly until the user's app is updated on their device.
-
-See the [iOS](/ios/path-configuration)- and [Android](/android/path-configuration)-specific pages on path configuration for more details and examples.
-
-The [path configuration reference](/reference/path-configuration) provides more information including all the behavior Hotwire Native provides out of the box.
diff --git a/_source/overview/04_bridge_components.md b/_source/overview/04_bridge_components.md
deleted file mode 100644
index ba4d1ab..0000000
--- a/_source/overview/04_bridge_components.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-permalink: /overview/bridge-components.html
-order: 04
-title: "Bridge Components"
-description: "Build HTML-driven native bridge components."
----
-
-# Bridge Components
-
-Hotwire Native apps seamlessly display your mobile web content within a native container with fully native animations and behaviors. If we were to use this siloed web content approach exclusively, we'd quickly run into a major limitation: there’s no way for the native app to know what’s happening within the web view and adapt to the content that it’s displaying.
-
-To overcome this gap in communication, your app can use Bridge Components.
-
-*Note: Bridge Components were formerly called [Strada](https://dev.37signals.com/announcing-strada/) components and work exactly as they did before. However, the framework is now included out-of-the-box in Hotwire Native and doesn't require additional dependencies or integrations in your app*.
-
-A Bridge Component is made up of two parts:
-- A __web component__ controller that leverages [Stimulus](https://stimulus.hotwired.dev/)
-- A __native component__ counterpart built in Swift or Kotlin.
-
-Your web code and your native app code communicate through Hotwire Native's component-based framework that abstracts away the complexity of communicating with JavaScript code in a web view and native code in your app.
-
-
-
-This component-based framework allows some web features to break out of the web view container and drive native features — whether it’s displaying native buttons in the top app bar, displaying native menu sheets, or calling native platform APIs. Bridge components enable you to do all of this and give you the flexibility to build components that are specific to your app’s needs.
-
-Example components include native buttons to submit forms, web dialogs rendered as a `UIActionSheet` on iOS or `BottomSheetDialog` on Android, and more. Check out the [iOS](/ios/bridge-components)- and [Android](/android/bridge-components)-specific pages for information and code snippets. And there's a guide for [installing the web library](/reference/bridge-installation) on your server.
-
-
-
-Being web-first means that _you_ get to decide which parts of your web-app become native. You can choose to quickly ship a purely web screen and then progressively enhance specific features natively. Sometimes a feature requires a more responsive interaction and Bridge Components are the perfect solution. And other times a screen requires a fully native implementation for a high fidelity experience.
-
-If that's the case, integrating fully native code is easy too.
diff --git a/_source/overview/05_native_screens.md b/_source/overview/05_native_screens.md
deleted file mode 100644
index 1b0939f..0000000
--- a/_source/overview/05_native_screens.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-permalink: /overview/native-screens.html
-order: 05
-title: "Native Screens"
-description: "Integrate fully native Kotlin and Swift screens in your Hotiwre Native app."
----
-
-# Native Screens
-
-There are times where neither web-based content nor [bridge components](/overview/bridge-components) are enough. Times where you need maximum fidelity or interaction with native SDKs and APIs. For these, you can build fully native screens in Kotlin and Swift.
-
-There are a few things to note:
-
-- It's strongly encouraged that each native screen has a corresponding URL, so it's easier to integrate into Hotwire Native's built-in navigation.
-- Purely native screens will likely take specialized experience from iOS and Android developers.
-- You'll need to write a version for every platform and go through the app store review process for any future changes
-
-Leveraging Hotwire Native allows you to build full products with smaller development teams. You can focus on high fidelity native development where it matters most and leverage your existing web app for everything else.
-
-Check out the [iOS](/ios/native-screens)- and [Android](/android/native-screens)-specific pages for information and code snippets.
diff --git a/_source/overview/overview.json b/_source/overview/overview.json
deleted file mode 100644
index f6c4044..0000000
--- a/_source/overview/overview.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "tags": [
- "overview"
- ],
- "layout": "docs.html",
- "section_title": "Overview"
-}
diff --git a/_source/reference/bridge_components.md b/_source/reference/bridge_components.md
deleted file mode 100644
index 3148d04..0000000
--- a/_source/reference/bridge_components.md
+++ /dev/null
@@ -1,90 +0,0 @@
----
-permalink: /reference/bridge-components.html
-order: 04
-title: "Bridge Components"
-description: "Advanced details for Bridge Components"
----
-
-# Bridge Components
-
-## Web Components
-
-The `BridgeComponent` class is an extension of a Stimulus [Controller](https://stimulus.hotwired.dev/reference/controllers). You have everything available in a standard `Controller` in addition to the following Hotwire Native-specific bridge functionality:
-
-* `static component`: The unique name of the component. This must match the name you use for the corresponding native component.
-* `this.platformOptingOut`: Specifies whether the controller is opted out for the current platform using the `data-controller-optout-` attribute.
-* `this.enabled`: Specifies whether the component is enabled and supported by the current version of the native app.
-* `this.bridgeElement`: Provides `this.element` for the component instance wrapped in a `BridgeElement`.
-* `this.send(event, data = {}, callback)`: Sends a message to the native component with the `event` name, optional JSON `data`, and a `callback` to be run when the native component replies to the message.
-
-For example, to create a `"form"` component that displays a native submit button in your native app, you'd add the following controller, target, and title attributes to your web `
-```
-
-Next, create a `BridgeComponent` with named `"form"` that sends a message to the native component with `data` that contains the form's `submitTitle`. Provide a callback to run when the native component replies to the message.
-
-```javascript
-// bridge/form_controller.js
-
-import { BridgeComponent, BridgeElement } from "@hotwired/hotwire-native-bridge"
-
-export default class extends BridgeComponent {
- static component = "form"
- static targets = [ "submit" ]
-
- submitTargetConnected(target) {
- const submitButton = new BridgeElement(target)
- const submitTitle = submitButton.title
-
- this.send("connect", { submitTitle }, () => {
- target.click()
- })
- }
-}
-```
-
-_Note: It's recommended to place your bridge components in a `/bridge` subdirectory where your Stimulus controllers live to make them easily identifiable and isolated from your other Stimulus controllers._
-
-# Bridge Elements
-
-The `BridgeElement` class lets you easily use bridge-specific data and behaviors on elements in your components. You can wrap any element in a `new BridgeElement(myElement)` within your bridge components to access the following:
-
-* `title`: Returns the title of the element, attempting to use a `data-bridge-title` value first, the `aria-label` value second, then otherwise falling back to the element's `textContent` or `value`.
-* `disabled`: Returns whether the element is disabled with the `data-bridge-disabled` attribute.
-* `enabled`: Returns the opposite of `disabled`.
-* `enableForComponent(component)`: Removes the `data-bridge-disabled` attribute on the element.
-* `hasClass(className)`: Returns whether the element has a particular class in its `classList`.
-* `attribute(name)`: Returns the value of an attribute on the element.
-* `bridgeAttribute(name)`: Returns the value of a `data-bridge-` attribute on the element.
-* `setBridgeAttribute(name, value)`: Sets the value of a `data-bridge-` attribute on the element.
-* `removeBridgeAttribute(name)`: Removes the `data-bridge-` attribute on the element.
-* `click()`: Performs a click on the element.
-
-## Data Attributes
-
-The following data attributes can be applied to any element accessed via the `BridgeElement` class:
-
-* `data-bridge-title="My Title"`: Specifies a custom bridge title for your element.
-* `data-bridge-disabled`: Specifies whether the bridge element should be enabled or disabled for a particular platform. Values must be `"true"`, `"false"`, `"ios"`, or `"android"`.
-* `data-bridge-*`: Specifies arbitrary attributes prefixed with `data-bridge-` whose values are accessible from a `BridgeElement`.
-
-The following data attributes can be applied to elements associated with a `data-controller` and a `BridgeComponent` class:
-
-* `data-controller-optout-ios`: Opt-out the component for your iOS app using [hotwire-native-ios](https://github.com/hotwired/hotwire-native-ios). Allows you to conditionally disable a component instance for iOS, even if the native app supports the component.
-* `data-controller-optout-android`: Opt-out the component for your Android app using [hotwire-native-android](https://github.com/hotwired/hotwire-native-android). Allows you to conditionally disable a component instance for Android, even if the native app supports the component.
diff --git a/_source/reference/bridge_installation.md b/_source/reference/bridge_installation.md
deleted file mode 100644
index 47f74cd..0000000
--- a/_source/reference/bridge_installation.md
+++ /dev/null
@@ -1,57 +0,0 @@
----
-permalink: /reference/bridge-installation.html
-order: 03
-title: "Bridge Installation"
-description: "Install Hotwire Native Bridge in your web app."
----
-
-# Installation
-
-To build Bridge Components in your native app, you'll need to first install the [Hotwire Native Bridge](https://github.com/hotwired/hotwire-native-bridge) javascript library in your web app. Hotwire Native Bridge can either be referenced in compiled form via the distributable script directly in the `` of your application, or through npm via a bundler like esbuild.
-
-## Prerequisite: Install Stimulus
-
-Bridge Components in your web app leverage [Stimulus](https://stimulus.hotwired.dev) and the core `BridgeComponent` class is an extension of a Stimulus `Controller`. You must have Stimulus installed in your web app before installing Hotwire Native Bridge. See the [Stimulus installation instructions](https://stimulus.hotwired.dev/handbook/installing).
-
-## In Compiled Form
-
-If you're using [importmap-rails](https://github.com/rails/importmap-rails) you just need to pin Stimulus and Hotwire Native Bridge in your config/importmap.rb file:
-
-```sh
-./bin/importmap pin @hotwired/stimulus @hotwired/hotwire-native-bridge
-```
-
-Alternatively, you can manually define importmap entries for both Hotwire Native Bridge and Stimulus, pointing to the latest versions of each:
-
-```html
-
-
-
-```
-
-Then you can import Hotwire Native Bridge anywhere in your application code:
-
-```js
-import { BridgeComponent } from "@hotwired/hotwire-native-bridge"
-
-class BridgeTest extends BridgeComponent {
- // ...
-}
-```
-
-## As An npm Package
-
-You can install Hotwire Native Bridge [from npm](https://www.npmjs.com/package/@hotwired/hotwire-native-bridge) via the `npm` or `yarn` packaging tools and use a JavaScript bundler, like webpack or esbuild, to import it in your application.
-
-```javascript
-import "@hotwired/hotwire-native-bridge"
-```
-
-
diff --git a/_source/reference/navigation.md b/_source/reference/navigation.md
deleted file mode 100644
index 93777ea..0000000
--- a/_source/reference/navigation.md
+++ /dev/null
@@ -1,233 +0,0 @@
----
-permalink: /reference/navigation.html
-order: 01
-title: "Navigation"
-description: "How to navigate between screens with Hotwire Native."
----
-
-# 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](/reference/path-configuration) rule to apply the logic in the following table.
-
-* **State** describes what state the app is currently in: `modal` if a modal is presented, `default` otherwise.
-* **Context** is the value of the `context` property on the tapped link: `modal` or `default`. No value defaults to `default`.
-* **Presentation** is the value of the `presentation` property on the tapped link: `replace`, `pop`, `refresh`, `clear_all`, `replace_root`, `none`, or `default`. No value defaults to `default`.
-
-
-
-
-
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](https://github.com/hotwired/turbo-rails) gem provides the following additional routes. Use these to customize the behavior for Hotwire Native apps but falling back to redirecting elsewhere.
-
-* `recede_or_redirect_to(url, **options)` - Pops the visible screen off of the navigation stack. If a modal is presented on iOS, the modal is dismissed instead.
-* `resume_or_redirect_to(url **options)` - No action is taken.
-* `refresh_or_redirect_to(url, **options)` - Reloads the visible screen by performing a new web request and invalidating the cache.
-
-Add the following to your path configuration to apply the presentation logic.
-
-```json
-{
- "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](/overview/native-screens) to another native screen or back to a web context.
-
-### iOS
-
-```swift
-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.
-
-```swift
-navigator.route(rootURL.appending(path: "foo"), animated: false)
-navigator.pop(animated: false)
-navigator.clearAll(animated: false)
-```
-
-### Android
-
-Inside of a `HotwireActivity` class:
-
-```kotlin
-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:
-
-```kotlin
-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()
-```
diff --git a/_source/reference/path_configuration.md b/_source/reference/path_configuration.md
deleted file mode 100644
index e922dc1..0000000
--- a/_source/reference/path_configuration.md
+++ /dev/null
@@ -1,130 +0,0 @@
----
-permalink: /reference/path-configuration.html
-order: 02
-title: "Path Configuration"
-description: "Advanced navigation via the path configuration."
----
-
-# Path Configuration
-
-The basics of *Path Configuration* are explained in the [overview](/overview/03-path-configuration). If you're ready to build your first Path Configuration, keep reading.
-
-## Settings
-
-`settings` is your sandbox for App-level configuration. As explained in the overview, common use cases include feature flags or any additional information that your app may use to configure itself. Feel free to add or modify any objects or arrays here, always remembering to [version](/overview/03-path-configuration) your path configuration if you make breaking changes.
-
-```json
-{
- "settings": {
- "use_local_db": true,
- "cable": {
- "script_url": "https://hotwire-native-demo.dev/configurations/action_cable.js"
- },
- "feature_flags": [
- {
- "name": "new_onboarding_flow",
- "enabled": true
- }
- ]
- }
- "rules": []
-}
-```
-
-## Rules
-
-`rules` contains individual entries that define how different URL path patterns should behave. Each rule consists of the `patterns` to match and the `properties` to apply.
-
-```json
-{
- "settings": {},
- "rules": [
- {
- patterns: "",
- properties: {}
- }
- ]
-}
-```
-
-Entries in `rules` are read sequentially and are applied to the caught URL (via path pattern regex matching) as they are read. This means that rules earlier in the array can be overwritten by rules further down the array. It's recommended that the first rule should establish the default behavior for all patterns and subsequent rules can override this for specific behavior.
-
-The following *Path Configuration* shows how a rule further down the array can override properties set by previous rules. Notice property `pull_to_refresh_enabled` is `true` for all URLs but `false` for URL path patterns matching `"/new$"`.
-
-```json
-{
- "settings": {},
- "rules": [
- {
- "patterns": [
- ".*"
- ],
- "properties": {
- "context": "default",
- "pull_to_refresh_enabled": true
- }
- },
- {
- "patterns": [
- "/new$"
- ],
- "properties": {
- "context": "modal",
- "pull_to_refresh_enabled": false
- }
- }
- ]
-}
-```
-
-Using the above Path Configuration, when a navigation is requested to `"/"`:
-1. *Path Configuration* matches `"/"` to the first rule `".*"`
-2. *Path Configuration* sets `pull_to_refresh_enabled = true`
-3. Since the second rule does not match the URL path pattern, it is ignored.
-
-However, when navigation is requested to `"/new"`:
-1. *Path Configuration* matches `"/new"` to the first rule `".*"`
-2. *Path Configuration* sets `pull_to_refresh_enabled = true`
-3. *Path Configuration* matches `"/new"` to the second rule `"/new$"`
-4. *Path Configuration* sets `pull_to_refresh_enabled = fase`
-
-A rule earlier in the array can be overwritten by rules further down the array.
-
-
-### Patterns
-
-The `patterns` array defines regular expression patterns that will be used to match URL paths.
-
-### Properties
-
-The `properties` hash contains a handful of key/value pairs that Hotwire Native supports out of the box.
-
-* `context` — Specifies the presentation context in which the view should be displayed. Hotwire Native will determine what the navigation behavior should be based on this value and `presentation`.
- * Optional.
- * Possible values: `default` or `modal`. Defaults to `default`.
-* `presentation` — Specifies what style to use when presenting the given destination. Hotwire Native will determine what the navigation behavior should be based on this value and `context`.
- * Optional.
- * Possible values: `default`, `push`, `pop`, `replace`, `replace_root`, `clear_all`, `refresh`, `none`. Defaults to `default`.
-* `pull_to_refresh_enabled` — Whether or not pull-to-refresh should be enabled.
- * Optional.
- * Possible values: `true`, `false`. Defaults to `false` on Android and `true` on iOS.
-
-You are free to add more properties as your app needs, but these are the ones the framework is aware of and will handle automatically.
-
-### Android-specific properties
-
-* `uri` — The target destination URI to navigate to. Must map to an Activity or Fragment that has implemented the [`TurboNavGraphDestination`](../turbo/src/main/kotlin/dev/hotwire/turbo/nav/TurboNavGraphDestination.kt) annotation with a matching `uri` value.
- * **Required**.
- * No explicit value options. No default value.
-* `fallback_uri` — Provides a fallback URI in case a destination cannot be found that maps to the `uri`. Can be useful in cases when pointing to a new `uri` that may not be available yet in older versions of the app.
- * Optional.
- * No explicit value options. No default value.
-* `title` — Specifies a default title that will be displayed in the toolbar for the destination. This is most useful for native destinations, since web destinations will render their title from the web view page's `` tag.
- * Optional.
- * No explicit value options. No default value.
-
-### iOS-specific properties
-
-* `view_controller` — The identifier for a native `UIViewController` to navigate to. Conform your custom controller to `PathConfigurationIdentifiable` to it to this identifier.
- * Optional.
- * No explicit value options. No default value.
diff --git a/_source/reference/reference.json b/_source/reference/reference.json
deleted file mode 100644
index 0acdc90..0000000
--- a/_source/reference/reference.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "tags": [
- "reference"
- ],
- "layout": "docs.html",
- "section_title": "Reference"
-}
\ No newline at end of file
diff --git a/android/bridge-components.html b/android/bridge-components.html
new file mode 100644
index 0000000..c8b663d
--- /dev/null
+++ b/android/bridge-components.html
@@ -0,0 +1,252 @@
+
+
+
+
+
+
+
+ Hotwire Native Android: Bridge Components
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Skip to content
+
+
+
+
+
+
Hotwire Native abstracts the integration with its corresponding web bridge (formerly Strada), making it even faster to get started. This assumes you’ve already installed the Hotwire Native Bridge javaScript package on your server.
+
Let’s walk through how to create a new component on Android.
+
The component will add a native button item to the right side of the toolbar. Tapping it will “click” the associated link in the HTML.
+
+
Components are made of three parts: the HTML markup, a BridgeComponentStimulus controller, and the native code. The HTML configures Stimulus which passes messages to Kotlin.
const element =this.bridgeElement const title = element.bridgeAttribute("title") this.send("connect",{title},()=>{ this.element.click() }) } }
+
This component identifies itself as "button" via the static component property. It will pass all messages to a native bridge component identified with the same name.
+
When data-controller="button" is found in the DOM then connect() is fired. This function calls send() which passes the title of the button in JSON to its native bridge component counterpart.
+
The third parameter of send, the callback block, is executed when the bridge component replies back to the message, which is explained below. Here, the button is clicked.
// Write native code to display a native submit button in the // toolbar displayed in the delegate.destination. Use the // incoming data.title to set the button title. }
// Use kotlinx.serialization annotations to define a serializable // data class that represents the incoming message.data json. @Serializable dataclassMessageData( @SerialName("title")val title: String ) }
+
This component subclasses the BridgeComponent available in the Android library.
+
onReceive(message) is called when a message is received from Stimulus. Here, the {title} object is unpacked to add a native button to the right side of the screen. When it’s tapped, the performButtonClick() is fired, replying to the message and calling the callback block, clicking the button.
+
Finally, register the component with the matching "button" name as the Stimulus controller. The best place for this is in an Applicationsubclass for your app, which runs immediately at app startup:
We’ve now set up "button" components in the web and native apps. Whenever a native app supports the "button" component, it’ll receive a message from the web component and display its native button.
+
There’s one final piece to finish. We want to hide the web button when a native button is being displayed in the native app. It’s easy to write scoped css that is only applied if:
+
+
A particular version of the native app supports the "button" component
+
A particular element in your app is connected to a "button" component
Customize your app by configuring options before your HotwireActivity instance is created by the system. We recommend using an Application instance to place the configuration code.
+
class MyApplication :Application(){ overridefunonCreate(){ super.onCreate()
// Set configuration options } }
+
To ensure this invoked when the app starts, add the name of your Application instance to AndroidManifest.xml via the android:name property on the <application> node.
+p
Click Run → Run ‘app’ to launch the app in the emulator. You should see the following screen in the emulator:
+
+
This example only touches on the core requirements of creating a HotwireActivity and routing start location. Feel free to change the URL used for the initial visit to point to your web app.
+
And note that we are pointing to a demo application server that expects a bit more native functionality. Some of the links, like native controls, won’t work out of the box. Check out the Hotwire Native Android demo app for examples on how to add bridge components, native screens, and more.
To render a native screen on Android you need match an identifier in the path configuration with your fragment.
+
First, match a URL path pattern and set the uri property. This path configuration routes all URLs ending in /numbers. You can also set a title to set the native title when the fragment is presented.
When a link is intercepted by Hotwire Native, it will go through its usual process of matching the link’s URL path to all rules in the app’s Path Configuration. When it matches the above rule, it will propose a visit and will find the matching HotwireDestination whose uri matches "hotwire://fragment/numbers".
+
Create a new fragment and provide a matching HotwireDestination annotation.
+
@HotwireDestination(uri ="hotwire://fragment/numbers") class NumbersFragment :HotwireFragment(){ // ... }
+
Finally, register this fragment with Hotwire Native to use it when the URL path matches. See the configuration docs for a recommendation on where to register fragments in your code.
In a purely native app, if a new screen presented an issue you’d be unable to react immediately. The usual process would be to rush out bug fixes and hope for a quick review. If the bug was severe or your team needed more time to fix a critical issue, you’d have to rollback to a previous app version and submit that to the Play Store for review.
+
Since even native screens are routed through Hotwire Native, the Path Configuration is a powerful ally when it comes to rolling out your native screens. If you were to find a critical issue with your native screen, you could easily update your remote Path Configuration and either point to your web-content so users don’t lose functionality, or immediately disable the screen altogether – no app review required for these measures.
+
Simply remove the "uri" property and Hotwire Native will stop using your native screen, instead presenting a web view controller which loads "/numbers": a web page you fully control.
Sets all URL path patterns to render the default fragment with a hotwire://fragment/web URI with pull-to-refresh enabled.
+
Overrides URL path patterns ending in /new to be presented as a modal with pull-to-refresh disabled. It is helpful to disable pull-to-refresh in modals so it doesn’t interfere with the dismiss gesture or clear form data that a user may have entered.
Path configuration has a location that can be loaded from your app. You can configure the location to be a locally bundled file, a remote file available from your server, or both. We recommend always including a bundled version even when loading remotely, so it will be available in case your app is offline.
Path Configuration will always load locally available configurations first. When providing both a bundled file and a server location, load order is as follows:
+
+
The bundled file
+
The cached server file (if a successful download has previously occurred)
+
The downloaded server file
+
+
Providing a bundled file and a server location will cause the path configuration to immediately load from the bundled version and – if it exists – a cached version of the server file. Then it will begin downloading the server file. Once the server file is successfully downloaded, it is loaded and cached for further use.
+
The path configuration reference provides more information including all the behavior Hotwire Native provides out of the box.
The Navigator is the central coordinator in a Hotwire Native Android application. Each NavigatorHost in your Activity maintains a Navigator instance, which manages the stack of HotwireFragment screens with a single, shared WebView instance. It lets your app choose how to handle link taps, present new screens, and deal with errors.
By default, all external urls outside of your app’s domain are opened in the default browser on the device. This is easily customizable, though. Out-of-the-box, Hotwire Native provides three route decision handlers for you to use to control how urls are routed:
+
+
AppNavigationRouteDecisionHandler: Routes all internal urls through your app (enabled by default).
+
BrowserRouteDecisionHandler: Routes all external urls to the device’s default browser (enabled by default).
+
BrowserTabRouteDecisionHandler: Routes all external urls to a Custom Tab in your app (disabled by default).
+
+
If you’d like to customize this behavior, it’s easy to do. For example, if you’d like to route external urls to Custom Tabs instead of the default browser, you can register the relevant decision handlers in order of importance:
+ Building fully native mobile apps can be a real pain. It often looks like this:
+
+
The development process is very slow
+
Large teams of specialized developers are required
+
Each feature must be re-implemented across every platform
+
Every update needs to wind its way through the app store review process
+
+
+
+
+ Hotwire Native provides an answer to all of these drawbacks with its web-first approach. The framework enables you to build your screens once, in HTML and CSS, and reuse them across every platform. If you already have a Hotwire web app, you can use the screens you've already built!
+
+
+
+ It unlocks bug fixes and new features without having to go through app store review. And you have full access to underlying iOS and Android SDKs and APIs as soon as they are released.
+
+
+
+ Small teams can build highly functional, beautiful, and sustainable mobile apps. All without the headache and rigmarole of traditional native development.
+
+
+
+ Hotwire Native is a high-level native framework, available for iOS and Android, that provides you with all the tools you need to leverage your web app and build great mobile apps. It wraps a web view within a native shell and renders HTML from your server. Native navigation and transition animations between screens work automatically out-of-the-box.
+