{"record":{"id":"1cdb63b7eb2976f7","repo":"unclecode/crawl4ai","slug":"body-element-is-hidden-visibility-info","errorCode":null,"errorMessage":"Body element is hidden: {visibility_info}","messagePattern":"Body element is hidden: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"crawl4ai/async_crawler_strategy.py","lineNumber":844,"sourceCode":"                    timeout=30000,\n                )\n\n                if not is_visible and not config.ignore_body_visibility:\n                    visibility_info = await self.check_visibility(page)\n                    raise Error(f\"Body element is hidden: {visibility_info}\")\n\n            except Error:\n                visibility_info = await self.check_visibility(page)\n\n                if self.browser_config.verbose:\n                    self.logger.debug(\n                        message=\"Body visibility info: {info}\",\n                        tag=\"DEBUG\",\n                        params={\"info\": visibility_info},\n                    )\n\n                if not config.ignore_body_visibility:\n                    raise Error(f\"Body element is hidden: {visibility_info}\")\n\n            # try:\n            #     await page.wait_for_selector(\"body\", state=\"attached\", timeout=30000)\n\n            #     await page.wait_for_function(\n            #         \"\"\"\n            #         () => {\n            #             const body = document.body;\n            #             const style = window.getComputedStyle(body);\n            #             return style.display !== 'none' &&\n            #                 style.visibility !== 'hidden' &&\n            #                 style.opacity !== '0';\n            #         }\n            #     \"\"\",\n            #         timeout=30000,\n            #     )\n            # except Error as e:\n            #     visibility_info = await page.evaluate(","sourceCodeStart":826,"sourceCodeEnd":862,"githubUrl":"https://github.com/unclecode/crawl4ai/blob/7e801521428ee12509994d39151006f64055ebe3/crawl4ai/async_crawler_strategy.py#L826-L862","documentation":"Raised when the crawled page's <body> element is detected as hidden (display:none, visibility:hidden, opacity:0, or zero size) after the Playwright wait_for_selector on body times out or errors. The visibility details from check_visibility(page) are embedded in the message. It is skipped entirely when config.ignore_body_visibility is true.","triggerScenarios":"Pages that keep body hidden until JS runs (loading screens, cookie walls, SPA shells, geo-block pages, pages that render only after user interaction). Also pages where an overlay CSS hides body, or where content is inside frames/containers while body itself never becomes visible.","commonSituations":"SPAs (React/Vue/Angular) with slow hydration hiding body behind a loader; sites that block bots by leaving body hidden; pages requiring cookies/login before revealing content; headless-mode-specific CSS (some sites hide body for headless user agents).","solutions":["Set CrawlerRunConfig(ignore_body_visibility=True) when the target is known to hide body initially.","Add wait_for / js_code to wait until the app finishes rendering (e.g. wait for a specific selector) before visibility is checked.","Increase page_timeout so hydration completes; use wait_until='networkidle' or 'domcontentloaded' as appropriate.","If the site blocks headless browsers, adjust the user agent or use an appropriate adapter."],"exampleFix":"// before\ncfg = CrawlerRunConfig()\nresult = await crawler.arun(url=spa_url, config=cfg)\n\n// after\ncfg = CrawlerRunConfig(\n    ignore_body_visibility=True,\n    wait_for=\"css:.app-root[data-ready='true']\",\n)\nresult = await crawler.arun(url=spa_url, config=cfg)","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    result = await crawler.arun(url, config=cfg)\nexcept Exception as e:\n    if \"Body element is hidden\" in str(e):\n        cfg2 = CrawlerRunConfig(**{**cfg.__dict__, \"ignore_body_visibility\": True})\n        result = await crawler.arun(url, config=cfg2)","preventionTips":["Set ignore_body_visibility=True for known SPAs","Use wait_for to wait for real content selectors","Prefer wait_until='networkidle' for hydration-heavy apps"],"tags":["visibility","spa","playwright","rendering"],"backgroundTag":null,"analyzedSha":"7e801521428ee12509994d39151006f64055ebe3","analyzedAt":"2026-08-14T20:46:20.673Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}