Skip to content

Commit 5908972

Browse files
feat(api): add dataDirectory setting config (#14091)
* feat(api): ad dataDirectory setting config * changefile fmt * chain, log if dirs::data_local_dir fails --------- Co-authored-by: Lucas Nogueira <lucas@tauri.app>
1 parent 1a6627e commit 5908972

File tree

6 files changed

+147
-2
lines changed

6 files changed

+147
-2
lines changed

.changes/data-dir-js.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"tauri-utils": "minor:enhance"
3+
"@tauri-apps/api": "minor:enhance"
4+
---
5+
6+
Added a config to set a data_directory relative to the app-specific data dir in JavaScript and `tauri.conf.json`.

crates/tauri-cli/config.schema.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,27 @@
572572
"description": "Allows disabling the input accessory view on iOS.\n\n The accessory view is the view that appears above the keyboard when a text input element is focused.\n It usually displays a view with \"Done\", \"Next\" buttons.",
573573
"default": false,
574574
"type": "boolean"
575+
},
576+
"dataDirectory": {
577+
"description": "Set a custom path for the webview's data directory (localStorage, cache, etc.) **relative to [`appDataDir()`]/${label}**.\n\n To set absolute paths, use [`WebviewWindowBuilder::data_directory`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.data_directory)\n\n #### Platform-specific:\n\n - **Windows**: WebViews with different values for settings like `additionalBrowserArgs`, `browserExtensionsEnabled` or `scrollBarStyle` must have different data directories.\n - **macOS / iOS**: Unsupported, use `dataStoreIdentifier` instead.\n - **Android**: Unsupported.",
578+
"type": [
579+
"string",
580+
"null"
581+
]
582+
},
583+
"dataStoreIdentifier": {
584+
"description": "Initialize the WebView with a custom data store identifier. This can be seen as a replacement for `dataDirectory` which is unavailable in WKWebView.\n See https://developer.apple.com/documentation/webkit/wkwebsitedatastore/init(foridentifier:)?language=objc\n\n The array must contain 16 u8 numbers.\n\n #### Platform-specific:\n\n - **iOS**: Supported since version 17.0+.\n - **macOS**: Supported since version 14.0+.\n - **Windows / Linux / Android**: Unsupported.",
585+
"type": [
586+
"array",
587+
"null"
588+
],
589+
"items": {
590+
"type": "integer",
591+
"format": "uint8",
592+
"minimum": 0.0
593+
},
594+
"maxItems": 16,
595+
"minItems": 16
575596
}
576597
},
577598
"additionalProperties": false

crates/tauri-schema-generator/schemas/config.schema.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,27 @@
572572
"description": "Allows disabling the input accessory view on iOS.\n\n The accessory view is the view that appears above the keyboard when a text input element is focused.\n It usually displays a view with \"Done\", \"Next\" buttons.",
573573
"default": false,
574574
"type": "boolean"
575+
},
576+
"dataDirectory": {
577+
"description": "Set a custom path for the webview's data directory (localStorage, cache, etc.) **relative to [`appDataDir()`]/${label}**.\n\n To set absolute paths, use [`WebviewWindowBuilder::data_directory`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.data_directory)\n\n #### Platform-specific:\n\n - **Windows**: WebViews with different values for settings like `additionalBrowserArgs`, `browserExtensionsEnabled` or `scrollBarStyle` must have different data directories.\n - **macOS / iOS**: Unsupported, use `dataStoreIdentifier` instead.\n - **Android**: Unsupported.",
578+
"type": [
579+
"string",
580+
"null"
581+
]
582+
},
583+
"dataStoreIdentifier": {
584+
"description": "Initialize the WebView with a custom data store identifier. This can be seen as a replacement for `dataDirectory` which is unavailable in WKWebView.\n See https://developer.apple.com/documentation/webkit/wkwebsitedatastore/init(foridentifier:)?language=objc\n\n The array must contain 16 u8 numbers.\n\n #### Platform-specific:\n\n - **iOS**: Supported since version 17.0+.\n - **macOS**: Supported since version 14.0+.\n - **Windows / Linux / Android**: Unsupported.",
585+
"type": [
586+
"array",
587+
"null"
588+
],
589+
"items": {
590+
"type": "integer",
591+
"format": "uint8",
592+
"minimum": 0.0
593+
},
594+
"maxItems": 16,
595+
"minItems": 16
575596
}
576597
},
577598
"additionalProperties": false

crates/tauri-utils/src/config.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1894,6 +1894,31 @@ pub struct WindowConfig {
18941894
alias = "disable_input_accessory_view"
18951895
)]
18961896
pub disable_input_accessory_view: bool,
1897+
///
1898+
/// Set a custom path for the webview's data directory (localStorage, cache, etc.) **relative to [`appDataDir()`]/${label}**.
1899+
///
1900+
/// To set absolute paths, use [`WebviewWindowBuilder::data_directory`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.data_directory)
1901+
///
1902+
/// #### Platform-specific:
1903+
///
1904+
/// - **Windows**: WebViews with different values for settings like `additionalBrowserArgs`, `browserExtensionsEnabled` or `scrollBarStyle` must have different data directories.
1905+
/// - **macOS / iOS**: Unsupported, use `dataStoreIdentifier` instead.
1906+
/// - **Android**: Unsupported.
1907+
#[serde(default, alias = "data-directory")]
1908+
pub data_directory: Option<PathBuf>,
1909+
///
1910+
/// Initialize the WebView with a custom data store identifier. This can be seen as a replacement for `dataDirectory` which is unavailable in WKWebView.
1911+
/// See https://developer.apple.com/documentation/webkit/wkwebsitedatastore/init(foridentifier:)?language=objc
1912+
///
1913+
/// The array must contain 16 u8 numbers.
1914+
///
1915+
/// #### Platform-specific:
1916+
///
1917+
/// - **iOS**: Supported since version 17.0+.
1918+
/// - **macOS**: Supported since version 14.0+.
1919+
/// - **Windows / Linux / Android**: Unsupported.
1920+
#[serde(default, alias = "data-store-identifier")]
1921+
pub data_store_identifier: Option<[u8; 16]>,
18971922
}
18981923

