Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
YouTube Security Videosheise & c't: Gebrauchte CPU gekauft – plötzlich ist der PC gesperrt(01.10.2026 um 13:08 Uhr)
•
Windows Tipps & SecuritySD-Karten sind teuer wie nie: So halten sie deutlich länger(01.10.2026 um 13:15 Uhr)
•••••••••
YouTube Security Videosheise & c't: Gebrauchte CPU gekauft – plötzlich ist der PC gesperrt(01.10.2026 um 13:08 Uhr)
•
Windows Tipps & SecuritySD-Karten sind teuer wie nie: So halten sie deutlich länger(01.10.2026 um 13:15 Uhr)
•••••••••
Intelligence View
⚡ tsecurity.de Intelligence

How to Take Screenshots in TypeScript with the PageBolt API

How to Take Screenshots in TypeScript with the PageBolt API You're building a TypeScript app that needs screenshots. You have a few options: Self-host…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!




How to Take Screenshots in TypeScript with the PageBolt API



You're building a TypeScript app that needs screenshots. You have a few options:





  1. Self-host Puppeteer — manage browser processes, handle crashes, scale in production


  2. Use a screenshot API — one endpoint, type-safe, no infrastructure



If you've chosen option 2, here's how to integrate PageBolt with full TypeScript support.






The Basic Pattern: Type-Safe API Calls






import * as fs from 'fs';

// Define your request shape
interface ScreenshotRequest {
url: string;
format: 'png' | 'jpeg' | 'webp';
width?: number;
height?: number;
fullPage?: boolean;
blockBanners?: boolean;
}

// Define the API response
interface ScreenshotResponse {
success: boolean;
message?: string;
}

// Define possible errors
type ScreenshotError =
| { code: 'INVALID_URL'; message: string }
| { code: 'API_ERROR'; status: number; message: string }
| { code: 'FILE_WRITE_ERROR'; message: string };

async function takeScreenshot(
request: ScreenshotRequest,
outputPath: string,
apiKey: string
): Promise<ScreenshotResponse | ScreenshotError> {
try {
const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: request.url,
format: request.format,
width: request.width || 1280,
height: request.height || 720,
fullPage: request.fullPage ?? false,
blockBanners: request.blockBanners ?? true
})
});

if (!response.ok) {
return {
code: 'API_ERROR',
status: response.status,
message: `Screenshot API returned ${response.status}`
};
}

// Get binary response as ArrayBuffer
const buffer = await response.arrayBuffer();

// Write to disk using Buffer
fs.writeFileSync(outputPath, Buffer.from(buffer));

return { success: true };
} catch (error) {
if (error instanceof Error) {
return {
code: 'FILE_WRITE_ERROR',
message: error.message
};
}
throw error;
}
}

// Usage
const result = await takeScreenshot(
{
url: 'https://example.com',
format: 'png',
fullPage: true,
blockBanners: true
},
'./screenshot.png',
'YOUR_API_KEY'
);

if (result.success) {
console.log('Screenshot saved');
} else {
console.error(`Error: ${result.message}`);
}






What this does:




  1. Defines strict types for request, response, and errors

  2. Uses response.arrayBuffer() to handle binary PNG data

  3. Writes to disk using Buffer.from()

  4. Returns typed error objects instead of throwing






Production Pattern: Class-Based API Client



For larger projects, wrap the API in a client class:




import * as fs from 'fs';
import * as path from 'path';

interface ScreenshotOptions {
url: string;
format?: 'png' | 'jpeg' | 'webp';
width?: number;
height?: number;
fullPage?: boolean;
blockBanners?: boolean;
blockAds?: boolean;
darkMode?: boolean;
}

