finish router refrence

This commit is contained in:
Evan Almloff committed 2023-06-01 17:31:13 -05:00
1 parent 07446386e6
commit b5a2f0d6cb
61 files changed
+676 -1908

No files matched your search

@@ -1,71 +0,0 @@
# External Navigation
In modern apps, and especially on the web, we often want to send our users to an
other website. [`External`] allows us to make a [`Link`] navigate to an
external page.
> You might already now about
> [external navigation failures](../failures/external.md). The [`Link`]
> component doesn't rely on the code path where those originate. Therefore a
> [`Link`] will never trigger an external navigation failure.
Strictly speaking, a [`Link`] is not necessary for navigating to external
targets, since by definition the router cannot handle them internally. However,
the [`Link`] component is more convenient to use, as it automatically sets the
`rel` attribute for the link, when the target is external.
## Code Example
```rust, no_run
# // Hidden lines (like this one) make the documentation tests work.
# extern crate dioxus;
use dioxus::prelude::*;
# extern crate dioxus_router;
use dioxus_router::prelude::*;
# extern crate dioxus_ssr;
fn App(cx: Scope) -> Element {
use_router(
cx,
&|| RouterConfiguration {
# synchronous: true,
..Default::default()
},
&|| Segment::empty()
);
render! {
// links need to be inside a router, even if they navigate to an
// external page
Link {
target: NavigationTarget::External("https://dioxuslabs.com/".into()),
"Go to the dioxus home page"
}
Link {
target: "https://dioxuslabs.com/", // short form
"Go to the dioxus home page 2"
}
}
}
#
# let mut vdom = VirtualDom::new(App);
# vdom.rebuild();
# let html = dioxus_ssr::render(&vdom);
# assert_eq!(
# html,
# format!(
# "<a {attr1} {attr2}>{text}</a><a {attr1} {attr2}>{text} 2</a>",
# attr1 = r#"href="https://dioxuslabs.com/" dioxus-prevent-default="""#,
# attr2 = r#"class="" id="" rel="noopener noreferrer" target="""#,
# text = "Go to the dioxus home page"
# )
# )
```
> Note that the short form for an [`ExternalTarget`] looks like the short form
> for an [`InternalTarget`]. The router will create an [`ExternalTarget`] only
> if the URL is absolute.
[`External`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External
[`Internal`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal
[`Link`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html
+11 -31
View File
@@ -1,59 +1,39 @@
# Links & Navigation
When we split our app into pages, we need to provide our users with a way to
navigate between them. On regular web pages we'd use an anchor element for that,
navigate between them. On regular web pages, we'd use an anchor element for that,
like this:
```html
<a href="/other">Link to an other page</a>
```
However, we cannot do that when using the router for two reasons:
However, we cannot do that when using the router for three reasons:
1. Anchor tags make the browser load a new page from the server. This takes a
lot of time, and it is much faster to let the router handle the navigation
client-side.
2. Navigation using anchor tags only works when the app is running inside a
browser. This means we cannot use them inside apps using Dioxus Desktop.
3. Anchor tags cannot check if the target page exists. This means we cannot
prevent accidentally linking to non-existent pages.
To solve these problems, the router provides us with a [`Link`] component we can
use like this:
```rust, no_run
# // Hidden lines (like this one) make the documentation tests work.
# extern crate dioxus;
# use dioxus::prelude::*;
# extern crate dioxus_router;
# use dioxus_router::prelude::*;
fn SomeComponent(cx: Scope) -> Element {
render! {
Link {
target: NavigationTarget::Internal(String::from("/some/path")),
"Link text"
}
Link {
target: "/some/path", // short form
"Other link text"
}
}
}
{{#include ../../../examples/links.rs:nav}}
```
The `target` in the example above is similar to the `href` of a regular anchor
element. However, it tells the router more about what kind of navigation it
should perform:
should perform. It accepts something that can be converted into a
[`NavigationTarget`]:
- The example uses [`Internal`]. We give it an arbitrary path that will be
merged with the current URL.
- [`Named`] allows us to navigate within our app using predefined names.
See the chapter about [named navigation](./name.md) for more details.
- [`External`] allows us to navigate to URLs outside of our app. See the
chapter about [external navigation](./external.md) for more details.
- The example uses a Internal route. This is the most common type of navigation.
It tells the router to navigate to a page within our app by passing a variant of a [`Routable`] enum. This type of navigation can never fail if the link component is used inside a router component.
- [`External`] allows us to navigate to URLs outside of our app. This is useful
for links to external websites. NavigationTarget::External accepts an URL to navigate to. This type of navigation can fail if the URL is invalid.
> The [`Link`] accepts several props that modify its behavior. See the API docs
> for more details.
[`External`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External
[`Internal`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal
[`Link`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html
[`Named`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named
@@ -1,120 +0,0 @@
# Named Navigation
When creating large applications, it can become difficult to keep track of all
routes and how to navigate to them. It also can be hard to find all links to
them, which makes it difficult to change paths.
To solve these problems, the router implements named navigation. When we define
our routes we can give them arbitrary, unique names (completely independent from
the path) and later ask the router to navigate to those names. The router will
automatically create the actual path to navigate to, even inserting required
parameters.
_Named_ navigation has a few advantages over _path-based_ navigation:
- Links can be created without knowing the actual path.
- It is much easier to find all links to a specific route.
- The router knows what links are invalid (and will panic in debug builds).
> When the router encounters an invalid link in a release build, it has to
> handle that problem. You can hook into that process, to display a custom error
> message. See the chapter about
> [named navigation failures](../failures/named.md).
> The router will automatically define the name [`RootIndex`] to refer to the
> root index route (`/`).
>
> It will also add other names (all of them are in the prelude module) in
> certain conditions. None of these names can be used for app defined routes.
## Code Example
```rust, no_run
# // Hidden lines (like this one) make the documentation tests work.
# extern crate dioxus;
use dioxus::prelude::*;
# extern crate dioxus_router;
use dioxus_router::prelude::*;
# extern crate dioxus_ssr;
// we define a unit struct which will serve as our name
struct TargetName;
fn Source(cx: Scope) -> Element {
render! {
Link {
// instead of InternalTarget we use NamedTarget (via the `named` fn)
// we can use the returned value to add parameters or a query
target: named::<TargetName>().query("query"),
"Go to target"
}
}
}
fn Target(cx: Scope) -> Element {
render! {
h1 { "Target" }
}
}
fn App(cx: Scope) -> Element {
use_router(
cx,
&|| RouterConfiguration {
# synchronous: true,
..Default::default()
},
&|| {
Segment::content(comp(Source))
.fixed(
"target_path",
Route::content(comp(Target)).name::<TargetName>()
)
}
);
render! {
Outlet { }
}
}
#
# let mut vdom = VirtualDom::new(App);
# vdom.rebuild();
# let html = dioxus_ssr::render(&vdom);
# assert_eq!(
# html,
# format!(
# "<a {attr1} {attr2}>Go to target</a>",
# attr1 = r#"href="/target_path?query" dioxus-prevent-default="onclick""#,
# attr2 = r#"class="" id="" rel="" target="""#
# )
# )
```
## Check if a name is present
You can check if a specific name is present for the current route. This works
similar to getting the value of a [parameter route](../routes/parameter.md) and
the same restrictions apply.
```rust, no_run
# // Hidden lines (like this one) make the documentation tests work.
# extern crate dioxus;
use dioxus::prelude::*;
# extern crate dioxus_router;
use dioxus_router::prelude::*;
struct SomeName;
fn Content(cx: Scope) -> Element {
let route = use_route(cx).expect("needs to be in router");
if route.is_at(&named::<SomeName>(), false) {
// do something
}
// ...
# todo!()
}
```
[`RootIndex`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/prelude/struct.RootIndex.html
@@ -3,68 +3,25 @@
Sometimes we want our application to navigate to another page without having the
user click on a link. This is called programmatic navigation.
## Acquiring a [`Navigator`]
## Using a Navigator
To use programmatic navigation, we first have to acquire a [`Navigator`]. For
that purpose we can use the [`use_navigate`] hook.
```rust, no_run
# // Hidden lines (like this one) make the documentation tests work.
# extern crate dioxus;
use dioxus::prelude::*;
# extern crate dioxus_router;
use dioxus_router::prelude::*;
fn Content(cx: Scope) -> Element {
let nav = use_navigate(cx).expect("called inside a router");
// ...
# unimplemented!()
}
```
## Triggering a Navigation
We can get a navigator with the [`use_navigator`] hook. This hook returns a [`Navigator`].
We can use the [`Navigator`] to trigger four different kinds of navigation:
- `push` will navigate to the target. It works like a regular anchor tag.
- `replace` works like `push`, except that it replaces the current history entry
instead of adding a new one. This means the prior page cannot be restored with
the browsers back button.
- `Go back` works like the browsers back button.
- `Go forward` works like the browsers forward button (the opposite of the back
button).
instead of adding a new one. This means the prior page cannot be restored with the browser's back button.
- `Go back` works like the browser's back button.
- `Go forward` works like the browser's forward button.
```rust, no_run
# // Hidden lines (like this one) make the documentation tests work.
# extern crate dioxus;
# use dioxus::prelude::*;
# extern crate dioxus_router;
# use dioxus_router::prelude::*;
#
fn Content(cx: Scope) -> Element {
let nav = use_navigate(cx).expect("called inside a router");
// push
nav.push("/target");
// replace
nav.replace("/target");
// go back
nav.go_back();
// go forward
nav.go_forward();
// ...
# unimplemented!()
}
{{#include ../../../examples/navigator.rs:nav}}
```
You might have noticed that, like [`Link`], the [`Navigator`]s `push` and
`replace` functions take a [`NavigationTarget`]. This means we can use
[`Internal`], [`Named`] and [`External`].
`replace` functions take a [`NavigationTarget`]. This means we can use either
[`Internal`], or [`External`] targets.
## External Navigation Targets
@@ -72,13 +29,4 @@ Unlike a [`Link`], the [`Navigator`] cannot rely on the browser (or webview) to
handle navigation to external targets via a generated anchor element.
This means, that under certain conditions, navigation to external targets can
fail. See the chapter about
[external navigation failures](../failures/external.md) for more details.
[`External`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.External
[`Internal`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Internal
[`Link`]: https://docs.rs/dioxus-router/latest/dioxus_router/components/fn.Link.html
[`Named`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html#variant.Named
[`NavigationTarget`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/navigation/enum.NavigationTarget.html
[`Navigator`]: https://docs.rs/dioxus-router-core/latest/dioxus_router_core/hooks/struct.Navigator.html
[`use_navigate`]: https://docs.rs/dioxus-router/latest/dioxus_router/hooks/fn.use_navigate.html
fail.