Skip to main content

Node.js Examples

Copy-paste ready examples for common use cases with the Browser7 Node.js SDK.

Basic Examples

Simple Page Render

The most basic example - render a page and get the HTML:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function basicRender() {
const result = await client.render('https://example.com');

console.log('Status:', result.status);
console.log('HTML length:', result.html.length);
console.log('City:', result.selectedCity.displayName);

return result.html;
}

basicRender();

Geo-Targeted Render

Render a page from a specific country:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function geoTargetedRender() {
// Render from United States
const result = await client.render('https://example.com', {
countryCode: 'US'
});

console.log(`Rendered from: ${result.selectedCity.displayName}, ${result.selectedCity.name}`);
console.log(`Coordinates: ${result.selectedCity.latitude}, ${result.selectedCity.longitude}`);
console.log(`Timezone: ${result.selectedCity.timezoneId}`);

return result.html;
}

geoTargetedRender();

Specific City Render

Target a specific city within a country:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function cityTargetedRender() {
// Render from London, UK
const result = await client.render('https://example.com', {
countryCode: 'GB',
city: 'london'
});

console.log(`Rendered from: ${result.selectedCity.displayName}`);
console.log(`Timezone: ${result.selectedCity.timezoneId}`);

return result.html;
}

cityTargetedRender();

Capture Screenshot

Capture and save a screenshot of the rendered page:

import Browser7 from 'browser7';
import fs from 'fs';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function captureScreenshot() {
const result = await client.render('https://example.com', {
countryCode: 'US',
includeScreenshot: true,
screenshotFormat: 'jpeg',
screenshotQuality: 80,
screenshotFullPage: false // Viewport only
});

// Save screenshot to file
const buffer = Buffer.from(result.screenshot, 'base64');
fs.writeFileSync('screenshot.jpg', buffer);

console.log('Screenshot saved to screenshot.jpg');
console.log('HTML length:', result.html.length);

return result;
}

captureScreenshot();

Full Page Screenshot

Capture a screenshot of the entire scrollable page:

import Browser7 from 'browser7';
import fs from 'fs';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function fullPageScreenshot() {
const result = await client.render('https://example.com/long-article', {
includeScreenshot: true,
screenshotFormat: 'png', // PNG for higher quality
screenshotFullPage: true // Capture entire page
});

const buffer = Buffer.from(result.screenshot, 'base64');
fs.writeFileSync('fullpage.png', buffer);

console.log('Full page screenshot saved');
console.log('File size:', Math.round(buffer.length / 1024), 'KB');

return result;
}

fullPageScreenshot();

Wait Actions

Wait for Element

Wait for a specific element to appear before capturing:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function waitForElement() {
const result = await client.render('https://example.com', {
countryCode: 'US',
waitFor: [
Browser7.waitForSelector('.main-content', 'visible', 10000)
]
});

console.log('Element loaded successfully');
return result.html;
}

waitForElement();

Dismiss a cookie consent banner before capturing:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function dismissCookieBanner() {
const result = await client.render('https://example.com', {
waitFor: [
// Wait for cookie banner to appear
Browser7.waitForSelector('.cookie-banner', 'visible', 5000),
// Click the accept button
Browser7.waitForClick('.cookie-accept', 5000),
// Wait for banner to disappear
Browser7.waitForSelector('.cookie-banner', 'hidden', 5000)
]
});

console.log('Cookie banner dismissed');
return result.html;
}

dismissCookieBanner();

Wait for Text Content

Wait for specific text to appear on the page:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function waitForTextContent() {
const result = await client.render('https://shop.example.com/product', {
waitFor: [
// Wait for "In Stock" text to appear in the availability section
Browser7.waitForText('In Stock', '.product-availability', 15000)
]
});

console.log('Product is in stock');
return result.html;
}

waitForTextContent();

Multiple Wait Actions

