{"record":{"id":"d06b5b04c8bbe646","repo":"yewstack/yew","slug":"no-body-node-found","errorCode":null,"errorMessage":"no body node found","messagePattern":"no body node found","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/yew/src/renderer.rs","lineNumber":80,"sourceCode":"        Self::default()\n    }\n\n    /// Creates a [Renderer] that renders into a custom root with default properties.\n    pub fn with_root(root: Element) -> Self {\n        Self::with_root_and_props(root, Default::default())\n    }\n}\n\nimpl<COMP> Renderer<COMP>\nwhere\n    COMP: BaseComponent + 'static,\n{\n    /// Creates a [Renderer] that renders into the document body with custom properties.\n    pub fn with_props(props: COMP::Properties) -> Self {\n        Self::with_root_and_props(\n            gloo::utils::document()\n                .body()\n                .expect(\"no body node found\")\n                .into(),\n            props,\n        )\n    }\n\n    /// Creates a [Renderer] that renders into a custom root with custom properties.\n    pub fn with_root_and_props(root: Element, props: COMP::Properties) -> Self {\n        Self { root, props }\n    }\n\n    /// Renders the application.\n    pub fn render(self) -> AppHandle<COMP> {\n        set_default_panic_hook();\n        AppHandle::<COMP>::mount_with_props(self.root, Rc::new(self.props))\n    }\n}\n\n#[cfg(feature = \"hydration\")]","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/yewstack/yew/blob/0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3/packages/yew/src/renderer.rs#L62-L98","documentation":"Renderer::new()/with_props defaults to mounting into gloo::utils::document().body(); this expect fires when document.body is null at the moment the Renderer is constructed. That means the entry code ran before the HTML body was parsed, or executes in an environment that simply has no body element. It is a bootstrap-order problem, not a rendering failure.","triggerScenarios":"Constructing Renderer inside #[wasm_bindgen(start)] or module-level code while the script loads in <head> without defer (body not yet parsed); running the CSR entry in a DOM host without a body element (bare test harnesses, workers).","commonSituations":"Bundler or framework templates that move the script into <head>; removing defer/type=module attributes; hydration entries that run during initial parse; headless tests using minimal document fixtures.","solutions":["Add defer to the script tag, or move it to the end of <body>","Defer construction and render until DOMContentLoaded fires","Mount into an explicit existing element with Renderer::with_root(document().get_element_by_id(\"app\").unwrap())","In tests, make sure the harness document actually contains a <body>"],"exampleFix":"// before: runs immediately; if the script is in <head>, body does not exist yet\n#[wasm_bindgen(start)]\nfn start() {\n    yew::Renderer::<App>::new().render();\n}\n\n// after: mount into a known element, with the script deferred or at the end of <body>\n#[wasm_bindgen(start)]\nfn start() {\n    let root = gloo::utils::document()\n        .get_element_by_id(\"app\")\n        .expect(\"missing #app mount point\");\n    yew::Renderer::<App>::with_root(root).render();\n}","handlingStrategy":"validation","validationCode":"// Guard before constructing the default Renderer:\nmatch gloo::utils::document().body() {\n    Some(_) => yew::Renderer::<App>::new().render(),\n    None => {\n        // body not parsed yet - defer or fail with a clear message\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Load the bundle with defer or place the script at the end of <body>","Prefer an explicit mount element via Renderer::with_root","In tests, ensure the DOM fixture includes a <body> element"],"tags":["bootstrap","renderer","dom","wasm"],"backgroundTag":"dom-not-ready","analyzedSha":"0e4a05472fac4e5fce1befe60fa4a1e43a36b6a3","analyzedAt":"2026-08-22T21:16:31.212Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}