diff --git a/src/controllers/shop.rs b/src/controllers/shop.rs index 8d7efc5..f9f35cf 100644 --- a/src/controllers/shop.rs +++ b/src/controllers/shop.rs @@ -347,8 +347,10 @@ async fn index( /// ([`products::Entity::search`]) with category, price-band, in-stock and sort /// filters, ranked and paginated by [`run_search`]. A blank query falls back to /// the full published listing, so the same endpoint powers both "browse" and -/// "search". htmx requests get just the results fragment (for live updates); -/// direct navigation (or no-JS) renders the whole page. +/// "search". Targeted htmx requests from the listing toolbar/pagination get just +/// the results fragment (for live updates); direct navigation, no-JS, and boosted +/// navigations (e.g. submitting the header search box, which hx-boost turns into +/// an AJAX nav) render the whole eshop page. #[debug_handler] async fn search( jar: CookieJar, @@ -362,7 +364,11 @@ async fn search( let mut context = run_search(&ctx, user.as_ref(), ¶ms, &cur).await?; let lang = current_lang(&jar); - if headers.contains_key("HX-Request") { + // A boosted request (the header search form, links) replaces the whole body, + // so it needs the full page — only the toolbar's own targeted hx-get requests + // (HX-Request without HX-Boosted) want the bare results fragment. + let fragment = headers.contains_key("HX-Request") && !headers.contains_key("HX-Boosted"); + if fragment { if let Some(map) = context.as_object_mut() { map.insert("lang".into(), json!(lang)); }