18991924
impl Default for WindowConfig {
@@ -1953,6 +1978,8 @@ impl Default for WindowConfig {
19531978
javascript_disabled: false,
19541979
allow_link_preview: true,
19551980
disable_input_accessory_view: false,
1981+
data_directory: None,
1982+
data_store_identifier: None,
19561983
}
19571984
}
19581985
}
@@ -3459,6 +3486,8 @@ mod build {
34593486
let javascript_disabled = self.javascript_disabled;
34603487
let allow_link_preview = self.allow_link_preview;
34613488
let disable_input_accessory_view = self.disable_input_accessory_view;
3489+
let data_directory = opt_lit(self.data_directory.as_ref().map(path_buf_lit).as_ref());
3490+
let data_store_identifier = opt_vec_lit(self.data_store_identifier, identity);
34623491

34633492
literal_struct!(
34643493
tokens,
@@ -3516,7 +3545,9 @@ mod build {
35163545
background_throttling,
35173546
javascript_disabled,
35183547
allow_link_preview,
3519-
disable_input_accessory_view
3548+
disable_input_accessory_view,
3549+
data_directory,
3550+
data_store_identifier
35203551
);
35213552
}
35223553
}

crates/tauri/src/webview/mod.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ use crate::{
4242
InvokeError, InvokeMessage, InvokeResolver, Origin, OwnedInvokeResponder, ScopeObject,
4343
},
4444
manager::AppManager,
45+
path::SafePathBuf,
4546
sealed::{ManagerBase, RuntimeOrDispatch},
4647
AppHandle, Emitter, Event, EventId, EventLoopMessage, EventName, Listener, Manager,
4748
ResourceTable, Runtime, Window,
@@ -387,9 +388,47 @@ async fn create_window(app: tauri::AppHandle) {
387388
///
388389
/// [the Webview2 issue]: https://github.com/tauri-apps/wry/issues/583
389390
pub fn from_config(config: &WindowConfig) -> Self {
391+
let mut config = config.to_owned();
392+
393+
if let Some(data_directory) = &config.data_directory {
394+
let resolve_data_dir_res = dirs::data_local_dir()
395+
.or({
396+
#[cfg(feature = "tracing")]
397+
tracing::error!("failed to resolve data directory");
398+
None
399+
})
400+
.and_then(|local_dir| {
401+
SafePathBuf::new(data_directory.clone())
402+
.inspect_err(|_err| {
403+
#[cfg(feature = "tracing")]
404+
tracing::error!(
405+
"data_directory `{}` is not a safe path, ignoring config. Validation error was: {_err}",
406+
data_directory.display()
407+
);
408+
})
409+
.map(|p| (local_dir, p))
410+
.ok()
411+
})
412+
.and_then(|(local_dir, data_directory)| {
413+
if data_directory.as_ref().is_relative() {
414+
Some(local_dir.join(&config.label).join(data_directory.as_ref()))
415+
} else {
416+
#[cfg(feature = "tracing")]
417+
tracing::error!(
418+
"data_directory `{}` is not a relative path, ignoring config.",
419+
data_directory.display()
420+
);
421+
None
422+
}
423+
});
424+
if let Some(resolved_data_directory) = resolve_data_dir_res {
425+
config.data_directory = Some(resolved_data_directory);
426+
}
427+
}
428+
390429
Self {
391430
label: config.label.clone(),
392-
webview_attributes: WebviewAttributes::from(config),
431+
webview_attributes: WebviewAttributes::from(&config),
393432
web_resource_request_handler: None,
394433
navigation_handler: None,
395434
new_window_handler: None,

packages/api/src/webview.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,33 @@ interface WebviewOptions {
854854
* It usually displays a view with "Done", "Next" buttons.
855855
*/
856856
disableInputAccessoryView?: boolean
857+
/**
858+
* Set a custom path for the webview's data directory (localStorage, cache, etc.) **relative to [`appDataDir()`]/${label}**.
859+
* For security reasons, paths outside of that location can only be configured on the Rust side.
860+
*
861+
* #### Platform-specific:
862+
*
863+
* - **Windows**: WebViews with different values for settings like `additionalBrowserArgs`, `browserExtensionsEnabled` or `scrollBarStyle` must have different data directories.
864+
* - **macOS / iOS**: Unsupported, use `dataStoreIdentifier` instead.
865+
* - **Android**: Unsupported.
866+
*
867+
* @since 2.9.0
868+
*/
869+
dataDirectory?: string
870+
/**
871+
* Initialize the WebView with a custom data store identifier. This can be seen as a replacement for `dataDirectory` which is unavailable in WKWebView.
872+
* See https://developer.apple.com/documentation/webkit/wkwebsitedatastore/init(foridentifier:)?language=objc
873+
*
874+
* The array must contain 16 u8 numbers.
875+
*
876+
* #### Platform-specific:
877+
*
878+
* - **macOS / iOS**: Available on macOS >= 14 and iOS >= 17
879+
* - **Windows / Linux / Android**: Unsupported.
880+
*
881+
* @since 2.9.0
882+
*/
883+
dataStoreIdentifier?: number[]
857884
}
858885

859886
export { Webview, getCurrentWebview, getAllWebviews }

0 commit comments

Comments
 (0)