fix queries

This commit is contained in:
Evan Almloff committed 2023-06-01 11:09:51 -05:00
1 parent 2f473f7c97
commit 037a248ad9
294 files changed
+60706 -263

No files matched your search

@@ -0,0 +1,463 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Building a Nest - Dioxus Router</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components &amp; Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links &amp; Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html" class="active"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Dioxus Router</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="building-a-nest"><a class="header" href="#building-a-nest">Building a Nest</a></h1>
<p>Not a bird's nest! A nest of routes!</p>
<p>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 <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a>.</p>
<h2 id="site-navigation"><a class="header" href="#site-navigation">Site Navigation</a></h2>
<p>Our site visitors won't know all the available pages and blogs on our site so we
should provide a navigation bar for them.
Let's create a new <code>NavBar</code> component:</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">
</span>fn NavBar(cx: Scope) -&gt; Element {
render! {
nav {
ul { }
}
}
}
<span class="boring">}
</span></code></pre></pre>
<p>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 <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> component provided by Dioxus Router.</p>
<p>The <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> is similar to a regular <code>a</code> tag. It takes a target (for now a path,
more on other targets later) and an element. Let's add our links</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">
</span>fn NavBar(cx: Scope) -&gt; Element {
render! {
nav {
ul {
// new stuff starts here
li { Link {
target: NavigationTarget::Internal(String::from(&quot;/&quot;)),
&quot;Home&quot;
} }
li { Link {
target: &quot;/blog&quot;, // short form
&quot;Blog&quot;
} }
// new stuff ends here
}
}
}
}
<span class="boring">}
</span></code></pre></pre>
<blockquote>
<p>Using this method, the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> component only works for links within our
application. To learn more about navigation targets see
<a href="./navigation-targets.html">here</a>.</p>
</blockquote>
<p>And finally, we add the navbar component in our app component:</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">fn Home(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn NavBar(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn PageNotFound(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">
</span>fn App(cx: Scope) -&gt; Element {
use_router(
cx,
&amp;|| RouterConfiguration::default(),
&amp;|| Segment::content(comp(Home)).fallback(comp(PageNotFound))
);
render! {
NavBar { } // this is new
Outlet { }
}
}
<span class="boring">}
</span></code></pre></pre>
<p>Now you should see a list of links near the top of your page. Click on one and
you should seamlessly travel between pages.</p>
<h3 id="active-link-styling"><a class="header" href="#active-link-styling">Active Link Styling</a></h3>
<p>You might want to style links differently, when their page is currently open.
To achieve this, we can tell the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html"><code>Link</code></a> to give its internal <code>a</code> tag a class
in that case.</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">
</span>fn NavBar(cx: Scope) -&gt; Element {
render! {
nav {
ul {
li { Link {
target: NavigationTarget::Internal(String::from(&quot;/&quot;)),
active_class: &quot;active&quot;, // this is new
&quot;Home&quot;
} }
li { Link {
target: &quot;/blog&quot;,
active_class: &quot;active&quot;, // this is new
&quot;Blog&quot;
} }
}
}
}
}
<span class="boring">}
</span></code></pre></pre>
<blockquote>
<p>This will not be reflected in the <a href="./full-code.html">full example code</a>.</p>
</blockquote>
<h2 id="url-parameters-and-nested-routes"><a class="header" href="#url-parameters-and-nested-routes">URL Parameters and Nested Routes</a></h2>
<p>Many websites such as GitHub put parameters in their URL. For example,
<code>https://github.com/DioxusLabs</code> utilizes the text after the domain to
dynamically search and display content about an organization.</p>
<p>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
want our users to be able to send people a link to a specific blog post.</p>
<p>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.</p>
<p>The path to our blog will look like <code>/blog/myBlogPage</code>, <code>myBlogPage</code> being the
URL parameter.</p>
<p>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.</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">
</span>fn Blog(cx: Scope) -&gt; Element {
render! {
h1 { &quot;Blog&quot; }
Outlet {}
}
}
<span class="boring">}
</span></code></pre></pre>
<blockquote>
<p>Note the <code>Outlet { }</code> component. For the components of a nested route to be
rendered, we need an equally nested outlet. For more details, see the
<a href="../features/routes/nested.html">nested routes</a> chapter of the features section.</p>
</blockquote>
<p>Now we'll create another index component, that'll be displayed when no blog post
is selected:</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">
</span>fn BlogList(cx: Scope) -&gt; Element {
render! {
h2 { &quot;Choose a post&quot; }
ul {
li { Link {
target: &quot;/blog/1&quot;,
&quot;Read the first blog post&quot;
} }
li { Link {
target: &quot;/blog/2&quot;,
&quot;Read the second blog post&quot;
} }
}
}
}
<span class="boring">}
</span></code></pre></pre>
<p>We also need to create a component that displays an actual blog post. Within
this component we can use the <code>use_route</code> hook to gain access to our URL
parameters:</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">
</span>struct PostId;
fn BlogPost(cx: Scope) -&gt; Element {
let route = use_route(cx).unwrap();
let post_id = route.parameter::&lt;PostId&gt;();
let post = post_id
.map(|id| id.to_string())
.unwrap_or(String::from(&quot;unknown&quot;));
render! {
h2 { &quot;Blog Post: {post}&quot;}
}
}
<span class="boring">}
</span></code></pre></pre>
<p>Finally, let's tell our router about those components.</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">fn Blog(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn BlogList(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">struct PostId;
</span><span class="boring">fn BlogPost(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn Home(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn NavBar(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn PageNotFound(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">
</span>fn App(cx: Scope) -&gt; Element {
use_router(
cx,
&amp;|| RouterConfiguration::default(),
&amp;|| {
Segment::content(comp(Home))
// new stuff starts here
.fixed(&quot;blog&quot;, Route::content(comp(Blog)).nested(
Segment::content(comp(BlogList))
.catch_all((comp(BlogPost), PostId { }))
))
// new stuff ends here
.fallback(comp(PageNotFound))
}
);
render! {
NavBar { }
Outlet { }
}
}
<span class="boring">}
</span></code></pre></pre>
<p>That's it! If you head to <code>/blog/1</code> you should see our sample post.</p>
<h2 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h2>
<p>In this chapter we utilized Dioxus Router's Link, URL Parameter, and <code>use_route</code>
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.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../example/first-route.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../example/navigation-targets.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../example/first-route.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../example/navigation-targets.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>
+91
View File
@@ -0,0 +1,91 @@
use dioxus::prelude::*;
use dioxus_router::prelude::*;
fn main() {
dioxus_web::launch(App);
}
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))
}
);
render! {
NavBar {}
Outlet {}
}
}
fn NavBar(cx: Scope) -> Element {
render! {
nav {
ul {
li { Link { target: named::<RootIndex>(), "Home" } }
li { Link { target: "/blog", "Blog" } }
}
}
}
}
fn Home(cx: Scope) -> Element {
render! {
h1 { "Welcome to the Dioxus Blog!" }
}
}
fn Blog(cx: Scope) -> Element {
render! {
h1 { "Blog" }
Outlet {}
}
}
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>("2"),
"Read the second blog post"
} }
}
}
}
struct PostId;
struct BlogPostName;
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}"}
}
}
fn PageNotFound(cx: Scope) -> Element {
render! {
h1 { "Page not found" }
p { "We are terribly sorry, but the page you requested doesn't exist." }
}
}
@@ -0,0 +1,313 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Creating Our First Route - Dioxus Router</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components &amp; Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links &amp; Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html" class="active"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Dioxus Router</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="creating-our-first-route"><a class="header" href="#creating-our-first-route">Creating Our First Route</a></h1>
<p>In this chapter, we will start utilizing Dioxus Router and add a homepage and a
404 page to our project.</p>
<h2 id="fundamentals"><a class="header" href="#fundamentals">Fundamentals</a></h2>
<p>Dioxus Router works based on a <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a> hook, a route definition in pure
rust and <a href="https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Outlet.html"><code>Outlet</code></a> components. If you've ever used <a href="https://router.vuejs.org/">Vue Router</a>, you should
feel right at home with Dioxus Router.</p>
<p>First we need an actual page to route to! Let's add a homepage component:</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">
</span>fn Home(cx: Scope) -&gt; Element {
render! {
h1 { &quot;Welcome to the Dioxus Blog!&quot; }
}
}
<span class="boring">}
</span></code></pre></pre>
<h2 id="to-route-or-not-to-route"><a class="header" href="#to-route-or-not-to-route">To Route or Not to Route</a></h2>
<p>We want to use Dioxus Router to separate our application into different &quot;pages&quot;.
Dioxus Router will then determine which page to render based on the URL path.</p>
<p>To start using Dioxus Router, we need to use the <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a> hook. All other
hooks and components the router provides can only be used as a descendant of a
component calling <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a>.</p>
<p>The <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_router.html"><code>use_router</code></a> hook takes three arguments:</p>
<ol>
<li><code>cx</code>, which is a common argument for all hooks.</li>
<li>A <a href="https://docs.rs/dioxus-router/latest/dioxus_router/hooks/struct.RouterConfiguration.html"><code>RouterConfiguration</code></a>, which allows us to modify its behavior.</li>
<li>A definition of all routes the application contains, in the form of its root
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/routes/struct.Segment.html"><code>Segment</code></a>.</li>
</ol>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span>use dioxus::prelude::*;
<span class="boring">extern crate dioxus_router;
</span>use dioxus_router::prelude::*;
<span class="boring">fn Home(cx: Scope) -&gt; Element { unimplemented!() }
</span>
fn App(cx: Scope) -&gt; Element {
use_router(
cx,
&amp;|| RouterConfiguration::default(),
&amp;|| Segment::content(comp(Home))
);
render! {
Outlet { }
}
}
<span class="boring">}
</span></code></pre></pre>
<p>If you head to your application's browser tab, you should now see the text
<code>Welcome to Dioxus Blog!</code> when on the root URL (<code>http://localhost:8080/</code>). If
you enter a different path for the URL, nothing should be displayed.</p>
<p>This is because we told Dioxus Router to render the <code>Home</code> component only when
the URL path is <code>/</code>. The <em>index</em> (<code>Segment::content()</code>) functionality we used
basically emulates how web servers treat <code>index.html</code> files.</p>
<h2 id="what-if-a-route-doesnt-exist"><a class="header" href="#what-if-a-route-doesnt-exist">What if a Route Doesn't Exist?</a></h2>
<p>In our example Dioxus Router doesn't render anything. Many sites also have a
&quot;404&quot; page for when a URL path leads to nowhere. Dioxus Router can do this too!</p>
<p>First, we create a new <code>PageNotFound</code> component.</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">
</span>fn PageNotFound(cx: Scope) -&gt; Element {
render! {
h1 { &quot;Page not found&quot; }
p { &quot;We are terribly sorry, but the page you requested doesn't exist.&quot; }
}
}
<span class="boring">}
</span></code></pre></pre>
<p>Now to tell Dioxus Router to render our new component when no route exists.</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">fn Home(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn PageNotFound(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">
</span>fn App(cx: Scope) -&gt; Element {
use_router(
cx,
&amp;|| RouterConfiguration::default(),
&amp;|| {
Segment::content(comp(Home))
.fallback(comp(PageNotFound)) // this is new
}
);
render! {
Outlet { }
}
}
<span class="boring">}
</span></code></pre></pre>
<p>Now when you go to a route that doesn't exist, you should see the page not found
text.</p>
<h2 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h2>
<p>In this chapter we learned how to create a route and tell Dioxus Router what
component to render when the URL path is <code>/</code>. 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.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../example/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../example/building-a-nest.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../example/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../example/building-a-nest.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>
+286
View File
@@ -0,0 +1,286 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Full Code - Dioxus Router</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components &amp; Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links &amp; Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html" class="active"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Dioxus Router</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="full-code"><a class="header" href="#full-code">Full Code</a></h1>
<pre><pre class="playground"><code class="language-rust no_run edition2021"><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">extern crate dioxus_web;
</span>use dioxus::prelude::*;
use dioxus_router::prelude::*;
fn main() {
dioxus_web::launch(App);
}
fn App(cx: Scope) -&gt; Element {
use_router(
cx,
&amp;|| RouterConfiguration::default(),
&amp;|| {
Segment::content(comp(Home))
.fixed(&quot;blog&quot;, Route::content(comp(Blog)).nested(
Segment::content(comp(BlogList)).catch_all(
ParameterRoute::content::&lt;PostId&gt;(comp(BlogPost))
.name::&lt;BlogPostName&gt;()
)
))
.fixed(&quot;myblog&quot;, &quot;/blog&quot;) // this is new
.fallback(comp(PageNotFound))
}
);
render! {
NavBar {}
Outlet {}
}
}
fn NavBar(cx: Scope) -&gt; Element {
render! {
nav {
ul {
li { Link { target: named::&lt;RootIndex&gt;(), &quot;Home&quot; } }
li { Link { target: &quot;/blog&quot;, &quot;Blog&quot; } }
}
}
}
}
fn Home(cx: Scope) -&gt; Element {
render! {
h1 { &quot;Welcome to the Dioxus Blog!&quot; }
}
}
fn Blog(cx: Scope) -&gt; Element {
render! {
h1 { &quot;Blog&quot; }
Outlet {}
}
}
fn BlogList(cx: Scope) -&gt; Element {
render! {
h2 { &quot;Choose a post&quot; }
ul {
li { Link {
target: named::&lt;BlogPostName&gt;().parameter::&lt;PostId&gt;(&quot;1&quot;),
&quot;Read the first blog post&quot;
} }
li { Link {
target: named::&lt;BlogPostName&gt;().parameter::&lt;PostId&gt;(&quot;2&quot;),
&quot;Read the second blog post&quot;
} }
}
}
}
struct PostId;
struct BlogPostName;
fn BlogPost(cx: Scope) -&gt; Element {
let route = use_route(cx).unwrap();
let post_id = route.parameter::&lt;PostId&gt;();
let post = post_id
.map(|id| id.to_string())
.unwrap_or(String::from(&quot;unknown&quot;));
render! {
h2 { &quot;Blog Post: {post}&quot;}
}
}
fn PageNotFound(cx: Scope) -&gt; Element {
render! {
h1 { &quot;Page not found&quot; }
p { &quot;We are terribly sorry, but the page you requested doesn't exist.&quot; }
}
}
</code></pre></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../example/redirection-perfection.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../example/redirection-perfection.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>
+224
View File
@@ -0,0 +1,224 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Overview - Dioxus Router</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components &amp; Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links &amp; Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html" class="active"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Dioxus Router</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="overview"><a class="header" href="#overview">Overview</a></h1>
<p>In this guide you'll learn to effectively use Dioxus Router whether you're
building a small todo app or the next FAANG company. We will create a small
website with a blog, homepage, and more!</p>
<blockquote>
<p>To follow along with the router example, you'll need a working Dioxus app.
Check out the <a href="https://dioxuslabs.com/guide/">Dioxus book</a> to get started.</p>
</blockquote>
<blockquote>
<p>Make sure to add Dioxus Router as a dependency, as explained in the
<a href="../index.html">introduction</a>.</p>
</blockquote>
<h2 id="youll-learn-how-to"><a class="header" href="#youll-learn-how-to">You'll learn how to</a></h2>
<ul>
<li>Create routes and render &quot;pages&quot;.</li>
<li>Utilize nested routes, create a navigation bar, and render content for a
set of routes.</li>
<li>Gather URL parameters to dynamically display content.</li>
<li>Redirect your visitors wherever you want.</li>
</ul>
<blockquote>
<p><strong>Disclaimer</strong></p>
<p>The example will only display the features of Dioxus Router. It will not
include any actual functionality. To keep things simple we will only be using
a single file, this is not the recommended way of doing things with a real
application.</p>
</blockquote>
<p>You can find the complete application in the <a href="./full-code.html">full code</a>
chapter.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../features/routing-update-callback.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../example/first-route.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../features/routing-update-callback.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../example/first-route.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>
@@ -0,0 +1,357 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Navigation Targets - Dioxus Router</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components &amp; Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links &amp; Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html" class="active"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Dioxus Router</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="navigation-targets"><a class="header" href="#navigation-targets">Navigation Targets</a></h1>
<p>In the previous chapter we learned how to create links to pages within our app.
We told them where to go using the <code>target</code> property. This property takes a
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html"><code>NavigationTarget</code></a>.</p>
<h2 id="what-is-a-navigation-target"><a class="header" href="#what-is-a-navigation-target">What is a navigation target?</a></h2>
<p>A <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html"><code>NavigationTarget</code></a> is similar to the <code>href</code> of an HTML anchor element.It
tells the router where to navigate to. The Dioxus Router knows three kinds of
navigation targets:</p>
<ul>
<li><a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal"><code>Internal</code></a>: we already saw that. It's basically an <code>href</code>, but cannot
link to content outside our app.</li>
<li><a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External"><code>External</code></a>: This works exactly like an HTML anchors <code>href</code>. 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.</li>
<li><a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named"><code>Named</code></a>: this is the most interesting form of navigation target. We'll look
at it in detail in this chapter.</li>
</ul>
<h2 id="external-navigation"><a class="header" href="#external-navigation">External navigation</a></h2>
<p>If we need a link to an external page we can do it like this:</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">
</span>fn GoToDioxus(cx: Scope) -&gt; Element {
render! {
Link {
target: NavigationTarget::External(&quot;https://dioxuslabs.com&quot;.into()),
&quot;Explicit ExternalTarget target&quot;
}
Link {
target: &quot;https://dioxuslabs.com&quot;, // short form
&quot;Implicit ExternalTarget target&quot;
}
}
}
<span class="boring">}
</span></code></pre></pre>
<blockquote>
<p>Note that we can use a <code>str</code>, just like with <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal"><code>Internal</code></a>s. The router will
convert a <code>str</code> to an <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External"><code>External</code></a> if the URL is absolute.</p>
</blockquote>
<h2 id="named-navigation"><a class="header" href="#named-navigation">Named navigation</a></h2>
<p>When defining our routes, we can optionally give them unique static names. This
is required for a feature we call named navigation.</p>
<p>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.</p>
<p>This has several advantages:</p>
<ul>
<li>We don't have to remember absolute paths or care about what the current path
is.</li>
<li>Changing paths later on won't break internal links.</li>
<li>Paths can easily be localized without affecting app logic.</li>
<li>The compiler makes sure we don't have typos.</li>
</ul>
<p>Let's try that now! First, we give our blog post route a name. We can reuse our
<code>BlogPost</code> component as a name.</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">fn Blog(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn BlogList(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">struct PostId;
</span><span class="boring">fn BlogPost(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn Home(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn PageNotFound(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">
</span>struct BlogPostName;
fn App(cx: Scope) -&gt; Element {
use_router(
cx,
&amp;|| RouterConfiguration::default(),
&amp;|| {
Segment::content(comp(Home))
.fixed(&quot;blog&quot;, Route::content(comp(Blog)).nested(
Segment::content(comp(BlogList)).catch_all(
ParameterRoute::content::&lt;PostId&gt;(comp(BlogPost))
.name::&lt;BlogPostName&gt;() // this is new
)
))
.fallback(comp(PageNotFound))
}
);
// ...
<span class="boring"> unimplemented!()
</span>}
<span class="boring">}
</span></code></pre></pre>
<p>Now we can change the targets of the links in our <code>BlogList</code> component.</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">struct PostId;
</span><span class="boring">struct BlogPostName;
</span><span class="boring">fn BlogPost(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">
</span>fn BlogList(cx: Scope) -&gt; Element {
render! {
h2 { &quot;Choose a post&quot; }
ul {
li { Link {
target: named::&lt;BlogPostName&gt;().parameter::&lt;PostId&gt;(&quot;1&quot;),
&quot;Read the first blog post&quot;
} }
li { Link {
target: named::&lt;BlogPostName&gt;()
.parameter::&lt;PostId&gt;(&quot;1&quot;)
.query(&quot;query&quot;),
&quot;Read the second blog post&quot;
} }
}
}
}
<span class="boring">}
</span></code></pre></pre>
<p>As you can see, a <a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named"><code>Named</code></a> requires three fields:</p>
<ol>
<li>the name to navigate to</li>
<li>a <code>Vec</code> containing all parameters that need to be inserted into the path</li>
<li>optionally a query string to use.</li>
</ol>
<h3 id="the-special-root-index-name"><a class="header" href="#the-special-root-index-name">The special root index name</a></h3>
<p>Whether we define any names or not, the router always knows about the
<a href="https://docs.rs/dioxus-router-core/latest/dioxus_router_core/prelude/struct.RootIndex.html"><code>RootIndex</code></a> name. Navigating to it tells the router to go to <code>/</code>.</p>
<p>We can change the link in our <code>NavBar</code> component to take advantage of that.</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">
</span>fn NavBar(cx: Scope) -&gt; Element {
render! {
nav {
ul {
li { Link { target: named::&lt;RootIndex&gt;(), &quot;Home&quot; } }
li { Link { target: &quot;/blog&quot;, &quot;Blog&quot; } }
}
}
}
}
<span class="boring">}
</span></code></pre></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../example/building-a-nest.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../example/redirection-perfection.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../example/building-a-nest.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../example/redirection-perfection.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>
@@ -0,0 +1,259 @@
<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Redirection Perfection - Dioxus Router</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff" />
<link rel="icon" href="../favicon.svg">
<link rel="shortcut icon" href="../favicon.png">
<link rel="stylesheet" href="../css/variables.css">
<link rel="stylesheet" href="../css/general.css">
<link rel="stylesheet" href="../css/chrome.css">
<link rel="stylesheet" href="../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" href="../highlight.css">
<link rel="stylesheet" href="../tomorrow-night.css">
<link rel="stylesheet" href="../ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "../";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded affix "><a href="../index.html">Introduction</a></li><li class="chapter-item expanded affix "><li class="part-title">Features</li><li class="chapter-item expanded "><a href="../features/index.html"><strong aria-hidden="true">1.</strong> Adding the Router to Your Application</a></li><li class="chapter-item expanded "><a href="../features/routes/index.html"><strong aria-hidden="true">2.</strong> Defining Routes</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/routes/nested.html"><strong aria-hidden="true">2.1.</strong> Nested Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/catch_all.html"><strong aria-hidden="true">2.2.</strong> Catch All Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/matching.html"><strong aria-hidden="true">2.3.</strong> Matching Routes</a></li><li class="chapter-item expanded "><a href="../features/routes/fallback.html"><strong aria-hidden="true">2.4.</strong> Fallback Routes (404 page)</a></li><li class="chapter-item expanded "><a href="../features/routes/multiple-and-redirect.html"><strong aria-hidden="true">2.5.</strong> Multiple Components &amp; Redirects</a></li></ol></li><li class="chapter-item expanded "><a href="../features/outlets.html"><strong aria-hidden="true">3.</strong> Outlets</a></li><li class="chapter-item expanded "><a href="../features/navigation/index.html"><strong aria-hidden="true">4.</strong> Links &amp; Navigation</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/navigation/name.html"><strong aria-hidden="true">4.1.</strong> Named Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/external.html"><strong aria-hidden="true">4.2.</strong> External Navigation</a></li><li class="chapter-item expanded "><a href="../features/navigation/programmatic.html"><strong aria-hidden="true">4.3.</strong> Programmatic Navigation</a></li></ol></li><li class="chapter-item expanded "><a href="../features/query.html"><strong aria-hidden="true">5.</strong> Query</a></li><li class="chapter-item expanded "><a href="../features/failures/index.html"><strong aria-hidden="true">6.</strong> Navigation Failures</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="../features/failures/named.html"><strong aria-hidden="true">6.1.</strong> Named Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/external.html"><strong aria-hidden="true">6.2.</strong> External Navigation Failure</a></li><li class="chapter-item expanded "><a href="../features/failures/redirection-limit.html"><strong aria-hidden="true">6.3.</strong> Redirection Limit Failure</a></li></ol></li><li class="chapter-item expanded "><a href="../features/history-providers.html"><strong aria-hidden="true">7.</strong> History Providers</a></li><li class="chapter-item expanded "><a href="../features/history-buttons.html"><strong aria-hidden="true">8.</strong> History Buttons</a></li><li class="chapter-item expanded "><a href="../features/sitemap-generation.html"><strong aria-hidden="true">9.</strong> Sitemap Generation</a></li><li class="chapter-item expanded "><a href="../features/routing-update-callback.html"><strong aria-hidden="true">10.</strong> Routing Update Callback</a></li><li class="chapter-item expanded affix "><li class="part-title">Example Project</li><li class="chapter-item expanded "><a href="../example/index.html"><strong aria-hidden="true">11.</strong> Overview</a></li><li class="chapter-item expanded "><a href="../example/first-route.html"><strong aria-hidden="true">12.</strong> Creating Our First Route</a></li><li class="chapter-item expanded "><a href="../example/building-a-nest.html"><strong aria-hidden="true">13.</strong> Building a Nest</a></li><li class="chapter-item expanded "><a href="../example/navigation-targets.html"><strong aria-hidden="true">14.</strong> Navigation Targets</a></li><li class="chapter-item expanded "><a href="../example/redirection-perfection.html" class="active"><strong aria-hidden="true">15.</strong> Redirection Perfection</a></li><li class="chapter-item expanded "><a href="../example/full-code.html"><strong aria-hidden="true">16.</strong> Full Code</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="light">Light (default)</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Dioxus Router</h1>
<div class="right-buttons">
<a href="../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="redirection-perfection"><a class="header" href="#redirection-perfection">Redirection Perfection</a></h1>
<p>You're well on your way to becoming a routing master!</p>
<p>In this chapter we will cover utilizing redirects so you can take Rickrolling to
the next level.</p>
<h2 id="what-is-this-redirect-thing"><a class="header" href="#what-is-this-redirect-thing">What Is This Redirect Thing?</a></h2>
<p>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.</p>
<p>As a simple example, let's say you want user to still land on your blog, even
if they used the path <code>/myblog</code>.</p>
<p>All we need to do is update our route definition in our app component:</p>
<pre><pre class="playground"><code class="language-rust no_run edition2021">
<span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span><span class="boring">// Hidden lines (like this one) make the documentation tests work.
</span><span class="boring">extern crate dioxus;
</span><span class="boring">use dioxus::prelude::*;
</span><span class="boring">extern crate dioxus_router;
</span><span class="boring">use dioxus_router::prelude::*;
</span><span class="boring">fn Blog(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn BlogList(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">struct PostId;
</span><span class="boring">struct BlogPostName;
</span><span class="boring">fn BlogPost(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn Home(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn NavBar(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn PageNotFound(cx: Scope) -&gt; Element { unimplemented!() }
</span><span class="boring">fn App(cx: Scope) -&gt; Element {
</span>use_router(
cx,
&amp;|| RouterConfiguration::default(),
&amp;|| {
Segment::content(comp(Home))
.fixed(&quot;blog&quot;, Route::content(comp(Blog)).nested(
Segment::content(comp(BlogList)).catch_all(
ParameterRoute::content::&lt;PostId&gt;(comp(BlogPost))
.name::&lt;BlogPostName&gt;()
)
))
.fixed(&quot;myblog&quot;, &quot;/blog&quot;) // this is new
.fallback(comp(PageNotFound))
}
);
<span class="boring">unimplemented!()
</span><span class="boring">}
</span><span class="boring">}
</span></code></pre></pre>
<p>That's it! Now your users will be redirected to the blog.</p>
<p>Notice that the <code>&quot;/blog&quot;</code> <code>str</code> is a <a href="./navigation-targets.html">navigation target</a>.
We could also use external or named targets.</p>
<h3 id="conclusion"><a class="header" href="#conclusion">Conclusion</a></h3>
<p>Well done! You've completed the Dioxus Router guide book. 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
can check out the <a href="https://docs.rs/dioxus-router/">API reference</a>.</p>
<h3 id="challenges"><a class="header" href="#challenges">Challenges</a></h3>
<ul>
<li>Organize your components into seperate files for better maintainability.</li>
<li>Give your app some style if you haven't already.</li>
<li>Build an about page so your visitors know who you are.</li>
<li>Add a user system that uses URL parameters.</li>
<li>Create a simple admin system to create, delete, and edit blogs.</li>
<li>If you want to go to the max, hook up your application to a rest API and database.</li>
</ul>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../example/navigation-targets.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../example/full-code.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../example/navigation-targets.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next" href="../example/full-code.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script type="text/javascript">
window.playground_copyable = true;
</script>
<script src="../elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="../clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="../book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>