DEV Community

Custodia-Admin
Custodia-Admin

Posted on • Originally published at pagebolt.dev

How to Capture a Full-Page Screenshot with JavaScript

How to Capture a Full-Page Screenshot with JavaScript

You need a screenshot of an entire page. Not just the viewport. The whole thing.

In traditional Puppeteer, this means:

  • Launch browser
  • Navigate to page
  • Call page.screenshot({ fullPage: true })
  • Wait for entire page to render
  • Save the PNG

With PageBolt, it's one parameter.

The Problem: Full-Page Screenshots Are Complex

Typical full-page screenshot code in Puppeteer:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');

  // Get full page height
  const fullHeight = await page.evaluate(() => {
    return document.documentElement.scrollHeight;
  });

  await page.screenshot({
    path: 'screenshot.png',
    fullPage: true,
    clip: { x: 0, y: 0, width: 1280, height: fullHeight }
  });

  await browser.close();
})();
Enter fullscreen mode Exit fullscreen mode

Issues:

  • 300MB+ dependency
  • Browser process overhead
  • Full page rendering can be slow (5-30 seconds depending on page)
  • Stitching multiple viewport captures is error-prone
  • Memory intensive for large pages
  • Fails in serverless environments

The Solution: One Parameter

PageBolt captures the full rendered page in a single API call:

const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${apiKey}` },
  body: JSON.stringify({
    url: 'https://example.com',
    fullPage: true
  })
});

const buffer = await response.arrayBuffer();
fs.writeFileSync('screenshot.png', Buffer.from(buffer));
Enter fullscreen mode Exit fullscreen mode

That's it. One parameter. fullPage: true.

Node.js Full-Page Screenshot

Save full page as PNG file:

const fs = require('fs');
const apiKey = process.env.PAGEBOLT_API_KEY;

async function captureFullPage(url, filename) {
  const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      url: url,
      fullPage: true,
      format: 'png'
    })
  });

  if (!response.ok) {
    throw new Error(`API error: ${response.status}`);
  }

  const buffer = await response.arrayBuffer();
  fs.writeFileSync(filename, Buffer.from(buffer));
  console.log(`Full-page screenshot saved: ${filename}`);
}

// Usage
captureFullPage('https://example.com', 'full-page.png')
  .catch(err => console.error('Error:', err.message));
Enter fullscreen mode Exit fullscreen mode

Browser Full-Page Screenshot

Display full page as base64-encoded image:

const apiKey = 'your_api_key';

async function captureFullPageBrowser(url) {
  const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      url: url,
      fullPage: true,
      format: 'png'
    })
  });

  const buffer = await response.arrayBuffer();
  const base64 = btoa(String.fromCharCode(...new Uint8Array(buffer)));

  const img = document.createElement('img');
  img.src = `data:image/png;base64,${base64}`;
  img.style.maxWidth = '100%';
  img.style.border = '1px solid #ddd';

  document.body.appendChild(img);
}

// Usage
captureFullPageBrowser('https://example.com');
Enter fullscreen mode Exit fullscreen mode

Batch Full-Page Screenshots

Capture multiple pages in parallel:

const fs = require('fs');
const apiKey = process.env.PAGEBOLT_API_KEY;

async function captureMultiplePages(urls) {
  const promises = urls.map((url, index) =>
    fetch('https://api.pagebolt.dev/v1/screenshot', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        url: url,
        fullPage: true
      })
    })
      .then(res => res.arrayBuffer())
      .then(buffer => {
        const filename = `page-${index + 1}.png`;
        fs.writeFileSync(filename, Buffer.from(buffer));
        console.log(`Saved: ${filename}`);
      })
  );

  await Promise.all(promises);
}

// Usage
const urls = [
  'https://example.com',
  'https://github.com',
  'https://stackoverflow.com'
];

captureMultiplePages(urls);
Enter fullscreen mode Exit fullscreen mode

With Device Emulation

Capture full page on specific device:

const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${apiKey}` },
  body: JSON.stringify({
    url: 'https://example.com',
    fullPage: true,
    viewportDevice: 'iphone_14_pro'
  })
});

