diff --git a/.changes/app-bound-domains.md b/.changes/app-bound-domains.md
new file mode 100644
index 000000000000..ea5a24f56939
--- /dev/null
+++ b/.changes/app-bound-domains.md
@@ -0,0 +1,8 @@
+---
+"tauri": minor:feat
+"tauri-runtime": minor:feat
+"tauri-runtime-wry": minor:feat
+"tauri-utils": minor:feat
+---
+
+Add `WebviewBuilder::limit_navigations_to_app_bound_domains`, `WebviewWindowBuilder::limit_navigations_to_app_bound_domains`, and limitNavigationsToAppBoundDomains to tauri.config.json.
diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json
index 4022d224f363..f62f28ee4ddd 100644
--- a/crates/tauri-cli/config.schema.json
+++ b/crates/tauri-cli/config.schema.json
@@ -614,6 +614,11 @@
}
]
},
+ "limitNavigationsToAppBoundDomains": {
+ "description": "Whether to limit navigations to App-Bound Domains. This is necessary to\n enable Service Workers on iOS according to\n [StackOverflow](https://stackoverflow.com/questions/49673399/service-workers-unavailable-in-wkwebview-in-ios-11-3/64155509#64155509).\n\n Default is false.\n\n Note: If you set this to `true` make sure to add localhost and any [`registrable\n domains`](https://developer.mozilla.org/en-US/docs/Glossary/Registrable_domain)\n used in this webview to tauri-src/Info.ios.plist:\n\n ```xml\n \n \n WKAppBoundDomains\n \n localhost\n aregistrabledomain.example\n \n \n \n ```\n\n You must add `localhost` if any webview with this set to true opens a\n local webpage, makes any localhost calls, or uses the isolation pattern\n because Tauri uses the `localhost` domain for hosting the application\n webpage, the IPC protocol, and the isolation pattern's iframe.\n\n Requests served through custom uri schemes are allowed so long as they use\n a registrable domain specified in the `WKAppBoundDomains` array for all the\n requests from the app, including requests for the `localhost` domain.\n\n In theory, you can whitelist an entire uri scheme by including the\n protocol name followed by a colon. For example, to allow all requests\n using a custom \"stream\" uri scheme (see [this tauri\n example](https://github.com/tauri-apps/tauri/blob/dev/examples/streaming/main.rs)),\n you could add `stream:` to the AppBoundDomains array. That said, I'm not\n sure whether Apple would let your app through app review if you do\n whitelist an entire protocol because this feature is not mentioned in\n [their blog post on App-Bound\n Domains](https://webkit.org/blog/10882/app-bound-domains/).\n\n See https://webkit.org/blog/10882/app-bound-domains/ and\n https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/limitsnavigationstoappbounddomains\n for the official documentation on App-Bound Domains.\n\n ## Platform-specific\n\n - **iOS**: Supported since version 14.0+.\n - **Linux / Windows / Android / MacOS:** Unsupported.",
+ "default": false,
+ "type": "boolean"
+ },
"activityName": {
"description": "The name of the Android activity to create for this window.",
"type": [
diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs
index 8a3da8d31fdc..178ad2ce4905 100644
--- a/crates/tauri-runtime-wry/src/lib.rs
+++ b/crates/tauri-runtime-wry/src/lib.rs
@@ -5051,6 +5051,10 @@ You may have it installed on another user account, but it is not available for t
#[cfg(target_os = "ios")]
{
+ webview_builder = webview_builder.with_limit_navigations_to_app_bound_domains(
+ webview_attributes.limit_navigations_to_app_bound_domains,
+ );
+
if let Some(input_accessory_view_builder) = webview_attributes.input_accessory_view_builder {
webview_builder = webview_builder
.with_input_accessory_view_builder(move |webview| input_accessory_view_builder.0(webview));
diff --git a/crates/tauri-runtime/src/webview.rs b/crates/tauri-runtime/src/webview.rs
index 8700041e9353..61bc15d0366b 100644
--- a/crates/tauri-runtime/src/webview.rs
+++ b/crates/tauri-runtime/src/webview.rs
@@ -402,6 +402,8 @@ pub struct WebviewAttributes {
/// This relies on [`objc2_ui_kit`] which does not provide a stable API yet, so it can receive breaking changes in minor releases.
#[cfg(target_os = "ios")]
pub input_accessory_view_builder: Option,
+ #[cfg(target_os = "ios")]
+ pub limit_navigations_to_app_bound_domains: bool,
/// Set the environment for the webview.
/// Useful if you need to share the same environment, for instance when using the [`PendingWebview::new_window_handler`].
@@ -460,6 +462,7 @@ impl From<&WindowConfig> for WebviewAttributes {
ConfigScrollBarStyle::FluentOverlay => ScrollBarStyle::FluentOverlay,
_ => ScrollBarStyle::Default,
})
+ .limit_navigations_to_app_bound_domains(config.limit_navigations_to_app_bound_domains)
.general_autofill_enabled(config.general_autofill_enabled);
#[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
@@ -538,6 +541,8 @@ impl WebviewAttributes {
general_autofill_enabled: true,
#[cfg(target_os = "ios")]
input_accessory_view_builder: None,
+ #[cfg(target_os = "ios")]
+ limit_navigations_to_app_bound_domains: false,
#[cfg(windows)]
environment: None,
#[cfg(any(
@@ -791,6 +796,65 @@ impl WebviewAttributes {
self
}
+ /// Whether to limit navigations to App-Bound Domains. This is necessary to
+ /// enable Service Workers on iOS according to
+ /// [StackOverflow](https://stackoverflow.com/questions/49673399/service-workers-unavailable-in-wkwebview-in-ios-11-3/64155509#64155509).
+ ///
+ /// Default is false.
+ ///
+ /// Note: If you pass in `true` make sure to add localhost and any [`registrable
+ /// domains`](https://developer.mozilla.org/en-US/docs/Glossary/Registrable_domain)
+ /// used in this webview to tauri-src/Info.ios.plist:
+ ///
+ /// ```xml
+ ///
+ ///
+ /// WKAppBoundDomains
+ ///
+ /// localhost
+ /// aregistrabledomain.example
+ ///
+ ///
+ ///
+ /// ```
+ ///
+ /// You must add `localhost` if any webview with this set to true opens a
+ /// local webpage, makes any localhost calls, or uses the isolation pattern
+ /// because Tauri uses the `localhost` domain for hosting the application
+ /// webpage, the IPC protocol, and the isolation pattern's iframe.
+ ///
+ /// Requests served through custom uri schemes are allowed so long as they use
+ /// a registrable domain specified in the `WKAppBoundDomains` array for all the
+ /// requests from the app, including requests for the `localhost` domain.
+ ///
+ /// In theory, you can whitelist an entire uri scheme by including the
+ /// protocol name followed by a colon. For example, to allow all requests
+ /// using a custom "stream" uri scheme (see [this tauri
+ /// example](https://github.com/tauri-apps/tauri/blob/dev/examples/streaming/main.rs)),
+ /// you could add `stream:` to the AppBoundDomains array. That said, I'm not
+ /// sure whether Apple would let your app through app review if you do
+ /// whitelist an entire protocol because this feature is not mentioned in
+ /// [their blog post on App-Bound
+ /// Domains](https://webkit.org/blog/10882/app-bound-domains/).
+ ///
+ /// See https://webkit.org/blog/10882/app-bound-domains/ and
+ /// https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/limitsnavigationstoappbounddomains
+ /// for the official documentation on App-Bound Domains.
+ ///
+ /// ## Platform-specific
+ ///
+ /// - **iOS**: Supported since version 14.0+.
+ /// - **Linux / Windows / Android / MacOS:** Unsupported.
+ #[must_use]
+ #[allow(unused_variables, unused_mut)]
+ pub fn limit_navigations_to_app_bound_domains(mut self, limit_navigations: bool) -> Self {
+ #[cfg(target_os = "ios")]
+ {
+ self.limit_navigations_to_app_bound_domains = limit_navigations;
+ }
+ self
+ }
+
/// Change the default background throttling behavior.
///
/// By default, browsers use a suspend policy that will throttle timers and even unload
diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json
index 4022d224f363..f62f28ee4ddd 100644
--- a/crates/tauri-schema-generator/schemas/config.schema.json
+++ b/crates/tauri-schema-generator/schemas/config.schema.json
@@ -614,6 +614,11 @@
}
]
},
+ "limitNavigationsToAppBoundDomains": {
+ "description": "Whether to limit navigations to App-Bound Domains. This is necessary to\n enable Service Workers on iOS according to\n [StackOverflow](https://stackoverflow.com/questions/49673399/service-workers-unavailable-in-wkwebview-in-ios-11-3/64155509#64155509).\n\n Default is false.\n\n Note: If you set this to `true` make sure to add localhost and any [`registrable\n domains`](https://developer.mozilla.org/en-US/docs/Glossary/Registrable_domain)\n used in this webview to tauri-src/Info.ios.plist:\n\n ```xml\n \n \n WKAppBoundDomains\n \n localhost\n aregistrabledomain.example\n \n \n \n ```\n\n You must add `localhost` if any webview with this set to true opens a\n local webpage, makes any localhost calls, or uses the isolation pattern\n because Tauri uses the `localhost` domain for hosting the application\n webpage, the IPC protocol, and the isolation pattern's iframe.\n\n Requests served through custom uri schemes are allowed so long as they use\n a registrable domain specified in the `WKAppBoundDomains` array for all the\n requests from the app, including requests for the `localhost` domain.\n\n In theory, you can whitelist an entire uri scheme by including the\n protocol name followed by a colon. For example, to allow all requests\n using a custom \"stream\" uri scheme (see [this tauri\n example](https://github.com/tauri-apps/tauri/blob/dev/examples/streaming/main.rs)),\n you could add `stream:` to the AppBoundDomains array. That said, I'm not\n sure whether Apple would let your app through app review if you do\n whitelist an entire protocol because this feature is not mentioned in\n [their blog post on App-Bound\n Domains](https://webkit.org/blog/10882/app-bound-domains/).\n\n See https://webkit.org/blog/10882/app-bound-domains/ and\n https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/limitsnavigationstoappbounddomains\n for the official documentation on App-Bound Domains.\n\n ## Platform-specific\n\n - **iOS**: Supported since version 14.0+.\n - **Linux / Windows / Android / MacOS:** Unsupported.",
+ "default": false,
+ "type": "boolean"
+ },
"activityName": {
"description": "The name of the Android activity to create for this window.",
"type": [
diff --git a/crates/tauri-utils/src/config.rs b/crates/tauri-utils/src/config.rs
index e7d4afec9a04..4297760ae58b 100644
--- a/crates/tauri-utils/src/config.rs
+++ b/crates/tauri-utils/src/config.rs
@@ -2282,6 +2282,58 @@ pub struct WindowConfig {
/// - **Linux / Android / iOS / macOS**: Unsupported. Only supports `Default` and performs no operation.
#[serde(default, alias = "scroll-bar-style")]
pub scroll_bar_style: ScrollBarStyle,
+
+ /// Whether to limit navigations to App-Bound Domains. This is necessary to
+ /// enable Service Workers on iOS according to
+ /// [StackOverflow](https://stackoverflow.com/questions/49673399/service-workers-unavailable-in-wkwebview-in-ios-11-3/64155509#64155509).
+ ///
+ /// Default is false.
+ ///
+ /// Note: If you set this to `true` make sure to add localhost and any [`registrable
+ /// domains`](https://developer.mozilla.org/en-US/docs/Glossary/Registrable_domain)
+ /// used in this webview to tauri-src/Info.ios.plist:
+ ///
+ /// ```xml
+ ///
+ ///
+ /// WKAppBoundDomains
+ ///
+ /// localhost
+ /// aregistrabledomain.example
+ ///
+ ///
+ ///
+ /// ```
+ ///
+ /// You must add `localhost` if any webview with this set to true opens a
+ /// local webpage, makes any localhost calls, or uses the isolation pattern
+ /// because Tauri uses the `localhost` domain for hosting the application
+ /// webpage, the IPC protocol, and the isolation pattern's iframe.
+ ///
+ /// Requests served through custom uri schemes are allowed so long as they use
+ /// a registrable domain specified in the `WKAppBoundDomains` array for all the
+ /// requests from the app, including requests for the `localhost` domain.
+ ///
+ /// In theory, you can whitelist an entire uri scheme by including the
+ /// protocol name followed by a colon. For example, to allow all requests
+ /// using a custom "stream" uri scheme (see [this tauri
+ /// example](https://github.com/tauri-apps/tauri/blob/dev/examples/streaming/main.rs)),
+ /// you could add `stream:` to the AppBoundDomains array. That said, I'm not
+ /// sure whether Apple would let your app through app review if you do
+ /// whitelist an entire protocol because this feature is not mentioned in
+ /// [their blog post on App-Bound
+ /// Domains](https://webkit.org/blog/10882/app-bound-domains/).
+ ///
+ /// See https://webkit.org/blog/10882/app-bound-domains/ and
+ /// https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/limitsnavigationstoappbounddomains
+ /// for the official documentation on App-Bound Domains.
+ ///
+ /// ## Platform-specific
+ ///
+ /// - **iOS**: Supported since version 14.0+.
+ /// - **Linux / Windows / Android / MacOS:** Unsupported.
+ #[serde(default, alias = "limit-navigations-to-app-bound-domains")]
+ pub limit_navigations_to_app_bound_domains: bool,
/// The name of the Android activity to create for this window.
#[serde(default, alias = "activity-name")]
pub activity_name: Option,
@@ -2379,6 +2431,7 @@ impl Default for WindowConfig {
data_directory: None,
data_store_identifier: None,
scroll_bar_style: ScrollBarStyle::Default,
+ limit_navigations_to_app_bound_domains: false,
activity_name: None,
created_by_activity_name: None,
requested_by_scene_identifier: None,
@@ -3956,6 +4009,7 @@ mod build {
let data_directory = opt_lit(self.data_directory.as_ref().map(path_buf_lit).as_ref());
let data_store_identifier = opt_vec_lit(self.data_store_identifier, identity);
let scroll_bar_style = &self.scroll_bar_style;
+ let limit_navigations_to_app_bound_domains = self.limit_navigations_to_app_bound_domains;
let activity_name = opt_lit(self.activity_name.as_ref());
let created_by_activity_name = opt_lit(self.created_by_activity_name.as_ref());
let requested_by_scene_identifier = opt_lit(self.requested_by_scene_identifier.as_ref());
@@ -4022,6 +4076,7 @@ mod build {
data_directory,
data_store_identifier,
scroll_bar_style,
+ limit_navigations_to_app_bound_domains,
activity_name,
created_by_activity_name,
requested_by_scene_identifier,
diff --git a/crates/tauri/src/webview/mod.rs b/crates/tauri/src/webview/mod.rs
index fba41cf321dd..a56ba676371a 100644
--- a/crates/tauri/src/webview/mod.rs
+++ b/crates/tauri/src/webview/mod.rs
@@ -1221,6 +1221,62 @@ fn main() {
.allow_link_preview(allow_link_preview);
self
}
+ /// Whether to limit navigations to App-Bound Domains. This is necessary to
+ /// enable Service Workers on iOS according to
+ /// [StackOverflow](https://stackoverflow.com/questions/49673399/service-workers-unavailable-in-wkwebview-in-ios-11-3/64155509#64155509).
+ ///
+ /// Default is false.
+ ///
+ /// Note: If you pass in `true` make sure to add localhost and any [`registrable
+ /// domains`](https://developer.mozilla.org/en-US/docs/Glossary/Registrable_domain)
+ /// used in this webview to tauri-src/Info.ios.plist:
+ ///
+ /// ```xml
+ ///
+ ///
+ /// WKAppBoundDomains
+ ///
+ /// localhost
+ /// aregistrabledomain.example
+ ///
+ ///
+ ///
+ /// ```
+ ///
+ /// You must add `localhost` if any webview with this set to true opens a
+ /// local webpage, makes any localhost calls, or uses the isolation pattern
+ /// because Tauri uses the `localhost` domain for hosting the application
+ /// webpage, the IPC protocol, and the isolation pattern's iframe.
+ ///
+ /// Requests served through custom uri schemes are allowed so long as they use
+ /// a registrable domain specified in the `WKAppBoundDomains` array for all the
+ /// requests from the app, including requests for the `localhost` domain.
+ ///
+ /// In theory, you can whitelist an entire uri scheme by including the
+ /// protocol name followed by a colon. For example, to allow all requests
+ /// using a custom "stream" uri scheme (see [this tauri
+ /// example](https://github.com/tauri-apps/tauri/blob/dev/examples/streaming/main.rs)),
+ /// you could add `stream:` to the AppBoundDomains array. That said, I'm not
+ /// sure whether Apple would let your app through app review if you do
+ /// whitelist an entire protocol because this feature is not mentioned in
+ /// [their blog post on App-Bound
+ /// Domains](https://webkit.org/blog/10882/app-bound-domains/).
+ ///
+ /// See https://webkit.org/blog/10882/app-bound-domains/ and
+ /// https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/limitsnavigationstoappbounddomains
+ /// for the official documentation on App-Bound Domains.
+ ///
+ /// ## Platform-specific
+ ///
+ /// - **iOS**: Supported since version 14.0+.
+ /// - **Linux / Windows / Android / MacOS:** Unsupported.
+ #[must_use]
+ pub fn limit_navigations_to_app_bound_domains(mut self, limit_navigations: bool) -> Self {
+ self.webview_attributes = self
+ .webview_attributes
+ .limit_navigations_to_app_bound_domains(limit_navigations);
+ self
+ }
/// Allows overriding the keyboard accessory view on iOS.
/// Returning `None` effectively removes the view.
diff --git a/crates/tauri/src/webview/webview_window.rs b/crates/tauri/src/webview/webview_window.rs
index 5be5d441eafa..dea14ad5e49f 100644
--- a/crates/tauri/src/webview/webview_window.rs
+++ b/crates/tauri/src/webview/webview_window.rs
@@ -1322,6 +1322,62 @@ impl> WebviewWindowBuilder<'_, R, M> {
self
}
+ /// Whether to limit navigations to App-Bound Domains. This is necessary to
+ /// enable Service Workers on iOS according to
+ /// [StackOverflow](https://stackoverflow.com/questions/49673399/service-workers-unavailable-in-wkwebview-in-ios-11-3/64155509#64155509).
+ ///
+ /// Default is false.
+ ///
+ /// Note: If you pass in `true` make sure to add localhost and any [`registrable
+ /// domains`](https://developer.mozilla.org/en-US/docs/Glossary/Registrable_domain)
+ /// used in this webview to tauri-src/Info.ios.plist:
+ ///
+ /// ```xml
+ ///
+ ///
+ /// WKAppBoundDomains
+ ///
+ /// localhost
+ /// aregistrabledomain.example
+ ///
+ ///
+ ///
+ /// ```
+ ///
+ /// You must add `localhost` if any webview with this set to true opens a
+ /// local webpage, makes any localhost calls, or uses the isolation pattern
+ /// because Tauri uses the `localhost` domain for hosting the application
+ /// webpage, the IPC protocol, and the isolation pattern's iframe.
+ ///
+ /// Requests served through custom uri schemes are allowed so long as they use
+ /// a registrable domain specified in the `WKAppBoundDomains` array for all the
+ /// requests from the app, including requests for the `localhost` domain.
+ ///
+ /// In theory, you can whitelist an entire uri scheme by including the
+ /// protocol name followed by a colon. For example, to allow all requests
+ /// using a custom "stream" uri scheme (see [this tauri
+ /// example](https://github.com/tauri-apps/tauri/blob/dev/examples/streaming/main.rs)),
+ /// you could add `stream:` to the AppBoundDomains array. That said, I'm not
+ /// sure whether Apple would let your app through app review if you do
+ /// whitelist an entire protocol because this feature is not mentioned in
+ /// [their blog post on App-Bound
+ /// Domains](https://webkit.org/blog/10882/app-bound-domains/).
+ ///
+ /// See https://webkit.org/blog/10882/app-bound-domains/ and
+ /// https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/limitsnavigationstoappbounddomains
+ /// for the official documentation on App-Bound Domains.
+ ///
+ /// ## Platform-specific
+ ///
+ /// - **iOS**: Supported since version 14.0+.
+ /// - **Linux / Windows / Android / MacOS:** Unsupported.
+ pub fn limit_navigations_to_app_bound_domains(mut self, limit_navigations: bool) -> Self {
+ self.webview_builder = self
+ .webview_builder
+ .limit_navigations_to_app_bound_domains(limit_navigations);
+ self
+ }
+
/// Set the environment for the webview.
/// Useful if you need to share the same environment, for instance when using the [`Self::on_new_window`].
#[cfg(all(feature = "wry", windows))]