Blog 8 min read

Screenshot Any URL in 3 Lines: Node.js and Python Quickstart

Take a screenshot of any URL in 3 lines of Node.js or Python. No headless browser, no Chromium, no config. Free tier included with 500 screenshots per month.

SnapRender Team
|

Screenshot Any URL in 3 Lines: Node.js and Python Quickstart

Three lines of code to take a screenshot of any URL in Node.js or Python. Install the SnapRender SDK, create a client, call capture(). That's it. No headless browser, no Chromium download, no Puppeteer config. You get a PNG, JPEG, WebP, or PDF back from a single function call, and the free tier gives you 500 screenshots per month.

Node.js: 3 Lines

npm install snaprender
const { SnapRender } = require('snaprender');
const client = new SnapRender({ apiKey: 'sk_live_...' });
const buffer = await client.capture({ url: 'https://example.com', format: 'png' });

That's a working screenshot. buffer contains the PNG image data. Write it to a file, pipe it to an HTTP response, or store it in S3.

const fs = require('fs');
fs.writeFileSync('screenshot.png', buffer);

Python: 3 Lines

pip install snaprender
from snaprender import SnapRender
client = SnapRender(api_key='sk_live_...')
image_bytes = client.capture(url='https://example.com', format='png')

Same idea. image_bytes is the raw image. Save it:

with open('screenshot.png', 'wb') as f:
    f.write(image_bytes)

For Comparison: Puppeteer

Here's the same screenshot in Puppeteer:

const puppeteer = require('puppeteer'); // downloads 300MB Chromium
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 720 });
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({ path: 'screenshot.png' });
await browser.close();

Seven lines, a 300 MB dependency, and you still need to handle:

  • Browser process management (what if it crashes?)
  • Memory usage (150-300 MB per browser instance)
  • Cookie consent banners (manual CSS selector dismissal)
  • Waiting strategies (which waitUntil option? Do you need waitForSelector?)
  • Timeout handling

Puppeteer is a great tool when you need full browser automation. But if you just need a screenshot of a URL, it's a lot of machinery for a simple job. For a deeper look at when Puppeteer makes sense and when an API is the better choice, see our Puppeteer screenshot guide.

Setup: Under 2 Minutes

Step 1: Get a free API key at snap-render.com. No credit card required. The free tier includes 500 screenshots per month.

Step 2: Install the SDK.

# Node.js
npm install snaprender

# Python
pip install snaprender

Step 3: Paste these 3 lines into your code with your API key.

That's it. Time from "I need a screenshot feature" to "I have a working screenshot" is under 2 minutes.

Every Option You Can Add

The 3-line version captures a 1280x720 viewport as PNG. SnapRender's API supports a full set of options that you can add as parameters:

Parameter Type Description
url string URL to capture
format string png, jpeg, webp, or pdf
width integer Viewport width (default: 1280)
height integer Viewport height (default: 720)
full_page boolean Capture full scrollable page (max 32,768px)
dark_mode boolean Force dark mode via prefers-color-scheme
block_ads boolean Remove ads before capture
remove_cookie_banners boolean Dismiss cookie consent popups
device string Emulate a device (e.g., iPhone 15, Pixel 7)
hide_selectors string[] CSS selectors to hide before capture
click_selector string Click an element before capture
cache_ttl integer Cache the result for N seconds (under 200ms on cache hit)

No feature gating. Every option is available on every plan, including the free tier.

Common Recipes

Each recipe is a small addition to the base 3 lines. I'm showing Node.js, but the Python SDK takes the same parameters.

Capture as Mobile Device

const buffer = await client.capture({
  url: 'https://example.com',
  format: 'png',
  device: 'iPhone 15'
});

The API sets the viewport, device scale factor, and user agent automatically. No manual viewport math.

Capture Full Page

const buffer = await client.capture({
  url: 'https://example.com',
  format: 'png',
  fullPage: true
});

SnapRender captures the entire scrollable page up to 32,768 pixels tall. Lazy-loaded images are scrolled into view before capture.

Capture as PDF

const buffer = await client.capture({
  url: 'https://example.com',
  format: 'pdf'
});

A4 format with print backgrounds included. Good for invoices, reports, and any content where users expect a downloadable document.

Capture with Dark Mode

const buffer = await client.capture({
  url: 'https://example.com',
  format: 'png',
  darkMode: true
});

