>();
-view! {
- "+1"
- {move || state.with(|state| state.name.clone())}
-}
-```
-
-In this example, clicking the button will cause the text inside `` to be updated, cloning `state.name` again! Because signals are the atomic unit of reactivity, updating any field of the signal triggers updates to everything that depends on the signal.
-
-There’s a better way. You can take fine-grained, reactive slices by using [`create_memo`](https://docs.rs/leptos/latest/leptos/fn.create_memo.html) or [`create_slice`](https://docs.rs/leptos/latest/leptos/fn.create_slice.html) (which uses `create_memo` but also provides a setter). “Memoizing” a value means creating a new reactive value which will only update when it changes. “Memoizing a slice” means creating a new reactive value which will only update when some field of the state struct updates.
-
-Here, instead of reading from the state signal directly, we create “slices” of that state with fine-grained updates via `create_slice`. Each slice signal only updates when the particular piece of the larger struct it accesses updates. This means you can create a single root signal, and then take independent, fine-grained slices of it in different components, each of which can update without notifying the others of changes.
-
-```rust
-/// A component that updates the count in the global state.
-#[component]
-fn GlobalStateCounter() -> impl IntoView {
- let state = expect_context::>();
-
- // `create_slice` lets us create a "lens" into the data
- let (count, set_count) = create_slice(
-
- // we take a slice *from* `state`
- state,
- // our getter returns a "slice" of the data
- |state| state.count,
- // our setter describes how to mutate that slice, given a new value
- |state, n| state.count = n,
- );
-
- view! {
-
-
- "Increment Global Count"
-
-
- "Count is: " {count}
-
- }
-}
-```
-
-Clicking this button only updates `state.count`, so if we create another slice
-somewhere else that only takes `state.name`, clicking the button won’t cause
-that other slice to update. This allows you to combine the benefits of a top-down
-data flow and of fine-grained reactive updates.
-
-> **Note**: There are some significant drawbacks to this approach. Both signals and memos need to own their values, so a memo will need to clone the field’s value on every change. The most natural way to manage state in a framework like Leptos is always to provide signals that are as locally-scoped and fine-grained as they can be, not to hoist everything up into global state. But when you _do_ need some kind of global state, `create_slice` can be a useful tool.
-
-[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/15-global-state-0-5-8c2ff6?file=%2Fsrc%2Fmain.rs%3A1%2C2)
-
-
-
-
-CodeSandbox Source
-
-```rust
-use leptos::*;
-
-// So far, we've only been working with local state in components
-// We've only seen how to communicate between parent and child components
-// But there are also more general ways to manage global state
-//
-// The three best approaches to global state are
-// 1. Using the router to drive global state via the URL
-// 2. Passing signals through context
-// 3. Creating a global state struct and creating lenses into it with `create_slice`
-//
-// Option #1: URL as Global State
-// The next few sections of the tutorial will be about the router.
-// So for now, we'll just look at options #2 and #3.
-
-// Option #2: Pass Signals through Context
-//
-// In virtual DOM libraries like React, using the Context API to manage global
-// state is a bad idea: because the entire app exists in a tree, changing
-// some value provided high up in the tree can cause the whole app to render.
-//
-// In fine-grained reactive libraries like Leptos, this is simply not the case.
-// You can create a signal in the root of your app and pass it down to other
-// components using provide_context(). Changing it will only cause rerendering
-// in the specific places it is actually used, not the whole app.
-#[component]
-fn Option2() -> impl IntoView {
- // here we create a signal in the root that can be consumed
- // anywhere in the app.
- let (count, set_count) = create_signal(0);
- // we'll pass the setter to specific components,
- // but provide the count itself to the whole app via context
- provide_context(count);
-
- view! {
- "Option 2: Passing Signals"
- // SetterButton is allowed to modify the count
-
- // These consumers can only read from it
- // But we could give them write access by passing `set_count` if we wanted
-
-
-
-
- }
-}
-
-/// A button that increments our global counter.
-#[component]
-fn SetterButton(set_count: WriteSignal) -> impl IntoView {
- view! {
-
-
- "Increment Global Count"
-
-
- }
-}
-
-/// A component that does some "fancy" math with the global count
-#[component]
-fn FancyMath() -> impl IntoView {
- // here we consume the global count signal with `use_context`
- let count = use_context::>()
- // we know we just provided this in the parent component
- .expect("there to be a `count` signal provided");
- let is_even = move || count() & 1 == 0;
-
- view! {
-
- "The number "
- {count}
- {move || if is_even() {
- " is"
- } else {
- " is not"
- }}
- " even."
-
- }
-}
-
-/// A component that shows a list of items generated from the global count.
-#[component]
-fn ListItems() -> impl IntoView {
- // again, consume the global count signal with `use_context`
- let count = use_context::>().expect("there to be a `count` signal provided");
-
- let squares = move || {
- (0..count())
- .map(|n| view! { {n}"2" " is " {n * n} })
- .collect::>()
- };
-
- view! {
-
- }
-}
-
-// Option #3: Create a Global State Struct
-//
-// You can use this approach to build a single global data structure
-// that holds the state for your whole app, and then access it by
-// taking fine-grained slices using `create_slice` or `create_memo`,
-// so that changing one part of the state doesn't cause parts of your
-// app that depend on other parts of the state to change.
-
-#[derive(Default, Clone, Debug)]
-struct GlobalState {
- count: u32,
- name: String,
-}
-
-#[component]
-fn Option3() -> impl IntoView {
- // we'll provide a single signal that holds the whole state
- // each component will be responsible for creating its own "lens" into it
- let state = create_rw_signal(GlobalState::default());
- provide_context(state);
-
- view! {
- "Option 3: Passing Signals"
-
-
"Current Global State"
-
- {move || {
- format!("{:#?}", state.get())
- }}
-
-
-
-
-
-
- }
-}
-
-/// A component that updates the count in the global state.
-#[component]
-fn GlobalStateCounter() -> impl IntoView {
- let state = use_context::>().expect("state to have been provided");
-
- // `create_slice` lets us create a "lens" into the data
- let (count, set_count) = create_slice(
-
- // we take a slice *from* `state`
- state,
- // our getter returns a "slice" of the data
- |state| state.count,
- // our setter describes how to mutate that slice, given a new value
- |state, n| state.count = n,
- );
-
- view! {
-
-
- "Increment Global Count"
-
-
- "Count is: " {count}
-
- }
-}
-
-/// A component that updates the count in the global state.
-#[component]
-fn GlobalStateInput() -> impl IntoView {
- let state = use_context::>().expect("state to have been provided");
-
- // this slice is completely independent of the `count` slice
- // that we created in the other component
- // neither of them will cause the other to rerun
- let (name, set_name) = create_slice(
- // we take a slice *from* `state`
- state,
- // our getter returns a "slice" of the data
- |state| state.name.clone(),
- // our setter describes how to mutate that slice, given a new value
- |state, n| state.name = n,
- );
-
- view! {
-
-
-
- "Name is: " {name}
-
- }
-}
-// This `main` function is the entry point into the app
-// It just mounts our component to the
-// Because we defined it as `fn App`, we can now use it in a
-// template as
-fn main() {
- leptos::mount_to_body(|| view! { })
-}
-```
-
-
-
+
+
diff --git a/docs/book/src/appendix_reactive_graph.md b/docs/book/src/appendix_reactive_graph.md
index b2c82770ed..c796cea688 100644
--- a/docs/book/src/appendix_reactive_graph.md
+++ b/docs/book/src/appendix_reactive_graph.md
@@ -1,243 +1,2 @@
-# Appendix: How does the Reactive System Work?
-
-You don’t need to know very much about how the reactive system actually works in order to use the library successfully. But it’s always useful to understand what’s going on behind the scenes once you start working with the framework at an advanced level.
-
-The reactive primitives you use are divided into three sets:
-
-- **Signals** (`ReadSignal`/`WriteSignal`, `RwSignal`, `Resource`, `Trigger`) Values you can actively change to trigger reactive updates.
-- **Computations** (`Memo`s) Values that depend on signals (or other computations) and derive a new reactive value through some pure computation.
-- **Effects** Observers that listen to changes in some signals or computations and run a function, causing some side effect.
-
-Derived signals are a kind of non-primitve computation: as plain closures, they simply allow you to refactor some repeated signal-based computation into a reusable function that can be called in multiple places, but they are not represented in the reactive system itself.
-
-All the other primitives actually exist in the reactive system as nodes in a reactive graph.
-
-Most of the work of the reactive system consists of propagating changes from signals to effects, possibly through some intervening memos.
-
-The assumption of the reactive system is that effects (like rendering to the DOM or making a network request) are orders of magnitude more expensive than things like updating a Rust data structure inside your app.
-
-So the **primary goal** of the reactive system is to **run effects as infrequently as possible**.
-
-Leptos does this through the construction of a reactive graph.
-
-> Leptos’s current reactive system is based heavily on the [Reactively](https://github.com/modderme123/reactively) library for JavaScript. You can read Milo’s article “[Super-Charging Fine-Grained Reactivity](https://dev.to/modderme123/super-charging-fine-grained-reactive-performance-47ph)” for an excellent account of its algorithm, as well as fine-grained reactivity in general—including some beautiful diagrams!
-
-## The Reactive Graph
-
-Signals, memos, and effects all share three characteristics:
-
-- **Value** They have a current value: either the signal’s value, or (for memos and effects) the value returned by the previous run, if any.
-- **Sources** Any other reactive primitives they depend on. (For signals, this is an empty set.)
-- **Subscribers** Any other reactive primitives that depend on them. (For effects, this is an empty set.)
-
-In reality then, signals, memos, and effects are just conventional names for one generic concept of a “node” in a reactive graph. Signals are always “root nodes,” with no sources/parents. Effects are always “leaf nodes,” with no subscribers. Memos typically have both sources and subscribers.
-
-### Simple Dependencies
-
-So imagine the following code:
-
-```rust
-// A
-let (name, set_name) = create_signal("Alice");
-
-// B
-let name_upper = create_memo(move |_| name.with(|n| n.to_uppercase()));
-
-// C
-create_effect(move |_| {
- log!("{}", name_upper());
-});
-
-set_name("Bob");
-```
-
-You can easily imagine the reactive graph here: `name` is the only signal/origin node, the `create_effect` is the only effect/terminal node, and there’s one intervening memo.
-
-```
-A (name)
-|
-B (name_upper)
-|
-C (the effect)
-```
-
-### Splitting Branches
-
-Let’s make it a little more complex.
-
-```rust
-// A
-let (name, set_name) = create_signal("Alice");
-
-// B
-let name_upper = create_memo(move |_| name.with(|n| n.to_uppercase()));
-
-// C
-let name_len = create_memo(move |_| name.len());
-
-// D
-create_effect(move |_| {
- log!("len = {}", name_len());
-});
-
-// E
-create_effect(move |_| {
- log!("name = {}", name_upper());
-});
-```
-
-This is also pretty straightforward: a signal source signal (`name`/`A`) divides into two parallel tracks: `name_upper`/`B` and `name_len`/`C`, each of which has an effect that depends on it.
-
-```
- __A__
-| |
-B C
-| |
-D E
-```
-
-Now let’s update the signal.
-
-```rust
-set_name("Bob");
-```
-
-We immediately log
-
-```
-len = 3
-name = BOB
-```
-
-Let’s do it again.
-
-```rust
-set_name("Tim");
-```
-
-The log should shows
-
-```
-name = TIM
-```
-
-`len = 3` does not log again.
-
-Remember: the goal of the reactive system is to run effects as infrequently as possible. Changing `name` from `"Bob"` to `"Tim"` will cause each of the memos to re-run. But they will only notify their subscribers if their value has actually changed. `"BOB"` and `"TIM"` are different, so that effect runs again. But both names have the length `3`, so they do not run again.
-
-### Reuniting Branches
-
-One more example, of what’s sometimes called **the diamond problem**.
-
-```rust
-// A
-let (name, set_name) = create_signal("Alice");
-
-// B
-let name_upper = create_memo(move |_| name.with(|n| n.to_uppercase()));
-
-// C
-let name_len = create_memo(move |_| name.len());
-
-// D
-create_effect(move |_| {
- log!("{} is {} characters long", name_upper(), name_len());
-});
-```
-
-What does the graph look like for this?
-
-```
- __A__
-| |
-B C
-| |
-|__D__|
-```
-
-You can see why it's called the “diamond problem.” If I’d connected the nodes with straight lines instead of bad ASCII art, it would form a diamond: two memos, each of which depend on a signal, which feed into the same effect.
-
-A naive, push-based reactive implementation would cause this effect to run twice, which would be bad. (Remember, our goal is to run effects as infrequently as we can.) For example, you could implement a reactive system such that signals and memos immediately propagate their changes all the way down the graph, through each dependency, essentially traversing the graph depth-first. In other words, updating `A` would notify `B`, which would notify `D`; then `A` would notify `C`, which would notify `D` again. This is both inefficient (`D` runs twice) and glitchy (`D` actually runs with the incorrect value for the second memo during its first run.)
-
-## Solving the Diamond Problem
-
-Any reactive implementation worth its salt is dedicated to solving this issue. There are a number of different approaches (again, [see Milo’s article](https://dev.to/modderme123/super-charging-fine-grained-reactive-performance-47ph) for an excellent overview).
-
-Here’s how ours works, in brief.
-
-A reactive node is always in one of three states:
-
-- `Clean`: it is known not to have changed
-- `Check`: it is possible it has changed
-- `Dirty`: it has definitely changed
-
-Updating a signal `Dirty` marks that signal `Dirty`, and marks all its descendants `Check`, recursively. Any of its descendants that are effects are added to a queue to be re-run.
-
-```
- ____A (DIRTY)___
- | |
-B (CHECK) C (CHECK)
- | |
- |____D (CHECK)__|
-```
-
-Now those effects are run. (All of the effects will be marked `Check` at this point.) Before re-running its computation, the effect checks its parents to see if they are dirty. So
-
-- So `D` goes to `B` and checks if it is `Dirty`.
-- But `B` is also marked `Check`. So `B` does the same thing:
- - `B` goes to `A`, and finds that it is `Dirty`.
- - This means `B` needs to re-run, because one of its sources has changed.
- - `B` re-runs, generating a new value, and marks itself `Clean`
- - Because `B` is a memo, it then checks its prior value against the new value.
- - If they are the same, `B` returns "no change." Otherwise, it returns "yes, I changed."
-- If `B` returned “yes, I changed,” `D` knows that it definitely needs to run and re-runs immediately before checking any other sources.
-- If `B` returned “no, I didn’t change,” `D` continues on to check `C` (see process above for `B`.)
-- If neither `B` nor `C` has changed, the effect does not need to re-run.
-- If either `B` or `C` did change, the effect now re-runs.
-
-Because the effect is only marked `Check` once and only queued once, it only runs once.
-
-If the naive version was a “push-based” reactive system, simply pushing reactive changes all the way down the graph and therefore running the effect twice, this version could be called “push-pull.” It pushes the `Check` status all the way down the graph, but then “pulls” its way back up. In fact, for large graphs it may end up bouncing back up and down and left and right on the graph as it tries to determine exactly which nodes need to re-run.
-
-**Note this important trade-off**: Push-based reactivity propagates signal changes more quickly, at the expense of over-re-running memos and effects. Remember: the reactive system is designed to minimize how often you re-run effects, on the (accurate) assumption that side effects are orders of magnitude more expensive than this kind of cache-friendly graph traversal happening entirely inside the library’s Rust code. The measurement of a good reactive system is not how quickly it propagates changes, but how quickly it propagates changes _without over-notifying_.
-
-## Memos vs. Signals
-
-Note that signals always notify their children; i.e., a signal is always marked `Dirty` when it updates, even if its new value is the same as the old value. Otherwise, we’d have to require `PartialEq` on signals, and this is actually quite an expensive check on some types. (For example, add an unnecessary equality check to something like `some_vec_signal.update(|n| n.pop())` when it’s clear that it has in fact changed.)
-
-Memos, on the other hand, check whether they change before notifying their children. They only run their calculation once, no matter how many times you `.get()` the result, but they run whenever their signal sources change. This means that if the memo’s computation is _very_ expensive, you may actually want to memoize its inputs as well, so that the memo only re-calculates when it is sure its inputs have changed.
-
-## Memos vs. Derived Signals
-
-All of this is cool, and memos are pretty great. But most actual applications have reactive graphs that are quite shallow and quite wide: you might have 100 source signals and 500 effects, but no memos or, in rare case, three or four memos between the signal and the effect. Memos are extremely good at what they do: limiting how often they notify their subscribers that they have changed. But as this description of the reactive system should show, they come with overhead in two forms:
-
-1. A `PartialEq` check, which may or may not be expensive.
-2. Added memory cost of storing another node in the reactive system.
-3. Added computational cost of reactive graph traversal.
-
-In cases in which the computation itself is cheaper than this reactive work, you should avoid “over-wrapping” with memos and simply use derived signals. Here’s a great example in which you should never use a memo:
-
-```rust
-let (a, set_a) = create_signal(1);
-// none of these make sense as memos
-let b = move || a() + 2;
-let c = move || b() % 2 == 0;
-let d = move || if c() { "even" } else { "odd" };
-
-set_a(2);
-set_a(3);
-set_a(5);
-```
-
-Even though memoizing would technically save an extra calculation of `d` between setting `a` to `3` and `5`, these calculations are themselves cheaper than the reactive algorithm.
-
-At the very most, you might consider memoizing the final node before running some expensive side effect:
-
-```rust
-let text = create_memo(move |_| {
- d()
-});
-create_effect(move |_| {
- engrave_text_into_bar_of_gold(&text());
-});
-```
+
+
diff --git a/docs/book/src/async/10_resources.md b/docs/book/src/async/10_resources.md
index 08a6ad392f..8201ce20f7 100644
--- a/docs/book/src/async/10_resources.md
+++ b/docs/book/src/async/10_resources.md
@@ -1,136 +1,2 @@
-# Loading Data with Resources
-
-A [Resource](https://docs.rs/leptos/latest/leptos/struct.Resource.html) is a reactive data structure that reflects the current state of an asynchronous task, allowing you to integrate asynchronous `Future`s into the synchronous reactive system. Rather than waiting for its data to load with `.await`, you transform the `Future` into a signal that returns `Some(T)` if it has resolved, and `None` if it’s still pending.
-
-You do this by using the [`create_resource`](https://docs.rs/leptos/latest/leptos/fn.create_resource.html) function. This takes two arguments:
-
-1. a source signal, which will generate a new `Future` whenever it changes
-2. a fetcher function, which takes the data from that signal and returns a `Future`
-
-Here’s an example
-
-```rust
-// our source signal: some synchronous, local state
-let (count, set_count) = create_signal(0);
-
-// our resource
-let async_data = create_resource(
- count,
- // every time `count` changes, this will run
- |value| async move {
- logging::log!("loading data from API");
- load_data(value).await
- },
-);
-```
-
-To create a resource that simply runs once, you can pass a non-reactive, empty source signal:
-
-```rust
-let once = create_resource(|| (), |_| async move { load_data().await });
-```
-
-To access the value you can use `.get()` or `.with(|data| /* */)`. These work just like `.get()` and `.with()` on a signal—`get` clones the value and returns it, `with` applies a closure to it—but for any `Resource<_, T>`, they always return `Option`, not `T`: because it’s always possible that your resource is still loading.
-
-So, you can show the current state of a resource in your view:
-
-```rust
-let once = create_resource(|| (), |_| async move { load_data().await });
-view! {
- "My Data"
- {move || match once.get() {
- None => view! { "Loading..."
}.into_view(),
- Some(data) => view! { }.into_view()
- }}
-}
-```
-
-Resources also provide a `refetch()` method that allows you to manually reload the data (for example, in response to a button click) and a `loading()` method that returns a `ReadSignal` indicating whether the resource is currently loading or not.
-
-[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/10-resources-0-5-x6h5j6?file=%2Fsrc%2Fmain.rs%3A2%2C3)
-
-
-
-
-CodeSandbox Source
-
-```rust
-use gloo_timers::future::TimeoutFuture;
-use leptos::*;
-
-// Here we define an async function
-// This could be anything: a network request, database read, etc.
-// Here, we just multiply a number by 10
-async fn load_data(value: i32) -> i32 {
- // fake a one-second delay
- TimeoutFuture::new(1_000).await;
- value * 10
-}
-
-#[component]
-fn App() -> impl IntoView {
- // this count is our synchronous, local state
- let (count, set_count) = create_signal(0);
-
- // create_resource takes two arguments after its scope
- let async_data = create_resource(
- // the first is the "source signal"
- count,
- // the second is the loader
- // it takes the source signal's value as its argument
- // and does some async work
- |value| async move { load_data(value).await },
- );
- // whenever the source signal changes, the loader reloads
-
- // you can also create resources that only load once
- // just return the unit type () from the source signal
- // that doesn't depend on anything: we just load it once
- let stable = create_resource(|| (), |_| async move { load_data(1).await });
-
- // we can access the resource values with .get()
- // this will reactively return None before the Future has resolved
- // and update to Some(T) when it has resolved
- let async_result = move || {
- async_data
- .get()
- .map(|value| format!("Server returned {value:?}"))
- // This loading state will only show before the first load
- .unwrap_or_else(|| "Loading...".into())
- };
-
- // the resource's loading() method gives us a
- // signal to indicate whether it's currently loading
- let loading = async_data.loading();
- let is_loading = move || if loading() { "Loading..." } else { "Idle." };
-
- view! {
-
- "Click me"
-
-
- "stable"
": " {move || stable.get()}
-
-
- "count"
": " {count}
-
-
- "async_value"
": "
- {async_result}
-
- {is_loading}
-
- }
-}
-
-fn main() {
- leptos::mount_to_body(App)
-}
-```
-
-
-
+
+
diff --git a/docs/book/src/async/11_suspense.md b/docs/book/src/async/11_suspense.md
index e23f764ea1..d6e1a2395c 100644
--- a/docs/book/src/async/11_suspense.md
+++ b/docs/book/src/async/11_suspense.md
@@ -1,156 +1,2 @@
-# ` `
-
-In the previous chapter, we showed how you can create a simple loading screen to show some fallback while a resource is loading.
-
-```rust
-let (count, set_count) = create_signal(0);
-let once = create_resource(count, |count| async move { load_a(count).await });
-
-view! {
- "My Data"
- {move || match once.get() {
- None => view! { "Loading..."
}.into_view(),
- Some(data) => view! { }.into_view()
- }}
-}
-```
-
-But what if we have two resources, and want to wait for both of them?
-
-```rust
-let (count, set_count) = create_signal(0);
-let (count2, set_count2) = create_signal(0);
-let a = create_resource(count, |count| async move { load_a(count).await });
-let b = create_resource(count2, |count| async move { load_b(count).await });
-
-view! {
- "My Data"
- {move || match (a.get(), b.get()) {
- (Some(a), Some(b)) => view! {
-
-
- }.into_view(),
- _ => view! { "Loading..."
}.into_view()
- }}
-}
-```
-
-That’s not _so_ bad, but it’s kind of annoying. What if we could invert the flow of control?
-
-The [` `](https://docs.rs/leptos/latest/leptos/fn.Suspense.html) component lets us do exactly that. You give it a `fallback` prop and children, one or more of which usually involves reading from a resource. Reading from a resource “under” a ` ` (i.e., in one of its children) registers that resource with the ` `. If it’s still waiting for resources to load, it shows the `fallback`. When they’ve all loaded, it shows the children.
-
-```rust
-let (count, set_count) = create_signal(0);
-let (count2, set_count2) = create_signal(0);
-let a = create_resource(count, |count| async move { load_a(count).await });
-let b = create_resource(count2, |count| async move { load_b(count).await });
-
-view! {
- "My Data"
- "Loading..."
}
- >
- "My Data"
- "A"
- {move || {
- a.get()
- .map(|a| view! { })
- }}
- "B"
- {move || {
- b.get()
- .map(|b| view! { })
- }}
-
-}
-```
-
-Every time one of the resources is reloading, the `"Loading..."` fallback will show again.
-
-This inversion of the flow of control makes it easier to add or remove individual resources, as you don’t need to handle the matching yourself. It also unlocks some massive performance improvements during server-side rendering, which we’ll talk about during a later chapter.
-
-## ` `
-
-In you’re simply trying to wait for some `Future` to resolve before rendering, you may find the ` ` component helpful in reducing boilerplate. ` ` essentially combines a resource with the source argument `|| ()` with a ` ` with no fallback.
-
-In other words:
-
-1. It only polls the `Future` once, and does not respond to any reactive changes.
-2. It does not render anything until the `Future` resolves.
-3. After the `Future` resolves, its binds its data to whatever variable name you choose and then renders its children with that variable in scope.
-
-```rust
-async fn fetch_monkeys(monkey: i32) -> i32 {
- // maybe this didn't need to be async
- monkey * 2
-}
-view! {
-
- // you receive the data by reference and can use it in your view here
- {*data} " little monkeys, jumping on the bed."
-
-}
-```
-
-[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/11-suspense-0-5-qzpgqs?file=%2Fsrc%2Fmain.rs%3A1%2C1)
-
-
-
-
-CodeSandbox Source
-
-```rust
-use gloo_timers::future::TimeoutFuture;
-use leptos::*;
-
-async fn important_api_call(name: String) -> String {
- TimeoutFuture::new(1_000).await;
- name.to_ascii_uppercase()
-}
-
-#[component]
-fn App() -> impl IntoView {
- let (name, set_name) = create_signal("Bill".to_string());
-
- // this will reload every time `name` changes
- let async_data = create_resource(
-
- name,
- |name| async move { important_api_call(name).await },
- );
-
- view! {
-
- "name:"
{name}
- "Loading..." }
- >
- // the children will be rendered once initially,
- // and then whenever any resources has been resolved
-
- "Your shouting name is "
- {move || async_data.get()}
-
-
- }
-}
-
-fn main() {
- leptos::mount_to_body(App)
-}
-```
-
-
-
+
+
diff --git a/docs/book/src/async/12_transition.md b/docs/book/src/async/12_transition.md
index 85db85b3fc..4773504f57 100644
--- a/docs/book/src/async/12_transition.md
+++ b/docs/book/src/async/12_transition.md
@@ -1,83 +1,2 @@
-# ` `
-
-You’ll notice in the ` ` example that if you keep reloading the data, it keeps flickering back to `"Loading..."`. Sometimes this is fine. For other times, there’s [` `](https://docs.rs/leptos/latest/leptos/fn.Transition.html).
-
-` ` behaves exactly the same as ` `, but instead of falling back every time, it only shows the fallback the first time. On all subsequent loads, it continues showing the old data until the new data are ready. This can be really handy to prevent the flickering effect, and to allow users to continue interacting with your application.
-
-This example shows how you can create a simple tabbed contact list with ` `. When you select a new tab, it continues showing the current contact until the new data loads. This can be a much better user experience than constantly falling back to a loading message.
-
-[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/12-transition-0-5-2jg5lz?file=%2Fsrc%2Fmain.rs%3A1%2C1)
-
-
-
-
-CodeSandbox Source
-
-```rust
-use gloo_timers::future::TimeoutFuture;
-use leptos::*;
-
-async fn important_api_call(id: usize) -> String {
- TimeoutFuture::new(1_000).await;
- match id {
- 0 => "Alice",
- 1 => "Bob",
- 2 => "Carol",
- _ => "User not found",
- }
- .to_string()
-}
-
-#[component]
-fn App() -> impl IntoView {
- let (tab, set_tab) = create_signal(0);
-
- // this will reload every time `tab` changes
- let user_data = create_resource(tab, |tab| async move { important_api_call(tab).await });
-
- view! {
-
-
- "Tab A"
-
-
- "Tab B"
-
-
- "Tab C"
-
- {move || if user_data.loading().get() {
- "Loading..."
- } else {
- ""
- }}
-
- "Loading..." }
- >
-
- {move || user_data.read()}
-
-
- }
-}
-
-fn main() {
- leptos::mount_to_body(App)
-}
-```
-
-
-
+
+
diff --git a/docs/book/src/async/13_actions.md b/docs/book/src/async/13_actions.md
index 625dc33baa..cf865fc12a 100644
--- a/docs/book/src/async/13_actions.md
+++ b/docs/book/src/async/13_actions.md
@@ -1,176 +1,2 @@
-# Mutating Data with Actions
-
-We’ve talked about how to load `async` data with resources. Resources immediately load data and work closely with ` ` and ` ` components to show whether data is loading in your app. But what if you just want to call some arbitrary `async` function and keep track of what it’s doing?
-
-Well, you could always use [`spawn_local`](https://docs.rs/leptos/latest/leptos/fn.spawn_local.html). This allows you to just spawn an `async` task in a synchronous environment by handing the `Future` off to the browser (or, on the server, Tokio or whatever other runtime you’re using). But how do you know if it’s still pending? Well, you could just set a signal to show whether it’s loading, and another one to show the result...
-
-All of this is true. Or you could use the final `async` primitive: [`create_action`](https://docs.rs/leptos/latest/leptos/fn.create_action.html).
-
-Actions and resources seem similar, but they represent fundamentally different things. If you’re trying to load data by running an `async` function, either once or when some other value changes, you probably want to use `create_resource`. If you’re trying to occasionally run an `async` function in response to something like a user clicking a button, you probably want to use `create_action`.
-
-Say we have some `async` function we want to run.
-
-```rust
-async fn add_todo_request(new_title: &str) -> Uuid {
- /* do some stuff on the server to add a new todo */
-}
-```
-
-`create_action` takes an `async` function that takes a reference to a single argument, which you could think of as its “input type.”
-
-> The input is always a single type. If you want to pass in multiple arguments, you can do it with a struct or tuple.
->
-> ```rust
-> // if there's a single argument, just use that
-> let action1 = create_action(|input: &String| {
-> let input = input.clone();
-> async move { todo!() }
-> });
->
-> // if there are no arguments, use the unit type `()`
-> let action2 = create_action(|input: &()| async { todo!() });
->
-> // if there are multiple arguments, use a tuple
-> let action3 = create_action(
-> |input: &(usize, String)| async { todo!() }
-> );
-> ```
->
-> Because the action function takes a reference but the `Future` needs to have a `'static` lifetime, you’ll usually need to clone the value to pass it into the `Future`. This is admittedly awkward but it unlocks some powerful features like optimistic UI. We’ll see a little more about that in future chapters.
-
-So in this case, all we need to do to create an action is
-
-```rust
-let add_todo_action = create_action(|input: &String| {
- let input = input.to_owned();
- async move { add_todo_request(&input).await }
-});
-```
-
-Rather than calling `add_todo_action` directly, we’ll call it with `.dispatch()`, as in
-
-```rust
-add_todo_action.dispatch("Some value".to_string());
-```
-
-You can do this from an event listener, a timeout, or anywhere; because `.dispatch()` isn’t an `async` function, it can be called from a synchronous context.
-
-Actions provide access to a few signals that synchronize between the asynchronous action you’re calling and the synchronous reactive system:
-
-```rust
-let submitted = add_todo_action.input(); // RwSignal>
-let pending = add_todo_action.pending(); // ReadSignal
-let todo_id = add_todo_action.value(); // RwSignal>
-```
-
-This makes it easy to track the current state of your request, show a loading indicator, or do “optimistic UI” based on the assumption that the submission will succeed.
-
-```rust
-let input_ref = create_node_ref:: ();
-
-view! {
-
- // use our loading state
- {move || pending().then("Loading...")}
-}
-```
-
-Now, there’s a chance this all seems a little over-complicated, or maybe too restricted. I wanted to include actions here, alongside resources, as the missing piece of the puzzle. In a real Leptos app, you’ll actually most often use actions alongside server functions, [`create_server_action`](https://docs.rs/leptos/latest/leptos/fn.create_server_action.html), and the [` `](https://docs.rs/leptos_router/latest/leptos_router/fn.ActionForm.html) component to create really powerful progressively-enhanced forms. So if this primitive seems useless to you... Don’t worry! Maybe it will make sense later. (Or check out our [`todo_app_sqlite`](https://github.com/leptos-rs/leptos/blob/main/examples/todo_app_sqlite/src/todo.rs) example now.)
-
-[Click to open CodeSandbox.](https://codesandbox.io/p/sandbox/13-actions-0-5-8xk35v?file=%2Fsrc%2Fmain.rs%3A1%2C1)
-
-
-
-
-CodeSandbox Source
-
-```rust
-use gloo_timers::future::TimeoutFuture;
-use leptos::{html::Input, *};
-use uuid::Uuid;
-
-// Here we define an async function
-// This could be anything: a network request, database read, etc.
-// Think of it as a mutation: some imperative async action you run,
-// whereas a resource would be some async data you load
-async fn add_todo(text: &str) -> Uuid {
- _ = text;
- // fake a one-second delay
- TimeoutFuture::new(1_000).await;
- // pretend this is a post ID or something
- Uuid::new_v4()
-}
-
-#[component]
-fn App() -> impl IntoView {
- // an action takes an async function with single argument
- // it can be a simple type, a struct, or ()
- let add_todo = create_action(|input: &String| {
- // the input is a reference, but we need the Future to own it
- // this is important: we need to clone and move into the Future
- // so it has a 'static lifetime
- let input = input.to_owned();
- async move { add_todo(&input).await }
- });
-
- // actions provide a bunch of synchronous, reactive variables
- // that tell us different things about the state of the action
- let submitted = add_todo.input();
- let pending = add_todo.pending();
- let todo_id = add_todo.value();
-
- let input_ref = create_node_ref:: ();
-
- view! {
-
- {move || pending().then(|| "Loading...")}
-
- "Submitted: "
- {move || format!("{:#?}", submitted())}
-
-
- "Pending: "
- {move || format!("{:#?}", pending())}
-
-
- "Todo ID: "
- {move || format!("{:#?}", todo_id())}
-
- }
-}
-
-fn main() {
- leptos::mount_to_body(App)
-}
-```
-
-
-
+
+
diff --git a/docs/book/src/async/README.md b/docs/book/src/async/README.md
index 84b20d7d2e..b6758d05af 100644
--- a/docs/book/src/async/README.md
+++ b/docs/book/src/async/README.md
@@ -1,9 +1,2 @@
-# Working with `async`
-
-So far we’ve only been working with synchronous users interfaces: You provide some input,
-the app immediately processes it and updates the interface. This is great, but is a tiny
-subset of what web applications do. In particular, most web apps have to deal with some kind of asynchronous data loading, usually loading something from an API.
-
-Asynchronous data is notoriously hard to integrate with the synchronous parts of your code. Leptos provides a cross-platform [`spawn_local`](https://docs.rs/leptos/latest/leptos/fn.spawn_local.html) function that makes it easy to run a `Future`, but there’s much more to it than that.
-
-In this chapter, we’ll see how Leptos helps smooth out that process for you.
+
+
diff --git a/docs/book/src/csr_wrapping_up.md b/docs/book/src/csr_wrapping_up.md
index b34c50468c..4c504b0654 100644
--- a/docs/book/src/csr_wrapping_up.md
+++ b/docs/book/src/csr_wrapping_up.md
@@ -1,26 +1,2 @@
-# Wrapping Up Part 1: Client-Side Rendering
-
-So far, everything we’ve written has been rendered almost entirely in the browser. When we create an app using Trunk, it’s served using a local development server. If you build it for production and deploy it, it’s served by whatever server or CDN you’re using. In either case, what’s served is an HTML page with
-
-1. the URL of your Leptos app, which has been compiled to WebAssembly (WASM)
-2. the URL of the JavaScript used to initialize this WASM blob
-3. an empty `` element
-
-When the JS and WASM have loaded, Leptos will render your app into the ``. This means that nothing appears on the screen until JS/WASM have loaded and run. This has some drawbacks:
-
-1. It increases load time, as your user’s screen is blank until additional resources have been downloaded.
-2. It’s bad for SEO, as load times are longer and the HTML you serve has no meaningful content.
-3. It’s broken for users for whom JS/WASM don’t load for some reason (e.g., they’re on a train and just went into a tunnel before WASM finished loading; they’re using an older device that doesn’t support WASM; they have JavaScript or WASM turned off for some reason; etc.)
-
-These downsides apply across the web ecosystem, but especially to WASM apps.
-
-However, depending the on the requirements of your project, you may be fine with these limitations.
-
-If you just want to deploy your Client-Side Rendered website, skip ahead to the chapter on ["Deployment"](https://leptos-rs.github.io/leptos/deployment/index.html) - there, you'll find directions on how best to deploy your Leptos CSR site.
-
-
-But what do you do if you want to return more than just an empty `` tag in your `index.html` page? Use “Server-Side Rendering”!
-
-Whole books could be (and probably have been) written about this topic, but at its core, it’s really simple: rather than returning an empty `` tag, with SSR, you'll return an initial HTML page that reflects the actual starting state of your app or site, so that while JS/WASM are loading, and until they load, the user can access the plain HTML version.
-
-Part 2 of this book, on Leptos SSR, will cover this topic in some detail!
+
+
diff --git a/docs/book/src/deployment/README.md b/docs/book/src/deployment/README.md
index fa6c2042af..0a3d6a2b57 100644
--- a/docs/book/src/deployment/README.md
+++ b/docs/book/src/deployment/README.md
@@ -1,74 +1,2 @@
-# Deployment
-
-There are as many ways to deploy a web application as there are developers, let alone applications. But there are a couple useful tips to keep in mind when deploying an app.
-
-## General Advice
-
-1. Remember: Always deploy Rust apps built in `--release` mode, not debug mode. This has a huge effect on both performance and binary size.
-2. Test locally in release mode as well. The framework applies certain optimizations in release mode that it does not apply in debug mode, so it’s possible for bugs to surface at this point. (If your app behaves differently or you do encounter a bug, it’s likely a framework-level bug and you should open a GitHub issue with a reproduction.)
-3. See the chapter on "Optimizing WASM Binary Size" for additional tips and tricks to further improve the time-to-interactive metric for your WASM app on first load.
-
-> We asked users to submit their deployment setups to help with this chapter. I’ll quote from them below, but you can read the full thread [here](https://github.com/leptos-rs/leptos/issues/1152).
-
-## Deploying a Client-Side-Rendered App
-
-If you’ve been building an app that only uses client-side rendering, working with Trunk as a dev server and build tool, the process is quite easy.
-
-```bash
-trunk build --release
-```
-
-`trunk build` will create a number of build artifacts in a `dist/` directory. Publishing `dist` somewhere online should be all you need to deploy your app. This should work very similarly to deploying any JavaScript application.
-
-> Read more: [Deploying to Vercel with GitHub Actions](https://github.com/leptos-rs/leptos/issues/1152#issuecomment-1577861900).
-
-## Deploying a Full-Stack App
-
-The most popular way for people to deploy full-stack apps built with `cargo-leptos` is to use a cloud hosting service that supports deployment via a Docker build. Here’s a sample `Dockerfile`, which is based on the one we use to deploy the Leptos website.
-
-```dockerfile
-# Get started with a build env with Rust nightly
-FROM rustlang/rust:nightly-bullseye as builder
-
-# If you’re using stable, use this instead
-# FROM rust:1.70-bullseye as builder
-
-# Install cargo-binstall, which makes it easier to install other
-# cargo extensions like cargo-leptos
-RUN wget https://github.com/cargo-bins/cargo-binstall/releases/latest/download/cargo-binstall-x86_64-unknown-linux-musl.tgz
-RUN tar -xvf cargo-binstall-x86_64-unknown-linux-musl.tgz
-RUN cp cargo-binstall /usr/local/cargo/bin
-
-# Install cargo-leptos
-RUN cargo binstall cargo-leptos -y
-
-# Add the WASM target
-RUN rustup target add wasm32-unknown-unknown
-
-# Make an /app dir, which everything will eventually live in
-RUN mkdir -p /app
-WORKDIR /app
-COPY . .
-
-# Build the app
-RUN cargo leptos build --release -vv
-
-FROM rustlang/rust:nightly-bullseye as runner
-# Copy the server binary to the /app directory
-COPY --from=builder /app/target/release/leptos-start /app/
-# /target/site contains our JS/WASM/CSS, etc.
-COPY --from=builder /app/target/site /app/site
-# Copy Cargo.toml if it’s needed at runtime
-COPY --from=builder /app/Cargo.toml /app/
-WORKDIR /app
-
-# Set any required env variables and
-ENV RUST_LOG="info"
-ENV LEPTOS_SITE_ADDR="0.0.0.0:8080"
-ENV LEPTOS_SITE_ROOT="site"
-EXPOSE 8080
-# Run the server
-CMD ["/app/leptos_start"]
-```
-
-> Read more: [`gnu` and `musl` build files for Leptos apps](https://github.com/leptos-rs/leptos/issues/1152#issuecomment-1634916088).
+
+
diff --git a/docs/book/src/deployment/binary_size.md b/docs/book/src/deployment/binary_size.md
index 267796fedc..9d3afd9019 100644
--- a/docs/book/src/deployment/binary_size.md
+++ b/docs/book/src/deployment/binary_size.md
@@ -1,72 +1,2 @@
-# Optimizing WASM Binary Size
-
-One of the primary downsides of deploying a Rust/WebAssembly frontend app is that splitting a WASM file into smaller chunks to be dynamically loaded is significantly more difficult than splitting a JavaScript bundle. There have been experiments like [`wasm-split`](https://emscripten.org/docs/optimizing/Module-Splitting.html) in the Emscripten ecosystem but at present there’s no way to split and dynamically load a Rust/`wasm-bindgen` binary. This means that the whole WASM binary needs to be loaded before your app becomes interactive. Because the WASM format is designed for streaming compilation, WASM files are much faster to compile per kilobyte than JavaScript files. (For a deeper look, you can [read this great article from the Mozilla team](https://hacks.mozilla.org/2018/01/making-webassembly-even-faster-firefoxs-new-streaming-and-tiering-compiler/) on streaming WASM compilation.)
-
-Still, it’s important to ship the smallest WASM binary to users that you can, as it will reduce their network usage and make your app interactive as quickly as possible.
-
-So what are some practical steps?
-
-## Things to Do
-
-1. Make sure you’re looking at a release build. (Debug builds are much, much larger.)
-2. Add a release profile for WASM that optimizes for size, not speed.
-
-For a `cargo-leptos` project, for example, you can add this to your `Cargo.toml`:
-
-```toml
-[profile.wasm-release]
-inherits = "release"
-opt-level = 'z'
-lto = true
-codegen-units = 1
-
-# ....
-
-[package.metadata.leptos]
-# ....
-lib-profile-release = "wasm-release"
-```
-
-This will hyper-optimize the WASM for your release build for size, while keeping your server build optimized for speed. (For a pure client-rendered app without server considerations, just use the `[profile.wasm-release]` block as your `[profile.release]`.)
-
-3. Always serve compressed WASM in production. WASM tends to compress very well, typically shrinking to less than 50% its uncompressed size, and it’s trivial to enable compression for static files being served from Actix or Axum.
-
-4. If you’re using nightly Rust, you can rebuild the standard library with this same profile rather than the prebuilt standard library that’s distributed with the `wasm32-unknown-unknown` target.
-
-To do this, create a file in your project at `.cargo/config.toml`
-
-```toml
-[unstable]
-build-std = ["std", "panic_abort", "core", "alloc"]
-build-std-features = ["panic_immediate_abort"]
-```
-
-Note that if you're using this with SSR too, the same Cargo profile will be applied. You'll need to explicitly specify your target:
-```toml
-[build]
-target = "x86_64-unknown-linux-gnu" # or whatever
-```
-
-Also note that in some cases, the cfg feature `has_std` will not be set, which may cause build errors with some dependencies which check for `has_std`. You may fix any build errors due to this by adding:
-```toml
-[build]
-rustflags = ["--cfg=has_std"]
-```
-
-And you'll need to add `panic = "abort"` to `[profile.release]` in `Cargo.toml`. Note that this applies the same `build-std` and panic settings to your server binary, which may not be desirable. Some further exploration is probably needed here.
-
-5. One of the sources of binary size in WASM binaries can be `serde` serialization/deserialization code. Leptos uses `serde` by default to serialize and deserialize resources created with `create_resource`. You might try experimenting with the `miniserde` and `serde-lite` features, which allow you to use those crates for serialization and deserialization instead; each only implements a subset of `serde`’s functionality, but typically optimizes for size over speed.
-
-## Things to Avoid
-
-There are certain crates that tend to inflate binary sizes. For example, the `regex` crate with its default features adds about 500kb to a WASM binary (largely because it has to pull in Unicode table data!). In a size-conscious setting, you might consider avoiding regexes in general, or even dropping down and calling browser APIs to use the built-in regex engine instead. (This is what `leptos_router` does on the few occasions it needs a regular expression.)
-
-In general, Rust’s commitment to runtime performance is sometimes at odds with a commitment to a small binary. For example, Rust monomorphizes generic functions, meaning it creates a distinct copy of the function for each generic type it’s called with. This is significantly faster than dynamic dispatch, but increases binary size. Leptos tries to balance runtime performance with binary size considerations pretty carefully; but you might find that writing code that uses many generics tends to increase binary size. For example, if you have a generic component with a lot of code in its body and call it with four different types, remember that the compiler could include four copies of that same code. Refactoring to use a concrete inner function or helper can often maintain performance and ergonomics while reducing binary size.
-
-## A Final Thought
-
-Remember that in a server-rendered app, JS bundle size/WASM binary size affects only _one_ thing: time to interactivity on the first load. This is very important to a good user experience: nobody wants to click a button three times and have it do nothing because the interactive code is still loading — but it's not the only important measure.
-
-It’s especially worth remembering that streaming in a single WASM binary means all subsequent navigations are nearly instantaneous, depending only on any additional data loading. Precisely because your WASM binary is _not_ bundle split, navigating to a new route does not require loading additional JS/WASM, as it does in nearly every JavaScript framework. Is this copium? Maybe. Or maybe it’s just an honest trade-off between the two approaches!
-
-Always take the opportunity to optimize the low-hanging fruit in your application. And always test your app under real circumstances with real user network speeds and devices before making any heroic efforts.
+
+
diff --git a/docs/book/src/getting_started/README.md b/docs/book/src/getting_started/README.md
index 567a60404c..a95f235d38 100644
--- a/docs/book/src/getting_started/README.md
+++ b/docs/book/src/getting_started/README.md
@@ -1,125 +1,2 @@
-# Getting Started
-
-There are two basic paths to getting started with Leptos:
-
-1. **Client-side rendering (CSR) with [Trunk](https://trunkrs.dev/)** - a great option if you just want to make a snappy website with Leptos, or work with a pre-existing server or API.
-In CSR mode, Trunk compiles your Leptos app to WebAssembly (WASM) and runs it in the browser like a typical Javascript single-page app (SPA). The advantages of Leptos CSR include faster build times and a quicker iterative development cycle, as well as a simpler mental model and more options for deploying your app. CSR apps do come with some disadvantages: initial load times for your end users are slower compared to a server-side rendering approach, and the usual SEO challenges that come along with using a JS single-page app model apply to Leptos CSR apps as well. Also note that, under the hood, an auto-generated snippet of JS is used to load the Leptos WASM bundle, so JS *must* be enabled on the client device for your CSR app to display properly. As with all software engineering, there are trade-offs here you'll need to consider.
-
-2. **Full-stack, server-side rendering (SSR) with [`cargo-leptos`](https://github.com/leptos-rs/cargo-leptos)** - SSR is a great option for building CRUD-style websites and custom web apps if you want Rust powering both your frontend and backend.
-With the Leptos SSR option, your app is rendered to HTML on the server and sent down to the browser; then, WebAssembly is used to instrument the HTML so your app becomes interactive - this process is called 'hydration'. On the server side, Leptos SSR apps integrate closely with your choice of either [Actix-web](https://docs.rs/leptos_actix/latest/leptos_actix/index.html) or [Axum](https://docs.rs/leptos_axum/latest/leptos_axum/index.html) server libraries, so you can leverage those communities' crates to help build out your Leptos server.
-The advantages of taking the SSR route with Leptos include helping you get the best initial load times and optimal SEO scores for your web app. SSR apps can also dramatically simplify working across the server/client boundary via a Leptos feature called "server functions", which lets you transparently call functions on the server from your client code (more on this feature later). Full-stack SSR isn't all rainbows and butterflies, though - disadvantages include a slower developer iteration loop (because you need to recompile both the server and client when making Rust code changes), as well as some added complexity that comes along with hydration.
-
-By the end of the book, you should have a good idea of which trade-offs to make and which route to take - CSR or SSR - depending on your project's requirements.
-
-
-In Part 1 of this book, we'll start with client-side rendering Leptos sites and building reactive UI's using `Trunk` to serve our JS and WASM bundle to the browser.
-
-We’ll introduce `cargo-leptos` in Part 2 of this book, which is all about working with the full power of Leptos in its full-stack, SSR mode.
-
-```admonish note
-If you're coming from the Javascript world and terms like client-side rendering (CSR) and server-side rendering (SSR) are unfamiliar to you, the easiest way to understand the difference is by analogy:
-
-Leptos' CSR mode is similar to working with React (or a 'signals'-based framework like SolidJS), and focuses on producing a client-side UI which you can use with any tech stack on the server.
-
-Using Leptos' SSR mode is similar to working with a full-stack framework like Next.js in the React world (or Solid's "SolidStart" framework) - SSR helps you build sites and apps that are rendered on the server then sent down to the client. SSR can help to improve your site's loading performance and accessibility as well as make it easier for one person to work on *both* client- and server-side without needing to context-switch between different languages for frontend and backend.
-
-The Leptos framework can be used either in CSR mode to just make a UI (like React), or you can use Leptos in full-stack SSR mode (like Next.js) so that you can build both your UI and your server with one language: Rust.
-
-```
-
-## Hello World! Getting Set up for Leptos CSR Development
-
-First up, make sure Rust is installed and up-to-date ([see here if you need instructions](https://www.rust-lang.org/tools/install)).
-
-If you don’t have it installed already, you can install the "Trunk" tool for running Leptos CSR sites by running the following on the command-line:
-
-```bash
-cargo install trunk
-```
-
-And then create a basic Rust project
-
-```bash
-cargo init leptos-tutorial
-```
-
-`cd` into your new `leptos-tutorial` project and add `leptos` as a dependency
-
-```bash
-cargo add leptos --features=csr,nightly
-```
-
-Or you can leave off `nightly` if you're using stable Rust
-
-```bash
-cargo add leptos --features=csr
-```
-
-> Using `nightly` Rust, and the `nightly` feature in Leptos enables the function-call syntax for signal getters and setters that is used in most of this book.
->
-> To use nightly Rust, you can either opt into nightly for all your Rust projects by running
->
-> ```bash
-> rustup toolchain install nightly
-> rustup default nightly
-> ```
->
-> or only for this project
->
-> ```bash
-> rustup toolchain install nightly
-> cd
-> rustup override set nightly
-> ```
->
-> [See here for more details.](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html)
->
-> If you’d rather use stable Rust with Leptos, you can do that too. In the guide and examples, you’ll just use the [`ReadSignal::get()`](https://docs.rs/leptos/latest/leptos/struct.ReadSignal.html#impl-SignalGet%3CT%3E-for-ReadSignal%3CT%3E) and [`WriteSignal::set()`](https://docs.rs/leptos/latest/leptos/struct.WriteSignal.html#impl-SignalGet%3CT%3E-for-ReadSignal%3CT%3E) methods instead of calling signal getters and setters as functions.
-
-Make sure you've added the `wasm32-unknown-unknown` target so that Rust can compile your code to WebAssembly to run in the browser.
-
-```bash
-rustup target add wasm32-unknown-unknown
-```
-
-Create a simple `index.html` in the root of the `leptos-tutorial` directory
-
-```html
-
-
-
-
-
-```
-
-And add a simple “Hello, world!” to your `main.rs`
-
-```rust
-use leptos::*;
-
-fn main() {
- mount_to_body(|| view! { "Hello, world!"
})
-}
-```
-
-Your directory structure should now look something like this
-
-```
-leptos_tutorial
-├── src
-│ └── main.rs
-├── Cargo.toml
-├── index.html
-```
-
-Now run `trunk serve --open` from the root of the `leptos-tutorial` directory.
-Trunk should automatically compile your app and open it in your default browser.
-If you make edits to `main.rs`, Trunk will recompile your source code and
-live-reload the page.
-
-
-Welcome to the world of UI development with Rust and WebAssembly (WASM), powered by Leptos and Trunk!
-
----
-
-Now before we get started building your first real UI's with Leptos, there are a couple of things you might want to know to help make your experience with Leptos just a little bit easier.
\ No newline at end of file
+
+
diff --git a/docs/book/src/getting_started/community_crates.md b/docs/book/src/getting_started/community_crates.md
index 510c0632dc..b2f5cd5a0d 100644
--- a/docs/book/src/getting_started/community_crates.md
+++ b/docs/book/src/getting_started/community_crates.md
@@ -1,23 +1,2 @@
-# The Leptos Community and `leptos-*` Crates
-
-## The Community
-
-One final note before we get to building with Leptos: if you haven't already, feel free to join the growing community on the Leptos [Discord](https://discord.gg/YdRAhS7eQB) and on [Github](https://github.com/leptos-rs/leptos). Our Discord channel in particular is very active and friendly - we'd love to have you there!
-
-```admonish note
-If you find a chapter or an explanation that isn't clear while you're working your way through the Leptos book, just mention it in the "docs-and-education" channel or ask a question in "help" so we can clear things up and update the book for others.
-```
-
-As you get further along in your Leptos journey and find that you have questions about "how to do 'x' with Leptos", then search the Discord "help" channel to see if a similar question has been asked before, or feel free to post your own question - the community is quite helpful and very responsive.
-
-The "[Discussions](https://github.com/leptos-rs/leptos/discussions)" on Github are also a great place for asking questions and keeping up with Leptos announcements.
-
-And of course, if you run into any bugs while developing with Leptos or would like to make a feature request (or contribute a bug fix / new feature), open up an issue on the [Github issue tracker](https://github.com/leptos-rs/leptos/issues).
-
-
-## Leptos-* Crates
-
-The community has built a growing number of Leptos-related crates that will help you get productive with Leptos projects more quickly - check out the list of crates built on top of Leptos and contributed by the community on the [Awesome Leptos](https://github.com/leptos-rs/awesome-leptos) repo on Github.
-
-If you want to find the newest, up-and-coming Leptos-related crates, check out the "Tools and Libraries" section of the Leptos Discord. In that section, there are channels for the Leptos `view!` macro formatter (in the "leptosfmt" channel); there's a channel for the utility library "leptos-use"; another channel for the UI component libary "leptonic"; and a "libraries" channel where new `leptos-*` crates are discussed before making their way into the growing list of crates and resources available on [Awesome Leptos](https://github.com/leptos-rs/awesome-leptos).
-
+
+
diff --git a/docs/book/src/getting_started/leptos_dx.md b/docs/book/src/getting_started/leptos_dx.md
index 39d799e0da..d7aa528335 100644
--- a/docs/book/src/getting_started/leptos_dx.md
+++ b/docs/book/src/getting_started/leptos_dx.md
@@ -1,92 +1,2 @@
-# Leptos Developer Experience Improvements
-
-
-There are a couple of things you can do to improve your experience of developing websites and apps with Leptos. You may want to take a few minutes and set up your environment to optimize your development experience, especially if you want to code along with the examples in this book.
-
-## 1) Editor Autocompletion inside `#[component]` and `#[server]`
-
-Because of the nature of macros (they can expand from anything to anything, but only if the input is exactly correct at that instant) it can be hard for rust-analyzer to do proper autocompletion and other support.
-
-
-If you run into issues using these macros in your editor, you can explicitly tell rust-analyzer to ignore certain proc macros. For the `#[server]` macro especially, which annotates function bodies but doesn't actually transform anything inside the body of your function, this can be really helpful.
-
-Starting in Leptos version 0.5.3, rust-analyzer support was added for the `#[component]` macro, but if you run into issues, you may want to add `#[component]` to the macro ignore list as well (see below).
-Note that this means that rust-analyzer doesn't know about your component props, which may generate its own set of errors or warnings in the IDE.
-
-VSCode `settings.json`:
-
-```json
-"rust-analyzer.procMacro.ignored": {
- "leptos_macro": [
- // optional:
- // "component",
- "server"
- ],
-}
-```
-
-neovim with lspconfig:
-
-```lua
-require('lspconfig').rust_analyzer.setup {
- -- Other Configs ...
- settings = {
- ["rust-analyzer"] = {
- -- Other Settings ...
- procMacro = {
- ignored = {
- leptos_macro = {
- -- optional: --
- -- "component",
- "server",
- },
- },
- },
- },
- }
-}
-```
-
-Helix, in `.helix/languages.toml`:
-
-```toml
-[[language]]
-name = "rust"
-
-[language-server.rust-analyzer]
-config = { procMacro = { ignored =
- { leptos_macro =
- [
- # Optional:
- # "component",
- "server"
- ]
- }
-} }
-```
-
-```admonish info
-The Jetbrains `intellij-rust` plugin (RustRover as well) currently does not support dynamic config for macro exclusion.
-However, the project currently maintains a hardcoded list of excluded macros.
-As soon as [this open PR](https://github.com/intellij-rust/intellij-rust/pull/10873) is merged, the `component` and
-`server` macro will be excluded automatically without additional configuration needed.
-
-Update (2023/10/02):
-The `intellij-rust` plugin got deprecated in favor of RustRover at the same time the PR was opened, but an official
-support request was made to integrate the contents of this PR.
-```
-
-## 2) Set up `leptosfmt` With Rust Analyzer (optional)
-
-"leptosfmt" is a formatter for the Leptos `view!` macro (inside of which you'll typically write your UI code). Because the view! macro enables an 'RSX' (like JSX) style of writing your UI's, cargo-fmt has a harder time auto-formatting your code that's inside the view! macro. leptosfmt is a crate that solves your formattting issues and keeps your RSX-style UI code looking nice and tidy!
-
-leptosfmt can be installed and used via the commandline or from within your code editor:
-
-First, install the tool with `cargo install leptosfmt`.
-
-If you just want to use the default options from the command line, just run `leptosfmt ./**/*.rs` from the root of your project to format all the rust files using leptosfmt.
-
-If you wish to set up your editor to work with leptosfmt, or if you wish to customize your leptosfmt experience, please see the instructions available on the [leptosfmt github repo's README.md page](https://github.com/bram209/leptosfmt).
-
-Just note that it's recommended to set up your editor with `leptosfmt` on a per-workspace basis for best results.
-
+
+
diff --git a/docs/book/src/interlude_projecting_children.md b/docs/book/src/interlude_projecting_children.md
index bd46ec7006..ff9d7f6fa5 100644
--- a/docs/book/src/interlude_projecting_children.md
+++ b/docs/book/src/interlude_projecting_children.md
@@ -1,175 +1,2 @@
-# Projecting Children
-
-As you build components you may occasionally find yourself wanting to “project” children through multiple layers of components.
-
-## The Problem
-
-Consider the following:
-
-```rust
-pub fn LoggedIn(fallback: F, children: ChildrenFn) -> impl IntoView
-where
- F: Fn() -> IV + 'static,
- IV: IntoView,
-{
- view! {
-
-
- {children()}
-
-
- }
-}
-```
-
-This is pretty straightforward: when the user is logged in, we want to show `children`. If the user is not logged in, we want to show `fallback`. And while we’re waiting to find out, we just render `()`, i.e., nothing.
-
-In other words, we want to pass the children of ` ` _through_ the ` ` component to become the children of the ` `. This is what I mean by “projection.”
-
-This won’t compile.
-
-```
-error[E0507]: cannot move out of `fallback`, a captured variable in an `Fn` closure
-error[E0507]: cannot move out of `children`, a captured variable in an `Fn` closure
-```
-
-The problem here is that both ` ` and ` ` need to be able to construct their `children` multiple times. The first time you construct ` `’s children, it would take ownership of `fallback` and `children` to move them into the invocation of ` `, but then they're not available for future ` ` children construction.
-
-## The Details
-
-> Feel free to skip ahead to the solution.
-
-If you want to really understand the issue here, it may help to look at the expanded `view` macro. Here’s a cleaned-up version:
-
-```rust
-Suspense(
- ::leptos::component_props_builder(&Suspense)
- .fallback(|| ())
- .children({
- // fallback and children are moved into this closure
- Box::new(move || {
- {
- // fallback and children captured here
- leptos::Fragment::lazy(|| {
- vec![
- (Show(
- ::leptos::component_props_builder(&Show)
- .when(|| true)
- // but fallback is moved into Show here
- .fallback(fallback)
- // and children is moved into Show here
- .children(children)
- .build(),
- )
- .into_view()),
- ]
- })
- }
- })
- })
- .build(),
-)
-```
-
-All components own their props; so the ` ` in this case can’t be called because it only has captured references to `fallback` and `children`.
-
-## Solution
-
-However, both ` ` and ` ` take `ChildrenFn`, i.e., their `children` should implement the `Fn` type so they can be called multiple times with only an immutable reference. This means we don’t need to own `children` or `fallback`; we just need to be able to pass `'static` references to them.
-
-We can solve this problem by using the [`store_value`](https://docs.rs/leptos/latest/leptos/fn.store_value.html) primitive. This essentially stores a value in the reactive system, handing ownership off to the framework in exchange for a reference that is, like signals, `Copy` and `'static`, which we can access or modify through certain methods.
-
-In this case, it’s really simple:
-
-```rust
-pub fn LoggedIn(fallback: F, children: ChildrenFn) -> impl IntoView
-where
- F: Fn() -> IV + 'static,
- IV: IntoView,
-{
- let fallback = store_value(fallback);
- let children = store_value(children);
- view! {
-
-
- {children.with_value(|children| children())}
-
-
- }
-}
-```
-
-At the top level, we store both `fallback` and `children` in the reactive scope owned by `LoggedIn`. Now we can simply move those references down through the other layers into the ` ` component and call them there.
-
-## A Final Note
-
-Note that this works because ` ` and ` ` only need an immutable reference to their children (which `.with_value` can give it), not ownership.
-
-In other cases, you may need to project owned props through a function that takes `ChildrenFn` and therefore needs to be called more than once. In this case, you may find the `clone:` helper in the`view` macro helpful.
-
-Consider this example
-
-```rust
-#[component]
-pub fn App() -> impl IntoView {
- let name = "Alice".to_string();
- view! {
-
-
-
-
-
- }
-}
-
-#[component]
-pub fn Outer(children: ChildrenFn) -> impl IntoView {
- children()
-}
-
-#[component]
-pub fn Inner(children: ChildrenFn) -> impl IntoView {
- children()
-}
-
-#[component]
-pub fn Inmost(name: String) -> impl IntoView {
- view! {
- {name}
- }
-}
-```
-
-Even with `name=name.clone()`, this gives the error
-
-```
-cannot move out of `name`, a captured variable in an `Fn` closure
-```
-
-It’s captured through multiple levels of children that need to run more than once, and there’s no obvious way to clone it _into_ the children.
-
-In this case, the `clone:` syntax comes in handy. Calling `clone:name` will clone `name` _before_ moving it into ` `’s children, which solves our ownership issue.
-
-```rust
-view! {
-
-
-
-
-
-}
-```
-
-These issues can be a little tricky to understand or debug, because of the opacity of the `view` macro. But in general, they can always be solved.
+
+
diff --git a/docs/book/src/interlude_styling.md b/docs/book/src/interlude_styling.md
index eaba34226d..328fbdd990 100644
--- a/docs/book/src/interlude_styling.md
+++ b/docs/book/src/interlude_styling.md
@@ -1,112 +1,2 @@
-# Interlude: Styling
-
-Anyone creating a website or application soon runs into the question of styling. For a small app, a single CSS file is probably plenty to style your user interface. But as an application grows, many developers find that plain CSS becomes increasingly hard to manage.
-
-Some frontend frameworks (like Angular, Vue, and Svelte) provide built-in ways to scope your CSS to particular components, making it easier to manage styles across a whole application without styles meant to modify one small component having a global effect. Other frameworks (like React or Solid) don’t provide built-in CSS scoping, but rely on libraries in the ecosystem to do it for them. Leptos is in this latter camp: the framework itself has no opinions about CSS at all, but provides a few tools and primitives that allow others to build styling libraries.
-
-Here are a few different approaches to styling your Leptos app, other than plain CSS.
-
-## TailwindCSS: Utility-first CSS
-
-[TailwindCSS](https://tailwindcss.com/) is a popular utility-first CSS library. It allows you to style your application by using inline utility classes, with a custom CLI tool that scans your files for Tailwind class names and bundles the necessary CSS.
-
-This allows you to write components like this:
-
-```rust
-#[component]
-fn Home() -> impl IntoView {
- let (count, set_count) = create_signal(0);
-
- view! {
-
- "Welcome to Leptos with Tailwind"
- "Tailwind will scan your Rust files for Tailwind class names and compile them into a CSS file."
-
- {move || if count() == 0 {
- "Click me!".to_string()
- } else {
- count().to_string()
- }}
-
-
- }
-}
-```
-
-It can be a little complicated to set up the Tailwind integration at first, but you can check out our two examples of how to use Tailwind with a [client-side-rendered `trunk` application](https://github.com/leptos-rs/leptos/tree/main/examples/tailwind_csr) or with a [server-rendered `cargo-leptos` application](https://github.com/leptos-rs/leptos/tree/main/examples/tailwind_actix). `cargo-leptos` also has some [built-in Tailwind support](https://github.com/leptos-rs/cargo-leptos#site-parameters) that you can use as an alternative to Tailwind’s CLI.
-
-## Stylers: Compile-time CSS Extraction
-
-[Stylers](https://github.com/abishekatp/stylers) is a compile-time scoped CSS library that lets you declare scoped CSS in the body of your component. Stylers will extract this CSS at compile time into CSS files that you can then import into your app, which means that it doesn’t add anything to the WASM binary size of your application.
-
-This allows you to write components like this:
-
-```rust
-use stylers::style;
-
-#[component]
-pub fn App() -> impl IntoView {
- let styler_class = style! { "App",
- ##two{
- color: blue;
- }
- div.one{
- color: red;
- content: raw_str(r#"\hello"#);
- font: "1.3em/1.2" Arial, Helvetica, sans-serif;
- }
- div {
- border: 1px solid black;
- margin: 25px 50px 75px 100px;
- background-color: lightblue;
- }
- h2 {
- color: purple;
- }
- @media only screen and (max-width: 1000px) {
- h3 {
- background-color: lightblue;
- color: blue
- }
- }
- };
-
- view! { class = styler_class,
-
-
"Hello"
- "World"
- "and"
- "friends!"
-
- }
-}
-```
-
-## Styled: Runtime CSS Scoping
-
-[Styled](https://github.com/eboody/styled) is a runtime scoped CSS library that integrates well with Leptos. It lets you declare scoped CSS in the body of your component function, and then applies those styles at runtime.
-
-```rust
-use styled::style;
-
-#[component]
-pub fn MyComponent() -> impl IntoView {
- let styles = style!(
- div {
- background-color: red;
- color: white;
- }
- );
-
- styled::view! { styles,
- "This text should be red with white text."
- }
-}
-```
-
-## Contributions Welcome
-
-Leptos has no opinions on how you style your website or app, but we’re very happy to provide support to any tools you’re trying to create to make it easier. If you’re working on a CSS or styling approach that you’d like to add to this list, please let us know!
+
+
diff --git a/docs/book/src/islands.md b/docs/book/src/islands.md
index ebaad678ba..da9012d25a 100644
--- a/docs/book/src/islands.md
+++ b/docs/book/src/islands.md
@@ -1,489 +1,2 @@
-# Guide: Islands
-
-Leptos 0.5 introduces the new `experimental-islands` feature. This guide will walk through the islands feature and core concepts, while implementing a demo app using the islands architecture.
-
-## The Islands Architecture
-
-The dominant JavaScript frontend frameworks (React, Vue, Svelte, Solid, Angular) all originated as frameworks for building client-rendered single-page apps (SPAs). The initial page load is rendered to HTML, then hydrated, and subsequent navigations are handled directly in the client. (Hence “single page”: everything happens from a single page load from the server, even if there is client-side routing later.) Each of these frameworks later added server-side rendering to improve initial load times, SEO, and user experience.
-
-This means that by default, the entire app is interactive. It also means that the entire app has to be shipped to the client as JavaScript in order to be hydrated. Leptos has followed this same pattern.
-
-> You can read more in the chapters on [server-side rendering](./ssr/22_life_cycle.md).
-
-But it’s also possible to work in the opposite direction. Rather than taking an entirely-interactive app, rendering it to HTML on the server, and then hydrating it in the browser, you can begin with a plain HTML page and add small areas of interactivity. This is the traditional format for any website or app before the 2010s: your browser makes a series of requests to the server and returns the HTML for each new page in response. After the rise of “single-page apps” (SPA), this approach has sometimes become known as a “multi-page app” (MPA) by comparison.
-
-The phrase “islands architecture” has emerged recently to describe the approach of beginning with a “sea” of server-rendered HTML pages, and adding “islands” of interactivity throughout the page.
-
-> ### Additional Reading
->
-> The rest of this guide will look at how to use islands with Leptos. For more background on the approach in general, check out some of the articles below:
->
-> - Jason Miller, [“Islands Architecture”](https://jasonformat.com/islands-architecture/), Jason Miller
-> - Ryan Carniato, [“Islands & Server Components & Resumability, Oh My!”](https://dev.to/this-is-learning/islands-server-components-resumability-oh-my-319d)
-> - [“Islands Architectures”](https://www.patterns.dev/posts/islands-architecture) on patterns.dev
-> - [Astro Islands](https://docs.astro.build/en/concepts/islands/)
-
-## Activating Islands Mode
-
-Let’s start with a fresh `cargo-leptos` app:
-
-```bash
-cargo leptos new --git leptos-rs/start
-```
-
-> I’m using Actix because I like it. Feel free to use Axum; there should be approximately no server-specific differences in this guide.
-
-I’m just going to run
-
-```bash
-cargo leptos build
-```
-
-in the background while I fire up my editor and keep writing.
-
-The first thing I’ll do is to add the `experimental-islands` feature in my `Cargo.toml`. I need to add this to both `leptos` and `leptos_actix`:
-
-```toml
-leptos = { version = "0.5", features = ["nightly", "experimental-islands"] }
-leptos_actix = { version = "0.5", optional = true, features = [
- "experimental-islands",
-] }
-```
-
-Next I’m going to modify the `hydrate` function exported from `src/lib.rs`. I’m going to remove the line that calls `leptos::mount_to_body(App)` and replace it with
-
-```rust
-leptos::leptos_dom::HydrationCtx::stop_hydrating();
-```
-
-Each “island” we create will actually act as its own entrypoint, so our `hydrate()` function just says “okay, hydration’s done now.”
-
-Okay, now fire up your `cargo leptos watch` and go to [`http://localhost:3000`](http://localhost:3000) (or wherever).
-
-Click the button, and...
-
-Nothing happens!
-
-Perfect.
-
-## Using Islands
-
-Nothing happens because we’ve just totally inverted the mental model of our app. Rather than being interactive by default and hydrating everything, the app is now plain HTML by default, and we need to opt into interactivity.
-
-This has a big effect on WASM binary sizes: if I compile in release mode, this app is a measly 24kb of WASM (uncompressed), compared to 355kb in non-islands mode. (355kb is quite large for a “Hello, world!” It’s really just all the code related to client-side routing, which isn’t being used in the demo.)
-
-When we click the button, nothing happens, because our whole page is static.
-
-So how do we make something happen?
-
-Let’s turn the `HomePage` component into an island!
-
-Here was the non-interactive version:
-
-```rust
-#[component]
-fn HomePage() -> impl IntoView {
- // Creates a reactive value to update the button
- let (count, set_count) = create_signal(0);
- let on_click = move |_| set_count.update(|count| *count += 1);
-
- view! {
- "Welcome to Leptos!"
- "Click Me: " {count}
- }
-}
-```
-
-Here’s the interactive version:
-
-```rust
-#[island]
-fn HomePage() -> impl IntoView {
- // Creates a reactive value to update the button
- let (count, set_count) = create_signal(0);
- let on_click = move |_| set_count.update(|count| *count += 1);
-
- view! {
- "Welcome to Leptos!"
- "Click Me: " {count}
- }
-}
-```
-
-Now when I click the button, it works!
-
-The `#[island]` macro works exactly like the `#[component]` macro, except that in islands mode, it designates this as an interactive island. If we check the binary size again, this is 166kb uncompressed in release mode; much larger than the 24kb totally static version, but much smaller than the 355kb fully-hydrated version.
-
-If you open up the source for the page now, you’ll see that your `HomePage` island has been rendered as a special `` HTML element which specifies which component should be used to hydrate it:
-
-```html
-
- Welcome to Leptos!
-
- Click Me:
- 11
-
-
-```
-
-The typical Leptos hydration keys and markers are only present inside the island, only the island is hydrated.
-
-## Using Islands Effectively
-
-Remember that _only_ code within an `#[island]` needs to be compiled to WASM and shipped to the browser. This means that islands should be as small and specific as possible. My `HomePage`, for example, would be better broken apart into a regular component and an island:
-
-```rust
-#[component]
-fn HomePage() -> impl IntoView {
- view! {
- "Welcome to Leptos!"
-
- }
-}
-
-#[island]
-fn Counter() -> impl IntoView {
- // Creates a reactive value to update the button
- let (count, set_count) = create_signal(0);
- let on_click = move |_| set_count.update(|count| *count += 1);
-
- view! {
- "Click Me: " {count}
- }
-}
-```
-
-Now the `` doesn’t need to be included in the client bundle, or hydrated. This seems like a silly distinction now; but note that you can now add as much inert HTML content as you want to the `HomePage` itself, and the WASM binary size will remain exactly the same.
-
-In regular hydration mode, your WASM binary size grows as a function of the size/complexity of your app. In islands mode, your WASM binary grows as a function of the amount of interactivity in your app. You can add as much non-interactive content as you want, outside islands, and it will not increase that binary size.
-
-## Unlocking Superpowers
-
-So, this 50% reduction in WASM binary size is nice. But really, what’s the point?
-
-The point comes when you combine two key facts:
-
-1. Code inside `#[component]` functions now _only_ runs on the server.
-2. Children and props can be passed from the server to islands, without being included in the WASM binary.
-
-This means you can run server-only code directly in the body of a component, and pass it directly into the children. Certain tasks that take a complex blend of server functions and Suspense in fully-hydrated apps can be done inline in islands.
-
-We’re going to rely on a third fact in the rest of this demo:
-
-3. Context can be passed between otherwise-independent islands.
-
-So, instead of our counter demo, let’s make something a little more fun: a tabbed interface that reads data from files on the server.
-
-## Passing Server Children to Islands
-
-One of the most powerful things about islands is that you can pass server-rendered children into an island, without the island needing to know anything about them. Islands hydrate their own content, but not children that are passed to them.
-
-As Dan Abramov of React put it (in the very similar context of RSCs), islands aren’t really islands: they’re donuts. You can pass server-only content directly into the “donut hole,” as it were, allowing you to create tiny atolls of interactivity, surrounded on _both_ sides by the sea of inert server HTML.
-
-> In the demo code included below, I added some styles to show all server content as a light-blue “sea,” and all islands as light-green “land.” Hopefully that will help picture what I’m talking about!
-
-To continue with the demo: I’m going to create a `Tabs` component. Switching between tabs will require some interactivity, so of course this will be an island. Let’s start simple for now:
-
-```rust
-#[island]
-fn Tabs(labels: Vec) -> impl IntoView {
- let buttons = labels
- .into_iter()
- .map(|label| view! { {label} })
- .collect_view();
- view! {
-
- {buttons}
-
- }
-}
-```
-
-Oops. This gives me an error
-
-```
-error[E0463]: can't find crate for `serde`
- --> src/app.rs:43:1
- |
-43 | #[island]
- | ^^^^^^^^^ can't find crate
-```
-
-Easy fix: let’s `cargo add serde --features=derive`. The `#[island]` macro wants to pull in `serde` here because it needs to serialize and deserialize the `labels` prop.
-
-Now let’s update the `HomePage` to use `Tabs`.
-
-```rust
-#[component]
-fn HomePage() -> impl IntoView {
- // these are the files we’re going to read
- let files = ["a.txt", "b.txt", "c.txt"];
- // the tab labels will just be the file names
- let labels = files.iter().copied().map(Into::into).collect();
- view! {
- "Welcome to Leptos!"
- "Click any of the tabs below to read a recipe."
-
- }
-}
-```
-
-If you take a look in the DOM inspector, you’ll see the island is now something like
-
-```html
-
-```
-
-Our `labels` prop is getting serialized to JSON and stored in an HTML attribute so it can be used to hydrate the island.
-
-Now let’s add some tabs. For the moment, a `Tab` island will be really simple:
-
-```rust
-#[island]
-fn Tab(index: usize, children: Children) -> impl IntoView {
- view! {
- {children()}
- }
-}
-```
-
-Each tab, for now will just be a `` wrapping its children.
-
-Our `Tabs` component will also get some children: for now, let’s just show them all.
-
-```rust
-#[island]
-fn Tabs(labels: Vec
, children: Children) -> impl IntoView {
- let buttons = labels
- .into_iter()
- .map(|label| view! { {label} })
- .collect_view();
- view! {
-
- {buttons}
-
- {children()}
- }
-}
-```
-
-Okay, now let’s go back into the `HomePage`. We’re going to create the list of tabs to put into our tab box.
-
-```rust
-#[component]
-fn HomePage() -> impl IntoView {
- let files = ["a.txt", "b.txt", "c.txt"];
- let labels = files.iter().copied().map(Into::into).collect();
- let tabs = move || {
- files
- .into_iter()
- .enumerate()
- .map(|(index, filename)| {
- let content = std::fs::read_to_string(filename).unwrap();
- view! {
-
- {filename.to_string()}
- {content}
-
- }
- })
- .collect_view()
- };
-
- view! {
- "Welcome to Leptos!"
- "Click any of the tabs below to read a recipe."
-
- {tabs()}
-
- }
-}
-```
-
-Uh... What?
-
-If you’re used to using Leptos, you know that you just can’t do this. All code in the body of components has to run on the server (to be rendered to HTML) and in the browser (to hydrate), so you can’t just call `std::fs`; it will panic, because there’s no access to the local filesystem (and certainly not to the server filesystem!) in the browser. This would be a security nightmare!
-
-Except... wait. We’re in islands mode. This `HomePage` component _really does_ only run on the server. So we can, in fact, just use ordinary server code like this.
-
-> **Is this a dumb example?** Yes! Synchronously reading from three different local files in a `.map()` is not a good choice in real life. The point here is just to demonstrate that this is, definitely, server-only content.
-
-Go ahead and create three files in the root of the project called `a.txt`, `b.txt`, and `c.txt`, and fill them in with whatever content you’d like.
-
-Refresh the page and you should see the content in the browser. Edit the files and refresh again; it will be updated.
-
-You can pass server-only content from a `#[component]` into the children of an `#[island]`, without the island needing to know anything about how to access that data or render that content.
-
-**This is really important.** Passing server `children` to islands means that you can keep islands small. Ideally, you don’t want to slap and `#[island]` around a whole chunk of your page. You want to break that chunk out into an interactive piece, which can be an `#[island]`, and a bunch of additional server content that can be passed to that island as `children`, so that the non-interactive subsections of an interactive part of the page can be kept out of the WASM binary.
-
-## Passing Context Between Islands
-
-These aren’t really “tabs” yet: they just show every tab, all the time. So let’s add some simple logic to our `Tabs` and `Tab` components.
-
-We’ll modify `Tabs` to create a simple `selected` signal. We provide the read half via context, and set the value of the signal whenever someone clicks one of our buttons.
-
-```rust
-#[island]
-fn Tabs(labels: Vec, children: Children) -> impl IntoView {
- let (selected, set_selected) = create_signal(0);
- provide_context(selected);
-
- let buttons = labels
- .into_iter()
- .enumerate()
- .map(|(index, label)| view! {
-
- {label}
-
- })
- .collect_view();
-// ...
-```
-
-And let’s modify the `Tab` island to use that context to show or hide itself:
-
-```rust
-#[island]
-fn Tab(children: Children) -> impl IntoView {
- let selected = expect_context::>();
- view! {
-
-// ...
-```
-
-Now the tabs behave exactly as I’d expect. `Tabs` passes the signal via context to each `Tab`, which uses it to determine whether it should be open or not.
-
-> That’s why in `HomePage`, I made `let tabs = move ||` a function, and called it like `{tabs()}`: creating the tabs lazily this way meant that the `Tabs` island would already have provided the `selected` context by the time each `Tab` went looking for it.
-
-Our complete tabs demo is about 220kb uncompressed: not the smallest demo in the world, but still about a third smaller than the counter button! Just for kicks, I built the same demo without islands mode, using `#[server]` functions and `Suspense`. and it was 429kb. So again, this was about a 50% savings in binary size. And this app includes quite minimal server-only content: remember that as we add additional server-only components and pages, this 220 will not grow.
-
-## Overview
-
-This demo may seem pretty basic. It is. But there are a number of immediate takeaways:
-
-- **50% WASM binary size reduction**, which means measurable improvements in time to interactivity and initial load times for clients.
-- **Reduced HTML page size.** This one is less obvious, but it’s true and important: HTML generated from `#[component]`s doesn’t need all the hydration IDs and other boilerplate added.
-- **Reduced data serialization costs.** Creating a resource and reading it on the client means you need to serialize the data, so it can be used for hydration. If you’ve also read that data to create HTML in a `Suspense`, you end up with “double data,” i.e., the same exact data is both rendered to HTML and serialized as JSON, increasing the size of responses, and therefore slowing them down.
-- **Easily use server-only APIs** inside a `#[component]` as if it were a normal, native Rust function running on the server—which, in islands mode, it is!
-- **Reduced `#[server]`/`create_resource`/`Suspense` boilerplate** for loading server data.
-
-## Future Exploration
-
-The `experimental-islands` feature included in 0.5 reflects work at the cutting edge of what frontend web frameworks are exploring right now. As it stands, our islands approach is very similar to Astro (before its recent View Transitions support): it allows you to build a traditional server-rendered, multi-page app and pretty seamlessly integrate islands of interactivity.
-
-There are some small improvements that will be easy to add. For example, we can do something very much like Astro's View Transitions approach:
-
-- add client-side routing for islands apps by fetching subsequent navigations from the server and replacing the HTML document with the new one
-- add animated transitions between the old and new document using the View Transitions API
-- support explicit persistent islands, i.e., islands that you can mark with unique IDs (something like `persist:searchbar` on the component in the view), which can be copied over from the old to the new document without losing their current state
-
-There are other, larger architectural changes that I’m [not sold on yet](https://github.com/leptos-rs/leptos/issues/1830).
-
-## Additional Information
-
-Check out the [islands PR](https://github.com/leptos-rs/leptos/pull/1660), [roadmap](https://github.com/leptos-rs/leptos/issues/1830), and [Hackernews demo](https://github.com/leptos-rs/leptos/tree/main/examples/hackernews_islands_axum) for additional discussion.
-
-## Demo Code
-
-```rust
-use leptos::*;
-use leptos_router::*;
-
-#[component]
-pub fn App() -> impl IntoView {
- view! {
-
-
-
-
-
-
-
- }
-}
-
-/// Renders the home page of your application.
-#[component]
-fn HomePage() -> impl IntoView {
- let files = ["a.txt", "b.txt", "c.txt"];
- let labels = files.iter().copied().map(Into::into).collect();
- let tabs = move || {
- files
- .into_iter()
- .enumerate()
- .map(|(index, filename)| {
- let content = std::fs::read_to_string(filename).unwrap();
- view! {
-
-
-
{filename.to_string()}
-
{content}
-
-
- }
- })
- .collect_view()
- };
-
- view! {
-
"Welcome to Leptos!"
-
"Click any of the tabs below to read a recipe."
-
- {tabs()}
-
- }
-}
-
-#[island]
-fn Tabs(labels: Vec
, children: Children) -> impl IntoView {
- let (selected, set_selected) = create_signal(0);
- provide_context(selected);
-
- let buttons = labels
- .into_iter()
- .enumerate()
- .map(|(index, label)| {
- view! {
-
- {label}
-
- }
- })
- .collect_view();
- view! {
-
- {buttons}
-
- {children()}
- }
-}
-
-#[island]
-fn Tab(index: usize, children: Children) -> impl IntoView {
- let selected = expect_context::>();
- view! {
-
- {children()}
-
- }
-}
-```
+
+
diff --git a/docs/book/src/metadata.md b/docs/book/src/metadata.md
index 0de45f7f5e..24a2c480ba 100644
--- a/docs/book/src/metadata.md
+++ b/docs/book/src/metadata.md
@@ -1,49 +1,2 @@
-# Metadata
-
-So far, everything we’ve rendered has been inside the `` of the HTML document. And this makes sense. After all, everything you can see on a web page lives inside the ``.
-
-However, there are plenty of occasions where you might want to update something inside the `` of the document using the same reactive primitives and component patterns you use for your UI.
-
-That’s where the [`leptos_meta`](https://docs.rs/leptos_meta/latest/leptos_meta/) package comes in.
-
-## Metadata Components
-
-`leptos_meta` provides special components that let you inject data from inside components anywhere in your application into the ``:
-
-[` `](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Title.html) allows you to set the document’s title from any component. It also takes a `formatter` function that can be used to apply the same format to the title set by other pages. So, for example, if you put ` ` in your ` ` component, and then ` ` and ` ` on your routes, you’ll get `Page 1 — My Awesome Site` and `Page 2 — My Awesome Site`.
-
-[` `](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Link.html) takes the standard attributes of the ` ` element.
-
-[` `](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Stylesheet.html) creates a ` ` with the `href` you give.
-
-[``](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Style.html) creates a ``.
-
-[` `](https://docs.rs/leptos_meta/latest/leptos_meta/fn.Meta.html) lets you set ` ` tags with descriptions and other metadata.
-
-## `` and `