Rendering Failures
Overview
Rendering failures occur when RndrKit's Puppeteer-based renderer cannot produce a valid HTML snapshot of your page. This guide covers the most common causes and how to fix them.
Quick Diagnosis
Test your page rendering by simulating a bot request:
# Fetch the pre-rendered version
curl -s -A "Googlebot/2.1" "https://www.example.com/page" | head -50
Expected: Full HTML with your page content, meta tags, and structured data.
Problem signs:
- Empty or near-empty HTML (just a
<div id="root"></div>) - Error page HTML
- Timeout or connection error
- Very small response size (under 1KB)
Common Issues
Blank or Empty Pages
Symptom: The pre-rendered HTML contains only the SPA shell with no content.
Possible causes:
-
JavaScript errors preventing render. Your application has a runtime error that stops content from rendering.
Diagnosis: Open your site in a browser and check the console for errors.
Fix: Fix the JavaScript errors in your application code. Common issues include:
- Missing environment variables that exist in your dev environment but not in production
- API calls failing due to CORS or network issues
- Missing dependencies or import errors
-
Content loads asynchronously after the render window. The renderer waits for network idle, but your content may load after an unusually long delay.
Diagnosis: Check the render time in your analytics. If renders are hitting the timeout (30 seconds), your page is taking too long.
Fix: Optimize your application to load critical content faster. Reduce API call chains and avoid waterfalls where one request depends on another.
-
Content requires user interaction. Some SPAs require a click, scroll, or other interaction to load content.
Fix: Ensure your page renders visible content on initial load without user interaction.
Render Timeout
Symptom: Renders take 30+ seconds and fail, or the pre-rendered HTML is incomplete.
Possible causes:
-
Slow API responses. Your application makes API calls during rendering, and those APIs are slow.
Fix: Optimize your backend APIs for faster response times, or implement loading states that show content even before all data is loaded.
-
Infinite loading states. Your application shows a spinner or skeleton that never resolves because an API call fails silently.
Fix: Add error handling for API calls. Show fallback content when APIs fail instead of spinning indefinitely.
-
Heavy asset loading. Large images, videos, or third-party scripts slow down the page.
Fix: Use lazy loading for below-the-fold images and defer non-critical scripts.
Authentication Walls
Symptom: The pre-rendered page shows a login screen instead of the actual content.
Cause: Your application requires authentication, and the Puppeteer renderer does not have valid session cookies.
Fix: Ensure your public pages are accessible without authentication. If your SPA checks for auth state on every page, make sure unauthenticated users see the public content rather than a redirect to a login page.
CORS Errors
Symptom: Page renders but is missing data that comes from API calls.
Cause: The Puppeteer renderer makes requests from RndrKit's server IP, which may not be in your API's CORS allowed origins list.
Fix: If your SPA makes client-side API calls during rendering, ensure your API accepts requests from the rendered page's origin. Since Puppeteer loads the page as if it were a browser, CORS rules apply.
Client-Side Routing Not Working
Symptom: Only the homepage renders correctly. Other pages show the homepage content or a 404.
Cause: Your origin server is not configured to handle client-side routing. When Puppeteer navigates to /about, the origin returns a 404 instead of the SPA shell that would handle the route client-side.
Fix: Configure your origin server to serve index.html for all routes (a "catch-all" or "fallback" route):
- Netlify: Add a
_redirectsfile:/* /index.html 200 - Vercel: Add a
vercel.jsonrewrite rule - Nginx: Use
try_files $uri $uri/ /index.html - Lovable/Bolt: This is typically handled automatically
Third-Party Script Issues
Symptom: Pages render but are missing certain widgets, embeds, or third-party content.
Cause: Some third-party scripts detect headless browsers and refuse to load, or they require user interaction.
Common offenders:
- Chat widgets (Intercom, Drift, etc.)
- Google Maps embeds
- reCAPTCHA widgets
- Social media embeds
Fix: These elements are typically not important for SEO. The page will still render correctly for search engines without chat widgets or map embeds. If you need specific third-party content indexed, ensure it is rendered server-side or included in your HTML directly.
Debugging Steps
Step 1: Compare Bot vs. Human Response
# Bot response (pre-rendered)
curl -s -A "Googlebot/2.1" "https://www.example.com/page" > bot.html
# Human response (origin)
curl -s "https://www.example.com/page" > human.html
# Compare sizes
wc -c bot.html human.html
The bot response should be significantly larger than the human response (since it includes rendered content vs. a minimal SPA shell).
Step 2: Check Render Logs
Go to your domain's Analytics tab in the dashboard. Look at the render logs for the affected page:
- Cache status: Is it HIT or MISS?
- Render time: Is it taking longer than expected?
- Error status: Are there any error entries?
Step 3: Purge and Re-render
Clear the cached version and trigger a fresh render:
- Purge the cache for the affected page.
- Request the page again as a bot:
curl -s -A "Googlebot/2.1" "https://www.example.com/page" > fresh-render.html
- Inspect the fresh render to see if the issue persists.
Step 4: Test the Origin
Verify your origin is responding correctly:
curl -s -I "https://your-origin.lovable.app/page"
If the origin is down or returning errors, the renderer cannot produce a valid render.
Next Steps
- DNS Issues -- Fix DNS-related problems
- SSL Problems -- Resolve SSL certificate issues
- Rendering Pipeline -- Understand how rendering works
- Cache Management -- Purge and re-render pages