Browse Source

update the router guide

Evan Almloff 2 years ago
parent
commit
0d3ea377ce
63 changed files with 622 additions and 1712 deletions
  1. 0 1
      docs/reference/.gitignore
  2. 0 25
      docs/reference/src/README_pt-br.md
  3. 0 47
      docs/reference/src/SUMMARY_pt-br.md
  4. 0 497
      docs/reference/src/guide/custom_renderer_pt-br.md
  5. 0 31
      docs/reference/src/guide/hot_reloading_pt-br.md
  6. 0 1
      docs/reference/src/guide/index_pt-br.md
  7. 0 228
      docs/reference/src/guide/rsx_in_depth.md
  8. 0 228
      docs/reference/src/guide/rsx_in_depth_pt-br.md
  9. 0 45
      docs/reference/src/platforms/desktop.md
  10. 0 11
      docs/reference/src/platforms/index.md
  11. 48 0
      docs/router/examples/catch_all.rs
  12. 115 0
      docs/router/examples/dynamic_route.rs
  13. 28 0
      docs/router/examples/external_link.rs
  14. 35 0
      docs/router/examples/first_route.rs
  15. 29 16
      docs/router/examples/full_example.rs
  16. 72 0
      docs/router/examples/links.rs
  17. 66 0
      docs/router/examples/nested_routes.rs
  18. 1 23
      docs/router/src/SUMMARY.md
  19. 52 215
      docs/router/src/example/building-a-nest.md
  20. 0 1
      docs/router/src/example/example.rs
  21. 29 90
      docs/router/src/example/first-route.md
  22. 2 6
      docs/router/src/example/full-code.md
  23. 14 148
      docs/router/src/example/navigation-targets.md
  24. 17 43
      docs/router/src/example/redirection-perfection.md
  25. 1 0
      docs/router/src/features/failures/external.md
  26. 1 0
      docs/router/src/features/failures/index.md
  27. 1 0
      docs/router/src/features/failures/named.md
  28. 1 0
      docs/router/src/features/failures/redirection-limit.md
  29. 1 0
      docs/router/src/features/history-buttons.md
  30. 1 0
      docs/router/src/features/history-providers.md
  31. 1 0
      docs/router/src/features/index.md
  32. 1 0
      docs/router/src/features/navigation/external.md
  33. 1 0
      docs/router/src/features/navigation/index.md
  34. 1 0
      docs/router/src/features/navigation/name.md
  35. 1 0
      docs/router/src/features/navigation/programmatic.md
  36. 1 0
      docs/router/src/features/outlets.md
  37. 1 0
      docs/router/src/features/query.md
  38. 1 0
      docs/router/src/features/routes/catch_all.md
  39. 1 0
      docs/router/src/features/routes/fallback.md
  40. 1 0
      docs/router/src/features/routes/index.md
  41. 1 0
      docs/router/src/features/routes/matching.md
  42. 1 0
      docs/router/src/features/routes/multiple-and-redirect.md
  43. 1 0
      docs/router/src/features/routes/nested.md
  44. 1 0
      docs/router/src/features/routing-update-callback.md
  45. 1 0
      docs/router/src/features/sitemap-generation.md
  46. 1 1
      docs/router/src/reference/failures/index.md
  47. 1 1
      docs/router/src/reference/history-buttons.md
  48. 1 1
      docs/router/src/reference/history-providers.md
  49. 1 1
      docs/router/src/reference/index.md
  50. 2 1
      docs/router/src/reference/navigation/external.md
  51. 4 1
      docs/router/src/reference/navigation/index.md
  52. 5 2
      docs/router/src/reference/navigation/name.md
  53. 6 2
      docs/router/src/reference/navigation/programmatic.md
  54. 17 22
      docs/router/src/reference/outlets.md
  55. 7 3
      docs/router/src/reference/query.md
  56. 8 3
      docs/router/src/reference/routes/catch_all.md
  57. 4 2
      docs/router/src/reference/routes/fallback.md
  58. 8 4
      docs/router/src/reference/routes/index.md
  59. 4 2
      docs/router/src/reference/routes/matching.md
  60. 3 1
      docs/router/src/reference/routes/multiple-and-redirect.md
  61. 9 4
      docs/router/src/reference/routes/nested.md
  62. 3 1
      docs/router/src/reference/routing-update-callback.md
  63. 9 4
      docs/router/src/reference/sitemap-generation.md

+ 0 - 1
docs/reference/.gitignore

@@ -1 +0,0 @@
-book

+ 0 - 25
docs/reference/src/README_pt-br.md

