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:

  1. 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
  2. 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.

  3. 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:

  1. 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.

  2. 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.

  3. 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 _redirects file: /* /index.html 200
  • Vercel: Add a vercel.json rewrite 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:

  1. Purge the cache for the affected page.
  2. Request the page again as a bot:
curl -s -A "Googlebot/2.1" "https://www.example.com/page" > fresh-render.html
  1. 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