Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled
- Add clip object parameter to crop rectangular areas from screenshots
- Support POST body: clip {x, y, width, height} number fields
- Support GET query: clipX, clipY, clipW, clipH params
- Validation: all fields required, x/y >=0, width/height >0, max 3840x2160
- Mutually exclusive with fullPage and selector
- Update OpenAPI docs with clip examples
- Update Node.js and Python SDK READMEs with clip usage
- Add comprehensive test coverage (11 new tests)
- Tests: missing fields, negative coords, zero dimensions, max limits, mutual exclusivity
6 KiB
6 KiB
SnapAPI Node.js SDK
Official Node.js client for SnapAPI — the EU-hosted screenshot API.
Installation
npm install snapapi
Quick Start
import { SnapAPI } from 'snapapi';
import fs from 'fs';
const snap = new SnapAPI('your-api-key');
// Simple screenshot
const png = await snap.capture('https://example.com');
fs.writeFileSync('screenshot.png', png);
Usage
Basic Screenshot
const screenshot = await snap.capture('https://example.com');
With Options
const screenshot = await snap.capture('https://example.com', {
format: 'jpeg',
width: 1920,
height: 1080,
quality: 90,
});
Full-Page Capture
const screenshot = await snap.capture({
url: 'https://example.com/blog',
fullPage: true,
format: 'png',
deviceScale: 2, // Retina
});
Mobile Viewport
const screenshot = await snap.capture({
url: 'https://example.com',
width: 375,
height: 812,
deviceScale: 2,
});
Wait for Dynamic Content
const screenshot = await snap.capture({
url: 'https://example.com/dashboard',
waitForSelector: '#chart-loaded',
waitUntil: 'networkidle2',
});
Dark Mode Capture
// Capture in dark mode (prefers-color-scheme: dark)
const darkScreenshot = await snap.capture({
url: 'https://example.com',
darkMode: true,
format: 'png',
});
Custom User Agent
// Set a custom User-Agent string for the request
const screenshot = await snap.capture({
url: 'https://example.com',
userAgent: 'Mozilla/5.0 (compatible; SnapAPI/1.0)',
format: 'png',
});
Hide Elements Before Capture
// Hide cookie banners, popups, ads
const cleanScreenshot = await snap.capture({
url: 'https://example.com',
hideSelectors: [
'.cookie-banner',
'.popup-overlay',
'#advertisement',
'.tracking-notice'
],
});
// Hide single element
const singleHide = await snap.capture('https://example.com', {
hideSelectors: '.newsletter-popup',
});
Custom CSS Injection
// Inject custom CSS before capture
const styled = await snap.capture({
url: 'https://example.com',
css: 'body { background: #1a1a2e !important; color: #eee !important; font-family: "Comic Sans MS" }',
});
// Combine with other options
const combined = await snap.capture({
url: 'https://example.com',
css: '.hero { padding: 80px 0 } h1 { font-size: 48px }',
darkMode: true,
hideSelectors: ['.cookie-banner'],
});
JavaScript Injection
// Execute custom JavaScript before capture
const interactiveScreenshot = await snap.capture({
url: 'https://example.com',
js: `
// Dismiss modal popup
document.querySelector('.modal-overlay')?.remove();
// Scroll to specific content
window.scrollTo(0, 500);
// Click button to reveal content
document.querySelector('#show-more-btn')?.click();
// Wait for animation to complete
await new Promise(resolve => setTimeout(resolve, 1000));
`,
});
// Combine with other options for complex scenarios
const complexCapture = await snap.capture({
url: 'https://example.com/app',
js: 'document.querySelector(".sidebar").style.display = "none";',
css: 'body { zoom: 0.8 }',
waitForSelector: '#content-loaded',
hideSelectors: ['.ad-banner', '.cookie-notice'],
});
Crop Specific Areas (Clip)
// Crop a specific rectangular area from the screenshot
const croppedScreenshot = await snap.capture({
url: 'https://example.com',
clip: {
x: 100, // X coordinate (pixels from left)
y: 50, // Y coordinate (pixels from top)
width: 800, // Width of the crop area
height: 600, // Height of the crop area
},
});
// Useful for capturing specific UI elements or sections
const headerScreenshot = await snap.capture({
url: 'https://example.com',
clip: { x: 0, y: 0, width: 1280, height: 120 }, // Top banner only
format: 'png',
});
API Reference
new SnapAPI(apiKey, config?)
| Parameter | Type | Description |
|---|---|---|
apiKey |
string |
Your SnapAPI API key (required) |
config.baseUrl |
string |
API base URL (default: https://snapapi.eu) |
config.timeout |
number |
Request timeout in ms (default: 30000) |
snap.capture(url, options?) / snap.capture(options)
Returns a Promise<Buffer> containing the screenshot image.
| Option | Type | Default | Description |
|---|---|---|---|
url |
string |
— | URL to capture (required) |
format |
'png' | 'jpeg' | 'webp' |
'png' |
Output format |
width |
number |
1280 |
Viewport width (320–3840) |
height |
number |
800 |
Viewport height (200–2160) |
fullPage |
boolean |
false |
Capture full scrollable page |
quality |
number |
80 |
JPEG/WebP quality (1–100) |
waitForSelector |
string |
— | CSS selector to wait for |
deviceScale |
number |
1 |
Device pixel ratio (1–3) |
delay |
number |
0 |
Extra delay in ms (0–5000) |
waitUntil |
string |
'domcontentloaded' |
Load event to wait for |
darkMode |
boolean |
false |
Emulate prefers-color-scheme: dark |
hideSelectors |
string | string[] |
— | CSS selectors to hide before capture |
css |
string |
— | Custom CSS to inject before capture (max 5000 chars) |
clip |
object |
— | Crop rectangle: {x, y, width, height} (mutually exclusive with fullPage/selector) |
snap.health()
Returns API health status.
Error Handling
import { SnapAPI, SnapAPIError } from 'snapapi';
try {
const screenshot = await snap.capture('https://example.com');
} catch (err) {
if (err instanceof SnapAPIError) {
console.error(`API error ${err.status}: ${err.detail}`);
}
}
EU-Hosted & GDPR Compliant
SnapAPI runs entirely on EU infrastructure (Germany). Your data never leaves the EU. Learn more.