@@ -1,25 +0,0 @@
-# Dioxus: Guias Avançados e Referência
-
-![dioxuslogo](./images/dioxuslogo_full.png)
-
-**Dioxus** é um framework e ecossistema para desenvolver interfaces rápidas, escaláveis e robustas com a linguagem de Programação Rust. Este guia irá ajudar você a começar com o Dioxus para Web, Desktop, Móvel e mais.
-
-> Este livro é a Referência e Guias Avançados para o framework Dioxus. Para um tutorial em como de fato _usar_ o Dioxus, procure o [guia oficial](https://dioxuslabs.com/guide/en/).
-
-## Guias e Referência
-
-Com a referência nós procuramos manter a documentar a funcionalidade que pode não ter sido mencionada no guia oficial para manter uma carga de informação mínima. Alguns tópicos não estão inclusos pelo guia, mas discutidos nesta referência incluindo:
-
-- Processo seguro (`ThreadSafe`) da `VirtualDOM`
-- Abordagem complete sobre o uso do `rsx!` e funções inclusas
-- Padrão `spread` para as propriedades dos componentes
-- Testes
-- Memoization à fundo
-- Elementos personalizados
-- Renderizadores personalizados
-
-## Contribuindo
-
-Se nesse documento estiver de algum forma confuso, contém erros de digitação ou você gostaria de ajudar a melhorar algo, sinta-se à vontade para fazer um PR no [repositório do Dioxus](https://github.com/DioxusLabs/dioxus/tree/master/docs/reference).
-
-Todas as contribuições serão licenciadas sob a licença MIT/Apache2.

+ 0 - 47
docs/reference/src/SUMMARY_pt-br.md

@@ -1,47 +0,0 @@
-# Summary
-
-- [Introdução](README.md)
-
-- [Platformas](platforms/index.md)
-
-  - [Web](platforms/web.md)
-  - [Renderização por Servidor(SSR)](platforms/ssr.md)
-  - [Desktop](platforms/desktop.md)
-  - [Móvel](platforms/mobile.md)
-  - [TUI](platforms/tui.md)
-
-- [Guias Avançados](guide/index.md)
-
-  - [RSX à fundo](guide/rsx_in_depth.md)
-  - [Componentes](guide/components.md)
-  - [Propriedades](guide/props.md)
-  - [Memoization](guide/memoization.md)
-  - [Desempenho](guide/performance.md)
-  - [Testes](guide/testing.md)
-  - [Construindo Elementos com o NodeFactory](guide/rsx.md)
-  - [Elementos Personalizados](guide/custom_elements.md)
-  - [Renderizadores Personalizados](guide/custom_renderer.md)
-  - [Componentes Renderizados por Servidor](guide/server_side_components.md)
-  - [Empacotando e Distribuindo](guide/bundline.md)
-  - [Recarregamento em Tempo-Real com RSX](guide/hot_reloading.md)
-
-- [Guia de Referência](reference/reference.md)
-  - [Anti-padrões](reference/anti.md)
-  - [Filhos](reference/children.md)
-  - [Renderização Condicional](reference/conditional.md)
-  - [Entradas Controladas](reference/controlled.md)
-  - [Elementos Personalizados](reference/custom.md)
-  - [Componentes Vazios](reference/empty.md)
-  - [Tratamento de Errors](reference/error.md)
-  - [Fragmentos](reference/fragments.md)
-  - [CSS Globais](reference/global.md)
-  - [Estilos em Linha](reference/inline.md)
-  - [Iteradores](reference/iterators.md)
-  - [Ouvintes](reference/listeners.md)
-  - [Memoization](reference/memoization.md)
-  - [Nós de Referência](reference/node.md)
-  - [Padrão Propagado (Spread)](reference/spread.md)
-  - [Gerenciamento de Estado](reference/state.md)
-  - [Suspensão](reference/suspense.md)
-  - [Tarefas](reference/task.md)
-  - [Testes](reference/testing.md)

+ 0 - 497
docs/reference/src/guide/custom_renderer_pt-br.md

@@ -1,497 +0,0 @@
-# Renderizador Personalizado
-
-Dioxus é uma estrutura incrivelmente portátil para desenvolvimento de interface do usuário. As lições, conhecimentos, hooks e componentes que você adquire ao longo do tempo sempre podem ser aproveitados ​​para projetos futuros. No entanto, às vezes, esses projetos não podem aproveitar um renderizador compatível ou você precisa implementar seu próprio renderizador melhor.
-
-Ótimas notícias: o design do renderizador depende inteiramente de você! Nós fornecemos sugestões e inspiração com os renderizadores originais, mas só realmente precisamos processar `DomEdits` e enviar `UserEvents`.
-
-## Em Detalhes:
-
-A implementação do renderizador é bastante simples. O renderizador precisa:
-
-1. Lidar com o fluxo de edições gerado por atualizações no DOM virtual
-2. Registrar ouvintes e passe eventos para o sistema de eventos do DOM virtual
-
-Essencialmente, seu renderizador precisa implementar o traço `RealDom` e gerar objetos `EventTrigger` para atualizar o `VirtualDOM`. A partir daí, você terá tudo o que precisa para renderizar o `VirtualDOM` na tela.
-
-Internamente, o Dioxus lida com o relacionamento da árvore, `diffing`, gerenciamento de memória e o sistema de eventos, deixando o mínimo necessário para que os renderizadores se implementem.
-
-Para referência, confira o interpretador JavaScript ou o renderizador TUI como ponto de partida para seu renderizador personalizado.
-
-## DomEdições
-
-O tipo "DomEdit" é uma enumeração serializada que representa uma operação atômica que ocorre no `RealDom`. As variantes seguem aproximadamente este conjunto:
-
-```rust
-enum DomEdit {
-    PushRoot,
-    AppendChildren,
-    ReplaceWith,
-    InsertAfter,
-    InsertBefore,
-    Remove,
-    CreateTextNode,
-    CreateElement,
-    CreateElementNs,
-    CreatePlaceholder,
-    NewEventListener,
-    RemoveEventListener,
-    SetText,
-    SetAttribute,
-    RemoveAttribute,
-    PopRoot,
-}
-```
-
-O mecanismo de diferenciação do Dioxus opera como uma [máquina de pilha] (https://en.wikipedia.org/wiki/Stack_machine) onde o método `push_root` empilhar um novo nó DOM "real" para a pilha e `append_child` e `replace_with` ambos removem nós da pilha.
-
-### Um exemplo
-
-Por uma questão de compreensão, vamos considerar este exemplo - uma declaração de interface do usuário muito simples:
-
-```rust
-rsx!( h1 {"hello world"} )
-```
-
-To get things started, Dioxus must first navigate to the container of this h1 tag. To "navigate" here, the internal diffing algorithm generates the DomEdit `PushRoot` where the ID of the root is the container.
-
-When the renderer receives this instruction, it pushes the actual Node onto its own stack. The real renderer's stack will look like this:
-
-```rust
-instructions: [
-    PushRoot(Container)
-]
-stack: [
-    ContainerNode,
-]
-```
-
-Em seguida, o Dioxus encontrará o nó `h1`. O algoritmo `diff` decide que este nó precisa ser criado, então o Dioxus irá gerar o DomEdit `CreateElement`. Quando o renderizador receber esta instrução, ele criará um nó desmontado e o enviará para sua própria pilha:
-
-```rust
-instructions: [
-    PushRoot(Container),
-    CreateElement(h1),
-]
-stack: [
-    ContainerNode,
-    h1,
-]
-```
-
-Em seguida, Dioxus vê o nó de texto e gera o DomEdit `CreateTextNode`:
-
-```rust
-instructions: [
-    PushRoot(Container),
-    CreateElement(h1),
-    CreateTextNode("hello world")
-]
-stack: [
-    ContainerNode,
-    h1,
-    "hello world"
-]
-```
-
-Lembre-se, o nó de texto não está anexado a nada (ele está desmontado), então o Dioxus precisa gerar um `Edit` que conecte o nó de texto ao elemento `h1`. Depende da situação, mas neste caso usamos `AppendChildren`. Isso remove o nó de texto da pilha, deixando o elemento `h1` como o próximo elemento na linha.
-
-```rust
-instructions: [
-    PushRoot(Container),
-    CreateElement(h1),
-    CreateTextNode("hello world"),
-    AppendChildren(1)
-]
-stack: [
-    ContainerNode,
-    h1
-]
-```
-
-Chamamos `AppendChildren` novamente, retirando o nó `h1` e anexando-o ao pai:
-
-```rust
-instructions: [
-    PushRoot(Container),
-    CreateElement(h1),
-    CreateTextNode("hello world"),
-    AppendChildren(1),
-    AppendChildren(1)
-]
-stack: [
-    ContainerNode,
-]
-```
-
-Finalmente, o contêiner é aberto, pois não precisamos mais dele.
-
-```rust
-instructions: [
-    PushRoot(Container),
-    CreateElement(h1),
-    CreateTextNode("hello world"),
-    AppendChildren(1),
-    AppendChildren(1),
-    PopRoot
-]
-stack: []
-```
-
-Com o tempo, nossa pilha ficou assim:
-
-```rust
-[]
-[Container]
-[Container, h1]
-[Container, h1, "hello world"]
-[Container, h1]
-[Container]
-[]
-```
-
-Observe como nossa pilha fica vazia depois que a interface do usuário é montada. Convenientemente, essa abordagem separa completamente o `VirtualDOM` e o `RealDOM`. Além disso, essas edições são serializáveis, o que significa que podemos até gerenciar UIs em uma conexão de rede. Esta pequena máquina de pilha e edições serializadas tornam o Dioxus independente das especificidades da plataforma.
-
-Dioxus também é muito rápido. Como o Dioxus divide a fase de `diff` e `patch`, ele é capaz de fazer todas as edições no `RealDOM` em um período de tempo muito curto (menos de um único quadro), tornando a renderização muito rápida. Ele também permite que o Dioxus cancele grandes operações de diferenciação se ocorrer um trabalho de prioridade mais alta durante a diferenciação.
-
-É importante notar que há uma camada de conexão entre o Dioxus e o renderizador. O Dioxus salva e carrega elementos (a edição `PushRoot`) com um ID. Dentro do `VirtualDOM`, isso é rastreado apenas como um `u64`.
-
-Sempre que uma edição `CreateElement` é gerada durante a comparação, o Dioxus incrementa seu contador de nós e atribui a esse novo elemento seu `NodeCount` atual. O `RealDom` é responsável por lembrar este ID e enviar o nó correto quando `PushRoot(ID)` é gerado. Dioxus recupera os IDs de elementos quando removidos. Para ficar em sincronia com Dioxus, você pode usar um `Sparce Vec` (`Vec<Option<T>>`) com itens possivelmente desocupados. Você pode usar os ids como índices no `Vec` para elementos e aumentar o `Vec` quando um id não existir.
-
-Esta pequena demonstração serve para mostrar exatamente como um renderizador precisaria processar um stream de edição para construir UIs. Um conjunto de DOMEdits serializados para várias demos está disponível para você testar seu renderizador personalizado.
-
-## Ciclo de eventos
-
-Como a maioria das GUIs, o Dioxus conta com um `loop` de eventos para progredir no `VirtualDOM`. O próprio `VirtualDOM` também pode produzir eventos, por isso é importante que seu renderizador personalizado também possa lidar com eles.
-
-O código para a implementação do `WebSys` é direto, então vamos adicioná-lo aqui para demonstrar como um `loop` de eventos é simples:
-
-```rust
-pub async fn run(&mut self) -> dioxus_core::error::Result<()> {
-    // Push the body element onto the WebsysDom's stack machine
-    let mut websys_dom = crate::new::WebsysDom::new(prepare_websys_dom());
-    websys_dom.stack.push(root_node);
-
-    // Rebuild or hydrate the virtualdom
-    let mutations = self.internal_dom.rebuild();
-    websys_dom.apply_mutations(mutations);
-
-    // Wait for updates from the real dom and progress the virtual dom
-    loop {
-        let user_input_future = websys_dom.wait_for_event();
-        let internal_event_future = self.internal_dom.wait_for_work();
-
-        match select(user_input_future, internal_event_future).await {
-            Either::Left((_, _)) => {
-                let mutations = self.internal_dom.work_with_deadline(|| false);
-                websys_dom.apply_mutations(mutations);
-            },
-            Either::Right((event, _)) => websys_dom.handle_event(event),
-        }
-
-        // render
-    }
-}
-```
-
-É importante que você decodifique os eventos reais do seu sistema de eventos no sistema de eventos sintético do Dioxus (significado sintético abstraído). Isso significa simplesmente combinar seu tipo de evento e criar um tipo Dioxus `UserEvent`. No momento, o sistema `VirtualEvent` é modelado quase inteiramente em torno da especificação HTML, mas estamos interessados em reduzi-lo.
-
-```rust
-fn virtual_event_from_websys_event(event: &web_sys::Event) -> VirtualEvent {
-    match event.type_().as_str() {
-        "keydown" => {
-            let event: web_sys::KeyboardEvent = event.clone().dyn_into().unwrap();
-            UserEvent::KeyboardEvent(UserEvent {
-                scope_id: None,
-                priority: EventPriority::Medium,
-                name: "keydown",
-                // This should be whatever element is focused
-                element: Some(ElementId(0)),
-                data: Arc::new(KeyboardData{
-                    char_code: event.char_code(),
-                    key: event.key(),
-                    key_code: event.key_code(),
-                    alt_key: event.alt_key(),
-                    ctrl_key: event.ctrl_key(),
-                    meta_key: event.meta_key(),
-                    shift_key: event.shift_key(),
-                    locale: "".to_string(),
-                    location: event.location(),
-                    repeat: event.repeat(),
-                    which: event.which(),
-                })
-            })
-        }
-        _ => todo!()
-    }
-}
-```
-
-## Elementos brutos personalizados
-
-Se você precisar ir mais longe a ponto de confiar em elementos personalizados para o seu renderizador - você pode. Isso ainda permitiria que você usasse a natureza reativa do Dioxus, sistema de componentes, estado compartilhado e outros recursos, mas acabará gerando nós diferentes. Todos os atributos e ouvintes para o namespace HTML e SVG são transportados por meio de estruturas auxiliares que essencialmente compilam (não representam sobrecarga de tempo de execução). Você pode colocar seus próprios elementos a qualquer hora que quiser, sem problemas. No entanto, você deve ter certeza absoluta de que seu renderizador pode lidar com o novo tipo, ou ele irá "bater e queimar".
-
-Esses elementos personalizados são definidos como `unit struct` com implementações de `traits`.
-
-Por exemplo, o elemento `div` é (aproximadamente!) definido assim:
-
-```rust
-struct div;
-impl div {
-    /// Some glorious documentation about the class property.
-    const TAG_NAME: &'static str = "div";
-    const NAME_SPACE: Option<&'static str> = None;
-    // define the class attribute
-    pub fn class<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-        cx.attr("class", val, None, false)
-    }
-    // more attributes
-}
-```
-
-Você provavelmente notou que muitos elementos nas macros `rsx!` suportam documentação em foco. A abordagem que adotamos para elementos personalizados significa que a estrutura da unidade é criada imediatamente onde o elemento é usado no macro. Quando o macro é expandido, os comentários doc ainda se aplicam à estrutura da unidade, dando toneladas de feedback no editor, mesmo dentro de uma macro procedural.
-
-# Núcleo Nativo
-
-Os renderizadores dão muito trabalho. Se você estiver criando um renderizador em Rust, o núcleo nativo fornece alguns utilitários para implementar um renderizador. Ele fornece uma abstração sobre DomEdits e manipula o layout para você.
-
-## RealDom
-
-O `RealDom` é uma abstração de nível superior sobre a atualização do DOM. Ele é atualizado com `DomEdits` e fornece uma maneira de atualizar lentamente o estado dos nós com base em quais atributos mudam.
-
-### Exemplo
-
-Vamos construir um renderizador de brinquedo com bordas, tamanho e cor do texto.
-Antes de começarmos, vamos dar uma olhada em um elemento de exemplo que podemos renderizar:
-
-```rust
-cx.render(rsx!{
-    div{
-        color: "red",
-        p{
-            border: "1px solid black",
-            "hello world"
-        }
-    }
-})
-```
-
-Nesta árvore a cor depende da cor do pai. O tamanho depende do tamanho das crianças, do texto atual e do tamanho do texto. A borda depende apenas do nó atual.
-
-```mermaid
-flowchart TB
-    subgraph context
-        text_width(text width)
-    end
-    subgraph div
-        state1(state)-->color1(color)
-        state1(state)-->border1(border)
-        border1-.->text_width
-        linkStyle 2 stroke:#5555ff,stroke-width:4px;
-        state1(state)-->layout_width1(layout width)
-    end
-    subgraph p
-        state2(state)-->color2(color)
-        color2-.->color1(color)
-        linkStyle 5 stroke:#0000ff,stroke-width:4px;
-        state2(state)-->border2(border)
-        border2-.->text_width
-        linkStyle 7 stroke:#5555ff,stroke-width:4px;
-        state2(state)-->layout_width2(layout width)
-        layout_width1-.->layout_width2
-        linkStyle 9 stroke:#aaaaff,stroke-width:4px;
-    end
-    subgraph hello world
-        state3(state)-->color3(color)
-        color3-.->color2(color)
-        linkStyle 11 stroke:#0000ff,stroke-width:4px;
-        state3(state)-->border3(border)
-        border3-.->text_width
-        linkStyle 13 stroke:#5555ff,stroke-width:4px;
-        state3(state)-->layout_width3(layout width)
-        layout_width2-.->layout_width3
-        linkStyle 15 stroke:#aaaaff,stroke-width:4px;
-    end
-```
-
-Para ajudar na construção de um Dom, o núcleo nativo fornece quatro características: `State`, `ChildDepState`, `ParentDepState` e `NodeDepState` e uma estrutura `RealDom`.
-
-```rust
-use dioxus_native_core::node_ref::*;
-use dioxus_native_core::state::{ChildDepState, NodeDepState, ParentDepState, State};
-use dioxus_native_core_macro::{sorted_str_slice, State};
-
-#[derive(Default, Copy, Clone)]
-struct Size(f32, f32);
-// Size only depends on the current node and its children, so it implements ChildDepState
-impl ChildDepState for Size {
-    // Size accepts a font size context
-    type Ctx = f32;
-    // Size depends on the Size part of each child
-    type DepState = Self;
-    // Size only cares about the width, height, and text parts of the current node
-    const NODE_MASK: NodeMask =
-        NodeMask::new_with_attrs(AttributeMask::Static(&sorted_str_slice!(["width", "height"]))).with_text();
-    fn reduce<'a>(
-        &mut self,
-        node: NodeView,
-        children: impl Iterator<Item = &'a Self::DepState>,
-        ctx: &Self::Ctx,
-    ) -> bool
-    where
-        Self::DepState: 'a,
-    {
-        let mut width;
-        let mut height;
-        if let Some(text) = node.text() {
-            // if the node has text, use the text to size our object
-            width = text.len() as f32 * ctx;
-            height = ctx;
-        } else {
-            // otherwise, the size is the maximum size of the children
-            width = *children
-                .reduce(|accum, item| if accum >= item.0 { accum } else { item.0 })
-                .unwrap_or(0.0));
-            height = *children
-                .reduce(|accum, item| if accum >= item.1 { accum } else { item.1 })
-                .unwrap_or(&0.0);
-        }
-        // if the node contains a width or height attribute it overrides the other size
-        for a in node.attibutes(){
-            match a.name{
-                "width" => width = a.value.parse().unwrap(),
-                "height" => height = a.value.parse().unwrap(),
-                // because Size only depends on the width and height, no other attributes will be passed to the member
-                _ => panic!()
-            }
-        }
-        // to determine what other parts of the dom need to be updated we return a boolean that marks if this member changed
-        let changed = (width != self.0) || (height != self.1);
-        *self = Self(width, height);
-        changed
-    }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Default)]
-struct TextColor {
-    r: u8,
-    g: u8,
-    b: u8,
-}
-// TextColor only depends on the current node and its parent, so it implements ParentDepState
-impl ParentDepState for TextColor {
-    type Ctx = ();
-    // TextColor depends on the TextColor part of the parent
-    type DepState = Self;
-    // TextColor only cares about the color attribute of the current node
-    const NODE_MASK: NodeMask = NodeMask::new_with_attrs(AttributeMask::Static(&["color"]));
-    fn reduce(
-        &mut self,
-        node: NodeView,
-        parent: Option<&Self::DepState>,
-        _ctx: &Self::Ctx,
-    ) -> bool {
-        // TextColor only depends on the color tag, so getting the first tag is equivilent to looking through all tags
-        let new = match node.attributes().next() {
-            // if there is a color tag, translate it
-            Some("red") => TextColor { r: 255, g: 0, b: 0 },
-            Some("green") => TextColor { r: 0, g: 255, b: 0 },
-            Some("blue") => TextColor { r: 0, g: 0, b: 255 },
-            Some(_) => panic!("unknown color"),
-            // otherwise check if the node has a parent and inherit that color
-            None => match parent {
-                Some(parent) => *parent,
-                None => Self::default(),
-            },
-        };
-        // check if the member has changed
-        let changed = new != *self;
-        *self = new;
-        changed
-    }
-}
-
-#[derive(Debug, Clone, PartialEq, Default)]
-struct Border(bool);
-// TextColor only depends on the current node, so it implements NodeDepState
-impl NodeDepState for Border {
-    type Ctx = ();
-    // Border does not depended on any other member in the current node
-    type DepState = ();
-    // Border does not depended on any other member in the current node
-    const NODE_MASK: NodeMask =
-        NodeMask::new_with_attrs(AttributeMask::Static(&["border"]));
-    fn reduce(&mut self, node: NodeView, _sibling: &Self::DepState, _ctx: &Self::Ctx) -> bool {
-        // check if the node contians a border attribute
-        let new = Self(node.attributes().next().map(|a| a.name == "border").is_some());
-        // check if the member has changed
-        let changed = new != *self;
-        *self = new;
-        changed
-    }
-}
-
-// State provides a derive macro, but anotations on the members are needed in the form #[dep_type(dep_member, CtxType)]
-#[derive(State, Default, Clone)]
-struct ToyState {
-    // the color member of it's parent and no context
-    #[parent_dep_state(color)]
-    color: TextColor,
-    // depends on the node, and no context
-    #[node_dep_state()]
-    border: Border,
-    // depends on the layout_width member of children and f32 context (for text size)
-    #[child_dep_state(size, f32)]
-    size: Size,
-}
-```
-
-Agora que temos nosso estado, podemos colocá-lo em uso em nosso DOM. Nós podemos atualizar o DOM com `update_state` para atualizar a estrutura do `DOM` (adicionando, removendo e alterando as propriedades dos nós) e então `apply_mutations` para atualizar o `ToyState` para cada um dos nós que foram alterados.
-
-```rust
-fn main(){
-    fn app(cx: Scope) -> Element {
-        cx.render(rsx!{
-            div{
-                color: "red",
-                "hello world"
-            }
-        })
-    }
-    let vdom = VirtualDom::new(app);
-    let rdom: RealDom<ToyState> = RealDom::new();
-
-    let mutations = dom.rebuild();
-    // update the structure of the real_dom tree
-    let to_update = rdom.apply_mutations(vec![mutations]);
-    let mut ctx = AnyMap::new();
-    // set the font size to 3.3
-    ctx.insert(3.3);
-    // update the ToyState for nodes in the real_dom tree
-    let _to_rerender = rdom.update_state(&dom, to_update, ctx).unwrap();
-
-    // we need to run the vdom in a async runtime
-    tokio::runtime::Builder::new_current_thread()
-        .enable_all()
-        .build()?
-        .block_on(async {
-            loop{
-                let wait = vdom.wait_for_work();
-                let mutations = vdom.work_with_deadline(|| false);
-                let to_update = rdom.apply_mutations(mutations);
-                let mut ctx = AnyMap::new();
-                ctx.insert(3.3);
-                let _to_rerender = rdom.update_state(vdom, to_update, ctx).unwrap();
-
-                // render...
-            }
-        })
-}
-```
-
-## Disposição
-
-Para a maioria das plataformas, o layout dos Elementos permanecerá o mesmo. O módulo layout_attributes fornece uma maneira de aplicar atributos `html` a um estilo de layout estendido.
-
-## Conclusão
-
-Pronto, é isso! Você deve ter quase todo o conhecimento necessário sobre como implementar seu próprio renderizador. Estamos super interessados em ver os aplicativos Dioxus trazidos para renderizadores de desktop personalizados, renderizador para dispositivos móveis, interface do usuário para videogames e até realidade aumentada! Se você estiver interessado em contribuir para qualquer um desses projetos, não tenha medo de entrar em contato ou se juntar à comunidade.

+ 0 - 31
docs/reference/src/guide/hot_reloading_pt-br.md

@@ -1,31 +0,0 @@
-# Recarregamento a Quente
-
-1. O recarregamento a quente permite tempos de iteração muito mais rápidos dentro de chamadas rsx, interpretando-as e transmitindo as edições.
-2. É útil ao alterar o estilo/layout de um programa, mas não ajudará na alteração da lógica de um programa.
-3. Atualmente, o cli implementa apenas o recarregamento a quente para o renderizador da web.
-
-# Configurar
-
-Instale o [dioxus-cli](https://github.com/DioxusLabs/cli).
-Habilite o recurso hot_reload no dioxus:
-
-```toml
-dioxus = { version = "*", features = ["web", "hot_reload"] }
-```
-
-# Como Usar
-
-1. run:
-
-```
-dioxus serve --hot-reload
-```
-
-2. alterar algum código dentro de uma macro rsx
-3. abra seu localhost em um navegador
-4. salve e observe a mudança de estilo sem recompilar
-
-# Limitações
-
-1. O intérprete só pode usar expressões que existiam na última recompilação completa. Se você introduzir uma nova variável ou expressão na chamada rsx, ela acionará uma recompilação completa para capturar a expressão.
-2. Componentes e Iteradores podem conter código de Rust arbitrário e acionarão uma recompilação completa quando alterados.

+ 0 - 1
docs/reference/src/guide/index_pt-br.md

@@ -1 +0,0 @@
-# Guias Avançados

+ 0 - 228
docs/reference/src/guide/rsx_in_depth.md

@@ -1,228 +0,0 @@
-# RSX in Depth
-
-The RSX macro makes it very easy to assemble complex UIs with a very natural Rust syntax:
-
-```rust
-rsx!(
-    div {
-        button {
-            onclick: move |e| todos.write().new_todo(),
-            "Add todo"
-        }
-        ul {
-            class: "todo-list",
-            todos.iter().map(|(key, todo)| rsx!(
-                li {
-                    class: "beautiful-todo"
-                    key: "f"
-                    h3 { "{todo.title}" }
-                    p { "{todo.contents}"}
-                }
-            ))
-        }
-    }
-)
-```
-
-In this section, we'll cover the `rsx!` macro in depth. If you prefer to learn through examples, the `code reference` guide has plenty of examples on how to use `rsx!` effectively.
-
-### Element structure
-
-Attributes must come before child elements
-
-```rust
-div {
-    hidden: "false",
-    "some text"
-    child {}
-    Component {} // uppercase
-    component() // lowercase is treated like a function call
-    (0..10).map(|f| rsx!{ "hi {f}" }) // arbitrary rust expressions
-}
-```
-
-Each element takes a comma-separated list of expressions to build the node. Roughly, here's how they work:
-
-- `name: value` sets a property on this element.
-- `"text"` adds a new text element
-- `tag {}` adds a new child element
-- `CustomTag {}` adds a new child component
-- `{expr}` pastes the `expr` tokens literally. They must be `IntoIterator<T> where T: IntoVnode` to work properly
-
-Commas are entirely optional, but might be useful to delineate between elements and attributes.
-
-The `render` function provides an **extremely efficient** allocator for VNodes and text, so try not to use the `format!` macro in your components. Rust's default `ToString` methods pass through the global allocator, but all text in components is allocated inside a manually-managed Bump arena. To push you in the right direction, all text-based attributes take `std::fmt::Arguments` directly, so you'll want to reach for `format_args!` when the built-in `f-string` interpolation just doesn't cut it.
-
-### Ignoring `cx.render` with `render!(...)`
-
-Sometimes, writing `cx.render` is a hassle. The `rsx! macro will accept any token followed by a comma as the target to call "render" on:
-
-```rust
-cx.render(rsx!( div {} ))
-// becomes
-render!(div {})
-```
-
-### Conditional Rendering
-
-Sometimes, you might not want to render an element given a condition. The rsx! macro will accept any tokens directly contained with curly braces, provided they resolve to a type that implements `IntoIterator<VNode>`. This lets us write any Rust expression that resolves to a VNode:
-
-```rust
-rsx!({
-    if enabled {
-        render!(div {"enabled"})
-    } else {
-        render!(li {"disabled"})
-    }
-})
-```
-
-A convenient way of hiding/showing an element is returning an `Option<VNode>`. When combined with `and_then`, we can succinctly control the display state given some boolean:
-
-```rust
-rsx!({
-    a.and_then(rsx!(div {"enabled"}))
-})
-```
-
-It's important to note that the expression `rsx!()` is typically lazy - this expression must be _rendered_ to produce a VNode. When using match statements, we must render every arm as to avoid the `no two closures are identical` rule that Rust imposes:
-
-```rust
-// this will not compile!
-match case {
-    true => rsx!(div {}),
-    false => rsx!(div {})
-}
-
-// the nodes must be rendered first
-match case {
-    true => render!(div {}),
-    false => render!(div {})
-}
-```
-
-### Lists
-
-Again, because anything that implements `IntoIterator<VNode>` is valid, we can use lists directly in our `rsx!`:
-
-```rust
-let items = vec!["a", "b", "c"];
-
-cx.render(rsx!{
-    ul {
-        {items.iter().map(|f| rsx!(li { "a" }))}
-    }
-})
-```
-
-Sometimes, it makes sense to render VNodes into a list:
-
-```rust
-let mut items = vec![];
-
-for _ in 0..5 {
-    items.push(render!(li {} ))
-}
-
-render!({items} )
-```
-
-#### Lists and Keys
-
-When rendering the VirtualDom to the screen, Dioxus needs to know which elements have been added and which have been removed. These changes are determined through a process called "diffing" - an old set of elements is compared to a new set of elements. If an element is removed, then it won't show up in the new elements, and Dioxus knows to remove it.
-
-However, with lists, Dioxus does not exactly know how to determine which elements have been added or removed if the order changes or if an element is added or removed from the middle of the list.
-
-In these cases, it is vitally important to specify a "key" alongside the element. Keys should be persistent between renders.
-
-```rust
-fn render_list(cx: Scope, items: HashMap<String, Todo>) -> DomTree {
-    render!(ul {
-        {items.iter().map(|key, item| {
-            li {
-                key: key,
-                h2 { "{todo.title}" }
-                p { "{todo.contents}" }
-            }
-        })}
-    })
-}
-```
-
-There have been many guides made for keys in React, so we recommend reading up to understand their importance:
-
-- [React guide on keys](https://reactjs.org/docs/lists-and-keys.html)
-- [Importance of keys (Medium)](https://kentcdodds.com/blog/understanding-reacts-key-prop)
-
-### Complete Reference
-
-```rust
-let text = "example";
-
-cx.render(rsx!{
-    div {
-        h1 { "Example" },
-
-        {title}
-
-        // fstring interpolation
-        "{text}"
-
-        p {
-            // Attributes
-            tag: "type",
-
-            // Anything that implements display can be an attribute
-            abc: 123,
-
-            enabled: true,
-
-            // attributes also supports interpolation
-            // `class` is not a restricted keyword unlike JS and ClassName
-            class: "big small wide short {text}",
-
-            class: format_args!("attributes take fmt::Arguments. {}", 99),
-
-            tag: {"these tokens are placed directly"}
-
-            // Children
-            a { "abcder" },
-
-            // Children with attributes
-            h2 { "hello", class: "abc-123" },
-
-            // Child components
-            CustomComponent { a: 123, b: 456, key: "1" },
-
-            // Child components with paths
-            crate::components::CustomComponent { a: 123, b: 456, key: "1" },
-
-            // Iterators
-            { (0..3).map(|i| rsx!( h1 {"{:i}"} )) },
-
-            // More rsx!, or even html!
-            { rsx! { div { } } },
-            { html! { <div> </div> } },
-
-            // Matching
-            // Requires rendering the nodes first.
-            // rsx! is lazy, and the underlying closures cannot have the same type
-            // Rendering produces the VNode type
-            {match rand::gen_range::<i32>(1..3) {
-                1 => render!(h1 { "big" })
-                2 => render!(h2 { "medium" })
-                _ => render!(h3 { "small" })
-            }}
-
-            // Optionals
-            {true.and_then(|f| rsx!( h1 {"Conditional Rendering"} ))}
-
-            // Child nodes
-            {cx.props.children}
-
-            // Any expression that is `IntoVNode`
-            {expr}
-        }
-    }
-})
-```

+ 0 - 228
docs/reference/src/guide/rsx_in_depth_pt-br.md

@@ -1,228 +0,0 @@
-# RSX à Fundo
-
-A macro RSX facilita muito a montagem de interfaces de usuário complexas com uma sintaxe Rust muito natural:
-
-```rust
-rsx!(
-    div {
-        button {
-            onclick: move |e| todos.write().new_todo(),
-            "Add todo"
-        }
-        ul {
-            class: "todo-list",
-            todos.iter().map(|(key, todo)| rsx!(
-                li {
-                    class: "beautiful-todo"
-                    key: "f"
-                    h3 { "{todo.title}" }
-                    p { "{todo.contents}"}
-                }
-            ))
-        }
-    }
-)
-```
-
-Nesta seção, abordaremos a macro `rsx!` em profundidade. Se você preferir aprender através de exemplos, o guia `referência de código` tem muitos exemplos sobre como usar `rsx!` efetivamente.
-
-### Estrutura do elemento
-
-Os atributos devem vir antes dos elementos filhos
-
-```rust
-div {
-    hidden: "false",
-    "some text"
-    child {}
-    Component {} // uppercase
-    component() // lowercase is treated like a function call
-    (0..10).map(|f| rsx!{ "hi {f}" }) // arbitrary rust expressions
-}
-```
-
-Cada elemento usa uma lista de expressões separadas por vírgulas para construir o nó. A grosso modo, veja como eles funcionam:
-
-- `name: value` define uma propriedade neste elemento.
-- `text` adiciona um novo elemento de texto
-- `tag {}` adiciona um novo elemento filho
-- `CustomTag {}` adiciona um novo componente filho
-- `{expr}` cola os tokens `expr` literalmente. Eles devem ser `IntoIterator<T> where T: IntoVnode` para funcionar corretamente
-
-As vírgulas são totalmente opcionais, mas podem ser úteis para delinear entre elementos e atributos.
-
-A função `render` fornece um alocador **extremamente eficiente** para `VNodes` e `text`, então tente não usar a macro `format!` em seus componentes. Os métodos `ToString` padrão do Rust passam pelo alocador global, mas todo o texto nos componentes é alocado dentro de uma ""arena Bump"" gerenciada manualmente. Para levá-lo na direção certa, todos os atributos baseados em texto recebem `std::fmt::Arguments` diretamente, então você vai querer usar `format_args!` quando a interpolação interna `f-string` simplesmente não funcionar.
-
-### Ignorando `cx.render` com `render!(...)`
-
-Às vezes, escrever `cx.render` é um aborrecimento. O `rsx!` macro aceitará qualquer token seguido por uma vírgula como destino para chamar "render" em:
-
-```rust
-cx.render(rsx!( div {} ))
-// becomes
-render!(div {})
-```
-
-### Renderização Condicional
-
-Às vezes, você pode não querer renderizar um elemento dada uma condição. O `rsx!` macro aceitará quaisquer tokens contidos diretamente com chaves, desde que resolvam para um tipo que implemente `IntoIterator<VNode>`. Isso nos permite escrever qualquer expressão Rust que resolva para um `VNode`:
-
-```rust
-rsx!({
-    if enabled {
-        render!(div {"enabled"})
-    } else {
-        render!(li {"disabled"})
-    }
-})
-```
-
-Uma maneira conveniente de ocultar/mostrar um elemento é retornar um `Option<VNode>`. Quando combinado com `and_then`, podemos controlar sucintamente o estado de exibição dado alguns booleanos:
-
-```rust
-rsx!({
-    a.and_then(rsx!(div {"enabled"}))
-})
-```
-
-É importante notar que a expressão `rsx!()` é tipicamente tardia - esta expressão deve ser _renderizada_ para produzir um `VNode`. Ao usar declarações de `match`, devemos renderizar todos os braços para evitar a regra 'não há dois fechamentos idênticos' que o Rust impõe:
-
-```rust
-// this will not compile!
-match case {
-    true => rsx!(div {}),
-    false => rsx!(div {})
-}
-
-// the nodes must be rendered first
-match case {
-    true => render!(div {}),
-    false => render!(div {})
-}
-```
-
-### Listas
-
-Novamente, porque qualquer coisa que implemente `IntoIterator<VNode>` é válida, podemos usar listas diretamente em nosso `rsx!`:
-
-```rust
-let items = vec!["a", "b", "c"];
-
-cx.render(rsx!{
-    ul {
-        {items.iter().map(|f| rsx!(li { "a" }))}
-    }
-})
-```
-
-Às vezes, faz sentido renderizar `VNodes` em uma lista:
-
-```rust
-let mut items = vec![];
-
-for _ in 0..5 {
-    items.push(render!(li {} ))
-}
-
-render!({items} )
-```
-
-#### Listas e chaves
-
-Ao renderizar o `VirtualDom` na tela, o Dioxus precisa saber quais elementos foram adicionados e quais foram removidos. Essas mudanças são determinadas através de um processo chamado "diffing" - um antigo conjunto de elementos é comparado a um novo conjunto de elementos. Se um elemento for removido, ele não aparecerá nos novos elementos, e Dioxus sabe removê-lo.
-
-No entanto, com listas, Dioxus não sabe exatamente como determinar quais elementos foram adicionados ou removidos se a ordem mudar ou se um elemento for adicionado ou removido do meio da lista.
-
-Nesses casos, é de vital importância especificar uma "chave" ao lado do elemento. As chaves devem ser persistentes entre as renderizações.
-
-```rust
-fn render_list(cx: Scope, items: HashMap<String, Todo>) -> DomTree {
-    render!(ul {
-        {items.iter().map(|key, item| {
-            li {
-                key: key,
-                h2 { "{todo.title}" }
-                p { "{todo.contents}" }
-            }
-        })}
-    })
-}
-```
-
-Existem muitos guias feitos para chaves no React, então recomendamos a leitura para entender sua importância:
-
-- [React guide on keys](https://reactjs.org/docs/lists-and-keys.html)
-- [Importância das chaves (Média)](https://kentcdodds.com/blog/understanding-reacts-key-prop)
-
-### Referência Completa
-
-```rust
-let text = "example";
-
-cx.render(rsx!{
-    div {
-        h1 { "Example" },
-
-        {title}
-
-        // fstring interpolation
-        "{text}"
-
-        p {
-            // Attributes
-            tag: "type",
-
-            // Anything that implements display can be an attribute
-            abc: 123,
-
-            enabled: true,
-
-            // attributes also supports interpolation
-            // `class` is not a restricted keyword unlike JS and ClassName
-            class: "big small wide short {text}",
-
-            class: format_args!("attributes take fmt::Arguments. {}", 99),
-
-            tag: {"these tokens are placed directly"}
-
-            // Children
-            a { "abcder" },
-
-            // Children with attributes
-            h2 { "hello", class: "abc-123" },
-
-            // Child components
-            CustomComponent { a: 123, b: 456, key: "1" },
-
-            // Child components with paths
-            crate::components::CustomComponent { a: 123, b: 456, key: "1" },
-
-            // Iterators
-            { (0..3).map(|i| rsx!( h1 {"{:i}"} )) },
-
-            // More rsx!, or even html!
-            { rsx! { div { } } },
-            { html! { <div> </div> } },
-
-            // Matching
-            // Requires rendering the nodes first.
-            // rsx! is lazy, and the underlying closures cannot have the same type
-            // Rendering produces the VNode type
-            {match rand::gen_range::<i32>(1..3) {
-                1 => render!(h1 { "big" })
-                2 => render!(h2 { "medium" })
-                _ => render!(h3 { "small" })
-            }}
-
-            // Optionals
-            {true.and_then(|f| rsx!( h1 {"Conditional Rendering"} ))}
-
-            // Child nodes
-            {cx.props.children}
-
-            // Any expression that is `IntoVNode`
-            {expr}
-        }
-    }
-})
-```

+ 0 - 45
docs/reference/src/platforms/desktop.md

@@ -1,45 +0,0 @@
-# Getting Started: Desktop
-
-One of Dioxus' killer features is the ability to quickly build a native desktop app that looks and feels the same across platforms. Apps built with Dioxus are typically <5mb in size and use existing system resources, so they won't hog extreme amounts of RAM or memory.
-
-Dioxus Desktop is built off Tauri. Right now there aren't any Dioxus abstractions over the menubar, handling, etc, so you'll want to leverage Tauri - mostly [Wry](http://github.com/tauri-apps/wry/) and [Tao](http://github.com/tauri-apps/tao)) directly. The next major release of Dioxus-Desktop will include components and hooks for notifications, global shortcuts, menubar, etc.
-
-## Getting Set up
-
-Getting Set up with Dioxus-Desktop is quite easy. Make sure you have Rust and Cargo installed, and then create a new project:
-
-```shell
-$ cargo new --bin demo
-$ cd demo
-```
-
-Add Dioxus with the `desktop` feature:
-
-```shell
-$ cargo add dioxus --features desktop
-```
-
-Edit your `main.rs`:
-
-```rust
-// main.rs
-use dioxus::prelude::*;
-
-fn main() {
-    dioxus::desktop::launch(app);
-}
-
-fn app(cx: Scope) -> Element {
-    cx.render(rsx!{
-        div {
-            "hello world!"
-        }
-    })
-}
-```
-
-To configure the webview, menubar, and other important desktop-specific features, checkout out some of the launch configuration in the [API reference](https://docs.rs/dioxus-desktop/).
-
-## Future Steps
-
-Make sure to read the [Dioxus Guide](https://dioxuslabs.com/guide/en) if you already haven't!

+ 0 - 11
docs/reference/src/platforms/index.md

@@ -1,11 +0,0 @@
-# Platforms
-
-Dioxus supports many different platforms. Below are a list of guides that walk you through setting up Dioxus for a specific platform.
-
-### Setup Guides
-
-- [Web](web.md)
-- [Server Side Rendering](ssr.md)
-- [Desktop](desktop.md)
-- [Mobile](mobile.md)
-- [TUI](tui.md)

+ 48 - 0
docs/router/examples/catch_all.rs

@@ -0,0 +1,48 @@
+#![allow(non_snake_case)]
+use dioxus::prelude::*;
+use dioxus_router::prelude::*;
+
+// ANCHOR: router
+#[derive(Routable, Clone)]
+enum Route {
+    #[route("/")]
+    Home {},
+    // PageNotFound is a catch all route that will match any route and placing the matched segments in the route field
+    #[route("/:...route")]
+    PageNotFound { route: Vec<String> },
+}
+// ANCHOR_END: router
+
+// ANCHOR: app
+#[inline_props]
+fn App(cx: Scope) -> Element {
+    render! {
+        Router {}
+    }
+}
+// ANCHOR_END: app
+
+// ANCHOR: home
+#[inline_props]
+fn Home(cx: Scope) -> Element {
+    render! {
+        h1 { "Welcome to the Dioxus Blog!" }
+    }
+}
+// ANCHOR_END: home
+
+// ANCHOR: fallback
+#[inline_props]
+fn PageNotFound(cx: Scope, route: Vec<String>) -> Element {
+    render! {
+        h1 { "Page not found" }
+        p { "We are terribly sorry, but the page you requested doesn't exist." }
+        pre {
+            color: "red",
+            "log:\nattemped to navigate to: {route:?}"
+        }
+    }
+}
+// ANCHOR_END: fallback
+
+fn main() {}

+ 115 - 0
docs/router/examples/dynamic_route.rs

@@ -0,0 +1,115 @@
+#![allow(non_snake_case)]
+
+use dioxus::prelude::*;
+use dioxus_router::prelude::*;
+
+fn main() {
+    #[cfg(target_arch = "wasm32")]
+    dioxus_web::launch(App);
+    #[cfg(not(target_arch = "wasm32"))]
+    dioxus_desktop::launch(App);
+}
+
+// ANCHOR: router
+#[derive(Routable, Clone)]
+#[rustfmt::skip]
+enum Route {
+    #[layout(NavBar)]
+        #[route("/")]
+        Home {},
+        #[nest("/blog")]
+            #[layout(Blog)]
+            #[route("/")]
+            BlogList {},
+            #[route("/blog/:name")]
+            BlogPost { name: String },
+            #[end_layout]
+        #[end_nest]
+    #[end_layout]
+    #[route("/:...route")]
+    PageNotFound {
+        route: Vec<String>,
+    },
+}
+// ANCHOR_END: router
+
+fn App(cx: Scope) -> Element {
+    render! {
+        Router {}
+    }
+}
+
+#[inline_props]
+fn NavBar(cx: Scope) -> Element {
+    render! {
+        nav {
+            ul {
+                li { Link { target: Route::Home {}, "Home" } }
+                li { Link { target: Route::BlogList {}, "Blog" } }
+            }
+        }
+        Outlet {}
+    }
+}
+
+#[inline_props]
+fn Home(cx: Scope) -> Element {
+    render! {
+        h1 { "Welcome to the Dioxus Blog!" }
+    }
+}
+
+// ANCHOR: blog
+#[inline_props]
+fn Blog(cx: Scope) -> Element {
+    render! {
+        h1 { "Blog" }
+        Outlet {}
+    }
+}
+// ANCHOR_END: blog
+
+// ANCHOR: blog_list
+#[inline_props]
+fn BlogList(cx: Scope) -> Element {
+    render! {
+        h2 { "Choose a post" }
+        ul {
+            li {
+                Link {
+                    target: Route::BlogPost { name: "Blog post 1".into() },
+                    "Read the first blog post"
+                }
+            }
+            li {
+                Link {
+                    target: Route::BlogPost { name: "Blog post 2".into() },
+                    "Read the second blog post"
+                }
+            }
+        }
+    }
+}
+// ANCHOR_END: blog_list
+
+// ANCHOR: blog_post
+// The name prop comes from the /:name route segment
+#[inline_props]
+fn BlogPost(cx: Scope, name: String) -> Element {
+    render! {
+        h2 { "Blog Post: {name}"}
+    }
+}
+// ANCHOR_END: blog_post
+
+#[inline_props]
+fn PageNotFound(cx: Scope, route: Vec<String>) -> Element {
+    render! {
+        h1 { "Page not found" }
+        p { "We are terribly sorry, but the page you requested doesn't exist." }
+        pre {
+            color: "red",
+            "log:\nattemped to navigate to: {route:?}"
+        }
+    }
+}

+ 28 - 0
docs/router/examples/external_link.rs

@@ -0,0 +1,28 @@
+#![allow(non_snake_case, unused)]
+
+use dioxus::prelude::*;
+use dioxus_router::prelude::*;
+
+#[derive(Routable, Clone)]
+enum Route {
+    #[route("/")]
+    Home {},
+}
+
+#[inline_props]
+fn Home(cx: Scope) -> Element {
+    todo!()
+}
+
+fn main() {}
+
+// ANCHOR: component
+fn GoToDioxus(cx: Scope) -> Element {
+    render! {
+        Link {
+            target: NavigationTarget::External("https://dioxuslabs.com".into()),
+            "ExternalTarget target"
+        }
+    }
+}
+// ANCHOR_END: component

+ 35 - 0
docs/router/examples/first_route.rs

@@ -0,0 +1,35 @@
+// ANCHOR: router
+#![allow(non_snake_case)]
+use dioxus::prelude::*;
+use dioxus_router::prelude::*;
+
+/// An enum of all of the possible routes in the app.
+#[derive(Routable, Clone)]
+enum Route {
+    // The home page is at the / route
+    #[route("/")]
+    // If the name of the component and variant are the same you can omit the component and props name
+    // #[route("/", ComponentName, PropsName)]
+    Home {},
+}
+// ANCHOR_END: router
+
+// ANCHOR: app
+#[inline_props]
+fn App(cx: Scope) -> Element {
+    render! {
+        Router {}
+    }
+}
+// ANCHOR_END: app
+
+// ANCHOR: home
+#[inline_props]
+fn Home(cx: Scope) -> Element {
+    render! {
+        h1 { "Welcome to the Dioxus Blog!" }
+    }
+}
+// ANCHOR_END: home
+
+fn main() {}

+ 29 - 16
docs/router/examples/full_example.rs

@@ -1,37 +1,49 @@
+#![allow(non_snake_case)]
+
 use dioxus::prelude::*;
 use dioxus_router::prelude::*;
 
 fn main() {
+    #[cfg(target_arch = "wasm32")]
     dioxus_web::launch(App);
+    #[cfg(not(target_arch = "wasm32"))]
+    dioxus_desktop::launch(App);
 }
 
-#[derive(Routable, Clone, Serialize, Deserialize)]
+// ANCHOR: router
+#[derive(Routable, Clone)]
 #[rustfmt::skip]
 enum Route {
-    #[route("/")]
-    Home {},
-    #[nest("/blog")]
-        #[layout(Blog)]
-            #[route("/")]
-            BlogList {},
-            #[route("/blog/:id")]
-            BlogPost { id: String },
-        #[end_layout]
+    #[layout(NavBar)]
+        #[route("/")]
+        Home {},
+        #[nest("/blog")]
+            #[layout(Blog)]
+                #[route("/")]
+                BlogList {},
+                #[route("/blog/:name")]
+                BlogPost { name: String },
+            #[end_layout]
+        #[end_nest]
+    #[end_layout]
+    #[nest("/myblog")]
+        #[redirect("/", || Route::BlogList {})]
+        #[redirect("/:name", |name: String| Route::BlogPost { name })]
     #[end_nest]
-    #[redirect("/myblog", || Route::BlogList {})]
     #[route("/:...route")]
     PageNotFound {
         route: Vec<String>,
     },
 }
+// ANCHOR_END: router
 
 fn App(cx: Scope) -> Element {
     render! {
-        NavBar {}
         Router {}
     }
 }
 
+#[inline_props]
 fn NavBar(cx: Scope) -> Element {
     render! {
         nav {
@@ -40,6 +52,7 @@ fn NavBar(cx: Scope) -> Element {
                 li { Link { target: Route::BlogList {}, "Blog" } }
             }
         }
+        Outlet {}
     }
 }
 
@@ -65,13 +78,13 @@ fn BlogList(cx: Scope) -> Element {
         ul {
             li {
                 Link {
-                    target: Route::BlogPost { id: 1 },
+                    target: Route::BlogPost { name: "Blog post 1".into() },
                     "Read the first blog post"
                 }
             }
             li {
                 Link {
-                    target: Route::BlogPost { id: 2 },
+                    target: Route::BlogPost { name: "Blog post 2".into() },
                     "Read the second blog post"
                 }
             }
@@ -80,9 +93,9 @@ fn BlogList(cx: Scope) -> Element {
 }
 
 #[inline_props]
-fn BlogPost(cx: Scope, id: usize) -> Element {
+fn BlogPost(cx: Scope, name: String) -> Element {
     render! {
-        h2 { "Blog Post: {id}"}
+        h2 { "Blog Post: {name}"}
     }
 }
 

+ 72 - 0
docs/router/examples/links.rs

@@ -0,0 +1,72 @@
+#![allow(non_snake_case)]
+use dioxus::prelude::*;
+use dioxus_router::prelude::*;
+
+// ANCHOR: router
+#[derive(Routable, Clone)]
+#[rustfmt::skip]
+enum Route {
+    // All routes under the NavBar layout will be rendered inside of the NavBar Outlet
+    #[layout(NavBar)]
+        #[route("/")]
+        Home {},
+    #[end_layout]
+    #[route("/:...route")]
+    PageNotFound { route: Vec<String> },
+}
+// ANCHOR_END: router
+
+// ANCHOR: nav
+#[inline_props]
+fn NavBar(cx: Scope) -> Element {
+    render! {
+        nav {
+            ul {
+                li {
+                    Link {
+                        // The Link component will navigate to the route specified
+                        // in the target prop which is checked to exist at compile time
+                        target: Route::Home {},
+                        "Home"
+                    }
+                }
+            }
+        }
+        Outlet {}
+    }
+}
+// ANCHOR_END: nav
+
+// ANCHOR: app
+#[inline_props]
+fn App(cx: Scope) -> Element {
+    render! {
+        Router {}
+    }
+}
+// ANCHOR_END: app
+
+// ANCHOR: home
+#[inline_props]
+fn Home(cx: Scope) -> Element {
+    render! {
+        h1 { "Welcome to the Dioxus Blog!" }
+    }
+}
+// ANCHOR_END: home
+
+// ANCHOR: fallback
+#[inline_props]
+fn PageNotFound(cx: Scope, route: Vec<String>) -> Element {
+    render! {
+        h1 { "Page not found" }
+        p { "We are terribly sorry, but the page you requested doesn't exist." }
+        pre {
+            color: "red",
+            "log:\nattemped to navigate to: {route:?}"
+        }
+    }
+}
+// ANCHOR_END: fallback
+
+fn main() {}

+ 66 - 0
docs/router/examples/nested_routes.rs

@@ -0,0 +1,66 @@
+#![allow(non_snake_case)]
+use dioxus::prelude::*;
+use dioxus_router::prelude::*;
+
+// ANCHOR: router
+#[derive(Routable, Clone)]
+#[rustfmt::skip]
+enum Route {
+    // All routes under the NavBar layout will be rendered inside of the NavBar Outlet
+    #[layout(NavBar)]
+        #[route("/")]
+        Home {},
+    #[end_layout]
+    #[route("/:...route")]
+    PageNotFound { route: Vec<String> },
+}
+// ANCHOR_END: router
+
+// ANCHOR: nav
+#[inline_props]
+fn NavBar(cx: Scope) -> Element {
+    render! {
+        nav {
+            ul {
+                li { "links" }
+            }
+        }
+        // The Outlet component will render child routes (In this case just the Home component) inside the Outlet component
+        Outlet {}
+    }
+}
+// ANCHOR_END: nav
+
+// ANCHOR: app
+#[inline_props]
+fn App(cx: Scope) -> Element {
+    render! {
+        Router {}
+    }
+}
+// ANCHOR_END: app
+
+// ANCHOR: home
+#[inline_props]
+fn Home(cx: Scope) -> Element {
+    render! {
+        h1 { "Welcome to the Dioxus Blog!" }
+    }
+}
+// ANCHOR_END: home
+
+// ANCHOR: fallback
+#[inline_props]
+fn PageNotFound(cx: Scope, route: Vec<String>) -> Element {
+    render! {
+        h1 { "Page not found" }
+        p { "We are terribly sorry, but the page you requested doesn't exist." }
+        pre {
+            color: "red",
+            "log:\nattemped to navigate to: {route:?}"
+        }
+    }
+}
+// ANCHOR_END: fallback
+
+fn main() {}

+ 1 - 23
docs/router/src/SUMMARY.md

@@ -2,30 +2,8 @@
 
 [Introduction](./index.md)
 
-# Features
-- [Adding the Router to Your Application](./features/index.md)
-- [Defining Routes](./features/routes/index.md)
-  - [Nested Routes](./features/routes/nested.md)
-  - [Catch All Routes](./features/routes/catch_all.md)
-  - [Matching Routes](./features/routes/matching.md)
-  - [Fallback Routes (404 page)](./features/routes/fallback.md)
-  - [Multiple Components & Redirects](./features/routes/multiple-and-redirect.md)
-- [Outlets](./features/outlets.md)
-- [Links & Navigation](./features/navigation/index.md)
-  - [Named Navigation](./features/navigation/name.md)
-  - [External Navigation](./features/navigation/external.md)
-  - [Programmatic Navigation](./features/navigation/programmatic.md)
-- [Query](./features/query.md)
-- [Navigation Failures](./features/failures/index.md)
-  - [Named Navigation Failure](./features/failures/named.md)
-  - [External Navigation Failure](./features/failures/external.md)
-  - [Redirection Limit Failure](./features/failures/redirection-limit.md)
-- [History Providers](./features/history-providers.md)
-- [History Buttons](./features/history-buttons.md)
-- [Sitemap Generation](./features/sitemap-generation.md)
-- [Routing Update Callback](./features/routing-update-callback.md)
-
 # Example Project
+
 - [Overview](./example/index.md)
 - [Creating Our First Route](./example/first-route.md)
 - [Building a Nest](./example/building-a-nest.md)

+ 52 - 215
docs/router/src/example/building-a-nest.md

@@ -1,137 +1,60 @@
 # Building a Nest
-Not a bird's nest! A nest of routes!
 
-In this chapter we will begin to build the blog portion of our site which will
-include links, nested URLs, and URL parameters. We will also explore the use
-case of rendering components directly in the component calling [`use_router`].
+In this chapter, we will begin to build the blog portion of our site which will
+include links, nested routes, and route parameters.
 
 ## Site Navigation
+
 Our site visitors won't know all the available pages and blogs on our site so we
-should provide a navigation bar for them.
+should provide a navigation bar for them. Our navbar will be a list of links going between our pages.
+
+We want our navbar component to be rendered on several different pages on our site. Instead of duplicating the code, we can create a component that wraps all children routes. This is called a layout component. To tell the router where to render the child routes, we use the [`Outlet`] component.
+
 Let's create a new `NavBar` component:
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-#
-fn NavBar(cx: Scope) -> Element {
-    render! {
-        nav {
-            ul { }
-        }
-    }
-}
+
+```rust, no_run
+{{#include ../../examples/nested_routes.rs:nav}}
+```
+
+Next, let's add our `NavBar` component as a layout to our Route enum:
+
+```rust, no_run
+{{#include ../../examples/nested_routes.rs:router}}
 ```
 
-Our navbar will be a list of links going between our pages. We could always use
-an HTML anchor element but that would cause our page to reload unnecessarily.
-Instead we want to use the [`Link`] component provided by Dioxus Router.
-
-The [`Link`] is similar to a regular `a` tag. It takes a target (for now a path,
-more on other targets later) and an element. Let's add our links
-
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-#
-fn NavBar(cx: Scope) -> Element {
-    render! {
-        nav {
-            ul {
-                // new stuff starts here
-                li { Link {
-                    target: NavigationTarget::Internal(String::from("/")),
-                    "Home"
-                } }
-                li { Link {
-                        target: "/blog", // short form
-                        "Blog"
-                } }
-                // new stuff ends here
-            }
-        }
-    }
-}
+To add links to our `NavBar`, we could always use an HTML anchor element but that has two issues:
+
+1. It causes a full-page reload
+2. We can accidentally link to a page that doesn't exist
+
+Instead, we want to use the [`Link`] component provided by Dioxus Router.
+
+The [`Link`] is similar to a regular `<a>` tag. It takes a target and children.
+
+Unlike a regular `<a>` tag, we can pass in our Route enum as the target. Because we annotated our routes with the [`route(path)`] attribute, the [`Link`] will know how to generate the correct URL. If we use the Route enum, the rust compiler will prevent us from linking to a page that doesn't exist.
+
+Let's add our links:
+
+```rust, no_run
+{{#include ../../examples/links.rs:nav}}
 ```
 
 > Using this method, the [`Link`] component only works for links within our
 > application. To learn more about navigation targets see
 > [here](./navigation-targets.md).
 
-And finally, we add the navbar component in our app component:
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-# fn Home(cx: Scope) -> Element { unimplemented!() }
-# fn NavBar(cx: Scope) -> Element { unimplemented!() }
-# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
-#
-fn App(cx: Scope) -> Element {
-    use_router(
-        cx,
-        &|| RouterConfiguration::default(),
-        &|| Segment::content(comp(Home)).fallback(comp(PageNotFound))
-    );
-
-    render! {
-        NavBar { } // this is new
-        Outlet { }
-    }
-}
-```
 Now you should see a list of links near the top of your page. Click on one and
 you should seamlessly travel between pages.
 
-### Active Link Styling
-You might want to style links differently, when their page is currently open.
-To achieve this, we can tell the [`Link`] to give its internal `a` tag a class
-in that case.
-
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-#
-fn NavBar(cx: Scope) -> Element {
-    render! {
-        nav {
-            ul {
-                li { Link {
-                    target: NavigationTarget::Internal(String::from("/")),
-                    active_class: "active", // this is new
-                    "Home"
-                } }
-                li { Link {
-                    target: "/blog",
-                    active_class: "active", // this is new
-                    "Blog"
-                } }
-            }
-        }
-    }
-}
-```
-
-> This will not be reflected in the [full example code](./full-code.md).
-
 ## URL Parameters and Nested Routes
+
 Many websites such as GitHub put parameters in their URL. For example,
 `https://github.com/DioxusLabs` utilizes the text after the domain to
 dynamically search and display content about an organization.
 
-We want to store our blogs in a database and load them as needed. This'll help
-prevent our app from being bloated therefor providing faster load times. We also
+We want to store our blogs in a database and load them as needed. We also
 want our users to be able to send people a link to a specific blog post.
+Instead of listing all of the blog titles at compile time, we can make a dynamic route.
 
 We could utilize a search page that loads a blog when clicked but then our users
 won't be able to share our blogs easily. This is where URL parameters come in.
@@ -139,124 +62,38 @@ won't be able to share our blogs easily. This is where URL parameters come in.
 The path to our blog will look like `/blog/myBlogPage`, `myBlogPage` being the
 URL parameter.
 
-First, lets create a component that wraps around all blog content. This allows
-us to add a heading that tells the user they are on the blog.
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-#
-fn Blog(cx: Scope) -> Element {
-    render! {
-        h1 { "Blog" }
-        Outlet {}
-    }
-}
-```
+First, let's create a layout component (similar to the navbar) that wraps the blog content. This allows us to add a heading that tells the user they are on the blog.
 
-> Note the `Outlet { }` component. For the components of a nested route to be
-> rendered, we need an equally nested outlet. For more details, see the
-> [nested routes](../features/routes/nested.md) chapter of the features section.
+```rust, no_run
+{{#include ../../examples/dynamic_route.rs:blog}}
+```
 
 Now we'll create another index component, that'll be displayed when no blog post
 is selected:
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-#
-fn BlogList(cx: Scope) -> Element {
-    render! {
-        h2 { "Choose a post" }
-        ul {
-            li { Link {
-                target: "/blog/1",
-                "Read the first blog post"
-            } }
-            li { Link {
-                target: "/blog/2",
-                "Read the second blog post"
-            } }
-        }
-    }
-}
+
+```rust, no_run
+{{#include ../../examples/dynamic_route.rs:blog_list}}
 ```
 
-We also need to create a component that displays an actual blog post. Within
-this component we can use the `use_route` hook to gain access to our URL
-parameters:
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-#
-struct PostId;
-
-fn BlogPost(cx: Scope) -> Element {
-    let route = use_route(cx).unwrap();
-
-    let post_id = route.parameter::<PostId>();
-    let post = post_id
-        .map(|id| id.to_string())
-        .unwrap_or(String::from("unknown"));
-
-    render! {
-        h2 { "Blog Post: {post}"}
-    }
-}
+We also need to create a component that displays an actual blog post. This component will accept the URL parameters as props:
+
+```rust, no_run
+{{#include ../../examples/dynamic_route.rs:blog_post}}
 ```
 
-Finally, let's tell our router about those components.
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-# fn Blog(cx: Scope) -> Element { unimplemented!() }
-# fn BlogList(cx: Scope) -> Element { unimplemented!() }
-# struct PostId;
-# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
-# fn Home(cx: Scope) -> Element { unimplemented!() }
-# fn NavBar(cx: Scope) -> Element { unimplemented!() }
-# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
-#
-fn App(cx: Scope) -> Element {
-    use_router(
-        cx,
-        &|| RouterConfiguration::default(),
-        &|| {
-            Segment::content(comp(Home))
-                // new stuff starts here
-                .fixed("blog", Route::content(comp(Blog)).nested(
-                    Segment::content(comp(BlogList))
-                        .catch_all((comp(BlogPost), PostId { }))
-                ))
-                // new stuff ends here
-            .fallback(comp(PageNotFound))
-        }
-    );
-
-    render! {
-        NavBar { }
-        Outlet { }
-    }
-}
+Finally, let's tell our router about those components:
+
+```rust, no_run
+{{#include ../../examples/dynamic_route.rs:router}}
 ```
 
 That's it! If you head to `/blog/1` you should see our sample post.
 
 ## Conclusion
-In this chapter we utilized Dioxus Router's Link, URL Parameter, and `use_route`
+
+In this chapter, we utilized Dioxus Router's Link, and Route Parameter
 functionality to build the blog portion of our application. In the next chapter,
 we will go over how navigation targets (like the one we passed to our links)
 work.
 
-[`Link`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html
-[`use_router`]: https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html
+[`Link`]: https://docs.rs/dioxus-router/latest/dioxus_router/prelude/fn.GenericLink<R>.html

+ 0 - 1
docs/router/src/example/example.rs

@@ -1 +0,0 @@
-

+ 29 - 90
docs/router/src/example/first-route.md

@@ -1,123 +1,62 @@
 # Creating Our First Route
+
 In this chapter, we will start utilizing Dioxus Router and add a homepage and a
 404 page to our project.
 
 ## Fundamentals
-Dioxus Router works based on a [`use_router`] hook, a route definition in pure
-rust and [`Outlet`] components. If you've ever used [Vue Router], you should
-feel right at home with Dioxus Router.
-
-First we need an actual page to route to! Let's add a homepage component:
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-#
-fn Home(cx: Scope) -> Element {
-    render! {
-        h1 { "Welcome to the Dioxus Blog!" }
-    }
-}
+
+The core of the Dioxus Router is the [`Routable`] macro and the [`Router`] component.
+
+First, we need an actual page to route to! Let's add a homepage component:
+
+```rust, no_run
+{{#include ../../examples/first_route.rs:home}}
 ```
 
 ## To Route or Not to Route
+
 We want to use Dioxus Router to separate our application into different "pages".
 Dioxus Router will then determine which page to render based on the URL path.
 
-To start using Dioxus Router, we need to use the [`use_router`] hook. All other
-hooks and components the router provides can only be used as a descendant of a
-component calling [`use_router`].
-
-The [`use_router`] hook takes three arguments:
-1. `cx`, which is a common argument for all hooks.
-2. A [`RouterConfiguration`], which allows us to modify its behavior.
-3. A definition of all routes the application contains, in the form of its root
-   [`Segment`].
-
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-use dioxus::prelude::*;
-# extern crate dioxus_router;
-use dioxus_router::prelude::*;
-# fn Home(cx: Scope) -> Element { unimplemented!() }
-
-fn App(cx: Scope) -> Element {
-    use_router(
-        cx,
-        &|| RouterConfiguration::default(),
-        &|| Segment::content(comp(Home))
-    );
-
-    render! {
-        Outlet { }
-    }
-}
+To start using Dioxus Router, we need to use the [`Routable`] macro.
+
+The [`Routable`] macro takes an enum with all of the possible routes in our application. Each variant of the enum represents a route and must be annotated with the [`route(path)`] attribute.
+
+```rust, no_run
+{{#include ../../examples/first_route.rs:router}}
 ```
 
+All other hooks and components the router provides can only be used as a descendant of a [`Router`] component.
+
 If you head to your application's browser tab, you should now see the text
 `Welcome to Dioxus Blog!` when on the root URL (`http://localhost:8080/`). If
 you enter a different path for the URL, nothing should be displayed.
 
 This is because we told Dioxus Router to render the `Home` component only when
-the URL path is `/`. The _index_ (`Segment::content()`) functionality we used
-basically emulates how web servers treat `index.html` files.
+the URL path is `/`.
 
 ## What if a Route Doesn't Exist?
-In our example Dioxus Router doesn't render anything. Many sites also have a
-"404" page for when a URL path leads to nowhere. Dioxus Router can do this too!
+
+In our example, when a route doesn't exist Dioxus Router doesn't render anything. Many sites also have a "404" page when a path does not exist. Let's add one to our site.
 
 First, we create a new `PageNotFound` component.
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-#
-fn PageNotFound(cx: Scope) -> Element {
-    render! {
-        h1 { "Page not found" }
-        p { "We are terribly sorry, but the page you requested doesn't exist." }
-    }
-}
+
+```rust, no_run
+{{#include ../../examples/catch_all.rs:fallback}}
 ```
 
-Now to tell Dioxus Router to render our new component when no route exists.
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-# fn Home(cx: Scope) -> Element { unimplemented!() }
-# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
-#
-fn App(cx: Scope) -> Element {
-    use_router(
-        cx,
-        &|| RouterConfiguration::default(),
-        &|| {
-            Segment::content(comp(Home))
-                .fallback(comp(PageNotFound)) // this is new
-        }
-    );
-
-    render! {
-        Outlet { }
-    }
-}
+Next, register the route in the Route enum to match if all other routes fail.
+
+```rust, no_run
+{{#include ../../examples/catch_all.rs:router}}
 ```
 
 Now when you go to a route that doesn't exist, you should see the page not found
 text.
 
 ## Conclusion
-In this chapter we learned how to create a route and tell Dioxus Router what
+
+In this chapter, we learned how to create a route and tell Dioxus Router what
 component to render when the URL path is `/`. We also created a 404 page to
 handle when a route doesn't exist. Next, we'll create the blog portion of our
 site. We will utilize nested routes and URL parameters.
-
-[`Outlet`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html
-[`RouterConfiguration`]: https://docs.rs/dioxus-router/latest/dioxus_router/hooks/struct.RouterConfiguration.html
-[`Segment`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html
-[`use_router`]: https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html
-[Vue Router]: https://router.vuejs.org/

+ 2 - 6
docs/router/src/example/full-code.md

@@ -1,9 +1,5 @@
 # Full Code
 
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# extern crate dioxus_router;
-# extern crate dioxus_web;
-{{#include example.rs}}
+```rust, no_run
+{{#include ../../examples/full_example.rs}}
 ```

+ 14 - 148
docs/router/src/example/navigation-targets.md

@@ -1,161 +1,27 @@
 # Navigation Targets
-In the previous chapter we learned how to create links to pages within our app.
-We told them where to go using the `target` property. This property takes a
-[`NavigationTarget`].
 
-## What is a navigation target?
-A [`NavigationTarget`] is similar to the `href` of an HTML anchor element.It
-tells the router where to navigate to. The Dioxus Router knows three kinds of
-navigation targets:
-- [`Internal`]: we already saw that. It's basically an `href`, but cannot
-  link to content outside our app.
-- [`External`]: This works exactly like an HTML anchors `href`. In fact,
-  it is just passed through. Don't use this for in-app navigation as it'll
-  trigger a page reload by the browser.
-- [`Named`]: this is the most interesting form of navigation target. We'll look
-  at it in detail in this chapter.
-
-## External navigation
-If we need a link to an external page we can do it like this:
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-#
-fn GoToDioxus(cx: Scope) -> Element {
-    render! {
-        Link {
-            target: NavigationTarget::External("https://dioxuslabs.com".into()),
-            "Explicit ExternalTarget target"
-        }
-        Link {
-            target: "https://dioxuslabs.com", // short form
-            "Implicit ExternalTarget target"
-        }
-    }
-}
-```
-
-> Note that we can use a `str`, just like with [`Internal`]s. The router will
-> convert a `str` to an [`External`] if the URL is absolute.
-
-## Named navigation
-When defining our routes, we can optionally give them unique static names. This
-is required for a feature we call named navigation.
-
-Up to now, when creating links we told the router the exact path to go to. With
-named navigation we instead give it a name, and let it figure out the path.
-
-This has several advantages:
-- We don't have to remember absolute paths or care about what the current path
-  is.
-- Changing paths later on won't break internal links.
-- Paths can easily be localized without affecting app logic.
-- The compiler makes sure we don't have typos.
+In the previous chapter, we learned how to create links to pages within our app.
+We told them where to go using the `target` property. This property takes something that can be converted to a [`NavigationTarget`].
 
-Let's try that now! First, we give our blog post route a name. We can reuse our
-`BlogPost` component as a name.
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-# fn Blog(cx: Scope) -> Element { unimplemented!() }
-# fn BlogList(cx: Scope) -> Element { unimplemented!() }
-# struct PostId;
-# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
-# fn Home(cx: Scope) -> Element { unimplemented!() }
-# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
-#
-struct BlogPostName;
-
-fn App(cx: Scope) -> Element {
-    use_router(
-        cx,
-        &|| RouterConfiguration::default(),
-        &|| {
-            Segment::content(comp(Home))
-                .fixed("blog", Route::content(comp(Blog)).nested(
-                    Segment::content(comp(BlogList)).catch_all(
-                        ParameterRoute::content::<PostId>(comp(BlogPost))
-                            .name::<BlogPostName>() // this is new
-                    )
-                ))
-                .fallback(comp(PageNotFound))
-        }
-    );
-
-    // ...
-    # unimplemented!()
-}
-```
+## What is a navigation target?
 
-Now we can change the targets of the links in our `BlogList` component.
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-# struct PostId;
-# struct BlogPostName;
-# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
-#
-fn BlogList(cx: Scope) -> Element {
-    render! {
-        h2 { "Choose a post" }
-        ul {
-            li { Link {
-                target: named::<BlogPostName>().parameter::<PostId>("1"),
-                "Read the first blog post"
-            } }
-            li { Link {
-                target: named::<BlogPostName>()
-                    .parameter::<PostId>("1")
-                    .query("query"),
-                "Read the second blog post"
-            } }
-        }
-    }
-}
-```
+A [`NavigationTarget`] is similar to the `href` of an HTML anchor element. It
+tells the router where to navigate to. The Dioxus Router knows two kinds of
+navigation targets:
 
-As you can see, a [`Named`] requires three fields:
-1. the name to navigate to
-2. a `Vec` containing all parameters that need to be inserted into the path
-3. optionally a query string to use.
+- [`Internal`]: We used internal links in the previous chapter. It's a link to a page within our
+  app represented as a Route enum.
+- [`External`]: This works exactly like an HTML anchors' `href`. Don't use this for in-app
+  navigation as it will trigger a page reload by the browser.
 
+## External navigation
 
-### The special root index name
-Whether we define any names or not, the router always knows about the
-[`RootIndex`] name. Navigating to it tells the router to go to `/`.
+If we need a link to an external page we can do it like this:
 
-We can change the link in our `NavBar` component to take advantage of that.
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-#
-fn NavBar(cx: Scope) -> Element {
-    render! {
-        nav {
-            ul {
-                li { Link { target: named::<RootIndex>(), "Home" } }
-                li { Link { target: "/blog", "Blog" } }
-            }
-        }
-    }
-}
+```rust, no_run
+{{#include ../../examples/external_link.rs:component}}
 ```
 
-
 [`External`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External
 [`Internal`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal
-[`Named`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named
 [`NavigationTarget`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html
-[`RootIndex`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/prelude/struct.RootIndex.html

+ 17 - 43
docs/router/src/example/redirection-perfection.md

@@ -1,65 +1,39 @@
 # Redirection Perfection
+
 You're well on your way to becoming a routing master!
 
-In this chapter we will cover utilizing redirects so you can take Rickrolling to
-the next level.
+In this chapter, we will cover creating redirects
+
+## Creating Redirects
 
-## What Is This Redirect Thing?
 A redirect is very simple. When dioxus encounters a redirect while finding out
 what components to render, it will redirect the user to the target of the
 redirect.
 
 As a simple example, let's say you want user to still land on your blog, even
-if they used the path `/myblog`.
+if they used the path `/myblog` or `/myblog/:name`.
+
+Redirects are special attributes in the router enum that accept a route and a closure
+with the route parameters. The closure should return a route to redirect to.
+
+Let's add a redirect to our router enum:
 
-All we need to do is update our route definition in our app component:
-```rust,no_run
-# // Hidden lines (like this one) make the documentation tests work.
-# extern crate dioxus;
-# use dioxus::prelude::*;
-# extern crate dioxus_router;
-# use dioxus_router::prelude::*;
-# fn Blog(cx: Scope) -> Element { unimplemented!() }
-# fn BlogList(cx: Scope) -> Element { unimplemented!() }
-# struct PostId;
-# struct BlogPostName;
-# fn BlogPost(cx: Scope) -> Element { unimplemented!() }
-# fn Home(cx: Scope) -> Element { unimplemented!() }
-# fn NavBar(cx: Scope) -> Element { unimplemented!() }
-# fn PageNotFound(cx: Scope) -> Element { unimplemented!() }
-# fn App(cx: Scope) -> Element {
-use_router(
-    cx,
-    &|| RouterConfiguration::default(),
-    &|| {
-        Segment::content(comp(Home))
-            .fixed("blog", Route::content(comp(Blog)).nested(
-                Segment::content(comp(BlogList)).catch_all(
-                    ParameterRoute::content::<PostId>(comp(BlogPost))
-                        .name::<BlogPostName>()
-                )
-            ))
-            .fixed("myblog", "/blog") // this is new
-            .fallback(comp(PageNotFound))
-    }
-);
-# unimplemented!()
-# }
+```rust, no_run
+{{#include ../../examples/full_example.rs:router}}
 ```
 
 That's it! Now your users will be redirected to the blog.
 
-Notice that the `"/blog"` `str` is a [navigation target](./navigation-targets.md).
-We could also use external or named targets.
-
 ### Conclusion
-Well done! You've completed the Dioxus Router guide book. You've built a small
+
+Well done! You've completed the Dioxus Router guide. You've built a small
 application and learned about the many things you can do with Dioxus Router.
-To continue your journey, you can find a list of challenges down below, or you
+To continue your journey, you attempt a challenge listed below, look at the [router examples](https://github.com/DioxusLabs/dioxus/tree/master/packages/router/examples), or
 can check out the [API reference](https://docs.rs/dioxus-router/).
 
 ### Challenges
-- Organize your components into seperate files for better maintainability.
+
+- Organize your components into separate files for better maintainability.
 - Give your app some style if you haven't already.
 - Build an about page so your visitors know who you are.
 - Add a user system that uses URL parameters.

+ 1 - 0
docs/router/src/features/failures/external.md

@@ -0,0 +1 @@
+# External Navigation Failure

+ 1 - 0
docs/router/src/features/failures/index.md

@@ -0,0 +1 @@
+# Navigation Failures

+ 1 - 0
docs/router/src/features/failures/named.md

@@ -0,0 +1 @@
+# Named Navigation Failure

+ 1 - 0
docs/router/src/features/failures/redirection-limit.md

@@ -0,0 +1 @@
+# Redirection Limit Failure

+ 1 - 0
docs/router/src/features/history-buttons.md

@@ -0,0 +1 @@
+# History Buttons

+ 1 - 0
docs/router/src/features/history-providers.md

@@ -0,0 +1 @@
+# History Providers

+ 1 - 0
docs/router/src/features/index.md

@@ -0,0 +1 @@
+# Adding the Router to Your Application

+ 1 - 0
docs/router/src/features/navigation/external.md

@@ -0,0 +1 @@
+# External Navigation

+ 1 - 0
docs/router/src/features/navigation/index.md

@@ -0,0 +1 @@
+# Links & Navigation

+ 1 - 0
docs/router/src/features/navigation/name.md

@@ -0,0 +1 @@
+# Named Navigation

+ 1 - 0
docs/router/src/features/navigation/programmatic.md

@@ -0,0 +1 @@
+# Programmatic Navigation

+ 1 - 0
docs/router/src/features/outlets.md

@@ -0,0 +1 @@
+# Outlets

+ 1 - 0
docs/router/src/features/query.md

@@ -0,0 +1 @@
+# Query

+ 1 - 0
docs/router/src/features/routes/catch_all.md

@@ -0,0 +1 @@
+# Catch All Routes

+ 1 - 0
docs/router/src/features/routes/fallback.md

@@ -0,0 +1 @@
+# Fallback Routes (404 page)

+ 1 - 0
docs/router/src/features/routes/index.md

@@ -0,0 +1 @@
+# Defining Routes

+ 1 - 0
docs/router/src/features/routes/matching.md

@@ -0,0 +1 @@
+# Matching Routes

+ 1 - 0
docs/router/src/features/routes/multiple-and-redirect.md

@@ -0,0 +1 @@
+# Multiple Components & Redirects

+ 1 - 0
docs/router/src/features/routes/nested.md

@@ -0,0 +1 @@
+# Nested Routes

+ 1 - 0
docs/router/src/features/routing-update-callback.md

@@ -0,0 +1 @@
+# Routing Update Callback

+ 1 - 0
docs/router/src/features/sitemap-generation.md

@@ -0,0 +1 @@
+# Sitemap Generation

+ 1 - 1
docs/router/src/reference/failures/index.md

@@ -34,7 +34,7 @@ You can override it by setting the `failure_external_navigation` value of the
 [`RouterConfiguration`]. The external URL will be provided via the
 [`FailureExternalNavigation`] parameter.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;

+ 1 - 1
docs/router/src/reference/history-buttons.md

@@ -14,7 +14,7 @@ forward buttons:
 > If you want to navigate through the history programmatically, take a look at
 > [`programmatic navigation`](./navigation/programmatic.md).
 
-```rust, no_run
+```rust, no_run, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;

+ 1 - 1
docs/router/src/reference/history-providers.md

@@ -15,7 +15,7 @@ By default the router uses the [`MemoryHistory`]. It might be changed to use
 
 You can override the default history:
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;

+ 1 - 1
docs/router/src/reference/index.md

@@ -11,7 +11,7 @@ In most cases we want to add the router to the root component of our app. This
 way, we can ensure that we have access to all its functionality everywhere. We
 add it by using the [`use_router`] hook
 
-```rust
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;

+ 2 - 1
docs/router/src/reference/navigation/external.md

@@ -15,7 +15,8 @@ the [`Link`] component is more convenient to use, as it automatically sets the
 `rel` attribute for the link, when the target is external.
 
 ## Code Example
-```rust
+
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;

+ 4 - 1
docs/router/src/reference/navigation/index.md

@@ -9,6 +9,7 @@ like this:
 ```
 
 However, we cannot do that when using the router for two reasons:
+
 1. Anchor tags make the browser load a new page from the server. This takes a
    lot of time, and it is much faster to let the router handle the navigation
    client-side.
@@ -17,7 +18,8 @@ However, we cannot do that when using the router for two reasons:
 
 To solve these problems, the router provides us with a [`Link`] component we can
 use like this:
-```rust,no_run
+
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -40,6 +42,7 @@ fn SomeComponent(cx: Scope) -> Element {
 The `target` in the example above is similar to the `href` of a regular anchor
 element. However, it tells the router more about what kind of navigation it
 should perform:
+
 - The example uses [`Internal`]. We give it an arbitrary path that will be
   merged with the current URL.
 - [`Named`] allows us to navigate within our app using predefined names.

+ 5 - 2
docs/router/src/reference/navigation/name.md

@@ -11,6 +11,7 @@ automatically create the actual path to navigate to, even inserting required
 parameters.
 
 _Named_ navigation has a few advantages over _path-based_ navigation:
+
 - Links can be created without knowing the actual path.
 - It is much easier to find all links to a specific route.
 - The router knows what links are invalid (and will panic in debug builds).
@@ -27,7 +28,8 @@ _Named_ navigation has a few advantages over _path-based_ navigation:
 > certain conditions. None of these names can be used for app defined routes.
 
 ## Code Example
-```rust
+
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;
@@ -90,11 +92,12 @@ fn App(cx: Scope) -> Element {
 ```
 
 ## Check if a name is present
+
 You can check if a specific name is present for the current route. This works
 similar to getting the value of a [parameter route](../routes/parameter.md) and
 the same restrictions apply.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;

+ 6 - 2
docs/router/src/reference/navigation/programmatic.md

@@ -4,10 +4,11 @@ Sometimes we want our application to navigate to another page without having the
 user click on a link. This is called programmatic navigation.
 
 ## Acquiring a [`Navigator`]
+
 To use programmatic navigation, we first have to acquire a [`Navigator`]. For
 that purpose we can use the [`use_navigate`] hook.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;
@@ -23,7 +24,9 @@ fn Content(cx: Scope) -> Element {
 ```
 
 ## Triggering a Navigation
+
 We can use the [`Navigator`] to trigger four different kinds of navigation:
+
 - `push` will navigate to the target. It works like a regular anchor tag.
 - `replace` works like `push`, except that it replaces the current history entry
   instead of adding a new one. This means the prior page cannot be restored with
@@ -32,7 +35,7 @@ We can use the [`Navigator`] to trigger four different kinds of navigation:
 - `Go forward` works like the browsers forward button (the opposite of the back
   button).
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -64,6 +67,7 @@ You might have noticed that, like [`Link`], the [`Navigator`]s `push` and
 [`Internal`], [`Named`] and [`External`].
 
 ## External Navigation Targets
+
 Unlike a [`Link`], the [`Navigator`] cannot rely on the browser (or webview) to
 handle navigation to external targets via a generated anchor element.
 

+ 17 - 22
docs/router/src/reference/outlets.md

@@ -3,7 +3,7 @@
 [`Outlet`]s tell the router where to render content. In the following example
 the active routes content will be rendered within the [`Outlet`].
 
-```rust
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -45,24 +45,21 @@ fn App(cx: Scope) -> Element {
 
 The example above will output the following HTML (line breaks added for
 readability):
+
 ```html
-<header>
-    header
-</header>
-<h1>
-    Index
-</h1>
-<footer>
-    footer
-</footer>
+<header>header</header>
+<h1>Index</h1>
+<footer>footer</footer>
 ```
 
 ## Nested Outlets
+
 When using nested routes, we need to provide equally nested [`Outlet`]s.
 
 > Learn more about [nested routes](./routes/nested.md) in their own chapter.
 
 ## Named Outlets
+
 When building complex apps, we often need to display multiple pieces of content
 simultaneously. For example, we might have a sidebar that changes its content in
 sync with the main part of the page.
@@ -74,7 +71,7 @@ tell the router about our content.
 We then can use a named [`Outlet`] in our output, to tell the router where to
 put the side content.
 
-```rust
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -127,23 +124,21 @@ fn App(cx: Scope) -> Element {
 
 The example above will output the following HTML (line breaks added for
 readability):
+
 ```html
-<main>
-    Main Content
-</main>
-<aside>
-    Side Content
-</aside>
+<main>Main Content</main>
+<aside>Side Content</aside>
 ```
 
 ## Outlet depth override
+
 When nesting [`Outlet`]s, they communicate with each other. This allows the
 nested [`Outlet`] to render the content of the nested route.
 
 We can override the detected value. Be careful when doing so, it is incredibly
 easy to create an unterminated recursion. See below for an example of that.
 
-```rust
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -197,17 +192,17 @@ fn App(cx: Scope) -> Element {
 
 The example above will output the following HTML (line breaks added for
 readability):
+
 ```html
-<h2>
-    Nested
-</h2>
+<h2>Nested</h2>
 ```
 
 ### Outlet recursion
+
 This code will create a crash due to an unterminated recursion using
 [`Outlet`]s.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;

+ 7 - 3
docs/router/src/reference/query.md

@@ -4,11 +4,12 @@ Some apps use the query part of the URL to encode information. The router allows
 you to easily access the query, as well as set it when navigating.
 
 ## Accessing the query
+
 The [`use_route`] hook allows us to access the current query in two ways. The
 returned `struct` contains a `query` field, that contains the query (without the
 leading `?`).
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;
@@ -26,13 +27,15 @@ fn SomeComponent(cx: Scope) -> Element {
 ```
 
 ## Setting the query
+
 When navigating we can tell the router to change the query. However, the method
 we use to do this is very different, depending on how we specify our target.
 
 ### [`Internal`] and [`External`]
+
 When using [`Internal`] or [`External`] we have to append our query manually.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -54,10 +57,11 @@ fn SomeComponent(cx: Scope) -> Element {
 ```
 
 ### [`Named`]
+
 When using [named navigation](./navigation/name.md) we can pass the query via
 a function.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;

+ 8 - 3
docs/router/src/reference/routes/catch_all.md

@@ -10,6 +10,7 @@ functionality with catch all routes.
 > The parameter will be URL decoded.
 
 ## Creating a content component
+
 We start by creating a component that uses the parameters value.
 
 We can get the current state of the router using the [`use_route`] hook. From
@@ -23,7 +24,7 @@ will later also define on our route.
 > The [`use_route`] hook can only be used in components nested within a
 > component that called [`use_router`].
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;
@@ -45,6 +46,7 @@ fn Greeting(cx: Scope) -> Element {
 ```
 
 ## Defining the routes
+
 Now we can define our route. Unlike a fixed [`Route`], a [`ParameterRoute`]
 needs two arguments to be created.
 
@@ -54,7 +56,7 @@ needs two arguments to be created.
 > For that reason, the example below would not work in practice, but showing
 > both forms (explicit and short) is more important for this example.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -83,6 +85,7 @@ fn App(cx: Scope) -> Element {
 ```
 
 ## Interaction with other routes
+
 Each individual [`Segment`] can only ever have one active route. This means that
 when a [`Segment`] has more than just a catch all route, the router has to
 decide which is active. It does that this way:
@@ -105,11 +108,13 @@ by the path, i.e. `//`.
 >
 > If you absolutely need an empty parameter on the root [`Segment`], a URL like
 > this _could_ work:
+>
 > - `https://your-site.example//` for web sites
 > - `dioxus://index.html//` for desktop apps
 
 ## Full Code
-```rust
+
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;

+ 4 - 2
docs/router/src/reference/routes/fallback.md

@@ -8,10 +8,11 @@ Fallback routes allow us to do that.
 > path, like web apps running in the browser.
 
 ## A single global fallback
+
 To catch all cases of invalid paths within our app, we can simply add a fallback
 route to our root [`Segment`].
 
-```rust
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;
@@ -59,6 +60,7 @@ fn App(cx: Scope) -> Element {
 ```
 
 ## More specific fallback routes
+
 In some cases we might want to show different fallback content depending on what
 section of our app the user is in.
 
@@ -73,7 +75,7 @@ will then replace the global fallback whenever our [`Segment`] was active.
 Note the `.clear_fallback(false)` part. If we didn't add this, the fallback
 content would be rendered inside the `Settings` component.
 
-```rust
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;

+ 8 - 4
docs/router/src/reference/routes/index.md

@@ -4,10 +4,11 @@ When creating a router we need to pass it a [`Segment`]. It tells the router
 about all the routes of our app.
 
 ## Example content
+
 To get a good understanding of how we define routes we first need to prepare
 some example content, so we can see the routing in action.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;
@@ -28,6 +29,7 @@ fn Other(cx: Scope) -> Element {
 ```
 
 ## Index routes
+
 The easiest thing to do is to define an index route.
 
 Index routes act very similar to `index.html` files in most web servers. They
@@ -36,7 +38,7 @@ are active, when we don't specify a route.
 > Note that we wrap our `Index` component with [`comp`]. This is because of
 > rust type system requirements.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -59,6 +61,7 @@ fn App(cx: Scope) -> Element {
 ```
 
 ## Fixed routes
+
 It is almost as easy to define a fixed route.
 
 Fixed routes work similar to how web servers treat files. They are active, when
@@ -66,7 +69,7 @@ specified in the path. In the example, the path must be `/other`.
 
 > The path will be URL decoded before checking if it matches our route.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -91,7 +94,8 @@ fn App(cx: Scope) -> Element {
 ```
 
 ## Full Code
-```rust
+
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;

+ 4 - 2
docs/router/src/reference/routes/matching.md

@@ -14,10 +14,11 @@ _Matching_ routes make it easy to implement such behavior.
 > unfit for all other purposes.
 
 ## Code Example
+
 > Notice that the parameter of a _matching route_ has the same type as a
 > [_catch all route_](./catch_all.md).
 
-```rust
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -112,6 +113,7 @@ fn App(cx: Scope) -> Element {
 ```
 
 ## Matcher
+
 In the example above, both _matching routes_ use a regular expression to specify
 when they match. However, _matching routes_ are not limited to those. They
 accept all types that implement the [`Matcher`] trait.
@@ -119,7 +121,7 @@ accept all types that implement the [`Matcher`] trait.
 For example, you could (but probably shouldn't) implement a matcher, that
 matches all values with an even number of characters:
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus_router;
 # use dioxus_router::prelude::*;

+ 3 - 1
docs/router/src/reference/routes/multiple-and-redirect.md

@@ -1,11 +1,13 @@
 # Multiple Components & Redirects
 
 ## Multiple Components
+
 When creating complex apps we sometimes want to have multiple pieces of content
 side by side. The router allows us to do this. For more details see the section
 about [named `Outlet`s](../outlets.md#named-outlets).
 
 ## Redirects
+
 In some cases we may want to redirect our users to another page whenever they
 open a specific path. We can tell the router to do this when defining our
 routes.
@@ -16,7 +18,7 @@ routes.
 In the following example we will redirect everybody from `/` and `/start` to
 `/home`.
 
-```rust
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;

+ 9 - 4
docs/router/src/reference/routes/nested.md

@@ -22,6 +22,7 @@ We might want to map this structure to these paths and components:
 Nested routes allow us to do this.
 
 ## Route Depth
+
 With nesting routes, the router manages content on multiple levels. In our
 example, when the path is `/settings`, there are two levels of content:
 
@@ -34,13 +35,14 @@ content of nested routes to actually be rendered, we also need nested
 [`Outlet`]s.
 
 ## Defining the content components
+
 We start by creating the components we want the router to render.
 
 Take a look at the `Settings` component. When it gets rendered by an [`Outlet`],
 it will render a second [`Outlet`]. Thus the second [`Outlet`] is nested within
 the first one, and will in turn render our nested content.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -74,13 +76,14 @@ fn PrivacySettings(cx: Scope) -> Element {
 ```
 
 ## Defining the root [`Segment`]
+
 Now we create the [`Segment`] that we will pass to the router.
 
 Note that we wrap `comp(Settings)` within a [`Route`]. For this exact code that
 is unnecessary, as this would be done automatically. However, in the next step
 we'll use a method of [`Route`], so we might as well add this now.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -103,6 +106,7 @@ fn App(cx: Scope) -> Element {
 ```
 
 ## Defining the nested [`Segment`]
+
 In order to create nested routes we need to create a nested [`Segment`]. We then
 pass it to the [`Route`] on the root segment.
 
@@ -110,7 +114,7 @@ pass it to the [`Route`] on the root segment.
 >
 > https://router.example/`root_segment`/`first_nested_segment`/`second_nested_segment`/...
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -143,7 +147,8 @@ fn App(cx: Scope) -> Element {
 ```
 
 ## Full Code
-```rust
+
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;

+ 3 - 1
docs/router/src/reference/routing-update-callback.md

@@ -4,6 +4,7 @@ In some cases we might want to run custom code when the current route changes.
 For this reason, the [`RouterConfiguration`] exposes an `on_update` field.
 
 ## How does the callback behave?
+
 The `on_update` is called whenever the current routing information changes. It
 is called after the router updated its internal state, but before depended
 components and hooks are updated.
@@ -19,7 +20,8 @@ initiated the navigation, was found as a redirect target or returned by the
 `on_update` itself.
 
 ## Code Example
-```rust
+
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # extern crate dioxus_router;

+ 9 - 4
docs/router/src/reference/sitemap-generation.md

@@ -5,8 +5,10 @@ generating all pages), Dioxus Router provides functions to extract that
 information from a [`Segment`].
 
 ## Preparing an app
+
 We will start by preparing an app with some routes like we normally would.
-```rust
+
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 use dioxus::prelude::*;
@@ -74,10 +76,11 @@ fn App(cx: Scope) -> Element {
 ```
 
 ## Modifying the app to make using sitemaps easier
+
 Preparing our app for sitemap generation is quite easy. We just need to extract
 our segment definition into its own function.
 
-```rust,no_run
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -117,13 +120,14 @@ fn prepare_routes() -> Segment<Component> {
 ```
 
 ## Sitemaps with parameter names
+
 The first variant to generate sitemaps is very simple. It finds all routes
 within the [`Segment`] and adds them to the returned `Vec`.
 
 Matching and parameter routes are represented by their `key`, prefixed with `\`.
 Besides that `\`, all paths are URL encoded.
 
-```rust
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 # extern crate dioxus;
 # use dioxus::prelude::*;
@@ -161,6 +165,7 @@ assert_eq!(sitemap, expected);
 ```
 
 ## Sitemaps with actual parameter values
+
 The second variant to generate sitemaps is a bit more involved. When it
 encounters a parameter route, it inserts all values with a matching `key` that
 were provided to it.
@@ -169,7 +174,7 @@ Matching routes only add their path if the value matches their regex.
 
 All paths are URL encoded.
 
-```rust
+```rust, no_run
 # // Hidden lines (like this one) make the documentation tests work.
 use std::collections::{BTreeMap, HashSet};
 # extern crate dioxus;