Browse Source

Merge pull request #1916 from DogeDark/master

Add Prerelease Doc Generation
Evan Almloff 1 year ago
parent
commit
f4651cecb8

+ 24 - 36
.github/workflows/docs.yml

@@ -1,49 +1,37 @@
-name: github pages
-
+name: Deploy Nightly Docs
 on:
-  workflow_dispatch:
-  # push:
-  #   paths:
-  #     - docs/**
-  #     - .github/workflows/docs.yml
-  #   branches:
-  #     - master
-
-concurrency:
-  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
-  cancel-in-progress: true
+  push:
+    branches:
+      - master
 
 jobs:
-  build-deploy:
+  deploy:
+    name: Build & Deploy
     runs-on: ubuntu-latest
-    environment: docs
-    steps:
-
-      # NOTE: Comment out when https://github.com/rust-lang/mdBook/pull/1306 is merged and released
-      # - name: Setup mdBook
-      #   uses: peaceiris/actions-mdbook@v1
-      #   with:
-      #     mdbook-version: "0.4.10"
+    permissions:
+      contents: write
 
-      # NOTE: Delete when the previous one is enabled
-      - name: Setup mdBook
-        run: |
-          cargo install mdbook --git https://github.com/Demonthos/mdBook.git --branch master
+    steps:
       - uses: actions/checkout@v4
+      - run: sudo apt-get update
+      - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev
+      - uses: dtolnay/rust-toolchain@nightly
+      - uses: Swatinem/rust-cache@v2
+        with:
+          cache-all-crates: "true"
+          save-if: ${{ github.ref == 'refs/heads/master' }}
+      - uses: ilammy/setup-nasm@v1
 
-      - name: Build
-        run: cd docs &&
-          cd guide && mdbook build -d ../nightly/guide && cd .. &&
-          cd router && mdbook build -d ../nightly/router && cd ..
-          # cd reference && mdbook build -d ../nightly/reference && cd .. &&
-          # cd fermi && mdbook build -d ../nightly/fermi && cd ..
+      - name: cargo doc
+        run: cargo doc --no-deps --workspace --all-features
 
-      - name: Deploy 🚀
+      - name: Deploy
         uses: JamesIves/github-pages-deploy-action@v4.5.0
         with:
-          branch: gh-pages # The branch the action should deploy to.
-          folder: docs/nightly # The folder the action should deploy.
-          target-folder: docs/nightly
+          branch: gh-pages
+          folder: target/doc
+          target-folder: api-docs/nightly
           repository-name: dioxuslabs/docsite
           clean: false
           token: ${{ secrets.DEPLOY_KEY }} # let's pretend I don't need it for now
+

+ 0 - 6
packages/cli/src/server/mod.rs

@@ -112,12 +112,6 @@ async fn setup_file_watcher<F: Fn() -> Result<BuildResult> + Send + 'static>(
                                         },
                                         web_info.clone(),
                                     );
