diff --git a/examples/hackernews_js_fetch/Cargo.toml b/examples/hackernews_js_fetch/Cargo.toml
index 11c1e14ca..d08d22474 100644
--- a/examples/hackernews_js_fetch/Cargo.toml
+++ b/examples/hackernews_js_fetch/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-name = "hackernews-js-fetch"
+name = "hackernews_js_fetch"
version = "0.1.0"
edition = "2021"
@@ -11,21 +11,20 @@ codegen-units = 1
lto = true
[dependencies]
-console_log = "1.0.0"
-console_error_panic_hook = "0.1.7"
-cfg-if = "1.0.0"
+console_error_panic_hook = "0.1"
+console_log = "1.0"
+log = "0.4"
leptos = { path = "../../leptos" }
leptos_axum = { path = "../../integrations/axum", default-features = false, optional = true }
leptos_meta = { path = "../../meta" }
leptos_router = { path = "../../router" }
-log = "0.4.17"
-simple_logger = "4.0.0"
-serde = { version = "1.0.148", features = ["derive"] }
+leptos_server = { path = "../../leptos_server", optional = true }
+serde = { version = "1.0", features = ["derive"] }
tracing = "0.1"
gloo-net = { version = "0.6", features = ["http"] }
reqwest = { version = "0.12", features = ["json"] }
axum = { version = "0.7", default-features = false, optional = true }
-tower = { version = "0.4.13", optional = true }
+tower = { version = "0.4", optional = true }
http = { version = "1.0", optional = true }
web-sys = { version = "0.3", features = [
"AbortController",
@@ -33,41 +32,43 @@ web-sys = { version = "0.3", features = [
"Request",
"Response",
] }
+getrandom = { version = "0.2.7", features = ["js"] }
wasm-bindgen = "0.2"
wasm-bindgen-futures = { version = "0.4.37", features = [
"futures-core-03-stream",
], optional = true }
axum-js-fetch = { git = "https://github.com/seanaye/axum-js-fetch", optional = true }
-lazy_static = "1.4.0"
+send_wrapper = { version = "0.6.0", features = ["futures"] }
[features]
-hydrate = ["leptos/hydrate", "leptos_meta/hydrate", "leptos_router/hydrate"]
+hydrate = ["leptos/hydrate"]
ssr = [
+ "dep:axum",
"dep:tower",
"dep:http",
- "dep:axum",
"dep:wasm-bindgen-futures",
"dep:axum-js-fetch",
"leptos/ssr",
"leptos_axum/wasm",
"leptos_meta/ssr",
"leptos_router/ssr",
+ "leptos_server/serde-wasm-bindgen",
]
[package.metadata.cargo-all-features]
denylist = ["axum", "tower", "http", "leptos_axum"]
-skip_feature_sets = [["ssr", "hydrate"]]
+skip_feature_sets = [["csr", "ssr"], ["csr", "hydrate"], ["ssr", "hydrate"]]
[package.metadata.leptos]
# The name used by wasm-bindgen/cargo-leptos for the JS/WASM bundle. Defaults to the crate name
-output-name = "hackernews_axum"
+output-name = "hackernews_js_fetch"
# The site root folder is where cargo-leptos generate all output. WARNING: all content of this folder will be erased on a rebuild. Use it in your server setup.
site-root = "target/site"
# The site-root relative folder where all compiled output (JS, WASM and CSS) is written
# Defaults to pkg
site-pkg-dir = "pkg"
# [Optional] The source CSS file. If it ends with .sass or .scss then it will be compiled by dart-sass into CSS. The CSS is optimized by Lightning CSS before being written to //app.css
-style-file = "./style.css"
+style-file = "style.css"
# [Optional] Files in the asset-dir will be copied to the site-root directory
assets-dir = "public"
# The IP and port (ex: 127.0.0.1:3000) where the server serves the content. Use it in your server setup.
diff --git a/examples/hackernews_js_fetch/Makefile.toml b/examples/hackernews_js_fetch/Makefile.toml
index 6d2dcf0bf..0a7519bc2 100644
--- a/examples/hackernews_js_fetch/Makefile.toml
+++ b/examples/hackernews_js_fetch/Makefile.toml
@@ -1,6 +1,6 @@
extend = [
- { path = "../cargo-make/main.toml" },
- { path = "../cargo-make/deno-build.toml" },
+ { path = "../cargo-make/main.toml" },
+ { path = "../cargo-make/deno-build.toml" },
]
[env]
diff --git a/examples/hackernews_js_fetch/README.md b/examples/hackernews_js_fetch/README.md
index c23a03029..e1f22c225 100644
--- a/examples/hackernews_js_fetch/README.md
+++ b/examples/hackernews_js_fetch/README.md
@@ -2,8 +2,6 @@
This example uses the basic Hacker News example as its basis, but shows how to run the server side as WASM running in a JS environment. In this example, Deno is used as the runtime.
-**NOTE**: This example is slightly out of date pending an update to [`axum-js-fetch`](https://github.com/seanaye/axum-js-fetch/), which was waiting on a version of `gloo-net` that uses `http` 1.0. It still works with Leptos 0.5 and Axum 0.6, but not with the versions of Leptos (0.6 and later) that support Axum 1.0.
-
## Server Side Rendering with Deno
To run the Deno version, run
diff --git a/examples/hackernews_js_fetch/deno.lock b/examples/hackernews_js_fetch/deno.lock
index 7d8564bb9..81642bd5d 100644
--- a/examples/hackernews_js_fetch/deno.lock
+++ b/examples/hackernews_js_fetch/deno.lock
@@ -1,5 +1,8 @@
{
- "version": "2",
+ "version": "3",
+ "redirects": {
+ "https://deno.land/std/http/file_server.ts": "https://deno.land/std@0.224.0/http/file_server.ts"
+ },
"remote": {
"https://deno.land/std@0.177.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462",
"https://deno.land/std@0.177.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3",
@@ -53,6 +56,49 @@
"https://deno.land/std@0.177.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d",
"https://deno.land/std@0.177.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1",
"https://deno.land/std@0.177.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba",
- "https://deno.land/std@0.177.0/version.ts": "259c8866ec257c3511b437baa95205a86761abaef852a9b2199072accb2ef046"
+ "https://deno.land/std@0.177.0/version.ts": "259c8866ec257c3511b437baa95205a86761abaef852a9b2199072accb2ef046",
+ "https://deno.land/std@0.224.0/assert/assert.ts": "09d30564c09de846855b7b071e62b5974b001bb72a4b797958fe0660e7849834",
+ "https://deno.land/std@0.224.0/assert/assertion_error.ts": "ba8752bd27ebc51f723702fac2f54d3e94447598f54264a6653d6413738a8917",
+ "https://deno.land/std@0.224.0/cli/parse_args.ts": "5250832fb7c544d9111e8a41ad272c016f5a53f975ef84d5a9fe5fcb70566ece",
+ "https://deno.land/std@0.224.0/encoding/_util.ts": "beacef316c1255da9bc8e95afb1fa56ed69baef919c88dc06ae6cb7a6103d376",
+ "https://deno.land/std@0.224.0/encoding/base64.ts": "dd59695391584c8ffc5a296ba82bcdba6dd8a84d41a6a539fbee8e5075286eaf",
+ "https://deno.land/std@0.224.0/fmt/bytes.ts": "7b294a4b9cf0297efa55acb55d50610f3e116a0ac772d1df0ae00f0b833ccd4a",
+ "https://deno.land/std@0.224.0/fmt/colors.ts": "508563c0659dd7198ba4bbf87e97f654af3c34eb56ba790260f252ad8012e1c5",
+ "https://deno.land/std@0.224.0/http/etag.ts": "9ca56531be682f202e4239971931060b688ee5c362688e239eeaca39db9e72cb",
+ "https://deno.land/std@0.224.0/http/file_server.ts": "2a5392195b8e7713288f274d071711b705bb5b3220294d76cce495d456c61a93",
+ "https://deno.land/std@0.224.0/http/status.ts": "ed61b4882af2514a81aefd3245e8df4c47b9a8e54929a903577643d2d1ebf514",
+ "https://deno.land/std@0.224.0/media_types/_db.ts": "19563a2491cd81b53b9c1c6ffd1a9145c355042d4a854c52f6e1424f73ff3923",
+ "https://deno.land/std@0.224.0/media_types/_util.ts": "e0b8da0c7d8ad2015cf27ac16ddf0809ac984b2f3ec79f7fa4206659d4f10deb",
+ "https://deno.land/std@0.224.0/media_types/content_type.ts": "ed3f2e1f243b418ad3f441edc95fd92efbadb0f9bde36219c7564c67f9639513",
+ "https://deno.land/std@0.224.0/media_types/format_media_type.ts": "ffef4718afa2489530cb94021bb865a466eb02037609f7e82899c017959d288a",
+ "https://deno.land/std@0.224.0/media_types/get_charset.ts": "277ebfceb205bd34e616fe6764ef03fb277b77f040706272bea8680806ae3f11",
+ "https://deno.land/std@0.224.0/media_types/parse_media_type.ts": "487f000a38c230ccbac25420a50f600862e06796d0eee19d19631b9e84ee9654",
+ "https://deno.land/std@0.224.0/media_types/type_by_extension.ts": "bf4e3f5d6b58b624d5daa01cbb8b1e86d9939940a77e7c26e796a075b60ec73b",
+ "https://deno.land/std@0.224.0/media_types/vendor/mime-db.v1.52.0.ts": "0218d2c7d900e8cd6fa4a866e0c387712af4af9a1bae55d6b2546c73d273a1e6",
+ "https://deno.land/std@0.224.0/path/_common/assert_path.ts": "dbdd757a465b690b2cc72fc5fb7698c51507dec6bfafce4ca500c46b76ff7bd8",
+ "https://deno.land/std@0.224.0/path/_common/constants.ts": "dc5f8057159f4b48cd304eb3027e42f1148cf4df1fb4240774d3492b5d12ac0c",
+ "https://deno.land/std@0.224.0/path/_common/normalize.ts": "684df4aa71a04bbcc346c692c8485594fc8a90b9408dfbc26ff32cf3e0c98cc8",
+ "https://deno.land/std@0.224.0/path/_common/normalize_string.ts": "33edef773c2a8e242761f731adeb2bd6d683e9c69e4e3d0092985bede74f4ac3",
+ "https://deno.land/std@0.224.0/path/_common/relative.ts": "faa2753d9b32320ed4ada0733261e3357c186e5705678d9dd08b97527deae607",
+ "https://deno.land/std@0.224.0/path/_os.ts": "8fb9b90fb6b753bd8c77cfd8a33c2ff6c5f5bc185f50de8ca4ac6a05710b2c15",
+ "https://deno.land/std@0.224.0/path/constants.ts": "0c206169ca104938ede9da48ac952de288f23343304a1c3cb6ec7625e7325f36",
+ "https://deno.land/std@0.224.0/path/extname.ts": "593303db8ae8c865cbd9ceec6e55d4b9ac5410c1e276bfd3131916591b954441",
+ "https://deno.land/std@0.224.0/path/join.ts": "ae2ec5ca44c7e84a235fd532e4a0116bfb1f2368b394db1c4fb75e3c0f26a33a",
+ "https://deno.land/std@0.224.0/path/posix/_util.ts": "1e3937da30f080bfc99fe45d7ed23c47dd8585c5e473b2d771380d3a6937cf9d",
+ "https://deno.land/std@0.224.0/path/posix/extname.ts": "e398c1d9d1908d3756a7ed94199fcd169e79466dd88feffd2f47ce0abf9d61d2",
+ "https://deno.land/std@0.224.0/path/posix/join.ts": "7fc2cb3716aa1b863e990baf30b101d768db479e70b7313b4866a088db016f63",
+ "https://deno.land/std@0.224.0/path/posix/normalize.ts": "baeb49816a8299f90a0237d214cef46f00ba3e95c0d2ceb74205a6a584b58a91",
+ "https://deno.land/std@0.224.0/path/posix/relative.ts": "3907d6eda41f0ff723d336125a1ad4349112cd4d48f693859980314d5b9da31c",
+ "https://deno.land/std@0.224.0/path/posix/resolve.ts": "08b699cfeee10cb6857ccab38fa4b2ec703b0ea33e8e69964f29d02a2d5257cf",
+ "https://deno.land/std@0.224.0/path/relative.ts": "ab739d727180ed8727e34ed71d976912461d98e2b76de3d3de834c1066667add",
+ "https://deno.land/std@0.224.0/path/resolve.ts": "a6f977bdb4272e79d8d0ed4333e3d71367cc3926acf15ac271f1d059c8494d8d",
+ "https://deno.land/std@0.224.0/path/windows/_util.ts": "d5f47363e5293fced22c984550d5e70e98e266cc3f31769e1710511803d04808",
+ "https://deno.land/std@0.224.0/path/windows/extname.ts": "165a61b00d781257fda1e9606a48c78b06815385e7d703232548dbfc95346bef",
+ "https://deno.land/std@0.224.0/path/windows/join.ts": "8d03530ab89195185103b7da9dfc6327af13eabdcd44c7c63e42e27808f50ecf",
+ "https://deno.land/std@0.224.0/path/windows/normalize.ts": "78126170ab917f0ca355a9af9e65ad6bfa5be14d574c5fb09bb1920f52577780",
+ "https://deno.land/std@0.224.0/path/windows/relative.ts": "3e1abc7977ee6cc0db2730d1f9cb38be87b0ce4806759d271a70e4997fc638d7",
+ "https://deno.land/std@0.224.0/path/windows/resolve.ts": "8dae1dadfed9d46ff46cc337c9525c0c7d959fb400a6308f34595c45bdca1972",
+ "https://deno.land/std@0.224.0/streams/byte_slice_stream.ts": "5bbdcadb118390affa9b3d0a0f73ef8e83754f59bb89df349add669dd9369713",
+ "https://deno.land/std@0.224.0/version.ts": "f6a28c9704d82d1c095988777e30e6172eb674a6570974a0d27a653be769bbbe"
}
}
diff --git a/examples/hackernews_js_fetch/src/api.rs b/examples/hackernews_js_fetch/src/api.rs
index 99c44c6e3..4ca650481 100644
--- a/examples/hackernews_js_fetch/src/api.rs
+++ b/examples/hackernews_js_fetch/src/api.rs
@@ -1,5 +1,5 @@
-use leptos::Serializable;
-use serde::{Deserialize, Serialize};
+use leptos::logging;
+use serde::{de::DeserializeOwned, Deserialize, Serialize};
pub fn story(path: &str) -> String {
format!("https://node-hnapi.herokuapp.com/{path}")
@@ -10,46 +10,51 @@ pub fn user(path: &str) -> String {
}
#[cfg(not(feature = "ssr"))]
-pub async fn fetch_api(path: &str) -> Option
+pub fn fetch_api(
+ path: &str,
+) -> impl std::future::Future
- }
- }
- />
- }
- .into_view()
-}
diff --git a/examples/hackernews_js_fetch/src/fallback.rs b/examples/hackernews_js_fetch/src/fallback.rs
deleted file mode 100644
index dddebd1ca..000000000
--- a/examples/hackernews_js_fetch/src/fallback.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-use crate::error_template::error_template;
-use axum::{
- body::Body,
- extract::State,
- http::{Request, Response, StatusCode, Uri},
- response::{IntoResponse, Response as AxumResponse},
-};
-//use tower::ServiceExt;
-use leptos::LeptosOptions;
-
-pub async fn file_and_error_handler(
- uri: Uri,
- State(options): State,
- req: Request,
-) -> AxumResponse {
- let root = options.site_root.clone();
- let res = get_static_file(uri.clone(), &root).await.unwrap();
-
- if res.status() == StatusCode::OK {
- res.into_response()
- } else {
- let handler =
- leptos_axum::render_app_to_stream(options.to_owned(), || {
- error_template(None)
- });
- handler(req).await.into_response()
- }
-}
-
-async fn get_static_file(
- uri: Uri,
- root: &str,
-) -> Result, (StatusCode, String)> {
- let req = Request::builder()
- .uri(uri.clone())
- .body(Body::empty())
- .unwrap();
- // `ServeDir` implements `tower::Service` so we can call it with `tower::ServiceExt::oneshot`
- // This path is relative to the cargo root
- _ = req;
- _ = root;
- todo!()
-}
diff --git a/examples/hackernews_js_fetch/src/lib.rs b/examples/hackernews_js_fetch/src/lib.rs
index ec85418a6..c365687e7 100644
--- a/examples/hackernews_js_fetch/src/lib.rs
+++ b/examples/hackernews_js_fetch/src/lib.rs
@@ -1,46 +1,71 @@
-use leptos::{component, view, IntoView};
-use leptos_meta::*;
-use leptos_router::*;
+use leptos::prelude::*;
mod api;
-pub mod error_template;
-#[cfg(feature = "ssr")]
-pub mod fallback;
mod routes;
+use leptos_meta::{provide_meta_context, Link, Meta, MetaTags, Stylesheet};
+use leptos_router::{
+ components::{FlatRoutes, Route, Router, RoutingProgress},
+ ParamSegment, StaticSegment,
+};
use routes::{nav::*, stories::*, story::*, users::*};
-use wasm_bindgen::prelude::wasm_bindgen;
+use std::time::Duration;
+
+pub fn shell(options: LeptosOptions) -> impl IntoView {
+ view! {
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+}
#[component]
pub fn App() -> impl IntoView {
provide_meta_context();
+ let (is_routing, set_is_routing) = signal(false);
+
view! {
-
+
-
-
+
+ // shows a progress bar while async data are loading
+
+
+
+
-
-
-
-
-
+
+
+
+
+ // TODO allow optional params without duplication
+
+
}
}
#[cfg(feature = "hydrate")]
-#[wasm_bindgen]
+#[wasm_bindgen::prelude::wasm_bindgen]
pub fn hydrate() {
- _ = console_log::init_with_level(log::Level::Debug);
console_error_panic_hook::set_once();
- leptos::mount_to_body(App);
+ leptos::mount::hydrate_body(App);
}
#[cfg(feature = "ssr")]
mod ssr_imports {
- use crate::App;
- use axum::{routing::post, Router};
+ use crate::{shell, App};
+ use axum::Router;
use leptos::prelude::*;
use leptos_axum::{generate_route_list, LeptosRoutes};
use log::{info, Level};
@@ -59,12 +84,15 @@ mod ssr_imports {
.output_name("client")
.site_pkg_dir("pkg")
.build();
+
let routes = generate_route_list(App);
// build our application with a route
- let app: axum::Router<()> = Router::new()
- .leptos_routes(&leptos_options, routes, App)
- .route("/api/*fn_name", post(leptos_axum::handle_server_fns))
+ let app = Router::new()
+ .leptos_routes(&leptos_options, routes, {
+ let leptos_options = leptos_options.clone();
+ move || shell(leptos_options.clone())
+ })
.with_state(leptos_options);
info!("creating handler instance");
diff --git a/examples/hackernews_js_fetch/src/routes/nav.rs b/examples/hackernews_js_fetch/src/routes/nav.rs
index b4dd03cc0..aee41f074 100644
--- a/examples/hackernews_js_fetch/src/routes/nav.rs
+++ b/examples/hackernews_js_fetch/src/routes/nav.rs
@@ -1,12 +1,12 @@
-use leptos::{component, view, IntoView};
-use leptos_router::*;
+use leptos::prelude::*;
+use leptos_router::components::A;
#[component]
pub fn Nav() -> impl IntoView {
view! {
- {if story.comments_count.unwrap_or_default() > 0 { - format!("{} comments", story.comments_count.unwrap_or_default()) - } else { - "No comments yet.".into() - }} -
--
-
-
-
++ {if story.comments_count.unwrap_or_default() > 0 { + format!("{} comments", story.comments_count.unwrap_or_default()) + } else { + "No comments yet.".into() + }} +
++
+
+
+
+