Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/DioxusLabs/dioxus/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Navigator type provides programmatic control over navigation and browser history. Use it to navigate between routes, go back/forward, and check navigation state from within components and event handlers.

Getting a Navigator

Using the Hook

use dioxus::prelude::*;

#[derive(Clone, Routable, PartialEq)]
enum Route {
    #[route("/")]
    Home {},
    #[route("/settings")]
    Settings {},
}

#[component]
fn Home() -> Element {
    let navigator = use_navigator();
    
    rsx! {
        button {
            onclick: move |_| {
                navigator.push(Route::Settings {});
            },
            "Go to Settings"
        }
    }
}

#[component]
fn Settings() -> Element {
    rsx! { h1 { "Settings" } }
}

Direct Access

You can also get a navigator without using the hook:
use dioxus_router::navigator;

let nav = navigator();
nav.push(Route::Home {});
Both methods panic if called outside of a Router context.

push

Navigate to a new location, adding it to the history stack:
let navigator = use_navigator();

// Navigate to a route variant
navigator.push(Route::About {});

// Navigate to a path string
navigator.push("/about");

// Navigate to an external URL
navigator.push("https://dioxuslabs.com");
target
impl Into<NavigationTarget>
required
The target to navigate to. Can be:
  • A route enum variant
  • A string path
  • An external URL
Returns: Option<ExternalNavigationFailure> - Returns an error if external navigation is not supported by the current history provider.

replace

Replace the current location without adding to history:
let navigator = use_navigator();

// Replace current route
navigator.replace(Route::Login {});

// User cannot go back to the previous page
target
impl Into<NavigationTarget>
required
The target to navigate to.
Returns: Option<ExternalNavigationFailure>

go_back

Navigate to the previous page in history:
let navigator = use_navigator();

rsx! {
    button {
        onclick: move |_| navigator.go_back(),
        "Back"
    }
}
Fails silently if there is no previous location.

go_forward

Navigate to the next page in history:
let navigator = use_navigator();

rsx! {
    button {
        onclick: move |_| navigator.go_forward(),
        "Forward"
    }
}
Fails silently if there is no next location.

can_go_back

Check if there is a previous page to navigate to:
let navigator = use_navigator();
let can_go_back = navigator.can_go_back();

rsx! {
    button {
        disabled: !can_go_back,
        onclick: move |_| navigator.go_back(),
        "Back"
    }
}
Returns: bool

can_go_forward

Check if there is a next page to navigate to:
let navigator = use_navigator();
let can_go_forward = navigator.can_go_forward();

rsx! {
    button {
        disabled: !can_go_forward,
        onclick: move |_| navigator.go_forward(),
        "Forward"
    }
}
Returns: bool The NavigationTarget enum represents where to navigate:
pub enum NavigationTarget<R = String> {
    Internal(R),      // Internal route
    External(String), // External URL
}
You rarely need to construct these manually, as they’re created automatically from routes and strings:
let navigator = use_navigator();

// These all create NavigationTarget internally:
navigator.push(Route::Home {});           // Internal
navigator.push("/about");                  // Internal
navigator.push("https://example.com");    // External

Common Patterns

#[component]
fn CreatePost() -> Element {
    let navigator = use_navigator();
    let mut title = use_signal(|| String::new());
    
    let submit = move |_| {
        // Save post logic...
        let post_id = 42;
        
        // Navigate to the new post
        navigator.push(Route::Post { id: post_id });
    };
    
    rsx! {
        form { onsubmit: submit,
            input { 
                value: "{title}",
                oninput: move |e| title.set(e.value())
            }
            button { "Create" }
        }
    }
}

Conditional Navigation

#[component]
fn ProtectedPage() -> Element {
    let navigator = use_navigator();
    let is_authenticated = use_signal(|| false);
    
    use_effect(move || {
        if !is_authenticated() {
            navigator.replace(Route::Login {});
        }
    });
    
    rsx! {
        h1 { "Protected Content" }
    }
}
#[component]
fn HistoryControls() -> Element {
    let navigator = use_navigator();
    
    rsx! {
        div { class: "history-controls",
            button {
                disabled: !navigator.can_go_back(),
                onclick: move |_| navigator.go_back(),
                "← Back"
            }
            button {
                disabled: !navigator.can_go_forward(),
                onclick: move |_| navigator.go_forward(),
                "Forward →"
            }
        }
    }
}
#[component]
fn UnsavedChanges() -> Element {
    let navigator = use_navigator();
    let has_unsaved_changes = use_signal(|| true);
    
    let navigate_away = move |_| {
        if has_unsaved_changes() {
            let confirmed = web_sys::window()
                .unwrap()
                .confirm_with_message("You have unsaved changes. Leave anyway?")
                .unwrap();
            
            if confirmed {
                navigator.push(Route::Home {});
            }
        } else {
            navigator.push(Route::Home {});
        }
    };
    
    rsx! {
        button { onclick: navigate_away, "Leave Page" }
    }
}

Redirect After Timeout

#[component]
fn SuccessMessage() -> Element {
    let navigator = use_navigator();
    
    use_effect(move || {
        spawn(async move {
            tokio::time::sleep(Duration::from_secs(3)).await;
            navigator.push(Route::Home {});
        });
    });
    
    rsx! {
        div { class: "success",
            "Success! Redirecting..."
        }
    }
}
The following types can be converted into NavigationTarget:
  • Route enum variants: Route::Home {}
  • String slices: "/about"
  • Strings: String::from("/about")
  • External URLs: "https://example.com"
// All of these work:
navigator.push(Route::Home {});
navigator.push("/about");
navigator.push(String::from("/contact"));
navigator.push("https://dioxuslabs.com");

Error Handling

External navigation may fail if the history provider doesn’t support it:
let navigator = use_navigator();

if let Some(error) = navigator.push("https://example.com") {
    println!("External navigation failed: {:?}", error);
}

Source

View the source code: packages/router/src/contexts/navigator.rs

Build docs developers (and LLMs) love