From 3d62fbf021994c3a6291a74d127527e49e699a91 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Wed, 27 Nov 2024 01:40:55 -0600 Subject: [PATCH] Fix base path on web and fullstack (#3247) * Create a crate for constant serialization of config structs for manganis * use SerializeConst for the image asset builder * switch to a declarative macro for assets * clean up asset macro a bit * add serializable options for each asset type * serialize const vec * Add unique path formatting * implement the new manganis macro * optimize assets in the CLI * Fix clippy * Fix assets with dioxus formattable * reduce fuzzing test limits * use the new syntax in examples * fix formatting * Final doc and test pass on const-serialize * fix avif support * Fix manganis doc tests * cache asset optimization * Split out asset and bundled asset * make hash pointer width independent * remove const serialize cargo lock * Fix manganis macro docs * all tests passing * add constvec::is_empty method to fix clippy lint * remove nasm feature * simplify test_rsplit_once test so typos passes * fix range syntax for stable * revert example change from clippy fix * remove dioxus-static-site-generation workspace dependency * always accept unix paths * fix windows path seperator * fix folder asset hash * Optimize assets in a blocking task * Fix asset options docs * Document Asset and BundledAsset * move manganis back into it's own folder * simplify the linker macro a bit * add more docs to AssetParser expansion * fix manganis core doc test * add image format helpers * Fill in new cargo.tomls * fix folders with explicit options * Split by both unix and windows path separators and take the smallest one * fix string length * Fix base path on web and fullstack * Fix assets with base path * fix fullstack base route with trailing slash * fix clippy --- Cargo.lock | 5 ++ packages/cli-config/Cargo.toml | 4 ++ packages/cli-config/src/lib.rs | 76 +++++++++++++++++++- packages/cli/src/build/request.rs | 10 +++ packages/cli/src/build/web.rs | 9 +++ packages/cli/src/config/web.rs | 12 +++- packages/cli/src/serve/handle.rs | 14 +++- packages/cli/src/serve/mod.rs | 4 +- packages/cli/src/serve/runner.rs | 13 ++-- packages/dioxus/Cargo.toml | 3 +- packages/dioxus/src/launch.rs | 13 ++++ packages/fullstack/src/render.rs | 17 ++++- packages/fullstack/src/server/launch.rs | 40 ++++++++++- packages/history/src/memory.rs | 31 ++++++-- packages/manganis/manganis-core/Cargo.toml | 3 +- packages/manganis/manganis-core/src/asset.rs | 17 ++++- packages/router/src/components/link.rs | 4 +- packages/router/src/contexts/router.rs | 7 +- packages/web/Cargo.toml | 2 +- packages/web/src/history/mod.rs | 11 ++- 20 files changed, 254 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a14102a8..b27d1c1f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3368,6 +3368,7 @@ version = "0.6.0-alpha.5" dependencies = [ "criterion", "dioxus", + "dioxus-cli-config", "dioxus-config-macro", "dioxus-core", "dioxus-core-macro", @@ -3570,6 +3571,9 @@ dependencies = [ [[package]] name = "dioxus-cli-config" version = "0.6.0-alpha.5" +dependencies = [ + "wasm-bindgen", +] [[package]] name = "dioxus-config-macro" @@ -7715,6 +7719,7 @@ version = "0.6.0-alpha.5" dependencies = [ "const-serialize", "dioxus", + "dioxus-cli-config", "dioxus-core-types", "manganis", "serde", diff --git a/packages/cli-config/Cargo.toml b/packages/cli-config/Cargo.toml index a0c5fdfdf..81db49c6e 100644 --- a/packages/cli-config/Cargo.toml +++ b/packages/cli-config/Cargo.toml @@ -10,3 +10,7 @@ description = "CLI Configuration for dioxus-cli" keywords = ["dom", "ui", "gui", "react", ] [dependencies] +wasm-bindgen = { workspace = true, optional = true } + +[features] +web = ["dep:wasm-bindgen"] diff --git a/packages/cli-config/src/lib.rs b/packages/cli-config/src/lib.rs index ac34cb29e..3d53303c0 100644 --- a/packages/cli-config/src/lib.rs +++ b/packages/cli-config/src/lib.rs @@ -12,6 +12,29 @@ pub const ASSET_ROOT_ENV: &str = "DIOXUS_ASSET_ROOT"; pub const APP_TITLE_ENV: &str = "DIOXUS_APP_TITLE"; pub const OUT_DIR: &str = "DIOXUS_OUT_DIR"; +/// Reads an environment variable at runtime in debug mode or at compile time in +/// release mode. When bundling in release mode, we will not be running under the +/// environment variables that the CLI sets, so we need to read them at compile time. +macro_rules! read_env_config { + ($name:expr) => {{ + #[cfg(debug_assertions)] + { + // In debug mode, read the environment variable set by the CLI at runtime + std::env::var($name).ok() + } + + #[cfg(not(debug_assertions))] + { + // In release mode, read the environment variable set by the CLI at compile time + // This means the value will still be available when running the application + // standalone. + // We don't always read the environment variable at compile time to avoid rebuilding + // this crate when the environment variable changes. + option_env!($name).map(ToString::to_string) + } + }}; +} + /// Get the address of the devserver for use over a raw socket /// /// This is not a websocket! There's no protocol! @@ -51,7 +74,7 @@ pub fn fullstack_address_or_localhost() -> SocketAddr { } pub fn app_title() -> Option { - std::env::var(APP_TITLE_ENV).ok() + read_env_config!("DIOXUS_APP_TITLE") } pub fn always_on_top() -> Option { @@ -64,8 +87,55 @@ pub fn is_cli_enabled() -> bool { std::env::var(CLI_ENABLED_ENV).is_ok() } -pub fn base_path() -> Option { - std::env::var("DIOXUS_ASSET_ROOT").ok().map(PathBuf::from) +#[cfg(feature = "web")] +#[wasm_bindgen::prelude::wasm_bindgen(inline_js = r#" + export function getMetaContents(meta_name) { + const selector = document.querySelector(`meta[name="${meta_name}"]`); + if (!selector) { + return null; + } + return selector.content; + } +"#)] +extern "C" { + #[wasm_bindgen(js_name = getMetaContents)] + pub fn get_meta_contents(selector: &str) -> Option; +} + +/// Get the path where the application will be served from. This is used by the router to format the URLs. +pub fn base_path() -> Option { + // This may trigger when compiling to the server if you depend on another crate that pulls in + // the web feature. It might be better for the renderers to provide the current platform + // as a global context + #[cfg(all(feature = "web", target_arch = "wasm32"))] + { + return web_base_path(); + } + + read_env_config!("DIOXUS_ASSET_ROOT") +} + +/// Get the path where the application is served from in the browser. +#[cfg(feature = "web")] +pub fn web_base_path() -> Option { + // In debug mode, we get the base path from the meta element which can be hot reloaded and changed without recompiling + #[cfg(debug_assertions)] + { + thread_local! { + static BASE_PATH: std::cell::OnceCell> = const { std::cell::OnceCell::new() }; + } + BASE_PATH.with(|f| f.get_or_init(|| get_meta_contents(ASSET_ROOT_ENV)).clone()) + } + + // In release mode, we get the base path from the environment variable + #[cfg(not(debug_assertions))] + { + option_env!("DIOXUS_ASSET_ROOT").map(ToString::to_string) + } +} + +pub fn format_base_path_meta_element(base_path: &str) -> String { + format!(r#""#,) } pub fn out_dir() -> Option { diff --git a/packages/cli/src/build/request.rs b/packages/cli/src/build/request.rs index 368d2d21f..912c0b889 100644 --- a/packages/cli/src/build/request.rs +++ b/packages/cli/src/build/request.rs @@ -5,6 +5,7 @@ use crate::{assets::AssetManifest, TraceSrc}; use crate::{link::LinkAction, BuildArgs}; use crate::{AppBundle, Platform}; use anyhow::Context; +use dioxus_cli_config::{APP_TITLE_ENV, ASSET_ROOT_ENV}; use serde::Deserialize; use std::{ path::{Path, PathBuf}, @@ -540,6 +541,15 @@ impl BuildRequest { // env_vars.push(("PATH", extended_path)); }; + // If this is a release build, bake the base path and title + // into the binary with env vars + if self.build.release { + if let Some(base_path) = &self.krate.config.web.app.base_path { + env_vars.push((ASSET_ROOT_ENV, base_path.clone())); + } + env_vars.push((APP_TITLE_ENV, self.krate.config.web.app.title.clone())); + } + Ok(env_vars) } diff --git a/packages/cli/src/build/web.rs b/packages/cli/src/build/web.rs index 37cb7c201..f89d43e7d 100644 --- a/packages/cli/src/build/web.rs +++ b/packages/cli/src/build/web.rs @@ -1,3 +1,5 @@ +use dioxus_cli_config::format_base_path_meta_element; + use crate::error::Result; use crate::BuildRequest; use std::fmt::Write; @@ -66,6 +68,13 @@ impl BuildRequest { )?; } + // Add the base path to the head if this is a debug build + if self.is_dev_build() { + if let Some(base_path) = &self.krate.config.web.app.base_path { + head_resources.push_str(&format_base_path_meta_element(base_path)); + } + } + if !style_list.is_empty() { self.send_resource_deprecation_warning(style_list, ResourceType::Style); } diff --git a/packages/cli/src/config/web.rs b/packages/cli/src/config/web.rs index 63d28d906..2678a8521 100644 --- a/packages/cli/src/config/web.rs +++ b/packages/cli/src/config/web.rs @@ -101,9 +101,15 @@ pub(crate) struct WebAppConfig { impl WebAppConfig { /// Get the normalized base path for the application with `/` trimmed from both ends. If the base path is not set, this will return `.`. pub(crate) fn base_path(&self) -> &str { - match &self.base_path { - Some(path) => path.trim_matches('/'), - None => ".", + let trimmed_path = self + .base_path + .as_deref() + .unwrap_or_default() + .trim_matches('/'); + if trimmed_path.is_empty() { + "." + } else { + trimmed_path } } } diff --git a/packages/cli/src/serve/handle.rs b/packages/cli/src/serve/handle.rs index 7f9683c34..4021cb2c8 100644 --- a/packages/cli/src/serve/handle.rs +++ b/packages/cli/src/serve/handle.rs @@ -69,7 +69,11 @@ impl AppHandle { // Set the env vars that the clients will expect // These need to be stable within a release version (ie 0.6.0) let mut envs = vec![ - ("DIOXUS_CLI_ENABLED", "true".to_string()), + (dioxus_cli_config::CLI_ENABLED_ENV, "true".to_string()), + ( + dioxus_cli_config::APP_TITLE_ENV, + self.app.build.krate.config.web.app.title.clone(), + ), ("RUST_BACKTRACE", "1".to_string()), ( dioxus_cli_config::DEVSERVER_RAW_ADDR_ENV, @@ -80,6 +84,10 @@ impl AppHandle { ("CARGO_MANIFEST_DIR", "".to_string()), ]; + if let Some(base_path) = &self.app.build.krate.config.web.app.base_path { + envs.push((dioxus_cli_config::ASSET_ROOT_ENV, base_path.clone())); + } + if let Some(addr) = fullstack_address { envs.push((dioxus_cli_config::SERVER_IP_ENV, addr.ip().to_string())); envs.push((dioxus_cli_config::SERVER_PORT_ENV, addr.port().to_string())); @@ -109,7 +117,7 @@ impl AppHandle { Platform::Web => { // Only the first build we open the web app, after that the user knows it's running if open_browser { - self.open_web(envs, devserver_ip); + self.open_web(devserver_ip); } None @@ -212,7 +220,7 @@ impl AppHandle { /// Open the web app by opening the browser to the given address. /// Check if we need to use https or not, and if so, add the protocol. /// Go to the basepath if that's set too. - fn open_web(&self, _envs: Vec<(&str, String)>, address: SocketAddr) { + fn open_web(&self, address: SocketAddr) { let base_path = self.app.build.krate.config.web.app.base_path.clone(); let https = self .app diff --git a/packages/cli/src/serve/mod.rs b/packages/cli/src/serve/mod.rs index ccf598eda..f8f05e64a 100644 --- a/packages/cli/src/serve/mod.rs +++ b/packages/cli/src/serve/mod.rs @@ -231,7 +231,9 @@ pub(crate) async fn serve_all(mut args: ServeArgs) -> Result<()> { } ServeUpdate::OpenApp => { - runner.open_existing(&devserver).await; + if let Err(err) = runner.open_existing(&devserver).await { + tracing::error!("Failed to open app: {err}") + } } ServeUpdate::Redraw => { diff --git a/packages/cli/src/serve/runner.rs b/packages/cli/src/serve/runner.rs index cd00237ac..3e7a49c33 100644 --- a/packages/cli/src/serve/runner.rs +++ b/packages/cli/src/serve/runner.rs @@ -146,12 +146,15 @@ impl AppRunner { } /// Open an existing app bundle, if it exists - pub(crate) async fn open_existing(&self, devserver: &WebServer) { - if let Some(address) = devserver.server_address() { - let url = format!("http://{address}"); - tracing::debug!("opening url: {url}"); - _ = open::that(url); + pub(crate) async fn open_existing(&mut self, devserver: &WebServer) -> Result<()> { + if let Some((_, app)) = self + .running + .iter_mut() + .find(|(platform, _)| **platform != Platform::Server) + { + app.open(devserver.devserver_address(), None, true).await?; } + Ok(()) } pub(crate) fn attempt_hot_reload( diff --git a/packages/dioxus/Cargo.toml b/packages/dioxus/Cargo.toml index b66949abf..a55da263f 100644 --- a/packages/dioxus/Cargo.toml +++ b/packages/dioxus/Cargo.toml @@ -29,6 +29,7 @@ dioxus-ssr = { workspace = true, optional = true } manganis = { workspace = true, features = ["dioxus"], optional = true } serde = { version = "1.0.136", optional = true } +dioxus-cli-config = { workspace = true, optional = true } [target.'cfg(not(any(target_arch = "wasm32", target_os = "ios", target_os = "android")))'.dependencies] dioxus-devtools = { workspace = true, optional = true } @@ -53,7 +54,7 @@ router = ["dep:dioxus-router"] fullstack = ["dep:dioxus-fullstack", "dioxus-config-macro/fullstack", "dep:serde"] desktop = ["dep:dioxus-desktop", "dioxus-fullstack?/desktop", "dioxus-config-macro/desktop"] mobile = ["dep:dioxus-mobile", "dioxus-fullstack?/mobile", "dioxus-config-macro/mobile"] -web = ["dep:dioxus-web", "dioxus-fullstack?/web", "dioxus-config-macro/web"] +web = ["dep:dioxus-web", "dioxus-fullstack?/web", "dioxus-config-macro/web", "dioxus-cli-config", "dioxus-cli-config/web"] ssr = ["dep:dioxus-ssr", "dioxus-config-macro/ssr"] liveview = ["dep:dioxus-liveview", "dioxus-config-macro/liveview"] server = ["dioxus-fullstack?/axum", "dioxus-fullstack?/server", "ssr", "dioxus-liveview?/axum"] diff --git a/packages/dioxus/src/launch.rs b/packages/dioxus/src/launch.rs index 1705eef53..aa22d3a0d 100644 --- a/packages/dioxus/src/launch.rs +++ b/packages/dioxus/src/launch.rs @@ -274,6 +274,19 @@ fn web_launch( .unwrap_or_default() .hydrate(true); + // If there is a base path set, call server functions from that base path + if let Some(base_path) = dioxus_cli_config::web_base_path() { + let base_path = base_path.trim_matches('/'); + crate::prelude::server_fn::client::set_server_url( + format!( + "{}/{}", + crate::prelude::server_fn::client::get_server_url(), + base_path + ) + .leak(), + ); + } + let factory = move || { let mut vdom = dioxus_core::VirtualDom::new(root); for context in contexts { diff --git a/packages/fullstack/src/render.rs b/packages/fullstack/src/render.rs index c7e641869..5d6b594ee 100644 --- a/packages/fullstack/src/render.rs +++ b/packages/fullstack/src/render.rs @@ -1,6 +1,7 @@ //! A shared pool of renderers for efficient server side rendering. use crate::document::ServerDocument; use crate::streaming::{Mount, StreamingRenderer}; +use dioxus_cli_config::base_path; use dioxus_interpreter_js::INITIALIZE_STREAMING_JS; use dioxus_isrg::{CachedRender, RenderFreshness}; use dioxus_lib::document::Document; @@ -169,9 +170,19 @@ impl SsrRendererPool { let mut virtual_dom = virtual_dom_factory(); let document = std::rc::Rc::new(crate::document::server::ServerDocument::default()); virtual_dom.provide_root_context(document.clone()); - virtual_dom.provide_root_context(Rc::new( - dioxus_history::MemoryHistory::with_initial_path(&route), - ) as Rc); + // If there is a base path, trim the base path from the route and add the base path formatting to the + // history provider + let history; + if let Some(base_path) = base_path() { + let base_path = base_path.trim_matches('/'); + let base_path = format!("/{base_path}"); + let route = route.strip_prefix(&base_path).unwrap_or(&route); + history = + dioxus_history::MemoryHistory::with_initial_path(route).with_prefix(base_path); + } else { + history = dioxus_history::MemoryHistory::with_initial_path(&route); + } + virtual_dom.provide_root_context(Rc::new(history) as Rc); virtual_dom.provide_root_context(document.clone() as std::rc::Rc); // poll the future, which may call server_context() diff --git a/packages/fullstack/src/server/launch.rs b/packages/fullstack/src/server/launch.rs index 29ab417b6..e73561d03 100644 --- a/packages/fullstack/src/server/launch.rs +++ b/packages/fullstack/src/server/launch.rs @@ -2,8 +2,16 @@ use std::any::Any; +use axum::{ + body::Body, + extract::{Request, State}, + response::IntoResponse, +}; +use dioxus_cli_config::base_path; use dioxus_lib::prelude::*; +use crate::server::{render_handler, RenderHandleState, SSRState}; + /// Launch a fullstack app with the given root component, contexts, and config. #[allow(unused)] pub fn launch( @@ -60,9 +68,37 @@ pub fn launch( } } - #[allow(unused_mut)] - let mut router = + let mut base_path = base_path(); + let config = platform_config.as_ref().ok().cloned(); + let dioxus_router = axum::Router::new().serve_dioxus_application(TryIntoResult(platform_config), root); + let mut router; + match base_path.as_deref() { + Some(base_path) => { + let base_path = base_path.trim_matches('/'); + // If there is a base path, nest the router under it and serve the root route manually + // Nesting a route in axum only serves /base_path or /base_path/ not both + router = axum::Router::new().nest(&format!("/{base_path}/"), dioxus_router); + async fn root_render_handler( + state: State, + mut request: Request, + ) -> impl IntoResponse { + // The root of the base path always looks like the root from dioxus fullstack + *request.uri_mut() = "/".parse().unwrap(); + render_handler(state, request).await + } + if let Some(cfg) = config { + let ssr_state = SSRState::new(&cfg); + router = router.route( + &format!("/{base_path}"), + axum::routing::method_routing::get(root_render_handler).with_state( + RenderHandleState::new(cfg, root).with_ssr_state(ssr_state), + ), + ) + } + } + None => router = dioxus_router, + } let router = router.into_make_service(); let listener = tokio::net::TcpListener::bind(address).await.unwrap(); diff --git a/packages/history/src/memory.rs b/packages/history/src/memory.rs index eadcc08b7..2a6f3b82c 100644 --- a/packages/history/src/memory.rs +++ b/packages/history/src/memory.rs @@ -11,6 +11,7 @@ struct MemoryHistoryState { /// A [`History`] provider that stores all navigation information in memory. pub struct MemoryHistory { state: RefCell, + base_path: Option, } impl Default for MemoryHistory { @@ -44,16 +45,36 @@ impl MemoryHistory { pub fn with_initial_path(path: impl ToString) -> Self { Self { state: MemoryHistoryState{ - current: path.to_string().parse().unwrap_or_else(|err| { - panic!("index route does not exist:\n{err}\n use MemoryHistory::with_initial_path to set a custom path") - }), - history: Vec::new(), - future: Vec::new(),}.into() + current: path.to_string().parse().unwrap_or_else(|err| { + panic!("index route does not exist:\n{err}\n use MemoryHistory::with_initial_path to set a custom path") + }), + history: Vec::new(), + future: Vec::new(), + }.into(), + base_path: None, } } + + /// Set the base path for the history. All routes will be prefixed with this path when rendered. + /// + /// ```rust + /// # use dioxus_history::*; + /// let mut history = MemoryHistory::default().with_prefix("/my-app"); + /// + /// // The base path is set to "/my-app" + /// assert_eq!(history.current_prefix(), Some("/my-app".to_string())); + /// ``` + pub fn with_prefix(mut self, prefix: impl ToString) -> Self { + self.base_path = Some(prefix.to_string()); + self + } } impl History for MemoryHistory { + fn current_prefix(&self) -> Option { + self.base_path.clone() + } + fn current_route(&self) -> String { self.state.borrow().current.clone() } diff --git a/packages/manganis/manganis-core/Cargo.toml b/packages/manganis/manganis-core/Cargo.toml index f09f174d9..d1f936d4f 100644 --- a/packages/manganis/manganis-core/Cargo.toml +++ b/packages/manganis/manganis-core/Cargo.toml @@ -16,10 +16,11 @@ keywords = ["dom", "ui", "gui", "assets"] serde = { workspace = true, features = ["derive"] } const-serialize = { workspace = true, features = ["serde"] } dioxus-core-types = { workspace = true, optional = true } +dioxus-cli-config = { workspace = true, optional = true } [dev-dependencies] manganis = { workspace = true } dioxus = { workspace = true } [features] -dioxus = ["dep:dioxus-core-types"] +dioxus = ["dep:dioxus-core-types", "dep:dioxus-cli-config"] diff --git a/packages/manganis/manganis-core/src/asset.rs b/packages/manganis/manganis-core/src/asset.rs index e37dea1fe..97ceb6ef7 100644 --- a/packages/manganis/manganis-core/src/asset.rs +++ b/packages/manganis/manganis-core/src/asset.rs @@ -124,8 +124,23 @@ impl Asset { return PathBuf::from(self.bundled.absolute_source_path.as_str()); } + #[cfg(feature = "dioxus")] + let bundle_root = { + let base_path = dioxus_cli_config::base_path(); + let base_path = base_path + .as_deref() + .map(|base_path| { + let trimmed = base_path.trim_matches('/'); + format!("/{trimmed}") + }) + .unwrap_or_default(); + PathBuf::from(format!("{base_path}/assets/")) + }; + #[cfg(not(feature = "dioxus"))] + let bundle_root = PathBuf::from("/assets/"); + // Otherwise presumably we're bundled and we can use the bundled path - PathBuf::from("/assets/").join(PathBuf::from( + bundle_root.join(PathBuf::from( self.bundled.bundled_path.as_str().trim_start_matches('/'), )) } diff --git a/packages/router/src/components/link.rs b/packages/router/src/components/link.rs index 956c207e1..994b29182 100644 --- a/packages/router/src/components/link.rs +++ b/packages/router/src/components/link.rs @@ -163,6 +163,8 @@ pub fn Link(props: LinkProps) -> Element { NavigationTarget::Internal(url) => url.clone(), NavigationTarget::External(route) => route.clone(), }; + // Add the history's prefix to the href for use in the rsx + let full_href = router.prefix().unwrap_or_default() + &href; let mut class_ = String::new(); if let Some(c) = class { @@ -240,7 +242,7 @@ pub fn Link(props: LinkProps) -> Element { a { onclick: action, "onclick": liveview_prevent_default, - href, + href: full_href, onmounted: onmounted, class, rel, diff --git a/packages/router/src/contexts/router.rs b/packages/router/src/contexts/router.rs index 0659267e8..b8bc8c235 100644 --- a/packages/router/src/contexts/router.rs +++ b/packages/router/src/contexts/router.rs @@ -47,9 +47,6 @@ pub(crate) type RoutingCallback = pub(crate) type AnyRoutingCallback = Arc Option>; struct RouterContextInner { - /// The current prefix. - prefix: Option, - unresolved_error: Option, subscribers: Arc>>, @@ -105,7 +102,6 @@ impl RouterContext { let mapping = consume_child_route_mapping(); let myself = RouterContextInner { - prefix: Default::default(), unresolved_error: None, subscribers: subscribers.clone(), routing_callback: cfg.on_update.map(|update| { @@ -259,7 +255,8 @@ impl RouterContext { /// The prefix that is currently active. pub fn prefix(&self) -> Option { - self.inner.read().prefix.clone() + let history = history(); + history.current_prefix() } /// Clear any unresolved errors diff --git a/packages/web/Cargo.toml b/packages/web/Cargo.toml index 9aed05f93..09de9f19a 100644 --- a/packages/web/Cargo.toml +++ b/packages/web/Cargo.toml @@ -12,7 +12,7 @@ keywords = ["dom", "ui", "gui", "react", "wasm"] [dependencies] dioxus-core = { workspace = true } dioxus-core-types = { workspace = true } -dioxus-cli-config = { workspace = true } +dioxus-cli-config = { workspace = true, features = ["web"] } dioxus-html = { workspace = true } dioxus-history = { workspace = true } dioxus-document = { workspace = true } diff --git a/packages/web/src/history/mod.rs b/packages/web/src/history/mod.rs index 6f8c51eb2..11a68e580 100644 --- a/packages/web/src/history/mod.rs +++ b/packages/web/src/history/mod.rs @@ -1,5 +1,4 @@ use scroll::ScrollPosition; -use std::path::PathBuf; use wasm_bindgen::JsCast; use wasm_bindgen::{prelude::Closure, JsValue}; use web_sys::{window, Window}; @@ -7,9 +6,8 @@ use web_sys::{Event, History, ScrollRestoration}; mod scroll; -#[allow(dead_code)] -fn base_path() -> Option { - let base_path = dioxus_cli_config::base_path(); +fn base_path() -> Option { + let base_path = dioxus_cli_config::web_base_path(); tracing::trace!("Using base_path from the CLI: {:?}", base_path); base_path } @@ -77,9 +75,10 @@ impl WebHistory { let prefix = prefix // If there isn't a base path, try to grab one from the CLI - .or_else(|| base_path().map(|s| s.display().to_string())) + .or_else(base_path) // Normalize the prefix to start and end with no slashes - .map(|prefix| prefix.trim_matches('/').to_string()) + .as_ref() + .map(|prefix| prefix.trim_matches('/')) // If the prefix is empty, don't add it .filter(|prefix| !prefix.is_empty()) // Otherwise, start with a slash