Routing

    use vertigo::{dom, router::Router};

    #[derive(Clone, PartialEq)]
    enum Route {
        Main,
        Post(String),
        NotFound(String),
    }

    impl std::fmt::Display for Route {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            match self {
                Route::Main => write!(f, "/main"),
                Route::Post(slug) => write!(f, "/post/{slug}"),
                Route::NotFound(x) => write!(f, "{x}"),
            }
        }
    }

    impl From<String> for Route {
        fn from(value: String) -> Self {
            if value == "/main" {
                return Self::Main;
            } else if value.starts_with("/post") {
                if let Some(slug) = value.split('/').nth(1) {
                    return Self::Post(slug.to_string());
                }
            }
            Self::NotFound(value)
        }
    }

    let routing = Router::new_history_router();

    let page = routing.route.render_value(|route| match route {
        Route::Main => dom! { <main>"Main Page"</main> },
        Route::Post(slug) => dom! { <main>"Post with slug " {slug}</main> },
        Route::NotFound(path) => dom! { <main>"Page " {path} " not found"</main> },
    });

    dom! {
        <div>
            {page}
        </div>
    }

Matching against current route

    use vertigo::{Computed, dom, router::Router};

    #[derive(Clone, PartialEq)]
    enum Route {
        Main,
        Post(String),
        NotFound(String),
    }

    impl Route {
        pub fn matches(self, current: &Computed<Self>) -> Computed<bool> {
            current.map(move |current| self == current)
        }
    }

    impl std::fmt::Display for Route {
        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
            match self {
                Route::Main => write!(f, "/main"),
                Route::Post(slug) => write!(f, "/post/{slug}"),
                Route::NotFound(x) => write!(f, "{x}"),
            }
        }
    }

    impl From<String> for Route {
        fn from(value: String) -> Self {
            if value == "/main" {
                return Self::Main;
            } else if value.starts_with("/post") {
                if let Some(slug) = value.split('/').nth(1) {
                    return Self::Post(slug.to_string());
                }
            }
            Self::NotFound(value)
        }
    }

    let routing = Router::new_history_router();

    // Will generate Some(<p>) only if Main is the current route.
    let main_page_info = Route::Main.matches(&routing.route)
        .render_value_option(|is_active|
            is_active.then(|| dom! { <p>"You're in the main menu!"</p> })
        );

    let page = routing.route.render_value(|route| match route {
        Route::Main => dom! { <main>"Main Page"</main> },
        Route::Post(slug) => dom! { <main>"Post with slug " {slug}</main> },
        Route::NotFound(path) => dom! { <main>"Page " {path} " not found"</main> },
    });

    dom! {
        <div>
            {main_page_info}
            {page}
        </div>
    }