{"record":{"id":"64952a1f3f058d0c","repo":"leptos-rs/leptos","slug":"there-to-be-a-body-element","errorCode":null,"errorMessage":"there to be a <body> element","messagePattern":"there to be a <body> element","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"meta/src/body.rs","lineNumber":70,"sourceCode":"struct BodyView<At> {\n    attributes: At,\n}\n\nstruct BodyViewState<At>\nwhere\n    At: Attribute,\n{\n    attributes: At::State,\n}\n\nimpl<At> Render for BodyView<At>\nwhere\n    At: Attribute,\n{\n    type State = BodyViewState<At>;\n\n    fn build(self) -> Self::State {\n        let el = document().body().expect(\"there to be a <body> element\");\n        let attributes = self.attributes.build(&el);\n\n        BodyViewState { attributes }\n    }\n\n    fn rebuild(self, state: &mut Self::State) {\n        self.attributes.rebuild(&mut state.attributes);\n    }\n}\n\nimpl<At> AddAnyAttr for BodyView<At>\nwhere\n    At: Attribute,\n{\n    type Output<SomeNewAttr: Attribute> =\n        BodyView<<At as NextAttribute>::Output<SomeNewAttr>>;\n\n    fn add_any_attr<NewAttr: Attribute>(","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/leptos-rs/leptos/blob/32d20f6c9d517451d77beb68d88c7716823dac41/meta/src/body.rs#L52-L88","documentation":"Leptos' <body> meta component (tachys RenderHtml impl) builds by fetching document().body() via web_sys. In a non-DOM or pre-DOM environment this is None, and expect('there to be a <body> element') panics. The library assumes the code runs in a browser after the document body exists.","triggerScenarios":"Calling .build() on leptos::prelude::Body (the <body> meta wrapper) when document().body() returns None — e.g. running in SSR/non-wasm stub, or executing before the HTML <body> tag has been parsed.","commonSituations":"Unit tests running wasm-dependent code without a DOM; scripts injected into <head> that run before <body> exists; executing hydration/mount logic inside a worker or server target.","solutions":["Ensure the code only runs in a browser context after the DOM is ready (e.g. inside on_mount or after DOMContentLoaded).","Guard with a check: if document().body().is_none() return early instead of building the Body component.","For tests, run in a wasm browser test harness (wasm-bindgen-test) rather than native cargo test."],"exampleFix":"// before\nlet body = document().body().expect(\"there to be a <body> element\");\n// after\nlet Some(body) = document().body() else { return; };","handlingStrategy":"validation","validationCode":"use wasm_bindgen::JsCast;\nfn has_body() -> bool {\n    web_sys::window().map(|w| w.document()).flatten()\n        .map(|d| d.body().is_some())\n        .unwrap_or(false)\n}","typeGuard":"fn get_body() -> Option<web_sys::HtmlElement> {\n    web_sys::window()?.document()?.body()\n}","tryCatchPattern":"// leptos panics are not catchable; check before mounting\nif has_body() {\n    mount_to_body(App);\n} else {\n    leptos::logging::error!(\"document body not available\");\n}","preventionTips":["Mount only after DOMContentLoaded or from a script at end of <body>","Never run DOM-dependent code in SSR or worker targets unguarded","Use cfg(target_arch = \"wasm32\") gates for browser-only code paths"],"tags":["leptos","wasm","dom","browser"],"backgroundTag":"missing-body-element","analyzedSha":"32d20f6c9d517451d77beb68d88c7716823dac41","analyzedAt":"2026-09-01T18:55:42.580Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}