### Define path configuration with settings and rules Source: https://native.hotwired.dev/overview/path-configuration Example showing feature flags in settings and a navigation rule that opens URLs ending in /new in a modal. ```json { "settings": { "feature_flags": [ { "name": "new_onboarding_flow", "enabled": true } ] }, "rules": [ { "patterns": [ "/new$" ], "properties": { "context": "modal" } }, ] } ``` -------------------------------- ### Implement MainActivity Source: https://native.hotwired.dev/android/getting-started Extend HotwireActivity and configure the navigator with a start location. ```kotlin package com.example.myapplication // update to match your project import android.os.Bundle import android.view.View import androidx.activity.enableEdgeToEdge import dev.hotwire.navigation.activities.HotwireActivity import dev.hotwire.navigation.navigator.NavigatorConfiguration import dev.hotwire.navigation.util.applyDefaultImeWindowInsets class MainActivity : HotwireActivity() { override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) findViewById(R.id.main_nav_host).applyDefaultImeWindowInsets() } override fun navigatorConfigurations() = listOf( NavigatorConfiguration( name = "main", startLocation = "https://hotwire-native-demo.dev", navigatorHostId = R.id.main_nav_host ) ) } ``` -------------------------------- ### Create Application Instance Source: https://native.hotwired.dev/android/configuration Use an Application instance to place configuration code. Ensure this is invoked when the app starts by adding the Application instance name to AndroidManifest.xml. ```kotlin class MyApplication : Application() { override fun onCreate() { super.onCreate() // Set configuration options } } ``` ```xml ``` -------------------------------- ### Bridge Component for Native Form Interaction Source: https://native.hotwired.dev/reference/bridge-components Implement a BridgeComponent to handle form submissions and communicate with the native 'form' component. This example sends a 'connect' event with the submit title and triggers a click on the submit button upon receiving a reply. ```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() }) } } ``` -------------------------------- ### Create Navigator with Path Configuration Source: https://native.hotwired.dev/ios/reference Initialize a Navigator with custom path configuration to define settings and path rules for navigation. ```swift let navigator = Navigator(pathConfiguration: pathConfiguration) ``` -------------------------------- ### Define Main Layout Source: https://native.hotwired.dev/android/getting-started Replace the contents of activity_main.xml with a FragmentContainerView configured as a NavigatorHost. ```xml ``` -------------------------------- ### Create Navigator with Delegate Source: https://native.hotwired.dev/ios/reference Set up a Navigator with a delegate to customize how URLs, errors, and external links are handled. ```swift let navigator = Navigator(delegate: delegate) extension SceneController: NavigatorDelgate { // ... } ``` -------------------------------- ### Load Path Configuration Source: https://native.hotwired.dev/android/path-configuration Initializes the path configuration by specifying local asset paths and remote server URLs. Always include a local asset file to ensure functionality when the app is offline. ```kotlin Hotwire.loadPathConfiguration( context = this, location = PathConfiguration.Location( assetFilePath = "json/configuration.json", remoteFileUrl = "https://example.com/configurations/android_v1.json" ) ) ``` -------------------------------- ### Create Default Navigator Source: https://native.hotwired.dev/ios/reference Instantiate a Navigator with default configuration to manage screen stacks and WKWebView. ```swift let navigator = Navigator() ``` -------------------------------- ### Define an empty path configuration Source: https://native.hotwired.dev/overview/path-configuration The base structure for a path configuration file requires both settings and rules keys. ```json { "settings": {}, "rules": [] } ``` -------------------------------- ### Add Hotwire Native Dependencies Source: https://native.hotwired.dev/android/getting-started Include the core and navigation-fragments libraries in your module-level build.gradle.kts file. ```kotlin dependencies { implementation("dev.hotwire:core:") implementation("dev.hotwire:navigation-fragments:") } ``` -------------------------------- ### App-Level Settings Configuration Source: https://native.hotwired.dev/reference/path-configuration Use the 'settings' object for app-level configuration like feature flags or connection details. Remember to version your configuration if breaking changes are made. ```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": [] } ``` -------------------------------- ### Load Path Configuration Source: https://native.hotwired.dev/ios/configuration Loads path configuration from local files or remote servers using Hotwire.loadPathConfiguration(from:). ```swift let localPathConfigURL = Bundle.main.url(forResource: "path-configuration", withExtension: "json")! let remotePathConfigURL = URL(string: "https://example.com/configurations/ios_v1.json")! Hotwire.loadPathConfiguration(from: [ .file(localPathConfigURL), .server(remotePathConfigURL) ]) ``` -------------------------------- ### Handle Navigation Proposals Source: https://native.hotwired.dev/ios/reference Implement the handle(proposal:) method to decide how to manage navigation events before they occur. This allows for custom handling of link taps or programmatic visits. ```swift func handle(proposal: Proposal) -> ProposalResult { // ... } ``` -------------------------------- ### Custom WebView Configuration Source: https://native.hotwired.dev/ios/reference Configuring the underlying WKWebView instance for the Navigator. ```APIDOC ## Custom WebView Configuration ### Description Customize the WKWebView configuration, such as setting a custom WKProcessPool to share cookies. ### Request Example Hotwire.config.makeCustomWebView = { config in config.processPool = processPool return WKWebView(frame: .zero, configuration: config) } ``` -------------------------------- ### Define Path Configuration Rules Source: https://native.hotwired.dev/android/path-configuration JSON structure defining URL patterns and their associated presentation properties. Use this to map URL paths to specific fragments and UI behaviors like pull-to-refresh. ```json { "settings": {}, "rules": [ { "patterns": [ ".*" ], "properties": { "context": "default", "uri": "hotwire://fragment/web", "pull_to_refresh_enabled": true } }, { "patterns": [ "/new$" ], "properties": { "context": "modal", "uri": "hotwire://fragment/web/modal/sheet", "pull_to_refresh_enabled": false } } ] } ``` -------------------------------- ### Load Path Configuration in AppDelegate.swift Source: https://native.hotwired.dev/ios/path-configuration Configure Hotwire Native by loading the path configuration from local and remote sources in your AppDelegate. This ensures Hotwire is set up before the first URL is routed. ```swift import HotwireNative import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let localPathConfigURL = Bundle.main.url(forResource: "path-configuration", withExtension: "json")! let remotePathConfigURL = URL(string: "https://example.com/configurations/ios_v1.json")! Hotwire.loadPathConfiguration(from: [ .file(localPathConfigURL), .server(remotePathConfigURL) ]) return true } } ``` -------------------------------- ### Configure Path for Native Screen Source: https://native.hotwired.dev/android/native-screens Define a URL path pattern and its associated native screen properties like URI and title in the Path Configuration. ```json { "settings": {}, "rules": [ { "patterns": [ "/numbers$" ], "properties": { "uri": "hotwire://fragment/numbers", "title": "Numbers" } } ] } ``` -------------------------------- ### Basic Rule Structure Source: https://native.hotwired.dev/reference/path-configuration Define URL path behaviors using 'rules', which contain 'patterns' to match and 'properties' to apply. An empty structure is shown here. ```json { "settings": {}, "rules": [ { "patterns": "", "properties": {} } ] } ``` -------------------------------- ### Annotate Fragment with Deep Link URI Source: https://native.hotwired.dev/android/native-screens Create a native fragment and annotate it with @HotwireDestinationDeepLink, matching the URI defined in the Path Configuration. ```kotlin @HotwireDestinationDeepLink(uri = "hotwire://fragment/numbers") class NumbersFragment : HotwireFragment() { // ... } ``` -------------------------------- ### Enable Debugging Source: https://native.hotwired.dev/android/configuration Enable debugging for both Hotwire and WebView in debug builds. ```kotlin Hotwire.config.debugLoggingEnabled = BuildConfig.DEBUG Hotwire.config.webViewDebuggingEnabled = BuildConfig.DEBUG ``` -------------------------------- ### Navigator Initialization Source: https://native.hotwired.dev/ios/reference Methods for initializing the Navigator, the central coordinator for Hotwire Native iOS applications. ```APIDOC ## Navigator Initialization ### Description Create a new Navigator instance to manage the navigation stack and shared WKWebView. ### Request Example // Default configuration let navigator = Navigator() // With path configuration let navigator = Navigator(pathConfiguration: pathConfiguration) // With delegate let navigator = Navigator(delegate: delegate) ``` -------------------------------- ### Custom WebView Configuration Source: https://native.hotwired.dev/android/reference Allows customization of the WebView component by subclassing `HotwireWebView`. ```APIDOC ## Custom WebView You can customize and subclass the `HotwireWebView` class to provide custom behaviors in your app: ```kotlin Hotwire.config.makeCustomWebView = { context -> MyCustomWebView(context, null) } ``` ``` -------------------------------- ### Set Application User Agent Prefix Source: https://native.hotwired.dev/android/configuration Set a custom user agent application prefix for every WebView instance. The library appends additional information to this prefix. ```kotlin Hotwire.config.applicationUserAgentPrefix = "My Application;" ``` -------------------------------- ### Pinning dependencies with importmap-rails Source: https://native.hotwired.dev/reference/bridge-installation Use this command to pin Stimulus and Hotwire Native Bridge when using importmap-rails. ```bash ./bin/importmap pin @hotwired/stimulus @hotwired/hotwire-native-bridge ``` -------------------------------- ### Configure Default View Controller Source: https://native.hotwired.dev/ios/configuration Sets a custom view controller for web requests in the Navigator. Must be a VisitableViewController or subclass. ```swift Hotwire.config.defaultViewController = { url in CustomViewController(url: url) } ``` -------------------------------- ### Customize WKWebView Configuration Source: https://native.hotwired.dev/ios/reference Configure the underlying WKWebView and its settings, such as sharing cookies via a custom WKProcessPool. ```swift Hotwire.config.makeCustomWebView = { config in config.processPool = processPool return WKWebView(frame: .zero, configuration: config) } ``` -------------------------------- ### Query String Matching with Wildcards Source: https://native.hotwired.dev/ios/path-configuration Configure path patterns to match URLs including query strings. Using wildcards like '.*' before and after the match ensures that the order of query parameters does not affect matching. ```json { "patterns": [".*\\?.*foo=bar.*"], "properties": { "foo": "bar" } } ``` -------------------------------- ### Define Path Configuration Rule Source: https://native.hotwired.dev/ios/native-screens Configure a JSON rule to map URL patterns to a specific view controller identifier. ```json { "settings": {}, "rules": [ { "patterns": [ "/numbers$" ], "properties": { "view_controller": "numbers" } } ] } ``` -------------------------------- ### Configure Stimulus Controller in HTML Source: https://native.hotwired.dev/android/bridge-components Add data attributes to your HTML elements to initialize the Stimulus controller and pass bridge-specific metadata. ```html View profile ``` -------------------------------- ### Path Configuration Structure Source: https://native.hotwired.dev/reference/path-configuration The root structure for Path Configuration, containing global settings and an array of navigation rules. ```APIDOC ## Path Configuration Structure ### Description The Path Configuration is a JSON object that defines application-level settings and a sequence of rules for URL path matching. ### Request Body - **settings** (object) - Optional - Sandbox for app-level configuration like feature flags or URLs. - **rules** (array) - Optional - A list of rule objects defining behavior for specific URL patterns. ### Request Example { "settings": { "use_local_db": true, "feature_flags": [ { "name": "new_onboarding_flow", "enabled": true } ] }, "rules": [ { "patterns": [".*"], "properties": { "context": "default", "pull_to_refresh_enabled": true } } ] } ``` -------------------------------- ### Handle Visit Proposal in NavigatorDelegate Source: https://native.hotwired.dev/ios/native-screens Implement the NavigatorDelegate to intercept visit proposals and return a custom native view controller when the identifier matches. ```swift class SceneDelegate: UIResponder, UIWindowSceneDelegate { private lazy var navigator = Navigator( configuration: .init(name: "main", startLocation: rootURL), delegate: self ) // ... } extension SceneDelegate: NavigatorDelegate { func handle(proposal: VisitProposal, from navigator: Navigator) -> ProposalResult { switch proposal.viewController { case NumbersViewController.pathConfigurationIdentifier: let numbersViewController = NumbersViewController(url: proposal.url) return .acceptCustom(numbersViewController) default: return .accept } } } ``` -------------------------------- ### NavigatorDelegate Methods Source: https://native.hotwired.dev/ios/reference Interface for customizing Navigator behavior, including handling visit proposals, external URLs, and errors. ```APIDOC ## NavigatorDelegate ### Description Implement these methods to customize how the application handles navigation proposals, external links, and network errors. ### Methods - **handle(proposal:)**: Called before every visit. Returns a `ProposalResult` (accept, acceptCustom, or reject). - **handle(externalURL:)**: Customizes behavior when a URL outside the app's domain is visited. - **visitableDidFailRequest(_:error:retryHandler:)**: Customizes error handling for network or HTTP errors. ``` -------------------------------- ### iOS Path Configuration JSON Source: https://native.hotwired.dev/ios/path-configuration Defines rules for matching URL paths and their associated properties. Use this to set default behaviors like pull-to-refresh and override them for specific patterns. ```json { "settings": {}, "rules": [ { "patterns": [ ".*" ], "properties": { "context": "default", "pull_to_refresh_enabled": true } }, { "patterns": [ "/new$" ], "properties": { "context": "modal", "pull_to_refresh_enabled": false } } ] } ``` -------------------------------- ### Conform View Controller to PathConfigurationIdentifiable Source: https://native.hotwired.dev/ios/native-screens Implement the PathConfigurationIdentifiable protocol to associate a view controller with a specific identifier for path configuration matching. ```swift class NumbersViewController: UITableViewController, PathConfigurationIdentifiable { static var pathConfigurationIdentifier: String { "numbers" } init(url: URL) { self.url = url } // ... } ``` -------------------------------- ### Configure Default Navigation Controller Source: https://native.hotwired.dev/ios/configuration Sets a custom navigation controller for the main and modal stacks. Must be a UINavigationController or subclass. ```swift Hotwire.config.defaultNavigationController = { CustomNavigationController() } ``` -------------------------------- ### Server-Driven Routing (Rails) Source: https://native.hotwired.dev/reference/navigation Helper methods provided by the turbo-rails gem to manipulate the navigation stack from the server. ```APIDOC ## Server-Driven Routing Methods ### Description These methods allow the server to control the navigation stack state, such as dismissing modals or refreshing screens, with a fallback to standard redirects. ### Methods - **recede_or_redirect_to(url, **options)**: Pops any modal screen, then pops the visible screen off the navigation stack. - **refresh_or_redirect_to(url, **options)**: Pops any modal screen, then reloads the visible screen by performing a new web request. - **resume_or_redirect_to(url, **options)**: Pops any modal screen off the navigation stack. ``` -------------------------------- ### Configure SceneDelegate for Hotwire Native Source: https://native.hotwired.dev/ios/getting-started Replaces the default SceneDelegate to initialize the Navigator with a specified root URL and set it as the window's root view controller. ```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(configuration: .init( name: "main", startLocation: rootURL )) func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { window?.rootViewController = navigator.rootViewController navigator.start() } } ``` -------------------------------- ### Configure Internet Permission Source: https://native.hotwired.dev/android/getting-started Add the internet permission to your AndroidManifest.xml file to allow network access. ```xml ``` -------------------------------- ### iOS-specific properties Source: https://native.hotwired.dev/reference/path-configuration Properties for configuring iOS native destinations. ```APIDOC ## iOS-specific properties ### Description Properties for configuring iOS native destinations. ### Parameters #### Request Body - **view_controller** (string) - Optional - The identifier for a native `UIViewController` to navigate to. Conform your custom controller to `PathConfigurationIdentifiable` to it to this identifier. - **modal_style** (string) - Optional - Specifies how a modal should be presented. Make sure to set `context` to `modal`, too. Possible values (defaults to `large`): `large`, `medium`, `full`, `page_sheet`, `form_sheet`. - **modal_dismiss_gesture_enabled** (boolean) - Optional - Whether or not swiping down (or tapping outside the content on iPads) on a modal will dismiss it. Possible values: `true`, `false`. Defaults to `true`. ``` -------------------------------- ### Defining importmap entries manually Source: https://native.hotwired.dev/reference/bridge-installation Manually configure importmap entries in the document head to load Stimulus and Hotwire Native Bridge from a CDN. ```html ``` -------------------------------- ### Register Native Fragments with Hotwire Source: https://native.hotwired.dev/android/native-screens Register your custom native fragments along with HotwireWebFragment for handling regular destinations. This step is crucial for Hotwire Native to recognize and use your fragments. ```kotlin Hotwire.registerFragmentDestinations( HotwireWebFragment::class, // Don't forget to register this for regular destinations NumbersFragment::class ) ``` -------------------------------- ### Importing via npm package Source: https://native.hotwired.dev/reference/bridge-installation Import the library in your application code when using a JavaScript bundler like webpack or esbuild. ```javascript import "@hotwired/hotwire-native-bridge" ``` -------------------------------- ### Registering Bridge Components in AppDelegate Source: https://native.hotwired.dev/ios/bridge-components Register custom bridge components in the `AppDelegate.swift` file using `Hotwire.registerBridgeComponents`. This ensures that Hotwire is configured with your components before the first URL is routed. ```swift import HotwireNative import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { Hotwire.registerBridgeComponents([ ButtonComponent.self ]) return true } } ``` -------------------------------- ### Android-specific properties Source: https://native.hotwired.dev/reference/path-configuration Properties for configuring Android native destinations. ```APIDOC ## Android-specific properties ### Description Properties for configuring Android native destinations. ### Parameters #### Request Body - **uri** (string) - Required - The target destination URI to navigate to. Must map to an Activity or Fragment that has implemented the `HotwireDestinationDeepLink` annotation with a matching `uri` value. - **fallback_uri** (string) - Optional - 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. - **title** (string) - Optional - 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. ``` -------------------------------- ### Android Navigation Actions in HotwireFragment Source: https://native.hotwired.dev/reference/navigation Navigate within a HotwireFragment using the available navigator instance. Supports routing, popping, and clearing the backstack. Animations are controlled by the underlying platform. ```kotlin val location = "https://..." // Visit a new page. avigator.route("$location/foo") // Pop the backstack to the previous destination. avigator.pop() // Clear the navigation backstack to the start destination. avigator.clearAll() ``` -------------------------------- ### Importing and extending BridgeComponent Source: https://native.hotwired.dev/reference/bridge-installation Import the BridgeComponent class to create custom bridge components in your application. ```javascript import { BridgeComponent } from "@hotwired/hotwire-native-bridge" class BridgeTest extends BridgeComponent { // ... } ``` -------------------------------- ### iOS Navigation Actions Source: https://native.hotwired.dev/reference/navigation Use the Navigator to visit new pages, pop the current controller, or clear the entire stack. Animations can be disabled. ```swift let rootURL = URL(string: "...")! let navigator = Navigator() // Visit a new page. avigator.route(rootURL.appending(path: "foo")) // Pop the top controller off the stack. avigator.pop() // Pop the entire stack of controllers. avigator.clearAll() ``` ```swift navigator.route(rootURL.appending(path: "foo"), animated: false) avigator.pop(animated: false) avigator.clearAll(animated: false) ``` -------------------------------- ### Navigator Overview Source: https://native.hotwired.dev/android/reference The Navigator is the central coordinator for managing screens within a Hotwire Native Android application. ```APIDOC ## Navigator 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. ``` -------------------------------- ### Register Fragment Destinations Source: https://native.hotwired.dev/android/configuration Register all fragment destinations that will be used by the application. This includes regular destinations and any custom fragments. ```kotlin Hotwire.registerFragmentDestinations( HotwireWebFragment::class, // Don't forget to register this for regular destinations MyCustomFragment::class ) ``` -------------------------------- ### Route Decision Handlers Source: https://native.hotwired.dev/reference/navigation Customizing how URLs are handled when tapped within the application. ```APIDOC ## Route Decision Handlers ### Description Handlers determine how a URL is opened (e.g., inside the app, in a browser tab, or via system navigation). You can register custom handlers to override default behavior. ### Registration Example (iOS) ```swift Hotwire.registerRouteDecisionHandlers([ AppNavigationRouteDecisionHandler(), MyCustomExternalRouteDecisionHandler() ]) ``` ### Registration Example (Android) ```kotlin Hotwire.registerRouteDecisionHandlers( AppNavigationRouteDecisionHandler(), MyCustomExternalRouteDecisionHandler() ) ``` ``` -------------------------------- ### Configure Custom WebView in Hotwire Native Android Source: https://native.hotwired.dev/android/reference Use this configuration to subclass and customize the HotwireWebView for custom behaviors in your application. Ensure the custom WebView class is correctly defined. ```kotlin Hotwire.config.makeCustomWebView = { context -> MyCustomWebView(context, null) } ``` -------------------------------- ### Disable Native Screen via Path Configuration Source: https://native.hotwired.dev/android/native-screens To disable a native screen and fall back to a web view, remove the "uri" property from the corresponding rule in the Path Configuration. This allows for progressive rollouts or quick disabling of problematic native screens without an app update. ```json { "settings": {}, "rules": [ { "patterns": [ "/numbers$" ], "properties": { } } ] } ``` -------------------------------- ### Rule Definition Source: https://native.hotwired.dev/reference/path-configuration Defines how specific URL patterns should behave using regex matching and property overrides. ```APIDOC ## Rule Definition ### Description Rules are processed sequentially. Properties defined in later rules override those defined in earlier rules for matching URL patterns. ### Parameters - **patterns** (array) - Required - A list of regular expression strings to match against URL paths. - **properties** (object) - Required - Configuration properties to apply when the pattern matches. ### Properties - **context** (string) - Optional - Presentation context. Values: "default", "modal". - **presentation** (string) - Optional - Navigation style. Values: "default", "push", "pop", "replace", "replace_root", "clear_all", "refresh", "none". - **pull_to_refresh_enabled** (boolean) - Optional - Enables pull-to-refresh. - **animated** (boolean) - Optional - Enables navigation animations. ``` -------------------------------- ### Implement Kotlin BridgeComponent Source: https://native.hotwired.dev/android/bridge-components Subclass BridgeComponent in Kotlin to handle incoming messages from the web and trigger native UI actions. ```kotlin class ButtonComponent( name: String, private val delegate: BridgeDelegate<HotwireDestination> ) : BridgeComponent<HotwireDestination>(name, delegate) { override fun onReceive(message: Message) { // Handle incoming messages based on the message `event`. when (message.event) { "connect" -> handleConnectEvent(message) else -> Log.w("ButtonComponent", "Unknown event for message: $message") } } private fun handleConnectEvent(message: Message) { val data = message.data<MessageData>() ?: return // 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. } private fun performButtonClick(): Boolean { return replyTo("connect") } // Use kotlinx.serialization annotations to define a serializable // data class that represents the incoming message.data json. @Serializable data class MessageData( @SerialName("title") val title: String ) } ``` -------------------------------- ### Register Route Decision Handlers for Android Source: https://native.hotwired.dev/reference/navigation Register custom route decision handlers for Android. Handlers are called in the order they are provided. ```kotlin Hotwire.registerRouteDecisionHandlers( AppNavigationRouteDecisionHandler(), MyCustomExternalRouteDecisionHandler() ) ``` -------------------------------- ### Handle Visit Errors Source: https://native.hotwired.dev/ios/reference Customize error handling for network requests or non-200 HTTP responses. The retryHandler can be invoked to reattempt the failed request. ```swift func visitableDidFailRequest(_ visitable: Visitable, error: Error, retryHandler: @escaping () -> Void) { // ... retryHandler() } ``` -------------------------------- ### Handle External URLs Source: https://native.hotwired.dev/ios/reference Customize the behavior for external URLs, which are defined as links not matching the initial domain. The default behavior presents an SFSafariViewController modally. ```swift func handle(externalURL: URL) -> ProposalResult { // ... } ``` -------------------------------- ### Swift BridgeComponent Implementation Source: https://native.hotwired.dev/ios/bridge-components Implement a Swift `BridgeComponent` that matches the Stimulus controller's name. The `onReceive(message:)` method unpacks data from the message to create and configure a native `UIBarButtonItem`. ```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 } } ``` -------------------------------- ### Android Navigation Actions in HotwireActivity Source: https://native.hotwired.dev/reference/navigation Navigate within a HotwireActivity by accessing the current navigator. Supports routing, popping, and clearing the backstack. Animations are controlled by the underlying platform. ```kotlin val location = "https://..." val navigator = delegate.currentNavigator // Visit a new page. avigator?.route("$location/foo") // Pop the backstack to the previous destination. avigator?.pop() // Clear the navigation backstack to the start destination. avigator?.clearAll() ``` -------------------------------- ### Register Bridge Components Source: https://native.hotwired.dev/ios/configuration Registers bridge components to enable communication between the web and native layers. ```swift Hotwire.registerBridgeComponents([ FormComponent.self, MenuComponent.self, OverflowMenuComponent.self, // ... ]) ``` -------------------------------- ### Create Stimulus BridgeComponent Controller Source: https://native.hotwired.dev/android/bridge-components Define a JavaScript controller that extends BridgeComponent to send messages to the native layer. ```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() }) } } ``` -------------------------------- ### Register Bridge Components Source: https://native.hotwired.dev/android/bridge-components Register the component factory in your Application subclass to link the Stimulus controller name to the Kotlin class. ```kotlin Hotwire.registerBridgeComponents( BridgeComponentFactory("button", ::ButtonComponent) ) ``` -------------------------------- ### HTML Form with Bridge Component Data Attributes Source: https://native.hotwired.dev/reference/bridge-components Use this HTML structure for a form that integrates with a native 'form' component. Ensure the data-controller attribute matches the bridge component name. ```html <form method="post" data-controller="bridge--form"> <!-- form elements --> <button class="button" type="submit" data-bridge--form-target="submit" data-bridge-title="Submit"> Submit Form </button> </form> ``` -------------------------------- ### Custom HTML Data Attributes Source: https://native.hotwired.dev/android/reference Provides custom data attributes for controlling WebView behaviors within the web app. ```APIDOC ## Custom HTML data attributes * `data-native-prevent-pull-to-refresh`: Apply to any element in your web app whose touch events conflict with the native pull-to-refresh behavior in the `WebView`. By default, scrollable elements prevent pull-to-refresh, but you may need to apply this custom attribute to elements that have draggable or swipeable behaviors. ``` -------------------------------- ### Register Route Decision Handlers for iOS Source: https://native.hotwired.dev/reference/navigation Register custom route decision handlers for iOS. Ensure your custom handlers are registered in the desired order of precedence. ```swift Hotwire.registerRouteDecisionHandlers([ AppNavigationRouteDecisionHandler(), MyCustomExternalRouteDecisionHandler() ]) ``` -------------------------------- ### Register Bridge Components Source: https://native.hotwired.dev/android/configuration Register bridge components that will be used for communication between Stimulus and the native application. The first argument is the component name to match in Stimulus. ```kotlin Hotwire.registerBridgeComponents( BridgeComponentFactory("my-custom", ::MyCustomComponent) ) ``` -------------------------------- ### Disable Query String Matching Source: https://native.hotwired.dev/ios/path-configuration Globally disable query string matching for path configurations in Hotwire Native. This simplifies matching when query parameters are not relevant. ```swift Hotwire.config.pathConfiguration.matchQueryStrings = false ``` -------------------------------- ### Set JSON Converter Source: https://native.hotwired.dev/android/configuration Set the JSON converter used for bridge components. This allows for custom JSON serialization and deserialization. ```kotlin Hotwire.config.jsonConverter = KotlinXJsonConverter() ``` -------------------------------- ### Set Default Fragment Destination Source: https://native.hotwired.dev/android/configuration Set the default fragment destination for Hotwire Native Android. This specifies which fragment to use when no specific destination is provided. ```kotlin Hotwire.defaultFragmentDestination = HotwireWebFragment::class ``` -------------------------------- ### Hide Web Elements via CSS Source: https://native.hotwired.dev/android/bridge-components Use CSS selectors to hide web-based elements when the native bridge component is active. ```css [data-bridge-components~="button"] [data-controller~="button"] { display: none; } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.