class PageBoltClient {
private apiKey: string;
private apiBase = 'https://api.pagebolt.dev/v1';

constructor(apiKey: string) {
this.apiKey = apiKey;
}

async screenshot(
options: ScreenshotOptions,
outputPath?: string
): Promise<{ data: Buffer; path?: string }> {
const payload = {
url: options.url,
format: options.format || 'png',
width: options.width || 1280,
height: options.height || 720,
fullPage: options.fullPage ?? false,
blockBanners: options.blockBanners ?? true,
blockAds: options.blockAds ?? false,
darkMode: options.darkMode ?? false
};

const response = await fetch(`${this.apiBase}/screenshot`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});

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

const buffer = Buffer.from(await response.arrayBuffer());

if (outputPath) {
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
fs.writeFileSync(outputPath, buffer);
return { data: buffer, path: outputPath };
}

return { data: buffer };
}

async batch(
urls: string[],
outputDir: string,
options?: Partial<ScreenshotOptions>
): Promise<{ path: string; url: string }[]> {
const results: { path: string; url: string }[] = [];

for (const url of urls) {
const filename = `${Date.now()}-${Math.random().toString(36).slice(2)}.png`;
const filepath = path.join(outputDir, filename);

const result = await this.screenshot(
{ ...options, url },
filepath
);

results.push({
url,
path: result.path || filepath
});
}

return results;
}
}

// Usage
const client = new PageBoltClient(process.env.PAGEBOLT_API_KEY!);

// Single screenshot
const { data, path: filePath } = await client.screenshot(
{
url: 'https://example.com',
fullPage: true
},
'./screenshots/homepage.png'
);

console.log(`Screenshot saved to ${filePath}`);

// Batch screenshots
const urls = [
'https://example.com',
'https://example.com/about',
'https://example.com/pricing'
];

const results = await client.batch(urls, './screenshots');
console.log(`Batch complete: ${results.length} screenshots`);









Node.js Integration: Screenshot on Route



Use PageBolt in an Express server:




import express, { Request, Response } from 'express';
import * as fs from 'fs';
import * as path from 'path';

const app = express();
const apiKey = process.env.PAGEBOLT_API_KEY!;

interface ScreenshotBody {
url: string;
format?: 'png' | 'jpeg' | 'webp';
fullPage?: boolean;
}

app.post('/api/screenshot', async (req: Request<{}, {}, ScreenshotBody>, res: Response) => {
const { url, format = 'png', fullPage = true } = req.body;

if (!url) {
return res.status(400).json({ error: 'url is required' });
}

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

if (!response.ok) {
return res.status(response.status).json({
error: `Screenshot API error: ${response.statusText}`
});
}

const buffer = Buffer.from(await response.arrayBuffer());

// Return image directly
res.setHeader('Content-Type', `image/${format}`);
res.setHeader('Content-Length', buffer.length);
res.send(buffer);
} catch (error) {
console.error('Screenshot error:', error);
res.status(500).json({
error: error instanceof Error ? error.message : 'Unknown error'
});
}
});

app.listen(3000, () => {
console.log('Server listening on :3000');
console.log('POST /api/screenshot with { url, format?, fullPage? }');
});






Test it:




curl -X POST http://localhost:3000/api/screenshot \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com","fullPage":true}' \
> example.png









Deno Integration: Modern Async TypeScript



Deno handles typed fetch natively. No Buffer needed — Deno has Uint8Array:




// deno.json
{
"imports": {
"std/": "https://deno.land/[email protected]/"
}
}









// screenshot.ts (Deno)
interface ScreenshotOptions {
url: string;
format?: 'png' | 'jpeg' | 'webp';
width?: number;
height?: number;
fullPage?: boolean;
blockBanners?: boolean;
}

async function takeScreenshot(
options: ScreenshotOptions,
outputPath: string,
apiKey: string
): Promise<void> {
const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: options.url,
format: options.format || 'png',
width: options.width || 1280,
height: options.height || 720,
fullPage: options.fullPage ?? false,
blockBanners: options.blockBanners ?? true
})
});

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

// Deno: use arrayBuffer() then write
const buffer = await response.arrayBuffer();
await Deno.writeFile(outputPath, new Uint8Array(buffer));