Combine multiple wait actions for complex interactions:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function complexWaitSequence() {
const result = await client.render('https://example.com', {
countryCode: 'US',
waitFor: [
// 1. Click cookie accept button
Browser7.waitForClick('.cookie-accept', 5000),
// 2. Wait for main content to load
Browser7.waitForSelector('.main-content', 'visible', 10000),
// 3. Click "Load More" button
Browser7.waitForClick('.load-more-btn', 5000),
// 4. Wait for additional content
Browser7.waitForText('Showing all items', '.results-info', 10000),
// 5. Give page time to stabilize
Browser7.waitForDelay(2000)
]
});

console.log('Complex interaction sequence completed');
return result.html;
}

complexWaitSequence();

Wait with Timeout Handling

Handle cases where elements might not appear:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function waitWithFallback() {
try {
const result = await client.render('https://example.com', {
waitFor: [
// Try to click popup close button (might not exist)
Browser7.waitForClick('.popup-close', 3000)
]
});

console.log('Popup was closed');
return result.html;
} catch (error) {
if (error.message.includes('Render failed')) {
console.log('Popup not found or timeout - this is okay');
// Retry without the wait action
const result = await client.render('https://example.com');
return result.html;
}
throw error;
}
}

waitWithFallback();

CAPTCHA Solving

Auto-Detect CAPTCHA

Let Browser7 automatically detect and solve any CAPTCHA type:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function autoSolveCaptcha() {
const result = await client.render('https://protected-site.com', {
countryCode: 'US',
captcha: 'auto' // Auto-detect and solve any CAPTCHA
});

console.log('CAPTCHA detected:', result.captcha.detected);
console.log('CAPTCHA solved:', result.captcha.handled);

if (result.captcha.handled) {
console.log('Successfully bypassed CAPTCHA!');
}

return result.html;
}

autoSolveCaptcha();

Solve Specific CAPTCHA Type

Target a specific CAPTCHA type for faster solving:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function solveRecaptchaV2() {
const result = await client.render('https://site-with-recaptcha.com', {
countryCode: 'US',
captcha: 'recaptcha_v2' // Specifically solve reCAPTCHA v2
});

console.log('reCAPTCHA v2 handling:', result.captcha);
return result.html;
}

async function solveTurnstile() {
const result = await client.render('https://site-with-turnstile.com', {
captcha: 'turnstile' // Cloudflare Turnstile
});

console.log('Turnstile handling:', result.captcha);
return result.html;
}

solveRecaptchaV2();

Two-Step CAPTCHA Detection

First render without CAPTCHA solving, then retry if needed:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function smartCaptchaHandling(url) {
// First attempt: No CAPTCHA solving (faster and cheaper)
console.log('Attempting render without CAPTCHA solving...');
let result = await client.render(url, {
countryCode: 'US',
captcha: 'disabled' // Default, but explicit here
});

// Check if HTML contains CAPTCHA indicators
const hasCaptcha = result.html.includes('captcha') ||
result.html.includes('challenge') ||
result.html.includes('g-recaptcha');

if (hasCaptcha) {
console.log('CAPTCHA detected in HTML, retrying with solver...');
result = await client.render(url, {
countryCode: 'US',
captcha: 'auto' // Now solve the CAPTCHA
});
console.log('CAPTCHA solved:', result.captcha.handled);
} else {
console.log('No CAPTCHA detected - we saved some time and money!');
}

return result.html;
}

smartCaptchaHandling('https://example.com');

Advanced Usage

Error Handling & Retries

Robust error handling with automatic retries:

