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();
Click Cookie Banner
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
- API Reference - Complete method documentation
- Quick Start - Get started with the basics
- Advanced API - Direct REST API usage
Need help? Check the Error Handling Guide or visit our Support.