use std::sync::Arc; use axum::body::Body; use axum::extract::Request; use axum::http::header; use axum::middleware::Next; use axum::response::Response; use crate::state::AppState; const OG_PLACEHOLDER: &str = r#""#; pub async fn og_middleware(request: Request, next: Next) -> Response { let path = request.uri().path().to_string(); // Capture the query string before passing the request through let query_string = request.uri().query().unwrap_or("").to_string(); // Get state from extensions let state = request.extensions().get::>().cloned(); let response = next.run(request).await; // Only inject OG tags into SPA HTML responses, not proxied PocketBase responses if path.starts_with("/pb/") || path.starts_with("/api/") { return response; } let content_type = response .headers() .get(header::CONTENT_TYPE) .and_then(|val| val.to_str().ok()) .unwrap_or(""); if !content_type.contains("text/html") { return response; } let state = match state { Some(st) => st, None => return response, }; let index_html = match &state.index_html { Some(html) => html, None => return response, }; // Build OG-injected HTML (og=1 triggers heading overlay on screenshot) let is_invite = path.starts_with("/invite/"); let og_image_url = if is_invite { // Include path= so the screenshot service navigates to /invite/CODE if query_string.is_empty() { format!("{}/api/screenshot?og=1&path={}", state.public_url, path) } else { format!( "{}/api/screenshot?og=1&path={}&{}", state.public_url, path, query_string ) } } else if query_string.is_empty() { format!("{}/api/screenshot?og=1", state.public_url) } else { format!("{}/api/screenshot?og=1&{}", state.public_url, query_string) }; let og_url = if query_string.is_empty() { format!("{}{}", state.public_url, path) } else { format!("{}{}?{}", state.public_url, path, query_string) }; let og_logo = format!("{}/favicon.svg", state.public_url); let (og_title, og_description) = if is_invite { ( "You\u{2019}re invited to Perfect Postcode", "Accept your invitation to explore property prices, energy ratings, crime stats, school ratings, and more across England.", ) } else { ( "Perfect Postcode \u{2014} Every neighbourhood in England", "Explore property prices, energy ratings, crime stats, school ratings, and more across England on one interactive map.", ) }; let og_tags = format!( r#" "# ); let html = index_html.replace(OG_PLACEHOLDER, &og_tags); let (parts, _body) = response.into_parts(); Response::from_parts(parts, Body::from(html)) }