import Browser7, { AuthenticationError, ValidationError, RateLimitError, RenderError } from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function renderWithRetries(url, options = {}, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
console.log(`Attempt ${attempt}/${maxRetries}...`);

const result = await client.render(url, options);

console.log('✅ Success!');
return result;

} catch (error) {
console.error(`❌ Attempt ${attempt} failed:`, error.message);

// Don't retry non-retriable errors
if (error instanceof AuthenticationError || error instanceof ValidationError) {
throw error; // Fix the root cause, don't retry
}

if (attempt === maxRetries) {
throw error;
}

// Exponential backoff for retriable errors
const delay = Math.pow(2, attempt) * 1000;
console.log(`Waiting ${delay}ms before retry...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}

// Usage
renderWithRetries('https://example.com', {
countryCode: 'US',
waitFor: [Browser7.waitForSelector('.content', 'visible')]
});

Progress Tracking

Monitor render progress with detailed callbacks:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function renderWithProgress() {
const startTime = Date.now();

const result = await client.render(
'https://example.com',
{ countryCode: 'US' },
(progress) => {
const elapsed = Math.round((Date.now() - startTime) / 1000);

switch (progress.type) {
case 'started':
console.log(`[${elapsed}s] ✓ Render started (ID: ${progress.renderId})`);
break;

case 'polling':
console.log(`[${elapsed}s] ⏳ Polling... status: ${progress.status} (attempt ${progress.attempt})`);
break;

case 'completed':
console.log(`[${elapsed}s] ✅ Render completed!`);
break;

case 'failed':
console.log(`[${elapsed}s] ❌ Render failed`);
break;
}
}
);

console.log(`\nTotal time: ${Math.round((Date.now() - startTime) / 1000)}s`);
return result;
}

renderWithProgress();

Manual Polling (Low-Level)

Use low-level API for custom polling logic:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function manualPolling() {
// Step 1: Create render job
const { renderId } = await client.createRender('https://example.com', {
countryCode: 'US'
});

console.log('Render created:', renderId);

// Step 2: Do something else while it processes
console.log('Doing other work...');
await new Promise(resolve => setTimeout(resolve, 3000));

// Step 3: Poll manually
let attempts = 0;
const maxAttempts = 60;

while (attempts < maxAttempts) {
attempts++;

const result = await client.getRender(renderId);
console.log(`Poll ${attempts}: ${result.status}`);

if (result.status === 'completed') {
console.log('✅ Completed!');
return result;
}

if (result.status === 'failed') {
throw new Error(`Render failed: ${result.error}`);
}

// Wait before next poll (use server suggestion)
const delay = (result.retryAfter || 1) * 1000;
await new Promise(resolve => setTimeout(resolve, delay));
}

throw new Error('Render timed out');
}

manualPolling();

Batch Processing

Render multiple URLs efficiently:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function batchRender(urls, options = {}) {
console.log(`Processing ${urls.length} URLs...`);

const results = [];

for (let i = 0; i < urls.length; i++) {
const url = urls[i];
console.log(`\n[${i + 1}/${urls.length}] Processing: ${url}`);

try {
const result = await client.render(url, options);
results.push({
url,
success: true,
html: result.html,
city: result.selectedCity.displayName
});
console.log(`✅ Success`);
} catch (error) {
results.push({
url,
success: false,
error: error.message
});
console.log(`❌ Failed: ${error.message}`);
}
}

// Summary
const successful = results.filter(r => r.success).length;
console.log(`\n📊 Summary: ${successful}/${urls.length} successful`);

return results;
}

// Usage
const urls = [
'https://example.com',
'https://example.org',
'https://example.net'
];

batchRender(urls, { countryCode: 'US' });

Parallel Batch Processing

Process multiple URLs in parallel (respects concurrent limits):

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function parallelBatchRender(urls, options = {}, concurrency = 3) {
console.log(`Processing ${urls.length} URLs with concurrency ${concurrency}...`);

const results = [];
const chunks = [];

// Split URLs into chunks
for (let i = 0; i < urls.length; i += concurrency) {
chunks.push(urls.slice(i, i + concurrency));
}

// Process each chunk in parallel
for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
const chunk = chunks[chunkIndex];
console.log(`\nProcessing chunk ${chunkIndex + 1}/${chunks.length}...`);

const chunkResults = await Promise.allSettled(
chunk.map(url =>
client.render(url, options)
.then(result => ({ url, success: true, result }))
.catch(error => ({ url, success: false, error: error.message }))
)
);

results.push(...chunkResults.map(r => r.value));
}

// Summary
const successful = results.filter(r => r.success).length;
console.log(`\n📊 Summary: ${successful}/${urls.length} successful`);

return results;
}

// Usage
const urls = [
'https://example.com/page1',
'https://example.com/page2',
'https://example.com/page3',
'https://example.com/page4',
'https://example.com/page5'
];

parallelBatchRender(urls, { countryCode: 'US' }, 2);

Fetch Additional URLs

Fetch additional URLs after the main render:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function fetchAdditionalUrls() {
const result = await client.render('https://example.com', {
countryCode: 'US',
fetchUrls: [
'https://example.com/api/data',
'https://example.com/api/user',
'https://example.com/api/config'
]
});

console.log('Main page HTML length:', result.html.length);
console.log('Additional fetches:', result.fetchResponses.length);

// Process each fetch response
result.fetchResponses.forEach((response, index) => {
console.log(`\nFetch ${index + 1}:`);
console.log(' URL:', response.url);
console.log(' Status:', response.statusCode);
console.log(' Body length:', response.body.length);

// Parse JSON if applicable
if (response.headers['content-type']?.includes('application/json')) {
try {
const data = JSON.parse(response.body);
console.log(' JSON data:', data);
} catch (e) {
console.log(' Could not parse JSON');
}
}
});

return result;
}

fetchAdditionalUrls();

Check Account Balance

Monitor your account balance and remaining renders:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function checkBalance() {
const balance = await client.getAccountBalance();

console.log('💰 Account Balance');
console.log('==================');
console.log(`Total: ${balance.totalBalanceFormatted}`);
console.log(`Renders remaining: ${balance.totalBalanceCents}`);
console.log('\nBreakdown:');
console.log(` 💵 Paid: ${balance.breakdown.paid.formatted} (${balance.breakdown.paid.cents} renders)`);
console.log(` 🎁 Free: ${balance.breakdown.free.formatted} (${balance.breakdown.free.cents} renders)`);
console.log(` ⭐ Bonus: ${balance.breakdown.bonus.formatted} (${balance.breakdown.bonus.cents} renders)`);

// Check if balance is low
if (balance.totalBalanceCents < 100) {
console.warn('\n⚠️ Low balance warning: Less than 100 renders remaining');
}

return balance;
}

checkBalance();

Real-World Scenarios

E-commerce Product Scraping

Scrape product information with price monitoring:

import Browser7 from 'browser7';
import fs from 'fs';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function scrapeProduct(productUrl) {
console.log(`Scraping product: ${productUrl}`);

const result = await client.render(productUrl, {
countryCode: 'US',
includeScreenshot: true,
screenshotFormat: 'jpeg',
waitFor: [
// Dismiss cookie banner
Browser7.waitForClick('.cookie-accept', 5000),
// Wait for product price to load
Browser7.waitForSelector('.product-price', 'visible', 10000),
// Wait for stock status
Browser7.waitForSelector('.stock-status', 'visible', 10000)
]
});

// Save HTML for parsing
fs.writeFileSync('product.html', result.html);

// Save screenshot for verification
const screenshot = Buffer.from(result.screenshot, 'base64');
fs.writeFileSync('product-screenshot.jpg', screenshot);

console.log('✅ Product scraped successfully');
console.log(`City: ${result.selectedCity.displayName}`);
console.log(`Time: ${result.timingBreakdown.totalMs}ms`);

return result;
}

scrapeProduct('https://shop.example.com/product/12345');

News Article Extraction

Extract news articles with cookie consent handling:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function scrapeNewsArticle(articleUrl) {
const result = await client.render(articleUrl, {
countryCode: 'GB',
city: 'london',
blockImages: true, // Faster loading for text content
waitFor: [
// Handle cookie banner
Browser7.waitForClick('[data-testid="cookie-accept"]', 5000),
// Wait for article content
Browser7.waitForSelector('article', 'visible', 10000),
// Ensure author info loaded
Browser7.waitForSelector('.author-info', 'visible', 5000)
]
});

console.log('Article scraped from:', result.selectedCity.displayName);
console.log('Load strategy:', result.loadStrategy);

// Now parse the HTML to extract article data
// (use cheerio, jsdom, or similar)

return {
html: result.html,
url: articleUrl,
scrapedAt: new Date().toISOString(),
city: result.selectedCity.displayName
};
}

scrapeNewsArticle('https://news.example.com/article/breaking-news');

Protected Site with CAPTCHA

Handle protected sites with CAPTCHA and wait actions:

import Browser7 from 'browser7';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function scrapeProtectedSite(url) {
console.log('Accessing protected site:', url);

const result = await client.render(url, {
countryCode: 'US',
captcha: 'auto', // Auto-solve any CAPTCHA
includeScreenshot: true, // Verify we got past CAPTCHA
waitFor: [
// Wait for CAPTCHA to be solved and page to load
Browser7.waitForSelector('.protected-content', 'visible', 30000),
// Wait for dynamic content
Browser7.waitForDelay(2000)
]
});

if (result.captcha.detected) {
console.log('✅ CAPTCHA detected and solved!');
console.log(' Type:', result.captcha.sitekey ? 'reCAPTCHA' : 'Unknown');
}

// Verify we got the protected content
if (result.html.includes('protected-content')) {
console.log('✅ Successfully accessed protected content');

// Save screenshot for manual verification
const screenshot = Buffer.from(result.screenshot, 'base64');
require('fs').writeFileSync('protected-content-proof.jpg', screenshot);
} else {
console.warn('⚠️ Warning: Protected content may not have loaded');
}

return result;
}

scrapeProtectedSite('https://protected.example.com/members-only');

Long Article with Full Page Screenshot

Capture long-form content with full page screenshot:

import Browser7 from 'browser7';
import fs from 'fs';

const client = new Browser7({ apiKey: 'b7_your_api_key_here' });

async function scrapeLongArticle(articleUrl) {
console.log('Scraping long article...');

const result = await client.render(articleUrl, {
countryCode: 'US',
includeScreenshot: true,
screenshotFormat: 'png', // PNG for better quality
screenshotFullPage: true, // Capture entire article
waitFor: [
// Dismiss overlays
Browser7.waitForClick('.modal-close', 3000),
// Wait for article to fully load
Browser7.waitForSelector('article', 'visible', 10000),
// Wait for images to load
Browser7.waitForDelay(3000)
]
});

// Save full page screenshot
const screenshot = Buffer.from(result.screenshot, 'base64');
fs.writeFileSync('article-fullpage.png', screenshot);

const screenshotSizeKB = Math.round(screenshot.length / 1024);
console.log(`✅ Full page screenshot saved (${screenshotSizeKB} KB)`);
console.log(`HTML size: ${Math.round(result.html.length / 1024)} KB`);
console.log(`Total time: ${result.timingBreakdown.totalMs}ms`);

return result;
}

scrapeLongArticle('https://blog.example.com/ultimate-guide-to-web-scraping');

Tips & Best Practices

Optimize for Performance

// ✅ GOOD: Block images when you only need text
const result = await client.render(url, {
blockImages: true // Faster, uses less bandwidth
});

// ✅ GOOD: Use specific CAPTCHA type if you know it
const result = await client.render(url, {
captcha: 'recaptcha_v2' // Faster than 'auto'
});

// ✅ GOOD: Use viewport screenshots unless you need full page
const result = await client.render(url, {
includeScreenshot: true,
screenshotFullPage: false // 50-150KB vs 200KB-2MB+
});

Handle Errors Gracefully

async function robustRender(url, options) {
try {
return await client.render(url, options);
} catch (error) {
// Log but don't crash
console.error('Render failed:', error.message);

// Return partial result or null
return null;
}
}

Monitor Your Balance

async function renderWithBalanceCheck(url, options) {
// Check balance before expensive operation
const balance = await client.getAccountBalance();

if (balance.totalBalanceCents < 10) {
throw new Error('Insufficient balance');
}

return await client.render(url, options);
}

Next Steps

Need help? Check the Error Handling Guide or visit our Support.