Capture screenshots of websites using Puppeteer with extensive customization options
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Advanced functionality including device emulation, content injection, authentication, and browser customization.
Emulate mobile devices, tablets, and other devices for responsive testing.
interface DeviceEmulationOptions {
/** Emulate a specific device (overrides width, height, scaleFactor, userAgent) */
emulateDevice?: string;
/** Enable dark mode preference */
darkMode?: boolean;
/** Custom user agent string */
userAgent?: string;
}Usage Examples:
import captureWebsite, { devices } from 'capture-website';
// List available devices
console.log(devices); // ['iPhone X', 'iPad', 'Pixel 2', ...]
// Emulate iPhone
await captureWebsite.file('https://responsive-site.com', 'iphone.png', {
emulateDevice: 'iPhone X'
});
// Emulate tablet
await captureWebsite.file('https://responsive-site.com', 'tablet.png', {
emulateDevice: 'iPad'
});
// Test dark mode
await captureWebsite.file('https://example.com', 'dark-mode.png', {
darkMode: true
});
// Custom user agent
await captureWebsite.file('https://example.com', 'custom-ua.png', {
userAgent: 'MyBot/1.0'
});Inject custom JavaScript, CSS, and other content into pages before capture.
interface ContentInjectionOptions {
/** JavaScript modules to inject (ES6 modules) */
modules?: string[];
/** JavaScript scripts to inject (regular scripts) */
scripts?: string[];
/** CSS styles to inject */
styles?: string[];
/** Function to execute before navigation */
preloadFunction?: EvaluateFunc<unknown[]>;
}
type EvaluateFunc<T extends unknown[]> = string | ((...args: T) => unknown);Usage Examples:
// Inject CSS to hide elements
await captureWebsite.file('https://example.com', 'styled.png', {
styles: [
'.sidebar { display: none !important; }',
'body { font-family: Arial !important; }'
]
});
// Inject external CSS
await captureWebsite.file('https://example.com', 'external-css.png', {
styles: [
'https://fonts.googleapis.com/css2?family=Roboto',
'./custom-styles.css'
]
});
// Inject JavaScript modules
await captureWebsite.file('https://example.com', 'with-js.png', {
modules: [
'https://cdn.jsdelivr.net/npm/lodash@4/lodash.min.js',
'./custom-module.js',
`
// Inline module code
document.body.style.backgroundColor = 'lightblue';
`
]
});
// Inject regular scripts
await captureWebsite.file('https://example.com', 'with-scripts.png', {
scripts: [
'https://code.jquery.com/jquery-3.6.0.min.js',
`
// Inline script
console.log('Script injected');
`
]
});
// Preload function for environment setup
await captureWebsite.file('https://example.com', 'preloaded.png', {
preloadFunction: () => {
// Mock Math.random for consistent results
Math.random = () => 0.5;
// Override navigator.language
Object.defineProperty(navigator, 'language', {
value: 'en-US',
configurable: true
});
}
});Control network behavior, authentication, and request headers.
interface NetworkOptions {
/** Custom HTTP headers */
headers?: Record<string, string>;
/** Cookies to set (browser format or object format) */
cookies?: Array<string | Protocol.Network.CookieParam>;
/** HTTP authentication credentials */
authentication?: Authentication;
}
interface Authentication {
username: string;
password?: string;
}
interface Protocol.Network.CookieParam {
name: string;
value: string;
url?: string;
domain?: string;
path?: string;
secure?: boolean;
httpOnly?: boolean;
sameSite?: 'Strict' | 'Lax' | 'None';
expires?: number;
priority?: 'Low' | 'Medium' | 'High';
}Usage Examples:
// Custom headers
await captureWebsite.file('https://api-site.com', 'with-headers.png', {
headers: {
'Authorization': 'Bearer token123',
'X-Custom-Header': 'value',
'Accept-Language': 'en-US,en;q=0.9'
}
});
// HTTP Basic Authentication
await captureWebsite.file('https://protected-site.com', 'authenticated.png', {
authentication: {
username: 'admin',
password: 'secret123'
}
});
// Set cookies (browser format)
await captureWebsite.file('https://example.com', 'with-cookies.png', {
cookies: [
'sessionId=abc123; Path=/; HttpOnly',
'theme=dark; Expires=Wed, 21 Oct 2025 07:28:00 GMT'
]
});
// Set cookies (object format)
await captureWebsite.file('https://example.com', 'with-object-cookies.png', {
cookies: [
{
name: 'userId',
value: '12345',
domain: 'example.com',
path: '/',
secure: true,
httpOnly: true,
sameSite: 'Strict'
}
]
});Advanced browser configuration and debugging options.
interface BrowserControlOptions {
/** Puppeteer launch options */
launchOptions?: PuppeteerNodeLaunchOptions;
/** Function called before screenshot capture */
beforeScreenshot?: BeforeScreenshot;
/** Enable debug mode (visible browser, console output, slow motion) */
debug?: boolean;
}
type BeforeScreenshot = (page: Page, browser: Browser) => void | Promise<void>;
interface PuppeteerNodeLaunchOptions {
headless?: boolean | 'new';
executablePath?: string;
slowMo?: number;
devtools?: boolean;
args?: string[];
timeout?: number;
// ... many more Puppeteer options
}
// Type alias export for convenience
type LaunchOptions = PuppeteerNodeLaunchOptions;Usage Examples:
// Debug mode - see what's happening
await captureWebsite.file('https://example.com', 'debug.png', {
debug: true // Shows browser window, console output, slow motion
});
// Custom browser launch options
await captureWebsite.file('https://example.com', 'custom-browser.png', {
launchOptions: {
headless: false,
slowMo: 250,
devtools: true,
args: [
'--disable-web-security',
'--disable-features=VizDisplayCompositor'
]
}
});
// Pre-screenshot interactions
await captureWebsite.file('https://interactive-site.com', 'interacted.png', {
beforeScreenshot: async (page, browser) => {
// Perform complex interactions
await page.click('#login-button');
await page.waitForSelector('#dashboard');
await page.hover('.tooltip-trigger');
await page.evaluate(() => {
window.scrollTo(0, 500);
});
}
});
// Advanced before-screenshot example
await captureWebsite.file('https://form-site.com', 'filled-form.png', {
beforeScreenshot: async (page) => {
// Fill out a form
await page.type('#name', 'John Doe');
await page.type('#email', 'john@example.com');
await page.select('#country', 'US');
await page.check('#newsletter');
// Wait for validation
await page.waitForFunction(() =>
document.querySelector('#submit').disabled === false
);
}
});// Capture login flow
const screenshots = [];
// Landing page
screenshots.push(await captureWebsite.buffer('https://app.com'));
// After login
screenshots.push(await captureWebsite.buffer('https://app.com/login', {
beforeScreenshot: async (page) => {
await page.type('#username', 'user');
await page.type('#password', 'pass');
await page.click('#login');
await page.waitForNavigation();
}
}));
// Dashboard
screenshots.push(await captureWebsite.buffer('https://app.com/dashboard', {
cookies: ['session=xyz123'] // Use session from login
}));// Test different themes
const themes = ['light', 'dark', 'auto'];
for (const theme of themes) {
await captureWebsite.file('https://example.com', `theme-${theme}.png`, {
cookies: [`theme=${theme}`],
darkMode: theme === 'dark'
});
}// Disable JavaScript and images for speed
await captureWebsite.file('https://heavy-site.com', 'no-js-images.png', {
isJavaScriptEnabled: false,
launchOptions: {
args: [
'--disable-images',
'--disable-javascript',
'--disable-plugins'
]
}
});// Capture with specific Chrome flags
await captureWebsite.file('https://webgl-site.com', 'webgl.png', {
launchOptions: {
args: [
'--enable-webgl',
'--ignore-gpu-blacklist',
'--disable-software-rasterizer'
]
}
});Install with Tessl CLI
npx tessl i tessl/npm-capture-website