Screenshot API for Angular
Integrate ScreenshotAPI with Angular to capture website screenshots. HttpClient examples, service patterns, and SSR support.
Last updated: 2026-03-25
Try ScreenshotAPI free
5 free credits. No credit card required.
Take Website Screenshots in Angular with ScreenshotAPI
Angular applications often need screenshot functionality for generating link previews, building site monitoring dashboards, or creating PDF reports. The typical approach involves installing Puppeteer or Playwright on the server, which adds a 50 MB Chromium binary and complicates CI/CD pipelines.
ScreenshotAPI offers a simpler path for your Angular screenshot API integration. One HTTP request from your backend returns a pixel-perfect PNG, JPEG, or WebP. No headless browser binary, no special Docker configuration, no runtime version conflicts.
Quick Start
- Sign up for ScreenshotAPI and copy your API key from the dashboard. 5 free credits are included to start.
- Create a backend proxy endpoint (Express, NestJS, or any Node.js server).
- Build an Angular service that calls the proxy and displays the result.
Installation
Your Angular frontend does not need any additional packages. On the backend, install the SDK if you want typed helpers:
bashnpm install screenshotapi
Store the API key as an environment variable on your server:
bashSCREENSHOTAPI_KEY=sk_live_xxxxx
Backend Proxy Setup
Angular apps should never call ScreenshotAPI directly from the browser because that would expose your API key. Set up a lightweight proxy. Here is an Express example:
typescript// server/screenshot.ts import express from 'express' const router = express.Router() const API_BASE = 'https://screenshotapi.to/api/v1/screenshot' router.get('/api/screenshot', async (req, res) => { const url = req.query.url as string if (!url) { return res.status(400).json({ error: 'url parameter is required' }) } const params = new URLSearchParams({ url, width: String(req.query.width ?? 1440), height: String(req.query.height ?? 900), type: String(req.query.type ?? 'webp'), quality: String(req.query.quality ?? 80), }) const response = await fetch(`${API_BASE}?${params}`, { headers: { 'x-api-key': process.env.SCREENSHOTAPI_KEY! }, }) if (!response.ok) { return res.status(502).json({ error: 'Screenshot capture failed' }) } const buffer = Buffer.from(await response.arrayBuffer()) const imageType = req.query.type ?? 'webp' res.set('Content-Type', `image/${imageType}`) res.set('Cache-Control', 'public, max-age=3600') res.send(buffer) }) export default router
See the full Express integration guide for more details on building the proxy layer.
Angular Screenshot Service
Create a dedicated service that encapsulates all screenshot logic. Configure provideHttpClient() in your application config first:
typescript// main.ts import { bootstrapApplication } from '@angular/platform-browser' import { provideHttpClient } from '@angular/common/http' import { AppComponent } from './app/app.component' bootstrapApplication(AppComponent, { providers: [provideHttpClient()], })
Then build the service:
typescript// screenshot.service.ts import { Injectable, inject } from '@angular/core' import { HttpClient, HttpParams } from '@angular/common/http' import { Observable, map } from 'rxjs' export interface ScreenshotOptions { url: string width?: number height?: number type?: 'png' | 'jpeg' | 'webp' quality?: number fullPage?: boolean colorScheme?: 'light' | 'dark' } @Injectable({ providedIn: 'root' }) export class ScreenshotService { private http = inject(HttpClient) capture(options: ScreenshotOptions): Observable<string> { let params = new HttpParams() .set('url', options.url) .set('width', String(options.width ?? 1440)) .set('height', String(options.height ?? 900)) .set('type', options.type ?? 'webp') if (options.quality) params = params.set('quality', String(options.quality)) if (options.fullPage) params = params.set('fullPage', 'true') if (options.colorScheme) params = params.set('colorScheme', options.colorScheme) return this.http .get('/api/screenshot', { params, responseType: 'blob' }) .pipe(map((blob) => URL.createObjectURL(blob))) } }
Basic Component
Use the service in a standalone component:
typescript// screenshot.component.ts import { Component, inject, signal } from '@angular/core' import { FormsModule } from '@angular/forms' import { ScreenshotService } from './screenshot.service' @Component({ selector: 'app-screenshot', standalone: true, imports: [FormsModule], template: ` <div class="screenshot-capture"> <div class="input-row"> <input [(ngModel)]="targetUrl" type="url" placeholder="https://example.com" (keyup.enter)="capture()" /> <button [disabled]="loading()" (click)="capture()"> {{ loading() ? 'Capturing...' : 'Capture' }} </button> </div> @if (error()) { <p class="error">{{ error() }}</p> } @if (loading()) { <div class="skeleton"></div> } @if (screenshotUrl()) { <img [src]="screenshotUrl()" alt="Website screenshot" /> } </div> `, }) export class ScreenshotComponent { private screenshotService = inject(ScreenshotService) targetUrl = '' screenshotUrl = signal<string | null>(null) loading = signal(false) error = signal<string | null>(null) capture() { if (!this.targetUrl) return this.loading.set(true) this.error.set(null) this.screenshotService .capture({ url: this.targetUrl, type: 'webp', quality: 80 }) .subscribe({ next: (url) => { this.screenshotUrl.set(url) this.loading.set(false) }, error: (err) => { this.error.set(err.message ?? 'Screenshot failed') this.loading.set(false) }, }) } }
Batch Screenshots with forkJoin
Capture multiple screenshots in parallel using RxJS forkJoin:
typescriptimport { forkJoin } from 'rxjs' const urls = [ 'https://github.com', 'https://angular.dev', 'https://stackoverflow.com', ] forkJoin( urls.map((url) => this.screenshotService.capture({ url, width: 1440, height: 900 }) ) ).subscribe({ next: (objectUrls) => { this.screenshots.set( urls.map((url, i) => ({ url, src: objectUrls[i] })) ) }, error: (err) => console.error('Batch capture failed:', err), })
HTTP Interceptor for Error Handling
Add a global interceptor to handle screenshot API errors consistently:
typescript// screenshot-error.interceptor.ts import { HttpInterceptorFn } from '@angular/common/http' import { catchError, throwError } from 'rxjs' export const screenshotErrorInterceptor: HttpInterceptorFn = (req, next) => { if (!req.url.includes('/api/screenshot')) { return next(req) } return next(req).pipe( catchError((error) => { const message = error.status === 400 ? 'Invalid URL provided' : error.status === 502 ? 'Screenshot service temporarily unavailable' : 'An unexpected error occurred' return throwError(() => new Error(message)) }) ) }
Register it in your application config:
typescriptimport { provideHttpClient, withInterceptors } from '@angular/common/http' import { screenshotErrorInterceptor } from './screenshot-error.interceptor' bootstrapApplication(AppComponent, { providers: [ provideHttpClient(withInterceptors([screenshotErrorInterceptor])), ], })
Dark Mode Comparison
Capture both light and dark variants side by side for visual regression testing:
typescriptcaptureComparison(url: string) { forkJoin({ light: this.screenshotService.capture({ url, colorScheme: 'light' }), dark: this.screenshotService.capture({ url, colorScheme: 'dark' }), }).subscribe(({ light, dark }) => { this.lightSrc.set(light) this.darkSrc.set(dark) }) }
Production Tips
Memory Cleanup
Revoke object URLs when the component is destroyed to prevent memory leaks:
typescriptimport { OnDestroy } from '@angular/core' export class ScreenshotComponent implements OnDestroy { ngOnDestroy() { const url = this.screenshotUrl() if (url) URL.revokeObjectURL(url) } }
Rate Limiting on the Proxy
Protect your API key by adding rate limiting to the backend proxy. Use middleware like express-rate-limit to cap requests per IP address.
Caching Strategy
Set Cache-Control headers on your proxy responses so the browser and CDN cache screenshots. For longer-lived thumbnails, store images in an object store and serve them directly. Visit the pricing page to select the credit tier that fits your usage.
Input Validation
Always validate the URL on the server before forwarding it to ScreenshotAPI:
typescriptfunction isValidUrl(input: string): boolean { try { const parsed = new URL(input) return ['http:', 'https:'].includes(parsed.protocol) } catch { return false } }
Further Reading
- How to Take Screenshots with JavaScript covers the fundamentals of browser screenshot capture.
- The JavaScript SDK documentation has the complete parameter reference.
- Explore the Express integration for a more detailed backend proxy setup.
Frequently asked questions
Do I need Puppeteer to take screenshots in Angular?
No. ScreenshotAPI handles all browser rendering remotely. Your Angular app makes an HTTP request and receives the image bytes. No headless browser installation is needed.
Should I call ScreenshotAPI from the Angular frontend or a backend?
Always proxy through a backend to protect your API key. Your Angular HttpClient calls your backend, which calls ScreenshotAPI with the key stored server-side.
Does ScreenshotAPI work with Angular SSR?
Yes. Angular Universal or the newer SSR support can call ScreenshotAPI during server-side rendering. Since it is a standard HTTP request, it works in both browser and Node.js environments.
How do I display a screenshot image returned as binary data?
Request the response as a Blob using HttpClient's responseType option, create an object URL with URL.createObjectURL, and bind it to an img element's src property.
Related resources
Start capturing screenshots today
Create a free account and get 5 credits to try the API. No credit card required. Pay only for what you use.