diff --git a/.github/workflows/publish-website.yml b/.github/workflows/publish-website.yml
index a62c68e1a4a..15167502349 100644
--- a/.github/workflows/publish-website.yml
+++ b/.github/workflows/publish-website.yml
@@ -63,7 +63,7 @@ jobs:
targets: website
channelId: "${{ env.CHANNEL_ID }}"
# link to the next version because that's what we care about
- commentURLPath: "/next"
+ commentURLPath: "/docs/next"
# PR information
prNumber: "${{ env.PR_NUMBER }}"
prBranchName: "${{ env.PR_BRANCH }}"
diff --git a/README.md b/README.md
index 8b8a97ff154..f4f2528687e 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@
Documentation (stable) |
- Documentation (latest)
+ Documentation (latest) | Examples |
diff --git a/examples/function_todomvc/README.md b/examples/function_todomvc/README.md
index 97e9c651a3d..3e7cd06f3a3 100644
--- a/examples/function_todomvc/README.md
+++ b/examples/function_todomvc/README.md
@@ -6,7 +6,7 @@ This is an implementation of [TodoMVC](http://todomvc.com/) for Yew using functi
## Concepts
-- Uses [`function_components`](https://yew.rs/next/concepts/function-components)
+- Uses [`function_components`](https://yew.rs/docs/next/concepts/function-components)
- Uses [`gloo_storage`](https://gloo-rs.web.app/docs/storage) to persist the state
## Improvements
diff --git a/website/docs/advanced-topics/optimizations.md b/website/docs/advanced-topics/optimizations.md
index 56cc3a3a2fd..5be06464a47 100644
--- a/website/docs/advanced-topics/optimizations.md
+++ b/website/docs/advanced-topics/optimizations.md
@@ -107,7 +107,7 @@ It is possible to configure release builds to be smaller using the available set
`[profile.release]` section of your `Cargo.toml`.
-```text
+```toml, title=Cargo.toml
[profile.release]
# less code to include into binary
panic = 'abort'
diff --git a/website/docs/concepts/components/callbacks.md b/website/docs/concepts/components/callbacks.md
index 9213be3bb3d..bed13179266 100644
--- a/website/docs/concepts/components/callbacks.md
+++ b/website/docs/concepts/components/callbacks.md
@@ -1,95 +1,9 @@
---
title: "Callbacks"
-description: "ComponentLink and Callbacks"
---
-## Component's `Scope<_>` API
-
-The component "`Scope`" is the mechanism through which components are able to create callbacks and update themselves
-using messages. We obtain a reference to this by calling `link()` on the context object passed to the component.
-
-### `send_message`
-
-Sends a message to the component.
-Messages are handled by the `update` method which determines whether the component should re-render.
-
-### `send_message_batch`
-
-Sends multiple messages to the component at the same time.
-This is similar to `send_message` but if any of the messages cause the `update` method to return `true`,
-the component will re-render after all messages in the batch have been processed.
-
-If the given vector is empty, this function doesn't do anything.
-
-### `callback`
-
-Create a callback that will send a message to the component when it is executed.
-Under the hood, it will call `send_message` with the message returned by the provided closure.
-
-There is a different method called `callback_once` which accepts a `FnOnce` instead of a `Fn`.
-You should use this with care though, as the resulting callback will panic if executed more than once.
-
-```rust
-use yew::{html, Component, Context, Html};
-
-enum Msg {
- Text(String),
-}
-
-struct Comp;
-
-impl Component for Comp {
-
- type Message = Msg;
- type Properties = ();
-
- fn create(_ctx: &Context) -> Self {
- Self
- }
-
- fn view(&self, ctx: &Context) -> Html {
- // Create a callback that accepts some text and sends it
- // to the component as the `Msg::Text` message variant.
- // highlight-next-line
- let cb = ctx.link().callback(|text: String| Msg::Text(text));
-
- // The previous line is needlessly verbose to make it clearer.
- // It can be simplified it to this:
- // highlight-next-line
- let cb = ctx.link().callback(Msg::Text);
-
- // Will send `Msg::Text("Hello World!")` to the component.
- // highlight-next-line
- cb.emit("Hello World!".to_owned());
-
- html! {
- // html here
- }
- }
-}
-```
-
-### `batch_callback`
-
-Create a callback that will send a batch of messages to the component when it is executed.
-The difference to `callback` is that the closure passed to this method doesn't have to return a message.
-Instead, the closure can return either `Vec` or `Option` where `Msg` is the component's message type.
-
-`Vec` is treated as a batch of messages and uses `send_message_batch` under the hood.
-
-`Option` calls `send_message` if it is `Some`. If the value is `None`, nothing happens.
-This can be used in cases where, depending on the situation, an update isn't required.
-
-This is achieved using the `SendAsMessage` trait which is only implemented for these types.
-You can implement `SendAsMessage` for your own types which allows you to use them in `batch_callback`.
-
-Like `callback`, this method also has a `FnOnce` counterpart, `batch_callback_once`.
-The same restrictions apply as for `callback_once`.
-
## Callbacks
-_\(This might need its own short page.\)_
-
Callbacks are used to communicate with services, agents, and parent components within Yew.
Internally their type is just `Fn` wrapped in `Rc` to allow them to be cloned.
diff --git a/website/docs/concepts/components/introduction.md b/website/docs/concepts/components/introduction.md
index abc1a274b70..3c11cab0e43 100644
--- a/website/docs/concepts/components/introduction.md
+++ b/website/docs/concepts/components/introduction.md
@@ -91,7 +91,7 @@ impl Component for MyComponent {
}
```
-For usage details, check out [the `html!` guide](./../html.md).
+For usage details, check out [the `html!` guide](../html/introduction).
### Rendered
diff --git a/website/docs/concepts/components/scope.md b/website/docs/concepts/components/scope.md
new file mode 100644
index 00000000000..0b070cca9e1
--- /dev/null
+++ b/website/docs/concepts/components/scope.md
@@ -0,0 +1,87 @@
+---
+title: "Scope"
+description: "Component's Scope"
+---
+
+## Component's `Scope<_>` API
+
+The component "`Scope`" is the mechanism through which components are able to create callbacks and update themselves
+using messages. We obtain a reference to this by calling `link()` on the context object passed to the component.
+
+### `send_message`
+
+Sends a message to the component.
+Messages are handled by the `update` method which determines whether the component should re-render.
+
+### `send_message_batch`
+
+Sends multiple messages to the component at the same time.
+This is similar to `send_message` but if any of the messages cause the `update` method to return `true`,
+the component will re-render after all messages in the batch have been processed.
+
+If the given vector is empty, this function doesn't do anything.
+
+### `callback`
+
+Create a callback that will send a message to the component when it is executed.
+Under the hood, it will call `send_message` with the message returned by the provided closure.
+
+There is a different method called `callback_once` which accepts a `FnOnce` instead of a `Fn`.
+You should use this with care though, as the resulting callback will panic if executed more than once.
+
+```rust
+use yew::{html, Component, Context, Html};
+
+enum Msg {
+ Text(String),
+}
+
+struct Comp;
+
+impl Component for Comp {
+
+ type Message = Msg;
+ type Properties = ();
+
+ fn create(_ctx: &Context) -> Self {
+ Self
+ }
+
+ fn view(&self, ctx: &Context) -> Html {
+ // Create a callback that accepts some text and sends it
+ // to the component as the `Msg::Text` message variant.
+ // highlight-next-line
+ let cb = ctx.link().callback(|text: String| Msg::Text(text));
+
+ // The previous line is needlessly verbose to make it clearer.
+ // It can be simplified it to this:
+ // highlight-next-line
+ let cb = ctx.link().callback(Msg::Text);
+
+ // Will send `Msg::Text("Hello World!")` to the component.
+ // highlight-next-line
+ cb.emit("Hello World!".to_owned());
+
+ html! {
+ // html here
+ }
+ }
+}
+```
+
+### `batch_callback`
+
+Create a callback that will send a batch of messages to the component when it is executed.
+The difference to `callback` is that the closure passed to this method doesn't have to return a message.
+Instead, the closure can return either `Vec` or `Option` where `Msg` is the component's message type.
+
+`Vec` is treated as a batch of messages and uses `send_message_batch` under the hood.
+
+`Option` calls `send_message` if it is `Some`. If the value is `None`, nothing happens.
+This can be used in cases where, depending on the situation, an update isn't required.
+
+This is achieved using the `SendAsMessage` trait which is only implemented for these types.
+You can implement `SendAsMessage` for your own types which allows you to use them in `batch_callback`.
+
+Like `callback`, this method also has a `FnOnce` counterpart, `batch_callback_once`.
+The same restrictions apply as for `callback_once`.
diff --git a/website/docs/concepts/html/fragments.md b/website/docs/concepts/html/fragments.md
index 8673d2c864a..9347643f831 100644
--- a/website/docs/concepts/html/fragments.md
+++ b/website/docs/concepts/html/fragments.md
@@ -2,9 +2,15 @@
title: "Fragments"
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
The `html!` macro always requires a single root node. In order to get around this restriction, you
can use an "empty tag" (these are also called "fragments").
+
+
+
```rust
use yew::html;
@@ -14,15 +20,24 @@ html! {
>
};
+
```
-```rust ,compile_fail
+
+
+
+
+```rust, compile_fail
use yew::html;
-/* error: only one root html element allowed */
+// error: only one root html element allowed
html! {
};
+
```
+
+
+
diff --git a/website/docs/concepts/wasm-bindgen/introduction.md b/website/docs/concepts/wasm-bindgen/introduction.md
index 16af569e554..6ca37613180 100644
--- a/website/docs/concepts/wasm-bindgen/introduction.md
+++ b/website/docs/concepts/wasm-bindgen/introduction.md
@@ -1,13 +1,14 @@
---
-title: "Project Setup"
-sidebar_label: Introduction
+title: "`wasm-bindgen`"
+sidebar_label: wasm-bindgen
+slug: /concepts/wasm-bindgen
---
[`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) is a library and tool to facilitate
high-level interactions between Wasm modules and JavaScript; it is built with Rust by
[The Rust and WebAssembly Working Group](https://rustwasm.github.io/).
-Yew builds off wasm-bindgen and specifically uses the following of its crates:
+Yew builds off `wasm-bindgen` and specifically uses the following of its crates:
- [`js-sys`](https://crates.io/crates/js-sys)
- [`wasm-bindgen`](https://crates.io/crates/wasm-bindgen)
@@ -28,14 +29,14 @@ over using `wasm-bindgen`.
## [`wasm-bindgen`](https://crates.io/crates/wasm-bindgen)
This crate provides many of the building blocks for the rest of the crates above. In this section we
-are only going to cover two main areas of the `wasm-bindgen` crate and that is the macro and some of
-the types / traits you will see pop up again and again.
+are only going to cover two main areas of the `wasm-bindgen` crate and that is the macro and some
+types / traits you will see pop up again and again.
### `#[wasm_bindgen]` macro
The `#[wasm_bindgen]` macro, in a high level view, is your translator between Rust and JavaScript, it
allows you to describe imported JavaScript types in terms of Rust and vice versa. Using this macro
-is more advanced and you shouldn't need to reach for it unless you are trying to interop with an
+is more advanced, and you shouldn't need to reach for it unless you are trying to interop with an
external JavaScript library. The `js-sys` and `web-sys` crates are essentially imported types using
this macro for JavaScript types and the browser API respectively.
@@ -80,7 +81,7 @@ _This example was adapted from [1.2 Using console.log of The `wasm-bindgen` Guid
Inheritance between JavaScript classes is a big part of the language and is a major part of how the
Document Object Model (DOM). When types are imported using `wasm-bindgen` you can
-also add attributes that describe it's inheritance.
+also add attributes that describe its inheritance.
In Rust this inheritance is simulated using the [`Deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html)
and [`AsRef`](https://doc.rust-lang.org/std/convert/trait.AsRef.html) traits. An example of this
@@ -122,7 +123,7 @@ _[`JsValue` documentation](https://rustwasm.github.io/wasm-bindgen/api/wasm_bind
Rust has a strong type system and JavaScript...doesn't 😞 So in order for Rust to maintain these
strong types but still be convenient the web assembly group came up with a pretty neat trait `JsCast`.
-Its job is to help you move from one JavaScript "type" to another, which sounds vague but it means
+Its job is to help you move from one JavaScript "type" to another, which sounds vague, but it means
that if you have one type which you know is really another then you can use the functions of `JsCast`
to jump from one type to the other. It's a nice trait to get to know when working with `web-sys`,
`wasm_bindgen`, `js-sys` - you'll notice lots of types will implement `JsCast` from those crates.
@@ -132,10 +133,10 @@ unsure what type a certain object is you can try to cast it which returns possib
[`Option`](https://doc.rust-lang.org/std/option/enum.Option.html) and
[`Result`](https://doc.rust-lang.org/std/result/enum.Result.html).
-A common example of this in [`web-sys`](wasm-bindgen/web-sys) is when you are trying to get the
+A common example of this in [`web-sys`](web-sys) is when you are trying to get the
target of an event, you might know what the target element is but the
[`web_sys::Event`](https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Event.html) API will always return an [`Option`](https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Event.html#method.target)
-so you will need to cast it to the element type so you can call it's methods.
+so you will need to cast it to the element type. so you can call its methods.
```rust
// need to import the trait.
diff --git a/website/docs/concepts/wasm-bindgen/web-sys.md b/website/docs/concepts/wasm-bindgen/web-sys.md
index db19edd6cdf..16d2845804e 100644
--- a/website/docs/concepts/wasm-bindgen/web-sys.md
+++ b/website/docs/concepts/wasm-bindgen/web-sys.md
@@ -1,3 +1,5 @@
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
The [`web-sys` crate](https://crates.io/crates/web-sys) provides bindings for Web APIs. This is
procedurally generated from browser WebIDL which is why some of the names are so long and why
@@ -86,6 +88,9 @@ The two code blocks below do essentially the same thing, the first is using `Nod
the second is using [`JsCast::dyn_into`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html#method.dyn_into)
on the `web_sys::Node` returned from `NodeRef::get`.
+
+
+
```rust
use web_sys::HtmlInputElement;
use yew::NodeRef;
@@ -97,6 +102,9 @@ fn with_node_ref_cast(node_ref: NodeRef) {
}
```
+
+
+
```rust
use wasm_bindgen::JsCast;
use web_sys::HtmlInputElement;
@@ -111,6 +119,10 @@ fn with_jscast(node_ref: NodeRef) {
}
```
+
+
+
+
## JavaScript example to Rust
This section is to help show that any examples that use JavaScript to interact with the Web APIs
diff --git a/website/docs/getting-started/build-a-sample-app.md b/website/docs/getting-started/build-a-sample-app.md
index b1444392a6f..0b6509cc27b 100644
--- a/website/docs/getting-started/build-a-sample-app.md
+++ b/website/docs/getting-started/build-a-sample-app.md
@@ -40,7 +40,7 @@ edition = "2018"
[dependencies]
# you can check the latest version here: https://crates.io/crates/yew
-yew = "0.17"
+yew = "0.19"
```
### Update main.rs
@@ -53,7 +53,7 @@ The line `yew::start_app::()` inside `main()` starts your application and
If you would like to start your application with any dynamic properties, you can instead use `yew::start_app_with_props::(..)`.
:::
-```rust ,no_run
+```rust ,no_run, title=main.rs
use yew::prelude::*;
enum Msg {
@@ -106,7 +106,7 @@ fn main() {
Finally, add an `index.html` file in the root directory of your app.
-```html
+```html, title=index.html
diff --git a/website/docs/getting-started/project-setup/introduction.md b/website/docs/getting-started/project-setup/introduction.md
index 39c95e87deb..6f03a94d772 100644
--- a/website/docs/getting-started/project-setup/introduction.md
+++ b/website/docs/getting-started/project-setup/introduction.md
@@ -10,7 +10,7 @@ Your local development environment will need a couple of tools to compile, build
## Installing Rust
-To install Rust follow the [official instructions](https://www.rust-lang.org/tools/install).
+To install Rust, follow the [official instructions](https://www.rust-lang.org/tools/install).
:::important
The minimum supported Rust version (MSRV) for Yew is `1.49.0`. Older versions can cause unexpected issues accompanied by incomprehensible error messages.
diff --git a/website/docs/intro.md b/website/docs/intro.md
deleted file mode 100644
index 5e8bc3d296f..00000000000
--- a/website/docs/intro.md
+++ /dev/null
@@ -1,79 +0,0 @@
----
-title: "Introduction"
-slug: /
----
-
-## What is Yew?
-
-**Yew** is a modern [Rust](https://www.rust-lang.org/) framework for creating multi-threaded
-front-end web apps using [WebAssembly](https://webassembly.org/).
-
-* It features a **component-based** framework which makes it easy to create interactive UIs.
-Developers who have experience with frameworks like [React](https://reactjs.org/) and
-[Elm](https://elm-lang.org/) should feel quite at home when using Yew.
-* It achieves **great performance** by minimizing DOM API calls and by helping developers to easily
-offload processing to background threads using web workers.
-* It supports **JavaScript interoperability**, allowing developers to leverage NPM packages and
-integrate with existing JavaScript applications.
-
-### Join Us 😊
-
-* You can report bugs and discuss features on the [GitHub issues page](https://github.com/yewstack/yew/issues)
-* We love pull requests. Check out the [good first issues](https://github.com/yewstack/yew/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
-if you'd like to help out!
-* Our [Discord chat](https://discord.gg/VQck8X4) is very active and is a great place to ask
-questions
-
-### Ready to dive in?
-
-Click the link below to learn how to build your first Yew app and learn from community-built example
-projects
-
-[Getting started](./../getting-started/project-setup.md)
-
-### Still not convinced?
-
-This project is built on cutting edge technology and is great for developers who like to develop the
-foundational projects of tomorrow. We think that the speed and reliability of the technologies on
-which Yew is built are set to become the standard for fast and resilient web applications of the
-future.
-
-#### Wait, why WebAssembly?
-
-WebAssembly _\(Wasm\)_ is a portable low-level language that Rust can compile to. It runs at native
-speeds in the browser and is interoperable with JavaScript and supported in all major modern
-browsers. For ideas on how to get the most out of WebAssembly for your app, check out this list of
-[use cases](https://webassembly.org/docs/use-cases/).
-
-It should be noted that using Wasm is not \(yet\) a silver bullet for improving the performance of
-web apps. As of the present, using DOM APIs from WebAssembly is still slower than calling them
-directly from JavaScript. This is a temporary issue which the
-[WebAssembly Interface Types](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md) proposal aims to resolve. If you would like to learn more, check out this
-[excellent article](https://hacks.mozilla.org/2019/08/webassembly-interface-types/) (from Mozilla)
-which describes the proposal.
-
-#### Ok, but why Rust?
-
-Rust is blazing fast and reliable with its rich type system and ownership model. It has a tough
-learning curve but is well worth the effort. Rust has been voted the most loved programming
-language in Stack Overflow's Developer Survey five years in a row:
-[2016](https://insights.stackoverflow.com/survey/2016#technology-most-loved-dreaded-and-wanted),
-[2017](https://insights.stackoverflow.com/survey/2017#most-loved-dreaded-and-wanted),
-[2018](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages),
-[2019](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages)
-and [2020](https://insights.stackoverflow.com/survey/2020#most-loved-dreaded-and-wanted).
-
-Rust also helps developers write safer code with its rich type system and ownership model. Say
-goodbye to hard to track down race condition bugs in JavaScript! In fact, with Rust, most of your
-bugs will be caught by the compiler before your app even runs. And don't worry, when your app does
-run into an error, you can still get full stack-traces for your Rust code in the browser console.
-
-#### Alternatives?
-
-We love to share ideas with other projects and believe we can all help each other reach the full
-potential of this exciting new technology. If you're not into Yew, you might like the following
-projects:
-
-* [Percy](https://github.com/chinedufn/percy) - _"A modular toolkit for building isomorphic web apps
-with Rust + WebAssembly"_
-* [Seed](https://github.com/seed-rs/seed) - _"A Rust framework for creating web apps"_
diff --git a/website/docs/tutorial.md b/website/docs/tutorial.md
index 9e39339eb8c..e4d88b03487 100644
--- a/website/docs/tutorial.md
+++ b/website/docs/tutorial.md
@@ -451,10 +451,10 @@ element returned by the `Iterator` with the `{ for ... }` syntax.
Remember the `use_state` used earlier? That is a special function, called a "hook". Hooks are used to "hook" into
lifecycle of a function component and perform actions. You can learn more about this hook, and others
-[here](/next/concepts/function-components/pre-defined-hooks#use_state)
+[here](concepts/function-components/pre-defined-hooks#use_state)
:::note
-Struct components act differently. See [the documentation](/concepts/components) to learn about those.
+Struct components act differently. See [the documentation](concepts/components) to learn about those.
:::
## Fetching data (using external REST API)
@@ -576,9 +576,9 @@ to learn how to add style sheets.
### More libraries
Our app made use of only a few external dependencies. There are lots of crates out there that can be used.
-See [external libraries](/next/more/external-libs) for more details.
+See [external libraries](more/external-libs) for more details.
### Learning more about Yew
-Read our [official documentation](/next). It explains a lot of concepts in much more details.
+Read our [official documentation](/docs). It explains a lot of concepts in much more details.
To learn more about our the Yew API, see our [API docs](https://docs.rs/yew).
diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js
index 28e2580a12c..351cc233c33 100644
--- a/website/docusaurus.config.js
+++ b/website/docusaurus.config.js
@@ -26,8 +26,10 @@ module.exports = {
position: 'left',
},
{
- to: '/',
- label: 'Docs'
+ type: 'doc',
+ position: 'left',
+ docId: 'getting-started/project-setup/introduction',
+ label: 'Docs',
},
{
href: 'https://docs.rs/yew',
@@ -108,7 +110,7 @@ module.exports = {
docs: {
sidebarPath: require.resolve('./sidebars.js'),
editUrl: 'https://github.com/yewstack/yew/blob/master/website/',
- routeBasePath: '/',
+ routeBasePath: '/docs',
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
@@ -116,4 +118,19 @@ module.exports = {
},
],
],
+ plugins: [
+ [
+ '@docusaurus/plugin-client-redirects',
+ {
+ redirects: [
+ // this handles the redirect from `/next` -> to the (current) first item in the docs sidebar
+ // note: if the first item is changed, it should be reflected here
+ {
+ to: '/docs/next/getting-started/project-setup/introduction', // string
+ from: ['/docs/next'], // string | string[]
+ },
+ ],
+ },
+ ],
+ ],
};
diff --git a/website/package-lock.json b/website/package-lock.json
index 88992634803..a0a22df5741 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@docusaurus/core": "^2.0.0-beta.9",
+ "@docusaurus/plugin-client-redirects": "^2.0.0-beta.9",
"@docusaurus/plugin-google-analytics": "*",
"@docusaurus/preset-classic": "^2.0.0-beta.9",
"@docusaurus/theme-search-algolia": "*",
@@ -2098,6 +2099,31 @@
"integrity": "sha512-FPy/Wa4dH0QvtR92/JJi7t2SB1tnySuSGVNf4e0llArZ4E7+vzTAmd4qVfzBuS+LMj/M6woKHLn+zKKUkfaZOw==",
"dev": true
},
+ "node_modules/@docusaurus/plugin-client-redirects": {
+ "version": "2.0.0-beta.9",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-2.0.0-beta.9.tgz",
+ "integrity": "sha512-rksXkA9keq9jsgxp0ZLX+MY68ViDhCpdLcxNCNmZl2c9XA2v8AQN4HU2e6Dq+OEefk/ltQYLIbfTa2Hj/ZEwzQ==",
+ "dependencies": {
+ "@docusaurus/core": "2.0.0-beta.9",
+ "@docusaurus/types": "2.0.0-beta.9",
+ "@docusaurus/utils": "2.0.0-beta.9",
+ "@docusaurus/utils-common": "2.0.0-beta.9",
+ "@docusaurus/utils-validation": "2.0.0-beta.9",
+ "chalk": "^4.1.2",
+ "eta": "^1.12.3",
+ "fs-extra": "^10.0.0",
+ "globby": "^11.0.2",
+ "lodash": "^4.17.20",
+ "tslib": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "react": "^16.8.4 || ^17.0.0",
+ "react-dom": "^16.8.4 || ^17.0.0"
+ }
+ },
"node_modules/@docusaurus/plugin-content-blog": {
"version": "2.0.0-beta.9",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.0.0-beta.9.tgz",
@@ -14287,6 +14313,24 @@
"integrity": "sha512-FPy/Wa4dH0QvtR92/JJi7t2SB1tnySuSGVNf4e0llArZ4E7+vzTAmd4qVfzBuS+LMj/M6woKHLn+zKKUkfaZOw==",
"dev": true
},
+ "@docusaurus/plugin-client-redirects": {
+ "version": "2.0.0-beta.9",
+ "resolved": "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-2.0.0-beta.9.tgz",
+ "integrity": "sha512-rksXkA9keq9jsgxp0ZLX+MY68ViDhCpdLcxNCNmZl2c9XA2v8AQN4HU2e6Dq+OEefk/ltQYLIbfTa2Hj/ZEwzQ==",
+ "requires": {
+ "@docusaurus/core": "2.0.0-beta.9",
+ "@docusaurus/types": "2.0.0-beta.9",
+ "@docusaurus/utils": "2.0.0-beta.9",
+ "@docusaurus/utils-common": "2.0.0-beta.9",
+ "@docusaurus/utils-validation": "2.0.0-beta.9",
+ "chalk": "^4.1.2",
+ "eta": "^1.12.3",
+ "fs-extra": "^10.0.0",
+ "globby": "^11.0.2",
+ "lodash": "^4.17.20",
+ "tslib": "^2.3.1"
+ }
+ },
"@docusaurus/plugin-content-blog": {
"version": "2.0.0-beta.9",
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.0.0-beta.9.tgz",
diff --git a/website/package.json b/website/package.json
index 06d276f03f6..b12e875fe88 100644
--- a/website/package.json
+++ b/website/package.json
@@ -15,6 +15,7 @@
},
"dependencies": {
"@docusaurus/core": "^2.0.0-beta.9",
+ "@docusaurus/plugin-client-redirects": "^2.0.0-beta.9",
"@docusaurus/plugin-google-analytics": "*",
"@docusaurus/preset-classic": "^2.0.0-beta.9",
"@docusaurus/theme-search-algolia": "*",
diff --git a/website/sidebars.js b/website/sidebars.js
index d90d6e371d4..17078dd6f22 100644
--- a/website/sidebars.js
+++ b/website/sidebars.js
@@ -13,122 +13,122 @@ module.exports = {
// By default, Docusaurus generates a sidebar from the docs folder structure
// conceptsSidebar: [{type: 'autogenerated', dirName: '.'}],
- // But you can create a sidebar manually
- sidebar: [
- "intro",
- {
- type: "category",
- label: "Getting Started",
- items: [
- "getting-started/build-a-sample-app",
- "getting-started/examples",
- "getting-started/starter-templates",
+ // But you can create a sidebar manually
+ sidebar: [
{
- type: "category",
- label: "Project Setup",
- items: [
- "getting-started/project-setup/introduction",
- "getting-started/project-setup/using-trunk",
- "getting-started/project-setup/using-wasm-pack",
- ],
+ type: 'category',
+ label: 'Getting Started',
+ items: [
+ {
+ type: 'category',
+ label: 'Project Setup',
+ items: [
+ 'getting-started/project-setup/introduction',
+ 'getting-started/project-setup/using-trunk',
+ 'getting-started/project-setup/using-wasm-pack',
+ ]
+ },
+ "getting-started/build-a-sample-app",
+ "getting-started/examples",
+ "getting-started/starter-templates",
+ ],
},
- ],
- },
- {
- type: "category",
- label: "Concepts",
- items: [
{
- type: "category",
- label: "wasm-bindgen",
- items: [
- "concepts/wasm-bindgen/introduction",
- "concepts/wasm-bindgen/web-sys"
- ],
+ type: "category",
+ label: "Concepts",
+ items: [
+ {
+ type: "category",
+ label: "wasm-bindgen",
+ items: [
+ "concepts/wasm-bindgen/introduction",
+ "concepts/wasm-bindgen/web-sys",
+ ]
+ },
+ {
+ type: "category",
+ label: "Components",
+ items: [
+ "concepts/components/introduction",
+ "concepts/components/callbacks",
+ "concepts/components/scope",
+ "concepts/components/properties",
+ "concepts/components/children",
+ "concepts/components/refs"
+ ],
+ },
+ {
+ type: "category",
+ label: "HTML",
+ items: [
+ "concepts/html/introduction",
+ "concepts/html/components",
+ "concepts/html/elements",
+ "concepts/html/events",
+ "concepts/html/classes",
+ "concepts/html/fragments",
+ "concepts/html/lists",
+ "concepts/html/literals-and-expressions"
+ ]
+ },
+ {
+ type: "category",
+ label: "Function Components",
+ items: [
+ "concepts/function-components/introduction",
+ "concepts/function-components/attribute",
+ "concepts/function-components/pre-defined-hooks",
+ "concepts/function-components/custom-hooks",
+ ]
+ },
+ "concepts/agents",
+ "concepts/contexts",
+ "concepts/router",
+ ]
},
{
- type: "category",
- label: "Components",
- items: [
- "concepts/components/introduction",
- "concepts/components/callbacks",
- "concepts/components/properties",
- "concepts/components/children",
- "concepts/components/refs",
- ],
+ type: 'category',
+ label: 'Advanced topics',
+ items: [
+ "advanced-topics/how-it-works",
+ "advanced-topics/optimizations",
+ "advanced-topics/portals",
+ ]
},
{
- type: "category",
- label: "HTML",
- items: [
- "concepts/html/introduction",
- "concepts/html/components",
- "concepts/html/elements",
- "concepts/html/events",
- "concepts/html/classes",
- "concepts/html/fragments",
- "concepts/html/lists",
- "concepts/html/literals-and-expressions",
- ],
+ type: 'category',
+ label: 'More',
+ items: [
+ "more/debugging",
+ "more/development-tips",
+ "more/external-libs",
+ "more/css",
+ "more/testing",
+ "more/roadmap",
+ "more/wasm-build-tools"
+ ]
},
{
- type: "category",
- label: "Function Components",
- items: [
- "concepts/function-components/introduction",
- "concepts/function-components/attribute",
- "concepts/function-components/pre-defined-hooks",
- "concepts/function-components/custom-hooks",
- ],
+ type: "category",
+ label: "Migration guides",
+ items: [
+ {
+ type: "category",
+ label: "yew",
+ items: ["migration-guides/yew/from-0_18_0-to-0_19_0"],
+ },
+ {
+ type: "category",
+ label: "yew-agent",
+ items: ["migration-guides/yew-agent/from-0_0_0-to-0_1_0"],
+ },
+ {
+ type: "category",
+ label: "yew-router",
+ items: ["migration-guides/yew-router/from-0_15_0-to-0_16_0"],
+ },
+ ],
},
- "concepts/agents",
- "concepts/contexts",
- "concepts/router",
- ],
- },
- {
- type: "category",
- label: "Advanced topics",
- items: [
- "advanced-topics/how-it-works",
- "advanced-topics/optimizations",
- "advanced-topics/portals",
- ],
- },
- {
- type: "category",
- label: "More",
- items: [
- "more/debugging",
- "more/development-tips",
- "more/external-libs",
- "more/css",
- "more/testing",
- "more/roadmap",
- "more/wasm-build-tools",
- ],
- },
- {
- type: "category",
- label: "Migration guides",
- items: [
- {
- type: "category",
- label: "yew",
- items: ["migration-guides/yew/from-0_18_0-to-0_19_0"],
- },
- {
- type: "category",
- label: "yew-agent",
- items: ["migration-guides/yew-agent/from-0_0_0-to-0_1_0"],
- },
- {
- type: "category",
- label: "yew-router",
- items: ["migration-guides/yew-router/from-0_15_0-to-0_16_0"],
- },
- ],
- },
- "tutorial",
- ],
+ "tutorial"
+ ],
};
diff --git a/website/versioned_docs/version-0.18.0/intro.md b/website/src/pages/index.mdx
similarity index 66%
rename from website/versioned_docs/version-0.18.0/intro.md
rename to website/src/pages/index.mdx
index 01bc9a4c616..5a564d08087 100644
--- a/website/versioned_docs/version-0.18.0/intro.md
+++ b/website/src/pages/index.mdx
@@ -1,82 +1,77 @@
----
-title: "Introduction"
-slug: /
----
+# What is Yew?
-## What is Yew?
-
-**Yew** is a modern [Rust](https://www.rust-lang.org/) framework for creating multi-threaded
+**Yew** is a modern [Rust](https://www.rust-lang.org/) framework for creating multi-threaded
front-end web apps using [WebAssembly](https://webassembly.org/).
-* It features a **component-based** framework which makes it easy to create interactive UIs.
-Developers who have experience with frameworks like [React](https://reactjs.org/) and
-[Elm](https://elm-lang.org/) should feel quite at home when using Yew.
-* It achieves **great performance** by minimizing DOM API calls and by helping developers to easily
-offload processing to background threads using web workers.
-* It supports **JavaScript interoperability**, allowing developers to leverage NPM packages and
-integrate with existing JavaScript applications.
+* It features a **component-based** framework which makes it easy to create interactive UIs.
+ Developers who have experience with frameworks like [React](https://reactjs.org/) and
+ [Elm](https://elm-lang.org/) should feel quite at home when using Yew.
+* It achieves **great performance** by minimizing DOM API calls and by helping developers to easily
+ offload processing to background threads using web workers.
+* It supports **JavaScript interoperability**, allowing developers to leverage NPM packages and
+ integrate with existing JavaScript applications.
-### Join Us 😊
+## Join Us 😊
* You can report bugs and discuss features on the [GitHub issues page](https://github.com/yewstack/yew/issues)
-* We love pull requests. Check out the [good first issues](https://github.com/yewstack/yew/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
-if you'd like to help out!
-* Our [Discord chat](https://discord.gg/VQck8X4) is very active and is a great place to ask
-questions
+* We love pull requests. Check out the [good first issues](https://github.com/yewstack/yew/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
+ if you'd like to help out!
+* Our [Discord chat](https://discord.gg/VQck8X4) is very active and is a great place to ask
+ questions
-### Ready to dive in?
+## Ready to dive in?
-Click the link below to learn how to build your first Yew app and learn from community-built example
+Click the link below to learn how to build your first Yew app and learn from community-built example
projects
-[Getting started](getting-started/project-setup.md)
+[Getting started](getting-started/project-setup/introduction)
-### Still not convinced?
+## Still not convinced?
-This project is built on cutting edge technology and is great for developers who like to develop the
+This project is built on cutting edge technology and is great for developers who like to develop the
foundational projects of tomorrow. We think that the speed and reliability of the technologies on
which Yew is built are set to become the standard for fast and resilient web applications of the
-future.
+future.
-#### Wait, why WebAssembly?
+### Wait, why WebAssembly?
-WebAssembly _\(Wasm\)_ is a portable low-level language that Rust can compile to. It runs at native
-speeds in the browser and is interoperable with JavaScript and supported in all major modern
-browsers. For ideas on how to get the most out of WebAssembly for your app, check out this list of
+WebAssembly _\(Wasm\)_ is a portable low-level language that Rust can compile to. It runs at native
+speeds in the browser and is interoperable with JavaScript and supported in all major modern
+browsers. For ideas on how to get the most out of WebAssembly for your app, check out this list of
[use cases](https://webassembly.org/docs/use-cases/).
-It should be noted that using Wasm is not \(yet\) a silver bullet for improving the performance of
-web apps. As of the present, using DOM APIs from WebAssembly is still slower than calling them
-directly from JavaScript. This is a temporary issue which the
-[WebAssembly Interface Types](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md) proposal aims to resolve. If you would like to learn more, check out this
-[excellent article](https://hacks.mozilla.org/2019/08/webassembly-interface-types/) (from Mozilla)
+It should be noted that using Wasm is not \(yet\) a silver bullet for improving the performance of
+web apps. As of the present, using DOM APIs from WebAssembly is still slower than calling them
+directly from JavaScript. This is a temporary issue which the
+[WebAssembly Interface Types](https://github.com/WebAssembly/interface-types/blob/master/proposals/interface-types/Explainer.md) proposal aims to resolve. If you would like to learn more, check out this
+[excellent article](https://hacks.mozilla.org/2019/08/webassembly-interface-types/) (from Mozilla)
which describes the proposal.
-#### Ok, but why Rust?
+### Ok, but why Rust?
-Rust is blazing fast and reliable with its rich type system and ownership model. It has a tough
-learning curve but is well worth the effort. Rust has been voted the most loved programming
-language in Stack Overflow's Developer Survey six years in a row:
-[2016](https://insights.stackoverflow.com/survey/2016#technology-most-loved-dreaded-and-wanted),
-[2017](https://insights.stackoverflow.com/survey/2017#most-loved-dreaded-and-wanted),
-[2018](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages),
-[2019](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages),
-[2020](https://insights.stackoverflow.com/survey/2020#most-loved-dreaded-and-wanted) and
+Rust is blazing fast and reliable with its rich type system and ownership model. It has a tough
+learning curve but is well worth the effort. Rust has been voted the most loved programming
+language in Stack Overflow's Developer Survey six years in a row:
+[2016](https://insights.stackoverflow.com/survey/2016#technology-most-loved-dreaded-and-wanted),
+[2017](https://insights.stackoverflow.com/survey/2017#most-loved-dreaded-and-wanted),
+[2018](https://insights.stackoverflow.com/survey/2018#technology-_-most-loved-dreaded-and-wanted-languages),
+[2019](https://insights.stackoverflow.com/survey/2019#technology-_-most-loved-dreaded-and-wanted-languages),
+[2020](https://insights.stackoverflow.com/survey/2020#most-loved-dreaded-and-wanted) and
[2021](https://insights.stackoverflow.com/survey/2021/#technology-most-loved-dreaded-and-wanted).
-Rust also helps developers write safer code with its rich type system and ownership model. Say
-goodbye to hard to track down race condition bugs in JavaScript! In fact, with Rust, most of your
-bugs will be caught by the compiler before your app even runs. And don't worry, when your app does
+Rust also helps developers write safer code with its rich type system and ownership model. Say
+goodbye to hard to track down race condition bugs in JavaScript! In fact, with Rust, most of your
+bugs will be caught by the compiler before your app even runs. And don't worry, when your app does
run into an error, you can still get full stack-traces for your Rust code in the browser console.
-#### Alternatives?
+### Alternatives?
-We love to share ideas with other projects and believe we can all help each other reach the full
-potential of this exciting new technology. If you're not into Yew, you might like the following
+We love to share ideas with other projects and believe we can all help each other reach the full
+potential of this exciting new technology. If you're not into Yew, you might like the following
projects:
-* [Percy](https://github.com/chinedufn/percy) - _"A modular toolkit for building isomorphic web apps
-with Rust + WebAssembly"_
+* [Percy](https://github.com/chinedufn/percy) - _"A modular toolkit for building isomorphic web apps
+ with Rust + WebAssembly"_
* [Seed](https://github.com/seed-rs/seed) - _"A Rust framework for creating web apps"_
* [Perseus](https://github.com/arctic-hen7/perseus) - _"A high-level web development framework for Rust with full support for server-side rendering and static generation"_
* [Sycamore](https://github.com/sycamore-rs/sycamore) - _"A reactive library for creating web apps in Rust and WebAssembly"_
diff --git a/website/versioned_docs/version-0.18.0/concepts/components.md b/website/versioned_docs/version-0.18.0/concepts/components/introduction.md
similarity index 99%
rename from website/versioned_docs/version-0.18.0/concepts/components.md
rename to website/versioned_docs/version-0.18.0/concepts/components/introduction.md
index 9999bd105f2..22fd283ad8c 100644
--- a/website/versioned_docs/version-0.18.0/concepts/components.md
+++ b/website/versioned_docs/version-0.18.0/concepts/components/introduction.md
@@ -67,7 +67,7 @@ impl Component for MyComponent {
}
```
-For usage details, check out [the `html!` guide](html.md).
+For usage details, check out [the `html!` guide](../html/introduction.md).
### Rendered
diff --git a/website/versioned_docs/version-0.18.0/concepts/html.md b/website/versioned_docs/version-0.18.0/concepts/html/introduction.md
similarity index 99%
rename from website/versioned_docs/version-0.18.0/concepts/html.md
rename to website/versioned_docs/version-0.18.0/concepts/html/introduction.md
index c805ab82462..a584410cf58 100644
--- a/website/versioned_docs/version-0.18.0/concepts/html.md
+++ b/website/versioned_docs/version-0.18.0/concepts/html/introduction.md
@@ -13,7 +13,7 @@ The `html!` macro allows you to write HTML and SVG code declaratively. It is sim
**Important notes**
1. The `html!` macro only accepts a single root HTML node \(this obstacle is easily overcome by
- [using fragments or iterators](html/lists.md)\)
+ [using fragments or iterators](../html/lists.md)\)
2. An empty `html! {}` invocation is valid and will not render anything
3. Literals must always be wrapped in quotes as well as braces (i.e.
`html! {
{"Hello, World"}
}` is valid, but not `html! {
Hello, World
}` or
diff --git a/website/versioned_docs/version-0.18.0/concepts/services.md b/website/versioned_docs/version-0.18.0/concepts/services/introduction.md
similarity index 100%
rename from website/versioned_docs/version-0.18.0/concepts/services.md
rename to website/versioned_docs/version-0.18.0/concepts/services/introduction.md
diff --git a/website/versioned_docs/version-0.18.0/concepts/wasm-bindgen.md b/website/versioned_docs/version-0.18.0/concepts/wasm-bindgen/wasm-bindgen.md
similarity index 100%
rename from website/versioned_docs/version-0.18.0/concepts/wasm-bindgen.md
rename to website/versioned_docs/version-0.18.0/concepts/wasm-bindgen/wasm-bindgen.md
diff --git a/website/versioned_docs/version-0.18.0/getting-started/project-setup.md b/website/versioned_docs/version-0.18.0/getting-started/project-setup/introduction.md
similarity index 93%
rename from website/versioned_docs/version-0.18.0/getting-started/project-setup.md
rename to website/versioned_docs/version-0.18.0/getting-started/project-setup/introduction.md
index 4390b9837e9..5879e5b89a7 100644
--- a/website/versioned_docs/version-0.18.0/getting-started/project-setup.md
+++ b/website/versioned_docs/version-0.18.0/getting-started/project-setup/introduction.md
@@ -32,7 +32,7 @@ It can bundle assets for your app and even ships with a Sass compiler.
All of our examples are built with Trunk.
-[Getting started with `trunk`](project-setup/using-trunk.md)
+[Getting started with `trunk`](../project-setup/using-trunk.md)
### [**`wasm-pack`**](https://rustwasm.github.io/docs/wasm-pack/)
@@ -41,20 +41,20 @@ together with the [`wasm-pack-plugin`](https://github.com/wasm-tool/wasm-pack-pl
The primary purpose of `wasm-pack` is building Wasm libraries for use in JavaScript.
Because of this, it can only build libraries and doesn't provide useful tools like a development server or automatic rebuilds.
-[Get started with `wasm-pack`](project-setup/using-wasm-pack.md)
+[Get started with `wasm-pack`](../project-setup/using-wasm-pack.md)
### [**`cargo-web`**](https://github.com/koute/cargo-web)
This was the best preferred tool to use before the creation of `wasm-bindgen`.
-[Getting started with `cargo web`](project-setup/using-cargo-web.md)
+[Getting started with `cargo web`](../project-setup/using-cargo-web.md)
### Comparison
| | `trunk` | `wasm-pack` | `cargo-web` |
| ----------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Project Status | Actively maintained | Actively maintained by the [Rust / Wasm Working Group](https://rustwasm.github.io) | No Github activity for over 6 months |
-| Dev Experience | Just works! Batteries included, no external dependencies needed. | Bare-bones. You'll need to write some scripts to streamline the experience or use the webpack plugin. | Works great for code but needs separate asset pipeline. |
+| Dev Experience | Just works! Batteries included, no external dependencies needed. | Bare-bones. You'll need to write some scripts to streamline the experience or use the webpack plugin. | Works great for code but needs separate asset pipeline. |
| Local Server | Supported | Only with webpack plugin | Supported |
| Auto rebuild on local changes | Supported | Only with webpack plugin | Supported |
| Asset handling | Supported | Only with webpack plugin | Static assets only |
@@ -62,4 +62,4 @@ This was the best preferred tool to use before the creation of `wasm-bindgen`.
| Supported Targets |
wasm32-unknown-unknown
|
wasm32-unknown-unknown
|
wasm32-unknown-unknown
wasm32-unknown-emscripten
asmjs-unknown-emscripten
|
| `web-sys` | Compatible | Compatible | Incompatible |
| `stdweb` | Incompatible | Compatible | Compatible |
-| Example Usage | [Sample app](./build-a-sample-app.md) | [Starter template](https://github.com/yewstack/yew-wasm-pack-minimal) | [Build script](https://www.github.com/yewstack/yew/tree/master/packages/yew-stdweb/examples) for `yew-stdweb` examples |
+| Example Usage | [Sample app](../build-a-sample-app.md) | [Starter template](https://github.com/yewstack/yew-wasm-pack-minimal) | [Build script](https://www.github.com/yewstack/yew/tree/master/packages/yew-stdweb/examples) for `yew-stdweb` examples |
diff --git a/website/versioned_docs/version-0.19.0/advanced-topics/how-it-works.md b/website/versioned_docs/version-0.19.0/advanced-topics/how-it-works.md
new file mode 100644
index 00000000000..16caea78ff7
--- /dev/null
+++ b/website/versioned_docs/version-0.19.0/advanced-topics/how-it-works.md
@@ -0,0 +1,71 @@
+---
+title: "How it works"
+description: "Low level details about the framework"
+---
+
+# Low-level library internals
+
+## Under the hood of the `html!` macro
+
+The `html!` macro turns code written in a custom HTML-like syntax into valid Rust code. Using this
+macro is not necessary for developing Yew applications, but it is recommended. The code generated
+by this macro makes use of the public Yew library API which can be used directly if you wish. Note
+that some methods used are undocumented intentionally to avoid accidental misuse. With each
+update of `yew-macro`, the generated code will be more efficient and handle any breaking changes
+without many (if any) modifications to the `html!` syntax.
+
+Because the `html!` macro allows you to write code in a declarative style, your UI layout code will
+closely match the HTML that is generated to the page. This becomes increasingly useful as your
+application gets more interactive and your codebase gets larger. Rather than manually writing the
+all of the code to manipulate the DOM yourself, the macro will handle it for you.
+
+Using the `html!` macro can feel pretty magic, but it has nothing to hide. If you're curious about
+how it works, try expanding the `html!` macro calls in your program. There's a useful command called
+`cargo expand` which allows you to see the expansion of Rust macros. `cargo expand` isn't shipped with
+`cargo` by default so you'll need to install it with `cargo install cargo-expand` if you haven't
+already.
+
+Note that when viewing expanded macro code, you're likely to encounter unusually verbose code. The
+reason is because generated code can sometimes clash with other code in an application. In order
+to prevent issues, `proc_macro` "hygiene" is adhered to. Some examples include:
+
+1. Instead of using `yew::` the macro generates `::yew::` to make sure that the
+Yew package is referenced correctly. This is also why `::alloc::vec::Vec::new()` is called instead
+of just `Vec::new()`.
+2. Due to potential trait method name collisions, `` is used to make sure that we're using items from the right trait.
+
+## What is a virtual DOM?
+
+The DOM ("document object model") is a representation of the HTML content that is managed by the browser
+for your web page. A "virtual" DOM is simply a copy of the DOM that is held in application memory. Managing
+a virtual DOM results in a higher memory overhead, but allows for batching and faster reads by avoiding
+or delaying the use of browser APIs.
+
+Having a copy of the DOM in memory can be really helpful for libraries which promote the use of
+declarative UIs. Rather than needing specific code for describing how the DOM should be modified
+in response to a user event, the library can use a generalized approach with DOM "diffing". When a Yew
+component is updated and wants to change how it is rendered, the Yew library will build a second copy
+of the virtual DOM and directly compare to a virtual DOM which mirrors what is currently on screen.
+The "diff" (or difference) between the two can be broken down into incremental updates and applied in
+a batch with browser APIs. Once the updates are applied, the old virtual DOM copy is discarded and the
+new copy is saved for future diff checks.
+
+This "diff" algorithm can be optimized over time to improve the performance of complex applications.
+Since Yew applications are run with WebAssembly, we believe that Yew has a competitive edge to adopt
+more sophisticated algorithms in the future.
+
+The Yew virtual DOM is not exactly one-to-one with the browser DOM. It also includes "lists" and
+"components" for organizing DOM elements. A list can simply be an ordered list of elements but can
+also be much more powerful. By annotating each list element with a "key", application developers
+can help Yew make additional optimizations to ensure that when a list changes, the least amount
+of work is done to calculate the diff update. Similarly, components provide custom logic to
+indicate whether a re-render is required to help with performance.
+
+## Yew scheduler and component-scoped event loop
+
+*Contribute to the docs – explain how `yew::scheduler` and `yew::html::scope` work in depth*
+
+## Further reading
+* [More information about macros from the Rust Book](https://doc.rust-lang.org/stable/book/ch19-06-macros.html)
+* [More information about `cargo-expand`](https://github.com/dtolnay/cargo-expand)
+* [The API documentation for `yew::virtual_dom`](https://docs.rs/yew/*/yew/virtual_dom/index.html)
diff --git a/website/versioned_docs/version-0.19.0/advanced-topics/optimizations.md b/website/versioned_docs/version-0.19.0/advanced-topics/optimizations.md
new file mode 100644
index 00000000000..5be06464a47
--- /dev/null
+++ b/website/versioned_docs/version-0.19.0/advanced-topics/optimizations.md
@@ -0,0 +1,152 @@
+---
+title: "Optimizations & Best Practices"
+sidebar_label: Optimizations
+description: "Make your app faster"
+---
+
+## Using smart pointers effectively
+
+**Note: if you're unsure about some of the terms used in this section, the Rust Book has a useful
+[chapter about smart pointers](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html).**
+
+In an effort to avoid cloning large amounts of data to create props when re-rendering, we can use
+smart pointers to only clone a reference to the data instead of the data itself. If you pass
+references to the relevant data in your props and child components instead of the actual data you
+can avoid cloning any data until you need to modify it in the child component, where you can
+use `Rc::make_mut` to clone and obtain a mutable reference to the data you want to alter.
+
+This brings further benefits in `Component::changed` when working out whether prop changes require
+the component to re-render. This is because instead of comparing the value of the data the
+underlying pointer addresses (i.e. the position in a machine's memory where the data is stored) can
+instead be compared; if two pointers point to the same data then the value of the data they point to
+must be the same. Note that the inverse might not be true! Even if two pointer addresses differ the
+underlying data might still be the same - in this case you should compare the underlying data.
+
+To do this comparison you'll need to use `Rc::ptr_eq` instead of just using `PartialEq` (which is
+automatically used when comparing data using the equality operator `==`). The Rust documentation
+has [more details about `Rc::ptr_eq`](https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#method.ptr_eq).
+
+This optimization is most useful for data types that don't implement `Copy`. If you can copy your
+data cheaply, then it isn't worth putting it behind a smart pointer. For structures that
+can be data-heavy like `Vec`s, `HashMap`s, and `String`s using smart pointers is likely to bring
+performance improvements.
+
+This optimization works best if the values are never updated by the children, and even better, if
+they are rarely updated by parents. This makes `Rc<_>s` a good choice for wrapping property values
+in for pure components.
+
+However, it must be noted that unless you need to clone the data yourself in the child component,
+this optimization is not only useless, it also adds unnecessary cost of reference counting. Props
+in Yew are already reference counted and no data clones occur internally.
+
+## View functions
+
+For code readability reasons, it often makes sense to migrate sections of `html!` to their own
+functions. Not only does this make your code more readable because it reduces the amount of
+indentation present, it also encourages good design patterns – particularly around building
+composable applications because these functions can be called in multiple places which reduces the
+amount of code that has to be written.
+
+## Pure Components
+
+Pure components are components that don't mutate their state, only displaying content and
+propagating messages up to normal, mutable components. They differ from view functions in that they
+can be used from within the `html!` macro using the component syntax \(``\)
+instead of expression syntax \(`{some_view_function()}`\), and that depending on their
+implementation, they can be memoized (this means that once a function is called its value is "saved"
+so that if it's called with the same arguments more than once it doesn't have to recompute its value
+and can just return the saved value from the first function call) - preventing re-renders for
+identical props. Yew compares the props internally and so the UI is only re-rendered if the props change.
+
+## Reducing compile time using workspaces
+
+Arguably, the largest drawback to using Yew is the long time it takes to compile Yew apps. The time
+taken to compile a project seems to be related to the quantity of code passed to the `html!` macro.
+This tends to not be much of an issue for smaller projects, but for larger applications it makes
+sense to split code across multiple crates to minimize the amount of work the compiler has to do for
+each change made to the application.
+
+One possible approach is to make your main crate handle routing/page selection, and then make a
+different crate for each page, where each page could be a different component, or just a big
+function that produces `Html`. Code which is shared between the crates containing different parts of
+the application could be stored in a separate crate which is depended on throughout the project.
+In the best case scenario, you go from rebuilding all of your code on each compile to rebuilding
+only the main crate, and one of your page crates. In the worst case, where you edit something in the
+"common" crate, you will be right back to where you started: compiling all code that depends on that
+commonly shared crate, which is probably everything else.
+
+If your main crate is too heavyweight, or you want to rapidly iterate on a deeply nested page \(eg.
+a page that renders on top of another page\), you can use an example crate to create a simplified
+implementation of the main page and render the component you are working on on top of that.
+
+## Reducing binary sizes
+
+* optimize Rust code
+ * `wee_alloc` \( using tiny allocator \)
+ * `cargo.toml` \( defining release profile \)
+* optimize wasm code using `wasm-opt`
+
+**Note: more information about reducing binary sizes can be found in the
+[Rust Wasm Book](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size).**
+
+### wee\_alloc
+
+[wee\_alloc](https://github.com/rustwasm/wee_alloc) is a tiny allocator that is much smaller than the allocator that is normally used in Rust binaries. Replacing the default allocator with this one will result in smaller Wasm file sizes, at the expense of speed and memory overhead.
+
+The slower speed and memory overhead are minor in comparison to the size gains made by not including the default allocator. This smaller file size means that your page will load faster, and so it is generally recommended that you use this allocator over the default, unless your app is doing some allocation-heavy work.
+
+```rust ,ignore
+// Use `wee_alloc` as the global allocator.
+#[global_allocator]
+static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
+```
+
+### Cargo.toml
+
+It is possible to configure release builds to be smaller using the available settings in the
+`[profile.release]` section of your `Cargo.toml`.
+
+
+```toml, title=Cargo.toml
+[profile.release]
+# less code to include into binary
+panic = 'abort'
+# optimization over all codebase ( better optimization, slower build )
+codegen-units = 1
+# optimization for size ( more aggressive )
+opt-level = 'z'
+# optimization for size
+# opt-level = 's'
+# link time optimization using using whole-program analysis
+lto = true
+```
+
+### wasm-opt
+
+Further more it is possible to optimize size of `wasm` code.
+
+The Rust Wasm Book has a section about reducing the size of Wasm binaries:
+[Shrinking .wasm size](https://rustwasm.github.io/book/game-of-life/code-size.html)
+
+* using `wasm-pack` which by default optimizes `wasm` code in release builds
+* using `wasm-opt` directly on `wasm` files.
+
+```text
+wasm-opt wasm_bg.wasm -Os -o wasm_bg_opt.wasm
+```
+
+#### Build size of 'minimal' example in yew/examples/
+
+Note: `wasm-pack` combines optimization for Rust and Wasm code. `wasm-bindgen` is used in this example without any Rust size optimization.
+
+| used tool | size |
+| :--- | :--- |
+| wasm-bindgen | 158KB |
+| wasm-bindgen + wasm-opt -Os | 116KB |
+| wasm-pack | 99 KB |
+
+## Further reading:
+ * [The Rust Book's chapter on smart pointers](https://doc.rust-lang.org/book/ch15-00-smart-pointers.html)
+ * [Information from the Rust Wasm Book about reducing binary sizes](https://rustwasm.github.io/book/reference/code-size.html#optimizing-builds-for-code-size)
+ * [Documentation about Rust profiles](https://doc.rust-lang.org/cargo/reference/profiles.html)
+ * [binaryen project](https://github.com/WebAssembly/binaryen)
diff --git a/website/versioned_docs/version-0.19.0/advanced-topics/portals.md b/website/versioned_docs/version-0.19.0/advanced-topics/portals.md
new file mode 100644
index 00000000000..f486c273231
--- /dev/null
+++ b/website/versioned_docs/version-0.19.0/advanced-topics/portals.md
@@ -0,0 +1,41 @@
+---
+title: "Portals"
+description: "Rendering into out-of-tree DOM nodes"
+---
+
+## How to think about portals?
+
+Portals provide a first-class way to render children into a DOM node that exists outside the DOM hierarchy of the parent component.
+`yew::create_portal(child, host)` returns a `Html` value that renders `child` not hierarchically under its parent component,
+but as a child of the `host` element.
+
+## Usage
+
+Typical uses of portals can include modal dialogs and hovercards, as well as more technical applications such as controlling the contents of an element's [`shadowRoot`](https://developer.mozilla.org/en-US/docs/Web/API/Element/shadowRoot), appending stylesheets to the surrounding document's `` and collecting referenced elements inside a central `` element of an `