-
-                                    #[cfg(feature = "plugin")]
-                                    let _ = PluginManager::on_serve_rebuild(
-                                        chrono::Local::now().timestamp(),
-                                        e.paths,
-                                    );
                                 }
                                 Err(e) => {
                                     last_update_time = chrono::Local::now().timestamp();

+ 4 - 4
packages/core/src/error_boundary.rs

@@ -140,12 +140,12 @@ impl ErrorBoundary {
 ///
 /// ```rust, ignore
 /// #[component]
-/// fn app( count: String) -> Element {
+/// fn app(count: String) -> Element {
 ///     let id: i32 = count.parse().throw()?;
 ///
 ///     rsx! {
 ///         div { "Count {}" }
-///     })
+///     }
 /// }
 /// ```
 pub trait Throw<S = ()>: Sized {
@@ -170,7 +170,7 @@ pub trait Throw<S = ()>: Sized {
     ///
     ///     rsx! {
     ///         div { "Count {}" }
-    ///     })
+    ///     }
     /// }
     /// ```
     fn throw(self) -> Option<Self::Out>;
@@ -193,7 +193,7 @@ pub trait Throw<S = ()>: Sized {
     ///
     ///     rsx! {
     ///         div { "Count {}" }
-    ///     })
+    ///     }
     /// }
     /// ```
     fn throw_with<D: Debug + 'static>(self, e: impl FnOnce() -> D) -> Option<Self::Out> {

+ 1 - 1
packages/core/src/events.rs

@@ -159,7 +159,7 @@ impl<T: std::fmt::Debug> std::fmt::Debug for Event<T> {
 ///         button {
 ///             onclick: move |evt| cx.onclick.call(evt),
 ///         }
-///     })
+///     }
 /// }
 ///
 /// ```

+ 2 - 2
packages/core/src/lib.rs

@@ -42,7 +42,7 @@ pub(crate) mod innerlude {
     /// An Errored [`Element`] will propagate the error to the nearest error boundary.
     pub type Element = Option<VNode>;
 
-    /// A [`Component`] is a function that takes a [`Scope`] and returns an [`Element`].
+    /// A [`Component`] is a function that takes [`Properties`] and returns an [`Element`].
     ///
     /// Components can be used in other components with two syntax options:
     /// - lowercase as a function call with named arguments (rust style)
@@ -84,7 +84,7 @@ pub use crate::innerlude::{
 
 /// The purpose of this module is to alleviate imports of many common types
 ///
-/// This includes types like [`Scope`], [`Element`], and [`Component`].
+/// This includes types like [`Element`], and [`Component`].
 pub mod prelude {
     pub use crate::innerlude::{
         consume_context, consume_context_from_scope, current_scope_id, fc_to_builder, flush_sync,

+ 3 - 3
packages/core/src/virtual_dom.rs

@@ -24,7 +24,7 @@ use std::{any::Any, collections::BTreeSet, rc::Rc};
 ///
 /// ## Guide
 ///
-/// Components are defined as simple functions that take [`Scope`] and return an [`Element`].
+/// Components are defined as simple functions that take [`crate::properties::Properties`] and return an [`Element`].
 ///
 /// ```rust
 /// # use dioxus::prelude::*;
@@ -218,7 +218,7 @@ impl VirtualDom {
     /// # Example
     /// ```rust, ignore
     /// fn Example() -> Element  {
-    ///     rsx!( div { "hello world" } ))
+    ///     rsx!( div { "hello world" } )
     /// }
     ///
     /// let dom = VirtualDom::new(Example);
@@ -526,7 +526,7 @@ impl VirtualDom {
     ///
     /// # Example
     /// ```rust, ignore
-    /// static app: Component = |cx|  rsx!{ "hello world" });
+    /// static app: Component = |cx|  rsx!{ "hello world" };
     ///
     /// let mut dom = VirtualDom::new();
     /// let edits = dom.rebuild();

+ 3 - 0
packages/dioxus/Cargo.toml

@@ -55,6 +55,9 @@ warp = ["dioxus-fullstack?/warp", "ssr", "dioxus-liveview?/warp"]
 rocket = ["dioxus-liveview?/rocket"]
 tui = ["dioxus-tui", "dioxus-config-macro/tui"]
 
+# This feature enables some nightly flags that make it more clear what structs/methods are available in each feature
+nightly-doc = []
+
 [dev-dependencies]
 futures-util = { workspace = true }
 tracing = { workspace = true }

+ 11 - 12
packages/dioxus/README.md

@@ -50,7 +50,7 @@ fn main() {
 // It's not required, but highly recommended. For example, UpperCamelCase components will not generate a warning.
 #[component]
 fn App() -> Element {
-    rsx!("hello world!"))
+    rsx!("hello world!")
 }
 ```
 
@@ -97,13 +97,12 @@ If we want to omit the boilerplate of `cx.render`, we can simply pass in
 render nodes in match statements.
 
 ```rust, ignore
-#[component[
+#[component]
 fn Example() -> Element {
-
     // both of these are equivalent
-    rsx!("hello world"))
+    rsx!("hello world");
 
-    rsx!("hello world!")
+    rsx!("hello world!");
 }
 ```
 
@@ -127,7 +126,7 @@ fn App() -> Element {
             ))
 
         }
-    ))
+    )
 }
 ```
 
@@ -147,7 +146,7 @@ fn App() -> Element {
             title: "My App",
             color: "red",
         }
-    ))
+    )
 }
 ```
 
@@ -169,7 +168,7 @@ fn Header(cx: Scope<HeaderProps>) -> Element {
             background_color: "{cx.props.color}"
             h1 { "{cx.props.title}" }
         }
-    ))
+    )
 }
 ```
 
@@ -184,7 +183,7 @@ fn Header(title: String, color: String) -> Element {
             background_color: "{color}"
             h1 { "{title}" }
         }
-    ))
+    )
 }
 ```
 
@@ -201,13 +200,13 @@ struct HeaderProps<'a> {
 }
 
 #[component]
-fn Header(props: HeaderProps -> Element {
+fn Header(props: HeaderProps) -> Element {
     rsx!(
         div {
             background_color: "{cx.props.color}"
             h1 { "{cx.props.title}" }
         }
-    ))
+    )
 }
 ```
 
@@ -299,7 +298,7 @@ fn App() -> Element {
         div { "Count: {count}" }
         button { onclick: move |_| count.set(count + 1), "Increment" }
         button { onclick: move |_| count.set(count - 1), "Decrement" }
-    ))
+    )
 }
 ```
 

+ 9 - 0
packages/dioxus/src/launch.rs

@@ -38,6 +38,7 @@ impl LaunchBuilder {
 
     /// Launch your web application.
     #[cfg(feature = "web")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "web")))]
     pub fn web() -> LaunchBuilder<dioxus_web::Config, UnsendContext> {
         LaunchBuilder {
             launch_fn: dioxus_web::launch::launch,
@@ -48,6 +49,7 @@ impl LaunchBuilder {
 
     /// Launch your desktop application.
     #[cfg(feature = "desktop")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "desktop")))]
     pub fn desktop() -> LaunchBuilder<dioxus_desktop::Config, UnsendContext> {
         LaunchBuilder {
             launch_fn: dioxus_desktop::launch::launch,
@@ -58,6 +60,7 @@ impl LaunchBuilder {
 
     /// Launch your fullstack application.
     #[cfg(feature = "fullstack")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "fullstack")))]
     pub fn fullstack() -> LaunchBuilder<dioxus_fullstack::Config, SendContext> {
         LaunchBuilder {
             launch_fn: dioxus_fullstack::launch::launch,
@@ -68,6 +71,7 @@ impl LaunchBuilder {
 
     /// Launch your fullstack application.
     #[cfg(feature = "mobile")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "mobile")))]
     pub fn mobile() -> LaunchBuilder<dioxus_mobile::Config, UnsendContext> {
         LaunchBuilder {
             launch_fn: dioxus_mobile::launch::launch,
@@ -77,6 +81,7 @@ impl LaunchBuilder {
     }
 
     #[cfg(feature = "tui")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "tui")))]
     /// Launch your tui application
     pub fn tui() -> LaunchBuilder<dioxus_tui::Config, UnsendContext> {
         LaunchBuilder {
@@ -209,24 +214,28 @@ pub fn launch(app: fn() -> Element) {
 }
 
 #[cfg(feature = "web")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "web")))]
 /// Launch your web application without any additional configuration. See [`LaunchBuilder`] for more options.
 pub fn launch_web(app: fn() -> Element) {
     LaunchBuilder::web().launch(app)
 }
 
 #[cfg(feature = "desktop")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "desktop")))]
 /// Launch your desktop application without any additional configuration. See [`LaunchBuilder`] for more options.
 pub fn launch_desktop(app: fn() -> Element) {
     LaunchBuilder::desktop().launch(app)
 }
 
 #[cfg(feature = "fullstack")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "fullstack")))]
 /// Launch your fullstack application without any additional configuration. See [`LaunchBuilder`] for more options.
 pub fn launch_fullstack(app: fn() -> Element) {
     LaunchBuilder::fullstack().launch(app)
 }
 
 #[cfg(feature = "tui")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "tui")))]
 /// Launch your tui application without any additional configuration. See [`LaunchBuilder`] for more options.
 pub fn launch_tui(app: fn() -> Element) {
     LaunchBuilder::tui().launch(app)

+ 26 - 0
packages/dioxus/src/lib.rs

@@ -1,88 +1,114 @@
 #![doc = include_str!("../README.md")]
 #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
 #![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
+#![cfg_attr(any(docsrs, feature = "nightly-doc"), feature(doc_cfg))]
 
 pub use dioxus_core;
 
 #[cfg(feature = "launch")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "launch")))]
 mod launch;
 
 #[cfg(feature = "hooks")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "hooks")))]
 pub use dioxus_hooks as hooks;
 
 #[cfg(feature = "signals")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "signals")))]
 pub use dioxus_signals as signals;
 
 pub mod events {
     #[cfg(feature = "html")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "html")))]
     pub use dioxus_html::prelude::*;
 }
 
 #[cfg(feature = "html")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "html")))]
 pub use dioxus_html as html;
 
 #[cfg(feature = "macro")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "macro")))]
 pub use dioxus_core_macro as core_macro;
 
 pub mod prelude {
     #[cfg(feature = "launch")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "launch")))]
     pub use crate::launch::*;
 
     #[cfg(feature = "hooks")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "hooks")))]
     pub use crate::hooks::*;
 
     #[cfg(feature = "signals")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "signals")))]
     pub use dioxus_signals::*;
 
     pub use dioxus_core::prelude::*;
 
     #[cfg(feature = "macro")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "macro")))]
     #[allow(deprecated)]
     pub use dioxus_core_macro::{component, format_args_f, inline_props, render, rsx, Props};
 
     #[cfg(feature = "launch")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "launch")))]
     pub use dioxus_config_macro::*;
 
     #[cfg(feature = "html")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "html")))]
     pub use dioxus_html as dioxus_elements;
 
     #[cfg(feature = "html")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "html")))]
     pub use dioxus_elements::{prelude::*, GlobalAttributes, SvgAttributes};
 
     #[cfg(all(not(target_arch = "wasm32"), feature = "hot-reload"))]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "hot-reload")))]
     pub use dioxus_hot_reload::{self, hot_reload_init};
 
     pub use dioxus_core;
 
     #[cfg(feature = "fullstack")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "fullstack")))]
     pub use dioxus_fullstack::prelude::*;
 
     #[cfg(feature = "router")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "router")))]
     pub use dioxus_router;
     #[cfg(feature = "router")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "router")))]
     pub use dioxus_router::prelude::*;
 }
 
 #[cfg(feature = "web")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "web")))]
 pub use dioxus_web as web;
 
 #[cfg(feature = "router")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "router")))]
 pub use dioxus_router as router;
 
 #[cfg(feature = "fullstack")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "fullstack")))]
 pub use dioxus_fullstack as fullstack;
 
 #[cfg(feature = "desktop")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "desktop")))]
 pub use dioxus_desktop as desktop;
 
 #[cfg(feature = "mobile")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "mobile")))]
 pub use dioxus_desktop as mobile;
 
 #[cfg(feature = "liveview")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "liveview")))]
 pub use dioxus_liveview as liveview;
 
 #[cfg(feature = "tui")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "tui")))]
 pub use dioxus_tui as tui;
 
 #[cfg(feature = "ssr")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "ssr")))]
 pub use dioxus_ssr as ssr;

+ 2 - 0
packages/fullstack/Cargo.toml

@@ -81,3 +81,5 @@ salvo = ["dep:salvo", "server", "http-body-util"]
 server = ["server_fn/ssr", "dioxus_server_macro/server", "tokio", "tokio-util", "tokio-stream", "dioxus-ssr", "dioxus-ssr/incremental", "tower", "hyper", "http", "tower-layer", "anymap", "tracing-futures", "pin-project", "thiserror", "dioxus-cli-config"]
 default-tls = ["server_fn/default-tls"]
 rustls = ["server_fn/rustls"]
+# This feature enables some nightly flags that make it more clear what structs/methods are available in each feature
+nightly-doc = []

+ 2 - 2
packages/fullstack/examples/axum-desktop/src/client.rs

@@ -4,10 +4,10 @@
 // ```
 
 use axum_desktop::*;