console.log(`Screenshot saved to ${outputPath}`);
}

// Usage
const apiKey = Deno.env.get('PAGEBOLT_API_KEY') || '';

await takeScreenshot(
{
url: 'https://example.com',
fullPage: true,
blockBanners: true
},
'./screenshot.png',
apiKey
);






Run it:




export PAGEBOLT_API_KEY=your_key_here
deno run --allow-net --allow-write screenshot.ts









Error Handling Patterns



Distinguish between recoverable and fatal errors:




type ApiErrorCode =
| 'INVALID_URL'
| 'TIMEOUT'
| 'INVALID_FORMAT'
| 'RATE_LIMIT'
| 'API_ERROR';

class ApiError extends Error {
constructor(
public code: ApiErrorCode,
public statusCode?: number,
message?: string
) {
super(message);
this.name = 'ApiError';
}
}

async function takeScreenshotWithRetry(
url: string,
apiKey: string,
maxRetries = 3
): Promise<Buffer> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch('https://api.pagebolt.dev/v1/screenshot', {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ url, format: 'png' })
});

if (response.status === 429) {
// Rate limit: wait and retry
if (attempt < maxRetries) {
const waitMs = 1000 * Math.pow(2, attempt - 1);
console.log(`Rate limited. Retrying in ${waitMs}ms...`);
await new Promise(resolve => setTimeout(resolve, waitMs));
continue;
}
throw new ApiError('RATE_LIMIT', 429);
}

if (!response.ok) {
throw new ApiError('API_ERROR', response.status);
}

return Buffer.from(await response.arrayBuffer());
} catch (error) {
if (error instanceof ApiError && error.code === 'RATE_LIMIT') {
if (attempt === maxRetries) throw error;
continue;
}
throw error;
}
}

throw new Error('Max retries exceeded');
}









Real Use Case: Marketing Email Screenshots



Generate screenshots for email campaigns:




import { PageBoltClient } from './pagebolt-client';

interface EmailVariant {
name: string;
url: string;
}

async function generateEmailProofs(
variants: EmailVariant[],
outputDir: string
): Promise<void> {
const client = new PageBoltClient(process.env.PAGEBOLT_API_KEY!);

console.log(`Generating ${variants.length} screenshots...`);

for (const variant of variants) {
const outputPath = `${outputDir}/${variant.name}.png`;

await client.screenshot(
{
url: variant.url,
width: 600, // Email width
fullPage: true,
blockBanners: true,
blockAds: true
},
outputPath
);

console.log(`✓ ${variant.name}`);
}

console.log(`All screenshots saved to ${outputDir}`);
}

// Usage
await generateEmailProofs(
[
{ name: 'variant-a', url: 'https://example.com?variant=a' },
{ name: 'variant-b', url: 'https://example.com?variant=b' },
{ name: 'variant-c', url: 'https://example.com?variant=c' }
],
'./email-proofs'
);









Pricing






































Plan Requests/Month Cost Best For
Free 100 $0 Learning, low-volume projects
Starter 5,000 $29 Small teams, moderate use
Growth 25,000 $79 Production apps, frequent calls
Scale 100,000 $199 High-volume automation





Summary




  • ✅ Full TypeScript support with proper types

  • ✅ response.arrayBuffer() for binary PNG handling

  • ✅ Buffer.from() for Node.js, Uint8Array for Deno

  • ✅ Error handling with typed error codes

  • ✅ Works in Node.js, Deno, and Express

  • ✅ Batch processing for multiple URLs

  • ✅ No browser management overhead



Get started free: pagebolt.dev — 100 requests/month, no credit card required.

2. Cyber Threat Intelligence & Forensik

CTI Threat Relationship Graph2 Knoten / 1 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten How to Take Screenshots in TypeScript with the PageBolt API

Thematisch verwandte Begriffe: Take, Screenshots, TypeScript, with · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag