diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md index 716f0ee..8044e26 100644 --- a/REQUIREMENTS.md +++ b/REQUIREMENTS.md @@ -121,7 +121,7 @@ slhx competes with React by making frontend frameworks unnecessary for most apps ## page_swap ### req: page_swap/001 -001 Minimal page swapping is a first-class slhx-axum happy path. Authors mark real anchors with `data-slhx-nav`; links keep valid `href` and work without JS. Missing `href` on a static `data-slhx-nav` anchor is a build error. +001 Minimal page swapping is a first-class slhx-axum happy path. Authors mark real anchors with `data-slhx-nav`; links keep valid `href` and work without JS. Missing or empty static `href` on a `data-slhx-nav` anchor is a build error. ### req: page_swap/002 002 A `data-slhx-nav` click fetches the target URL as a slhx partial request. The response updates the canonical content slot, optionally navigation and title, then applies a `Navigate` effect. diff --git a/slhx-build/src/lib.rs b/slhx-build/src/lib.rs index f1200d6..3c27714 100644 --- a/slhx-build/src/lib.rs +++ b/slhx-build/src/lib.rs @@ -1067,7 +1067,9 @@ fn reject_invalid_slhx_attr_values(path: &Path, attrs: &[SurfaceAttribute]) -> i } fn reject_invalid_slhx_attr_placement(path: &Path, tag: &str, attrs: &[SurfaceAttribute]) -> io::Result<()> { - if has_attr(attrs, "data-slhx-nav") && (tag != "a" || !has_attr(attrs, "href")) { + if has_attr(attrs, "data-slhx-nav") + && (tag != "a" || !has_attr(attrs, "href") || static_attr(attrs, "href").is_some_and(|href| href.trim().is_empty())) + { return Err(invalid_slhx_placement( path, "data-slhx-nav", @@ -1665,6 +1667,12 @@ fn main() {{ "data-slhx-nav", "", ), + ( + "nav-empty-href", + r#"Docs"#, + "data-slhx-nav", + "", + ), ( "boost-anchor", r#"Docs"#,