-use dioxus_fullstack::prelude::server_fn::set_server_url;
 
 fn main() {
     // Set the url of the server where server functions are hosted.
-    set_server_url("http://127.0.0.1:8080");
+    #[cfg(not(feature = "server"))]
+    dioxus::fullstack::prelude::server_fn::set_server_url("http://127.0.0.1:8080");
     dioxus::desktop::launch(app)
 }

+ 1 - 1
packages/fullstack/examples/axum-desktop/src/server.rs

@@ -4,7 +4,7 @@
 // ```
 
 use axum_desktop::*;
-use dioxus_fullstack::prelude::*;
+use dioxus::prelude::*;
 
 #[tokio::main]
 async fn main() {

+ 1 - 1
packages/fullstack/examples/static-hydrated/src/main.rs

@@ -27,7 +27,7 @@ async fn main() {
 }
 
 // Hydrate the page
-#[cfg(feature = "web")]
+#[cfg(all(feature = "web", not(feature = "server")))]
 fn main() {
     dioxus_web::launch_with_props(
         dioxus_fullstack::router::RouteWithCfg::<Route>,

+ 3 - 3
packages/fullstack/src/adapters/axum_adapter.rs

@@ -332,7 +332,7 @@ where
     }
 
     fn connect_hot_reload(self) -> Self {
-        #[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))]
+        #[cfg(all(debug_assertions, feature = "hot-reload"))]
         {
             self.nest(
                 "/_dioxus",
@@ -354,7 +354,7 @@ where
                     .route("/hot_reload", get(hot_reload_handler)),
             )
         }
-        #[cfg(not(all(debug_assertions, feature = "hot-reload", feature = "server")))]
+        #[cfg(not(all(debug_assertions, feature = "hot-reload")))]
         {
             self
         }
@@ -476,7 +476,7 @@ fn report_err<E: std::fmt::Display>(e: E) -> Response<BoxBody> {
 }
 
 /// A handler for Dioxus web hot reload websocket. This will send the updated static parts of the RSX to the client when they change.
-#[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))]
+#[cfg(all(debug_assertions, feature = "hot-reload"))]
 pub async fn hot_reload_handler(ws: axum::extract::WebSocketUpgrade) -> impl IntoResponse {
     use axum::extract::ws::Message;
     use futures_util::StreamExt;

+ 2 - 2
packages/fullstack/src/adapters/mod.rs

@@ -12,8 +12,8 @@
 
 #[cfg(feature = "axum")]
 pub mod axum_adapter;
-#[cfg(feature = "salvo")]
-pub mod salvo_adapter;
+// #[cfg(feature = "salvo")]
+// pub mod salvo_adapter;
 #[cfg(feature = "warp")]
 pub mod warp_adapter;
 

+ 11 - 8
packages/fullstack/src/adapters/salvo_adapter.rs

@@ -291,17 +291,20 @@ impl DioxusRouterExt for Router {
     ) -> Self {
         let cfg = cfg.into();
 
-        self.serve_static_assets(cfg.assets_path)
+        self.serve_static_assets(cfg.assets_path.clone())
             .connect_hot_reload()
             .register_server_fns(server_fn_path)
-            .push(Router::with_path("/<**any_path>").get(SSRHandler { cfg }))
+            .push(Router::with_path("/<**any_path>").get(SSRHandler {
+                config: cfg,
+                virtual_dom: virtual_dom_factory,
+            }))
     }
 
     fn connect_hot_reload(self) -> Self {
         let mut _dioxus_router = Router::with_path("_dioxus");
         _dioxus_router =
             _dioxus_router.push(Router::with_path("hot_reload").handle(HotReloadHandler));
-        #[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))]
+        #[cfg(all(debug_assertions, feature = "hot-reload"))]
         {
             _dioxus_router = _dioxus_router.push(Router::with_path("disconnect").handle(ignore_ws));
         }
@@ -485,11 +488,11 @@ fn handle_error(error: impl Error + Send + Sync, res: &mut Response) {
 }
 
 /// A handler for Dioxus web hot reload websocket. This will send the updated static parts of the RSX to the client when they change.
-#[cfg(not(all(debug_assertions, feature = "hot-reload", feature = "server")))]
+#[cfg(not(all(debug_assertions, feature = "hot-reload")))]
 #[derive(Default)]
 pub struct HotReloadHandler;
 
-#[cfg(not(all(debug_assertions, feature = "hot-reload", feature = "server")))]
+#[cfg(not(all(debug_assertions, feature = "hot-reload")))]
 #[handler]
 impl HotReloadHandler {
     async fn handle(
@@ -503,11 +506,11 @@ impl HotReloadHandler {
 }
 
 /// A handler for Dioxus web hot reload websocket. This will send the updated static parts of the RSX to the client when they change.
-#[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))]
+#[cfg(all(debug_assertions, feature = "hot-reload"))]
 #[derive(Default)]
 pub struct HotReloadHandler;
 
-#[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))]
+#[cfg(all(debug_assertions, feature = "hot-reload"))]
 #[handler]
 impl HotReloadHandler {
     async fn handle(
@@ -561,7 +564,7 @@ impl HotReloadHandler {
     }
 }
 
-#[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))]
+#[cfg(all(debug_assertions, feature = "hot-reload"))]
 #[handler]
 async fn ignore_ws(req: &mut Request, res: &mut Response) -> Result<(), salvo::http::StatusError> {
     use salvo::websocket::WebSocketUpgrade;

+ 5 - 5
packages/fullstack/src/adapters/warp_adapter.rs

@@ -187,7 +187,7 @@ pub fn serve_dioxus_application(
 ) -> BoxedFilter<(impl Reply,)> {
     let cfg = cfg.into();
     // Serve the dist folder and the index.html file
-    let serve_dir = warp::fs::dir(cfg.assets_path);
+    let serve_dir = warp::fs::dir(cfg.assets_path.clone());
 
     let virtual_dom_factory =
         Arc::new(virtual_dom_factory) as Arc<dyn Fn() -> VirtualDom + Send + Sync + 'static>;
@@ -332,13 +332,13 @@ impl warp::reject::Reject for RecieveFailed {}
 /// ```
 pub fn connect_hot_reload() -> impl Filter<Extract = (impl Reply,), Error = warp::Rejection> + Clone
 {
-    #[cfg(not(all(debug_assertions, feature = "hot-reload", feature = "server")))]
+    #[cfg(not(all(debug_assertions, feature = "hot-reload")))]
     {
         warp::path!("_dioxus" / "hot_reload")
             .map(warp::reply)
             .map(|reply| warp::reply::with_status(reply, warp::http::StatusCode::NOT_FOUND))
     }
-    #[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))]
+    #[cfg(all(debug_assertions, feature = "hot-reload"))]
     {
         use crate::hot_reload::HotReloadState;
         use futures_util::sink::SinkExt;
@@ -349,7 +349,7 @@ pub fn connect_hot_reload() -> impl Filter<Extract = (impl Reply,), Error = warp
             .and(warp::any().then(crate::hot_reload::spawn_hot_reload))
             .and(warp::ws())
             .map(move |state: &'static HotReloadState, ws: warp::ws::Ws| {
-                #[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))]
+                // #[cfg(all(debug_assertions, feature = "hot-reload"))]
                 ws.on_upgrade(move |mut websocket| {
                     async move {
                         println!("🔥 Hot Reload WebSocket connected");
@@ -393,7 +393,7 @@ pub fn connect_hot_reload() -> impl Filter<Extract = (impl Reply,), Error = warp
                 .and(warp::ws())
                 .map(move |ws: warp::ws::Ws| {
                     println!("disconnect");
-                    #[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))]
+                    #[cfg(all(debug_assertions, feature = "hot-reload",))]
                     ws.on_upgrade(move |mut websocket| async move {
                         struct DisconnectOnDrop(Option<warp::ws::WebSocket>);
                         impl Drop for DisconnectOnDrop {

+ 8 - 0
packages/fullstack/src/config.rs

@@ -53,6 +53,7 @@ impl Config {
 
     /// Set the address to serve the app on.
     #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     pub fn addr(self, addr: impl Into<std::net::SocketAddr>) -> Self {
         let addr = addr.into();
         Self { addr, ..self }
@@ -60,6 +61,7 @@ impl Config {
 
     /// Set the route to the server functions.
     #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     pub fn server_fn_route(self, server_fn_route: &'static str) -> Self {
         Self {
             server_fn_route,
@@ -69,6 +71,7 @@ impl Config {
 
     /// Set the incremental renderer config.
     #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     pub fn incremental(self, cfg: IncrementalRendererConfig) -> Self {
         Self {
             server_cfg: self.server_cfg.incremental(cfg),
@@ -78,18 +81,21 @@ impl Config {
 
     /// Set the server config.
     #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     pub fn server_cfg(self, server_cfg: ServeConfigBuilder) -> Self {
         Self { server_cfg, ..self }
     }
 
     /// Set the web config.
     #[cfg(feature = "web")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "web")))]
     pub fn web_cfg(self, web_cfg: dioxus_web::Config) -> Self {
         Self { web_cfg, ..self }
     }
 
     /// Set the desktop config.
     #[cfg(feature = "desktop")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "desktop")))]
     pub fn desktop_cfg(self, desktop_cfg: dioxus_desktop::Config) -> Self {
         Self {
             desktop_cfg,
@@ -99,11 +105,13 @@ impl Config {
 
     /// Set the mobile config.
     #[cfg(feature = "mobile")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "mobile")))]
     pub fn mobile_cfg(self, mobile_cfg: dioxus_mobile::Config) -> Self {
         Self { mobile_cfg, ..self }
     }
 
     #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     /// Launch a server application
     pub async fn launch_server(
         self,

+ 56 - 6
packages/fullstack/src/lib.rs

@@ -2,6 +2,7 @@
 #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
 #![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
 #![deny(missing_docs)]
+#![cfg_attr(any(docsrs, feature = "nightly-doc"), feature(doc_cfg))]
 
 pub use once_cell;
 
@@ -9,8 +10,20 @@ mod html_storage;
 
 #[cfg(feature = "server")]
 mod adapters;
+// Splitting up the glob export lets us document features required for each adapter
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "axum")))]
+#[cfg(feature = "axum")]
+pub use adapters::axum_adapter;
+// TODO: Compilation seems to be broken with the salvo feature enabled. Fix and add more features to checks in CI
+// #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "salvo")))]
+// #[cfg(feature = "salvo")]
+// pub use adapters::salvo_adapter;
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "warp")))]
+#[cfg(feature = "warp")]
+pub use adapters::warp_adapter;
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
 #[cfg(feature = "server")]
-pub use adapters::*;
+pub use adapters::{server_fn_service, ServerFnHandler};
 mod config;
 mod hooks;
 #[cfg(all(debug_assertions, feature = "hot-reload", feature = "server"))]
@@ -30,35 +43,57 @@ mod server_fn;
 /// A prelude of commonly used items in dioxus-fullstack.
 pub mod prelude {
     #[cfg(feature = "axum")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "axum")))]
     pub use crate::adapters::axum_adapter::*;
-    #[cfg(feature = "salvo")]
-    pub use crate::adapters::salvo_adapter::*;
+    // #[cfg(feature = "salvo")]
+    // #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "salvo")))]
+    // pub use crate::adapters::salvo_adapter::*;
     #[cfg(feature = "warp")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "warp")))]
     pub use crate::adapters::warp_adapter::*;
     use crate::hooks;
     #[cfg(not(feature = "server"))]
+    #[cfg_attr(
+        any(docsrs, feature = "nightly-doc"),
+        doc(cfg(not(feature = "server")))
+    )]
     pub use crate::html_storage::deserialize::get_root_props_from_document;
     #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     pub use crate::layer::{Layer, Service};
     #[cfg(all(feature = "server", feature = "router"))]
+    #[cfg_attr(
+        any(docsrs, feature = "nightly-doc"),
+        doc(cfg(all(feature = "server", feature = "router")))
+    )]
     pub use crate::render::pre_cache_static_routes_with_props;
     #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     pub use crate::render::SSRState;
     #[cfg(feature = "router")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "router")))]
     pub use crate::router::FullstackRouterConfig;
     #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     pub use crate::serve_config::{ServeConfig, ServeConfigBuilder};
     #[cfg(all(feature = "server", feature = "axum"))]
+    #[cfg_attr(
+        any(docsrs, feature = "nightly-doc"),
+        doc(cfg(all(feature = "server", feature = "axum")))
+    )]
     pub use crate::server_context::Axum;
     #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     pub use crate::server_context::{
         extract, server_context, DioxusServerContext, FromServerContext, ProvideServerContext,
     };
     pub use crate::server_fn::DioxusServerFn;
     #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     pub use crate::server_fn::{ServerFnMiddleware, ServerFnTraitObj, ServerFunction};
     pub use dioxus_server_macro::*;
     #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     pub use dioxus_ssr::incremental::IncrementalRendererConfig;
     pub use server_fn::{self, ServerFn as _, ServerFnError};
 
@@ -66,11 +101,26 @@ pub mod prelude {
 }
 
 // Warn users about overlapping features
-#[cfg(all(feature = "server", feature = "web", not(doc)))]
+#[cfg(all(
+    feature = "server",
+    feature = "web",
+    not(doc),
+    not(feature = "nightly-doc")
+))]
 compile_error!("The `ssr` feature (enabled by `warp`, `axum`, or `salvo`) and `web` feature are overlapping. Please choose one or the other.");
 
-#[cfg(all(feature = "server", feature = "desktop", not(doc)))]
+#[cfg(all(
+    feature = "server",
+    feature = "desktop",
+    not(doc),
+    not(feature = "nightly-doc")
+))]
 compile_error!("The `ssr` feature (enabled by `warp`, `axum`, or `salvo`) and `desktop` feature are overlapping. Please choose one or the other.");
 
-#[cfg(all(feature = "server", feature = "mobile", not(doc)))]
+#[cfg(all(
+    feature = "server",
+    feature = "mobile",
+    not(doc),
+    not(feature = "nightly-doc")
+))]
 compile_error!("The `ssr` feature (enabled by `warp`, `axum`, or `salvo`) and `mobile` feature are overlapping. Please choose one or the other.");

+ 1 - 0
packages/fullstack/src/server_context.rs

@@ -228,6 +228,7 @@ impl<T: Send + Sync + Clone + 'static> FromServerContext for FromContext<T> {
 }
 
 #[cfg(feature = "axum")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "axum")))]
 /// An adapter for axum extractors for the server context
 pub struct Axum;
 

+ 14 - 8
packages/fullstack/src/server_fn.rs

@@ -1,9 +1,10 @@
-#[cfg(any(feature = "server", doc))]
+#[cfg(feature = "server")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
 #[derive(Clone)]
 /// A trait object for a function that be called on serializable arguments and returns a serializable result.
 pub struct ServerFnTraitObj(server_fn::ServerFnTraitObj<()>);
 
-#[cfg(any(feature = "server", doc))]
+#[cfg(feature = "server")]
 impl std::ops::Deref for ServerFnTraitObj {
     type Target = server_fn::ServerFnTraitObj<()>;
 
@@ -12,14 +13,14 @@ impl std::ops::Deref for ServerFnTraitObj {
     }
 }
 
-#[cfg(any(feature = "server", doc))]
+#[cfg(feature = "server")]
 impl std::ops::DerefMut for ServerFnTraitObj {
     fn deref_mut(&mut self) -> &mut Self::Target {
         &mut self.0
     }
 }
 
-#[cfg(any(feature = "server", doc))]
+#[cfg(feature = "server")]
 impl ServerFnTraitObj {
     fn new(
         prefix: &'static str,
@@ -40,6 +41,7 @@ impl ServerFnTraitObj {
 server_fn::inventory::collect!(ServerFnTraitObj);
 
 #[cfg(feature = "server")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
 /// Middleware for a server function
 pub struct ServerFnMiddleware {
     /// The prefix of the server function.
@@ -72,7 +74,8 @@ pub(crate) static MIDDLEWARE: once_cell::sync::Lazy<
 #[cfg(feature = "server")]
 server_fn::inventory::collect!(ServerFnMiddleware);
 
-#[cfg(any(feature = "server", doc))]
+#[cfg(feature = "server")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
 /// A server function that can be called on serializable arguments and returns a serializable result.
 pub type ServerFunction = server_fn::SerializedFnTraitObj<()>;
 
@@ -88,7 +91,8 @@ static REGISTERED_SERVER_FUNCTIONS: once_cell::sync::Lazy<
     std::sync::Arc::new(std::sync::RwLock::new(map))
 });
 
-#[cfg(any(feature = "server", doc))]
+#[cfg(feature = "server")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
 /// The registry of all Dioxus server functions.
 pub struct DioxusServerFnRegistry;
 
@@ -155,7 +159,8 @@ impl server_fn::ServerFunctionRegistry<()> for DioxusServerFnRegistry {
     }
 }
 
-#[cfg(any(feature = "server", doc))]
+#[cfg(feature = "server")]
+#[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
 /// Errors that can occur when registering a server function.
 #[derive(thiserror::Error, Debug, Clone, serde::Serialize, serde::Deserialize)]
 pub enum ServerRegistrationFnError {
@@ -178,7 +183,8 @@ pub enum ServerRegistrationFnError {
 /// Technically, the trait is implemented on a type that describes the server function's arguments, not the function itself.
 pub trait DioxusServerFn: server_fn::ServerFn<()> {
     /// Registers the server function, allowing the client to query it by URL.
-    #[cfg(any(feature = "server", doc))]
+    #[cfg(feature = "server")]
+    #[cfg_attr(any(docsrs, feature = "nightly-doc"), doc(cfg(feature = "server")))]
     fn register_explicit() -> Result<(), server_fn::ServerFnError> {
         Self::register_in_explicit::<DioxusServerFnRegistry>()
     }

+ 0 - 1
packages/hooks/src/lib.rs

@@ -1,7 +1,6 @@
 #![doc = include_str!("../README.md")]
 #![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")]
 #![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")]
-#![cfg_attr(feature = "nightly-features", feature(debug_refcell))]
 
 #[macro_export]
 /// A helper macro for using hooks and properties in async environments.

+ 2 - 2
packages/liveview/src/launch.rs

@@ -3,9 +3,9 @@ use std::any::Any;
 
 #[cfg(feature = "axum")]
 pub type Config = crate::Config<axum::Router>;
-#[cfg(feature = "salvo")]
+#[cfg(all(feature = "salvo", not(feature = "axum")))]
 pub type Config = crate::Config<salvo::Router>;
-#[cfg(feature = "rocket")]
+#[cfg(all(feature = "rocket", not(any(feature = "axum", feature = "salvo"))))]
 pub type Config = crate::Config<rocket::Rocket<rocket::Build>>;
 
 /// Launches the WebView and runs the event loop, with configuration and root props.

+ 0 - 1
packages/router/Cargo.toml

@@ -35,7 +35,6 @@ default = []
 ssr = ["dioxus-ssr/incremental", "tokio", "dioxus-fullstack?/server"]
 liveview = ["dioxus-liveview", "tokio", "dep:serde", "serde_json"]
 wasm_test = []
-serde = ["dep:serde", "gloo-utils?/serde"]
 web = ["gloo", "web-sys", "wasm-bindgen", "gloo-utils", "js-sys"]
 fullstack = ["dioxus-fullstack"]
 

+ 0 - 78
packages/router/src/components/router.rs

@@ -11,18 +11,6 @@ pub struct RouterConfigFactory<R: Routable> {
     config: Rc<RefCell<Option<Box<dyn FnOnce() -> RouterConfig<R>>>>>,
 }
 
-#[cfg(feature = "serde")]
-impl<R: Routable> Default for RouterConfigFactory<R>
-where
-    <R as FromStr>::Err: std::fmt::Display,
-    R: serde::Serialize + serde::de::DeserializeOwned,
-{
-    fn default() -> Self {
-        Self::from(RouterConfig::default)
-    }
-}
-
-#[cfg(not(feature = "serde"))]
 impl<R: Routable> Default for RouterConfigFactory<R>
 where
     <R as FromStr>::Err: std::fmt::Display,
@@ -40,19 +28,6 @@ impl<R: Routable, F: FnOnce() -> RouterConfig<R> + 'static> From<F> for RouterCo
     }
 }
 
-#[cfg(feature = "serde")]
-/// The props for [`Router`].
-#[derive(Props)]
-pub struct RouterProps<R: Routable>
-where
-    <R as FromStr>::Err: std::fmt::Display,
-    R: serde::Serialize + serde::de::DeserializeOwned,
-{
-    #[props(default, into)]
-    config: RouterConfigFactory<R>,
-}
-
-#[cfg(not(feature = "serde"))]
 /// The props for [`Router`].
 #[derive(Props)]
 pub struct RouterProps<R: Routable>
@@ -74,23 +49,9 @@ where
     }
 }
 
-#[cfg(not(feature = "serde"))]
-impl<R: Routable> Default for RouterProps<R>
-where
-    <R as FromStr>::Err: std::fmt::Display,
-{
-    fn default() -> Self {
-        Self {
-            config: RouterConfigFactory::default(),
-        }
-    }
-}
-
-#[cfg(feature = "serde")]
 impl<R: Routable> Default for RouterProps<R>
 where
     <R as FromStr>::Err: std::fmt::Display,
-    R: serde::Serialize + serde::de::DeserializeOwned,
 {
     fn default() -> Self {
         Self {
@@ -99,22 +60,9 @@ where
     }
 }
 
-#[cfg(not(feature = "serde"))]
-impl<R: Routable> PartialEq for RouterProps<R>
-where
-    <R as FromStr>::Err: std::fmt::Display,
-{
-    fn eq(&self, _: &Self) -> bool {
-        // prevent the router from re-rendering when the initial url or config changes
-        true
-    }
-}
-
-#[cfg(feature = "serde")]
 impl<R: Routable> PartialEq for RouterProps<R>
 where
     <R as FromStr>::Err: std::fmt::Display,
-    R: serde::Serialize + serde::de::DeserializeOwned,
 {
     fn eq(&self, _: &Self) -> bool {
         // prevent the router from re-rendering when the initial url or config changes
@@ -122,7 +70,6 @@ where
     }
 }
 
-#[cfg(not(feature = "serde"))]
 /// A component that renders the current route.
 pub fn Router<R: Routable + Clone>(props: RouterProps<R>) -> Element
 where
@@ -148,28 +95,3 @@ where
 
     rsx! { Outlet::<R> {} }
 }
-
-#[cfg(feature = "serde")]
-/// A component that renders the current route.
-pub fn Router<R: Routable + Clone>(cx: ScopeState<RouterProps<R>>) -> Element
-where
-    <R as FromStr>::Err: std::fmt::Display,
-    R: serde::Serialize + serde::de::DeserializeOwned,
-{
-    use_context_provider(|| {
-        RouterContext::new(
-            (cx.props
-                .config
-                .config
-                .take()
-                .expect("use_context_provider ran twice"))(),
-            cx.schedule_update_any(),
-        )
-    });
-    use_context_provider(|| OutletContext::<R> {
-        current_level: 0,
-        _marker: std::marker::PhantomData,
-    });
-
-    rsx! { Outlet::<R> {} }
-}

+ 0 - 168
packages/router/src/history/web.rs

@@ -23,7 +23,6 @@ fn base_path() -> Option<&'static str> {
     base_path
 }
 
-#[cfg(not(feature = "serde"))]
 #[allow(clippy::extra_unused_type_parameters)]
 fn update_scroll<R>(window: &Window, history: &History) {
     let scroll = ScrollPosition::of_window(window);
@@ -32,27 +31,6 @@ fn update_scroll<R>(window: &Window, history: &History) {
     }
 }
 
-#[cfg(feature = "serde")]
-fn update_scroll<R: serde::Serialize + serde::de::DeserializeOwned + Routable>(
-    window: &Window,
-    history: &History,
-) {
-    if let Some(WebHistoryState { state, .. }) = get_current::<WebHistoryState<R>>(history) {
-        let scroll = ScrollPosition::of_window(window);
-        let state = WebHistoryState { state, scroll };
-        if let Err(err) = replace_state_with_url(history, &state, None) {
-            error!(err);
-        }
-    }
-}
-
-#[cfg(feature = "serde")]
-#[derive(serde::Deserialize, serde::Serialize)]
-struct WebHistoryState<R> {
-    state: R,
-    scroll: ScrollPosition,
-}
-
 /// A [`HistoryProvider`] that integrates with a browser via the [History API](https://developer.mozilla.org/en-US/docs/Web/API/History_API).
 ///
 /// # Prefix
@@ -75,21 +53,9 @@ pub struct WebHistory<R: Routable> {
     phantom: std::marker::PhantomData<R>,
 }
 
-#[cfg(not(feature = "serde"))]
-impl<R: Routable> Default for WebHistory<R>
-where
-    <R as std::str::FromStr>::Err: std::fmt::Display,
-{
-    fn default() -> Self {
-        Self::new(None, true)
-    }
-}
-
-#[cfg(feature = "serde")]
 impl<R: Routable> Default for WebHistory<R>
 where
     <R as std::str::FromStr>::Err: std::fmt::Display,
-    R: serde::Serialize + serde::de::DeserializeOwned,
 {
     fn default() -> Self {
         Self::new(None, true)
@@ -97,7 +63,6 @@ where
 }
 
 impl<R: Routable> WebHistory<R> {
-    #[cfg(not(feature = "serde"))]
     /// Create a new [`WebHistory`].
     ///
     /// If `do_scroll_restoration` is [`true`], [`WebHistory`] will take control of the history
@@ -116,47 +81,6 @@ impl<R: Routable> WebHistory<R> {
         myself
     }
 
-    #[cfg(feature = "serde")]
-    /// Create a new [`WebHistory`].
-    ///
-    /// If `do_scroll_restoration` is [`true`], [`WebHistory`] will take control of the history
-    /// state. It'll also set the browsers scroll restoration to `manual`.
-    pub fn new(prefix: Option<String>, do_scroll_restoration: bool) -> Self
-    where
-        <R as std::str::FromStr>::Err: std::fmt::Display,
-        R: serde::Serialize + serde::de::DeserializeOwned,
-    {
-        let w = window().expect("access to `window`");
-        let h = w.history().expect("`window` has access to `history`");
-        let document = w.document().expect("`window` has access to `document`");
-
-        let myself = Self::new_inner(
-            prefix,
-            do_scroll_restoration,
-            EventListener::new(&document, "scroll", {
-                let mut last_updated = 0.0;
-                move |evt| {
-                    // the time stamp in milliseconds
-                    let time_stamp = evt.time_stamp();
-                    // throttle the scroll event to 100ms
-                    if (time_stamp - last_updated) < 100.0 {
-                        return;
-                    }
-                    update_scroll::<R>(&w, &h);
-                    last_updated = time_stamp;
-                }
-            }),
-        );
-
-        let current_route = myself.current_route();
-        tracing::trace!("initial route: {:?}", current_route);
-        let current_url = current_route.to_string();
-        let state = myself.create_state(current_route);
-        let _ = replace_state_with_url(&myself.history, &state, Some(&current_url));
-
-        myself
-    }
-
     fn new_inner(prefix: Option<String>, do_scroll_restoration: bool) -> Self
     where
         <R as std::str::FromStr>::Err: std::fmt::Display,
@@ -191,17 +115,10 @@ impl<R: Routable> WebHistory<R> {
             .unwrap_or_default()
     }
 
-    #[cfg(not(feature = "serde"))]
     fn create_state(&self, _state: R) -> [f64; 2] {
         let scroll = self.scroll_pos();
         [scroll.x, scroll.y]
     }
-
-    #[cfg(feature = "serde")]
-    fn create_state(&self, state: R) -> WebHistoryState<R> {
-        let scroll = self.scroll_pos();
-        WebHistoryState { state, scroll }
-    }
 }
 
 impl<R: Routable> WebHistory<R>
@@ -254,91 +171,6 @@ where
     }
 }
 
-#[cfg(feature = "serde")]
-impl<R: serde::Serialize + serde::de::DeserializeOwned + Routable> HistoryProvider<R>
-    for WebHistory<R>
-where
-    <R as std::str::FromStr>::Err: std::fmt::Display,
-{
-    fn current_route(&self) -> R {
-        match get_current::<WebHistoryState<_>>(&self.history) {
-            // Try to get the route from the history state
-            Some(route) => route.state,
-            // If that fails, get the route from the current URL
-            None => self.route_from_location(),
-        }
-    }
-
-    fn current_prefix(&self) -> Option<String> {
-        self.prefix.clone()
-    }
-
-    fn go_back(&mut self) {
-        if let Err(e) = self.history.back() {
-            error!("failed to go back: ", e)
-        }
-    }
-
-    fn go_forward(&mut self) {
-        if let Err(e) = self.history.forward() {
-            error!("failed to go forward: ", e)
-        }
-    }
-
-    fn push(&mut self, state: R) {
-        use gloo_utils::format::JsValueSerdeExt;
-        if JsValue::from_serde(&state) != JsValue::from_serde(&self.current_route()) {
-            // don't push the same state twice
-            return;
-        }
-
-        let w = window().expect("access to `window`");
-        let h = w.history().expect("`window` has access to `history`");
-
-        // update the scroll position before pushing the new state
-        update_scroll::<R>(&w, &h);
-
-        let path = self.full_path(&state);
-
-        let state = self.create_state(state);
-
-        self.handle_nav(push_state_and_url(&self.history, &state, path));
-    }
-
-    fn replace(&mut self, state: R) {
-        let path = match &self.prefix {
-            None => format!("{state}"),
-            Some(prefix) => format!("{prefix}{state}"),
-        };
-
-        let state = self.create_state(state);
-
-        self.handle_nav(replace_state_with_url(&self.history, &state, Some(&path)));
-    }
-
-    fn external(&mut self, url: String) -> bool {
-        self.navigate_external(url)
-    }
-
-    fn updater(&mut self, callback: std::sync::Arc<dyn Fn() + Send + Sync>) {
-        let w = self.window.clone();
-        let h = self.history.clone();
-        let s = self.listener_animation_frame.clone();
-        let d = self.do_scroll_restoration;
-
-        self.listener_navigation = Some(EventListener::new(&self.window, "popstate", move |_| {
-            (*callback)();
-            if d {
-                let mut s = s.lock().expect("unpoisoned scroll mutex");
-                if let Some(current_state) = get_current::<WebHistoryState<R>>(&h) {
-                    *s = Some(current_state.scroll.scroll_to(w.clone()));
-                }
-            }
-        }));
-    }
-}
-
-#[cfg(not(feature = "serde"))]
 impl<R: Routable> HistoryProvider<R> for WebHistory<R>
 where
     <R as std::str::FromStr>::Err: std::fmt::Display,

+ 0 - 42
packages/router/src/history/web_history.rs

@@ -1,10 +1,7 @@
 use gloo::console::error;
-#[cfg(feature = "serde")]
-use gloo_utils::format::JsValueSerdeExt;
 use wasm_bindgen::JsValue;
 use web_sys::History;
 
-#[cfg(not(feature = "serde"))]
 pub(crate) fn replace_state_with_url(
     history: &History,
     value: &[f64; 2],
@@ -17,18 +14,6 @@ pub(crate) fn replace_state_with_url(
     history.replace_state_with_url(&position, "", url)
 }
 
-#[cfg(feature = "serde")]
-pub(crate) fn replace_state_with_url<V: serde::Serialize>(
-    history: &History,
-    value: &V,
-    url: Option<&str>,
-) -> Result<(), JsValue> {
-    let position = JsValue::from_serde(value).unwrap();
-
-    history.replace_state_with_url(&position, "", url)
-}
-
-#[cfg(not(feature = "serde"))]
 pub(crate) fn push_state_and_url(
     history: &History,
     value: &[f64; 2],
@@ -41,33 +26,6 @@ pub(crate) fn push_state_and_url(
     history.push_state_with_url(&position, "", Some(&url))
 }
 
-#[cfg(feature = "serde")]
-pub(crate) fn push_state_and_url<V: serde::Serialize>(
-    history: &History,
-    value: &V,
-    url: String,
-) -> Result<(), JsValue> {
-    let position = JsValue::from_serde(value).unwrap();
-
-    history.push_state_with_url(&position, "", Some(&url))
-}
-
-#[cfg(feature = "serde")]
-pub(crate) fn get_current<V: serde::de::DeserializeOwned>(history: &History) -> Option<V> {
-    let state = history.state();
-    if let Err(err) = &state {
-        error!(err);
-    }
-    state.ok().and_then(|state| {
-        let deserialized = state.into_serde();
-        if let Err(err) = &deserialized {
-            error!(format!("{}", err));
-        }
-        deserialized.ok()
-    })
-}
-
-#[cfg(not(feature = "serde"))]
 pub(crate) fn get_current(history: &History) -> Option<[f64; 2]> {
     use wasm_bindgen::JsCast;
 

+ 0 - 33
packages/router/src/router_cfg.rs

@@ -31,21 +31,6 @@ pub struct RouterConfig<R: Routable> {
     pub(crate) initial_route: Option<R>,
 }
 
-#[cfg(feature = "serde")]
-impl<R: Routable + Clone> Default for RouterConfig<R>
-where
-    <R as std::str::FromStr>::Err: std::fmt::Display,
-    R: serde::Serialize + serde::de::DeserializeOwned,
-{
-    fn default() -> Self {
-        Self {
-            failure_external_navigation: FailureExternalNavigation::<R>,
-            history: None,
-            on_update: None,
-        }
-    }
-}
-
 macro_rules! default_history {
     ($initial_route:ident) => {
         {
@@ -83,24 +68,6 @@ macro_rules! default_history {
     };
 }
 
-#[cfg(feature = "serde")]
-impl<R: Routable + Clone> RouterConfig<R>
-where
-    <R as std::str::FromStr>::Err: std::fmt::Display,
-    R: serde::Serialize + serde::de::DeserializeOwned,
-{
-    pub(crate) fn get_history(self) -> Box<dyn HistoryProvider<R>> {
-        #[allow(unused)]
-        let initial_route = self.initial_route.clone().unwrap_or("/".parse().unwrap_or_else(|err|
-            panic!("index route does not exist:\n{}\n use MemoryHistory::with_initial_path or RouterConfig::initial_route to set a custom path", err)
-        ));
-        self.history
-            .take()
-            .unwrap_or_else(|| default_history!(initial_route))
-    }
-}
-
-#[cfg(not(feature = "serde"))]
 impl<R: Routable + Clone> Default for RouterConfig<R>
 where
     <R as std::str::FromStr>::Err: std::fmt::Display,