Full-Page Screenshot
by kuligaposten 2025-02-01
Building a Full-Page Screenshot Capture Tool with Puppeteer and Express
Capturing full-page screenshots of websites can be incredibly useful for various purposes, such as website archiving, UI testing, and content monitoring. In this post, we'll explore how to build a simple web-based screenshot capture tool using Node.js, Express, and Puppeteer.
Overview of the Script
The script consists of an Express.js router that provides two main functionalities:
- A homepage (
GET /) that renders a form for users to enter a URL. - A screenshot route (
POST /) that uses Puppeteer to capture a full-page screenshot of the given website and displays the result.
Technologies Used:
- Express.js: Web framework for handling routes.
- Puppeteer: Headless Chrome automation for taking screenshots.
- EJS Layouts: Used for rendering dynamic pages.
- Path & URL Modules: Manage file paths and resolve module URLs.
Setting Up the Express Router
Importing Required Modules
import express from "express";
import puppeteer from "puppeteer";
import path from "path";
import { fileURLToPath } from "url";
import { renderWithLayout } from "../utils/renderWithLayout.js";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const router = express.Router();
We import necessary modules, including puppeteer for browser automation, path for handling file paths, and fileURLToPath for module resolution in ES modules.
Homepage Route - Rendering the Form
router.get("/", (req, res) => {
renderWithLayout(res, "layouts/main", {
page: "screenshot",
title: "Screenshot",
description: `taking a screenshot`,
});
});
This route serves the form page where users can input the URL, select an image format, and specify the viewport width.
Capturing Screenshots with Puppeteer
Handling Screenshot Requests
router.post("/", async (req, res) => {
let { url, format, width } = req.body;
if (!url) return res.status(400).send("URL is required");
// Auto-add "https://" if missing
if (!/^https?:\/\//i.test(url)) {
url = `https://${url}`;
}
const timestamp = Date.now();
const screenshotPath = path.join(
__dirname,
"../public/screenshots",
`screenshot-${timestamp}.${format}`,
);
let browser = null;
try {
console.log(
`📸 Capturing full-page screenshot: ${url} | Format: ${format} | Width: ${width}px`,
);
browser = await puppeteer.launch({
headless: "new",
args: ["--no-sandbox", "--disable-setuid-sandbox"],
});
const page = await browser.newPage();
await page.setViewport({ width: parseInt(width), height: 1080 });
await page.goto(url, { waitUntil: "networkidle2" });
// Get full page height
const pageHeight = await page.evaluate(
() => document.documentElement.scrollHeight,
);
await page.setViewport({ width: parseInt(width), height: pageHeight });
// Capture Screenshot with Selected Format
await page.screenshot({
path: screenshotPath,
fullPage: true,
type: format,
});
console.log(`Screenshot saved: ${screenshotPath}`);
// Render result page
renderWithLayout(res, "layouts/main", {
page: "result",
title: "Captured screenshot",
description: `Captured screenshot of ${url}`,
screenshotPath: `/screenshots/screenshot-${timestamp}.${format}`,
format,
});
} catch (error) {
console.error("❌ Error capturing screenshot:", error);
renderWithLayout(res, "layouts/main", {
page: "500",
title: "Internal error",
description: `Internal error`,
});
} finally {
if (browser) await browser.close(); // Ensure browser closes
}
});
Key Features:
- Auto-adds HTTPS: Ensures URLs are properly formatted before navigation.
- Dynamic Viewport Adjustment: Captures the full height of the page dynamically.
- Format Selection: Allows users to choose PNG, JPEG, or WebP output.
- Handles Errors Gracefully: Catches exceptions and renders an error page if anything fails.
Running the Screenshot Tool
Install Dependencies
npm install express puppeteer
Start the Server
node server.js
Make sure to configure your Express app to use this router.
Enhancements & Next Steps
- Add an Image Preview: Display the captured screenshot directly on the result page.
- Allow Custom Image Quality: Enable users to choose compression levels for JPEG/WebP formats.
- Store Screenshots in Cloud Storage: Save images to AWS S3 or Cloudinary instead of local storage.
- Optimize Performance: Implement caching to avoid redundant screenshots of the same URL.
Conclusion
This script provides a straightforward way to capture full-page screenshots using Puppeteer and Express. With additional optimizations, it can be expanded into a powerful screenshot API for developers or a simple online tool for users.