Capturing SPAs: waitFor Strategies for React, Vue, and Svelte
Single-page apps render content after the initial HTML loads. A screenshot taken too early captures a loading spinner or an empty container. The fix is telling the browser to wait for the right signal before the shutter fires.
How wait strategies work
Two parameters control the wait:
-
waitUntil— a network or lifecycle event:"load","domcontentloaded","networkidle0", or"networkidle2"(default) -
waitForSelector— a CSS selector that appears when the content you care about is ready
React
Add a marker element that renders after the app mounts:
// App.tsx
import { useEffect, useState } from "react"
export default function App() {
const [mounted, setMounted] = useState(false)
useEffect(() => {
setMounted(true)
}, [])
return (
<>
{mounted && <div id="app-loaded" style={{ display: "none" }} />}
{/* rest of your app */}
</>
)
}
// capture.ts
import { Rendex } from "@copperline/rendex"
const rendex = new Rendex(process.env.RENDEX_API_KEY!)
const result = await rendex.screenshot({
url: "https://myapp.example.com",
waitForSelector: "#app-loaded",
waitUntil: "domcontentloaded",
fullPage: true,
})
Vue 3
<!-- App.vue -->
<script setup>
import { ref, onMounted } from "vue"
const isReady = ref(false)
onMounted(() => { isReady.value = true })
</script>
<template>
<div v-if="isReady" id="vue-ready" style="display:none" />
</template>
const result = await rendex.screenshot({
url: "https://vueapp.example.com",
waitForSelector: "#vue-ready",
waitUntil: "domcontentloaded",
fullPage: true,
})
Svelte
For most Svelte apps, networkidle0 is sufficient:
const result = await rendex.screenshot({
url: "https://svelteapp.example.com",
waitUntil: "networkidle0",
fullPage: true,
})
Troubleshooting
Selector never appears and capture times out. Validate in DevTools with document.querySelector('#your-selector'). If it returns null, the element does not exist.
Partial render even with selector. The selector appeared but assets had not loaded. Add a delay in milliseconds or wait for a more specific element.
networkidle0 times out. The page has long-polling or WebSocket connections. Switch to "networkidle2" or use waitForSelector instead.
Next steps
- Python screenshot guide — same wait params with the Python SDK
- API reference — full parameter list
- Free screenshot tool — test selectors against a live URL
Get a free API key and start with 100 captures per month.
Top comments (0)