DioxusLabs/dioxus · error

Outlet must be inside of a router

Error message

Outlet must be inside of a router

What it means

Outlet renders the next nested route level by reading the router context via use_router_internal(). With no Router component among the ancestors the context is missing and the expect panics — Outlet only works inside a Router's route tree where a RouterContext has been provided.

Source

Thrown at packages/router/src/contexts/outlet.rs:45

    /// Creates a new outlet context for the next nesting level
    pub fn next(&self) -> Self {
        Self {
            current_level: self.current_level + 1,
            _marker: std::marker::PhantomData,
        }
    }

    /// Returns the current nesting level of this outlet
    pub fn level(&self) -> usize {
        self.current_level
    }

    pub(crate) fn render() -> Element
    where
        R: Routable + Clone,
    {
        let router = use_router_internal().expect("Outlet must be inside of a router");
        let outlet: OutletContext<R> = use_outlet_context();
        let current_level = outlet.level();
        provide_context(outlet.next());

        if let Some(error) = router.render_error() {
            return if current_level == 0 {
                error
            } else {
                VNode::empty()
            };
        }

        router.current::<R>().render(current_level)
    }
}

/// Returns the current outlet context from the component hierarchy.
///

View on GitHub (pinned to 393d190a80)

Solutions

  1. Render route components only inside Router::<Route> {} so every Outlet has the router context
  2. Replace misused Outlet with regular nested components for non-routed composition
  3. In previews/tests, wrap the component in a Router with a minimal Routable enum

Example fix

// before (App without router)
rsx! { SomeLayout {} } // SomeLayout contains Outlet -> panics
// after
rsx! { Router::<Route> {} } // layouts render under the router's route tree
Defensive patterns

Strategy: validation

Validate before calling

// Only render Outlet-bearing layouts as part of a route tree:
#[derive(Clone, Routable)]
enum Route {
    #[layout(ShellLayout)] // ShellLayout contains Outlet
    #[route("/")]
    Home {},
}
// root: rsx! { Router::<Route> {} }

Prevention

When it happens

Trigger: Rendering an Outlet in a plain component that is not part of a #[derive(Routable)] route tree: using Outlet for arbitrary composition without a Router, or mounting a route-layout component (which contains Outlet) outside Router.

Common situations: Extracting a route layout into a shared component and reusing it on a non-routed page; previewing or unit-testing route components in isolation; copying Outlet usage into a standalone library example.

Related errors


AI-assisted analysis of DioxusLabs/dioxus@393d190a80 (2026-08-16). Data as JSON: /api/errors/59306dce60c814d9. Report an issue: GitHub.