const buffer = await response.arrayBuffer();
fs.writeFileSync('mobile-full-page.png', Buffer.from(buffer));
Enter fullscreen mode Exit fullscreen mode

Available devices: iphone_14_pro, iphone_15_plus, ipad_air, pixel_8, macbook_pro_16, and 20+ others.

Real-World Use Cases

Website Archiving — Capture entire pages for long-term storage or compliance:

async function archiveWebsite(url, archiveDir) {
  const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${apiKey}` },
    body: JSON.stringify({ url, fullPage: true })
  });

  const timestamp = new Date().toISOString().split('T')[0];
  const filename = `${archiveDir}/${timestamp}-archive.png`;
  fs.writeFileSync(filename, Buffer.from(await response.arrayBuffer()));
}
Enter fullscreen mode Exit fullscreen mode

Design Comparison — Full-page before/after screenshots for A/B testing:

async function compareDesigns(controlUrl, variantUrl) {
  const [control, variant] = await Promise.all([
    fetch('https://api.pagebolt.dev/v1/screenshot', {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${apiKey}` },
      body: JSON.stringify({ url: controlUrl, fullPage: true })
    }).then(r => r.arrayBuffer()),
    fetch('https://api.pagebolt.dev/v1/screenshot', {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${apiKey}` },
      body: JSON.stringify({ url: variantUrl, fullPage: true })
    }).then(r => r.arrayBuffer())
  ]);

  fs.writeFileSync('control.png', Buffer.from(control));
  fs.writeFileSync('variant.png', Buffer.from(variant));
  console.log('Compare control.png vs variant.png');
}
Enter fullscreen mode Exit fullscreen mode

Landing Page Documentation — Capture full landing pages for design handoff:

async function documentLandingPage(url, title) {
  const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
    method: 'POST',
    headers: { 'Authorization': `Bearer ${apiKey}` },
    body: JSON.stringify({ url, fullPage: true, format: 'png' })
  });

  const slug = title.toLowerCase().replace(/\s+/g, '-');
  fs.writeFileSync(`docs/${slug}.png`, Buffer.from(await response.arrayBuffer()));
}
Enter fullscreen mode Exit fullscreen mode

Environment Setup

.env file:

PAGEBOLT_API_KEY=your_api_key_here
Enter fullscreen mode Exit fullscreen mode

Load in Node.js:

require('dotenv').config();
const apiKey = process.env.PAGEBOLT_API_KEY;
Enter fullscreen mode Exit fullscreen mode

Error Handling

Handle API errors gracefully:

async function captureWithErrorHandling(url) {
  try {
    const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
      method: 'POST',
      headers: { 'Authorization': `Bearer ${apiKey}` },
      body: JSON.stringify({ url, fullPage: true })
    });

    if (response.status === 401) {
      throw new Error('Invalid API key');
    }
    if (response.status === 429) {
      throw new Error('Rate limit exceeded. Upgrade your plan.');
    }
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }

    return await response.arrayBuffer();
  } catch (error) {
    console.error('Screenshot failed:', error.message);
    throw error;
  }
}
Enter fullscreen mode Exit fullscreen mode

Pricing

Plan Requests/Month Cost Best For
Free 100 $0 Testing & prototyping
Starter 5,000 $29 Small projects
Growth 25,000 $79 Production apps
Scale 100,000 $199 High-volume automation

Summary

Full-page screenshots in JavaScript:

  • ✅ One parameter: fullPage: true
  • ✅ No browser management
  • ✅ No stitching or scrolling loops
  • ✅ Works in Node.js and browsers
  • ✅ 100+ requests/month free

Get started: Try PageBolt free — 100 requests/month, no credit card required →

Top comments (0)