# SnapAPI Node.js SDK Official Node.js client for [SnapAPI](https://snapapi.eu) — the EU-hosted screenshot API. ## Installation ```bash npm install snapapi ``` ## Quick Start ```typescript 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 ```typescript const screenshot = await snap.capture('https://example.com'); ``` ### With Options ```typescript const screenshot = await snap.capture('https://example.com', { format: 'jpeg', width: 1920, height: 1080, quality: 90, }); ``` ### Full-Page Capture ```typescript const screenshot = await snap.capture({ url: 'https://example.com/blog', fullPage: true, format: 'png', deviceScale: 2, // Retina }); ``` ### Mobile Viewport ```typescript const screenshot = await snap.capture({ url: 'https://example.com', width: 375, height: 812, deviceScale: 2, }); ``` ### Wait for Dynamic Content ```typescript const screenshot = await snap.capture({ url: 'https://example.com/dashboard', waitForSelector: '#chart-loaded', waitUntil: 'networkidle2', }); ``` ### Dark Mode Capture ```typescript // Capture in dark mode (prefers-color-scheme: dark) const darkScreenshot = await snap.capture({ url: 'https://example.com', darkMode: true, format: 'png', }); ``` ### Custom User Agent ```typescript // 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 ```typescript // 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 ```typescript // 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 ```typescript // 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) ```typescript // 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` 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.batch(urls, options?)` Take multiple screenshots in a single request. Each URL counts as one screenshot toward usage limits. ```typescript const results = await snap.batch( ['https://example.com', 'https://example.org'], { format: 'jpeg', width: 1920, height: 1080 } ); for (const result of results) { if (result.status === 'success') { fs.writeFileSync(`${result.url}.jpg`, Buffer.from(result.image, 'base64')); } else { console.error(`Failed: ${result.url} — ${result.error}`); } } ``` - **Max 10 URLs per batch** - All options (format, width, height, etc.) are shared across all URLs - Returns partial results — some may succeed while others fail - Response is always JSON with `{ results: [...] }` ### `snap.health()` Returns API health status. ### Error Handling ```typescript 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](https://snapapi.eu). ## License MIT — [Cloonar Technologies GmbH](https://snapapi.eu)