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