Forces prefers-color-scheme: dark at the browser level. Any site that respects the media query will render in dark mode. Useful for generating OG images that match your app's dark theme.

Capture with Ad Blocking and Cookie Banner Removal

const buffer = await client.capture({
  url: 'https://news-site.com',
  format: 'png',
  blockAds: true,
  removeCookieBanners: true
});

Two boolean flags replace what would be dozens of lines of CSS selector maintenance in Puppeteer. Ad networks change their selectors constantly; SnapRender keeps up with that so you don't have to.

Custom Viewport with Hidden Elements

const buffer = await client.capture({
  url: 'https://example.com',
  format: 'png',
  width: 1920,
  height: 1080,
  hideSelectors: ['.sticky-header', '.popup-overlay', '#chat-widget']
});

The hideSelectors parameter accepts an array of CSS selectors. Matched elements are hidden before the screenshot is taken. Good for removing sticky navigation, chat widgets, or any element that clutters the capture.

Click Before Capture

const buffer = await client.capture({
  url: 'https://example.com',
  format: 'png',
  clickSelector: '#show-more-content'
});

SnapRender clicks the element matching the selector, waits for the page to settle, then captures. Useful for pages that hide content behind "Read more" or "Show all" buttons.

Cached Screenshots for Speed

const buffer = await client.capture({
  url: 'https://example.com',
  format: 'png',
  cacheTtl: 3600
});

First request takes 2-5 seconds (fresh render). Subsequent requests within the TTL return in under 200ms. If you're generating link previews or thumbnails for URLs that don't change often, caching cuts your response time by 90%+.

Python: Full Recipe Example

The same patterns work in the Python SDK:

from snaprender import SnapRender

client = SnapRender(api_key='sk_live_...')

# Mobile + dark mode + no ads
image_bytes = client.capture(
    url='https://example.com',
    format='webp',
    device='iPhone 15',
    dark_mode=True,
    block_ads=True,
    remove_cookie_banners=True
)

with open('mobile-dark.webp', 'wb') as f:
    f.write(image_bytes)

All the options compose freely. Stack device emulation with dark mode, ad blocking, and full-page capture in a single call.

No SDK? Use the Raw API

If you don't want any dependency, SnapRender's API is a single GET endpoint. Works from any language, any HTTP client, even curl:

curl "https://app.snap-render.com/v1/screenshot?url=https://example.com&format=png" \
  -H "X-API-Key: sk_live_..." \
  -o screenshot.png

Node.js with fetch:

const url = new URL('https://app.snap-render.com/v1/screenshot');
url.searchParams.set('url', 'https://example.com');
url.searchParams.set('format', 'png');
url.searchParams.set('full_page', 'true');

const response = await fetch(url, {
  headers: { 'X-API-Key': 'sk_live_...' }
});

const buffer = Buffer.from(await response.arrayBuffer());

Python with requests:

import requests

response = requests.get(
    'https://app.snap-render.com/v1/screenshot',
    headers={'X-API-Key': 'sk_live_...'},
    params={
        'url': 'https://example.com',
        'format': 'png',
        'full_page': True
    }
)

with open('screenshot.png', 'wb') as f:
    f.write(response.content)

The SDK is a thin wrapper around this endpoint. It handles retries and response parsing, but the raw API is just as capable. For a full breakdown of how the API compares to other providers, see our screenshot API comparison.

Pricing

Plan Price Screenshots/month
Free $0 500
Starter $9 2,000
Growth $29 10,000
Business $79 50,000
Scale $199 200,000

Every feature is available on every plan. The free tier has no feature restrictions, no watermarks, no rate limits beyond the monthly cap. Start free, upgrade when you need more volume.

When to Use This vs. Puppeteer/Playwright

The 3-line approach is the fastest way to take a screenshot of a URL in Node.js or Python. It's the right choice when:

  • Screenshots are a feature, not a test artifact
  • You don't want to manage headless browser infrastructure
  • You need features like ad blocking or cookie removal without writing selector scripts
  • You want sub-200ms cached responses
  • You're building link previews, OG images, PDF exports, or visual monitoring

If you need full browser automation (form filling, navigation flows, scraping, E2E testing), use Puppeteer or Playwright. But if the goal is "give me an image of this URL," SnapRender does it in 3 lines with zero operational overhead.

Get your free API key at snap-render.com and take your first screenshot in under 2 minutes.

Try SnapRender Free

500 free screenshots/month, no credit card required.

Sign up free