Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Render the API response in a dedicated Angular element, wait for Angular and its images and fonts to finish, then pass that element to html2canvas. Bind the string with Angular’s sanitized [innerHTML] rather than assigning untrusted markup through element.innerHTML. Export the resulting canvas with toDataURL('image/png') for a simple data URL or toBlob() for downloads and uploads.

What the conversion actually does

An HTML string is not an image file. Angular must first parse and render it in the browser. html2canvas then walks the rendered DOM and reconstructs the supported layout, text, colors and images on a canvas. It is not a native browser screenshot, so CSS that the library does not support can differ from what the user sees.

This approach is suitable when the conversion happens in a browser and the target is an Angular component. It does not run in Node.js, and it cannot render cross-origin iframes. For server-side or pixel-accurate output, use a real browser renderer such as Puppeteer or Playwright instead.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Install html2canvas

npm install html2canvas

Import the package in the component that performs the capture. Keep the capture element separate from the rest of the page so navigation controls, loading messages and buttons are not included accidentally.

Complete Angular example

Component template and code

import { AfterViewInit, Component, ElementRef, ViewChild } from '@angular/core';
import html2canvas from 'html2canvas';

@Component({
  selector: 'app-html-image',
  standalone: true,
  template: `
    <div #capture class="capture" [innerHTML]="apiHtml"></div>
    <img *ngIf="imageUrl" [src]="imageUrl" alt="Rendered API HTML">
    <button type="button" (click)="makeImage()">Create image</button>
  `,
  styles: [
    `.capture { background: #fff; }`
  ]
})
export class HtmlImageComponent implements AfterViewInit {
  @ViewChild('capture', { static: false }) capture!: ElementRef<HTMLElement>;

  apiHtml = '';
  imageUrl = '';

  ngAfterViewInit(): void {
    // Fetch the API response here or from a service. The response must be text.
  }

  async makeImage(): Promise<void> {
    const element = this.capture.nativeElement;
    await this.waitForImages(element);
    await document.fonts?.ready;

    const canvas = await html2canvas(element, {
      backgroundColor: '#ffffff',
      useCORS: true,
      scale: window.devicePixelRatio,
      windowWidth: element.scrollWidth,
      windowHeight: element.scrollHeight
    });

    this.imageUrl = canvas.toDataURL('image/png');
  }

  private async waitForImages(root: HTMLElement): Promise<void> {
    const images = Array.from(root.querySelectorAll('img'));
    await Promise.all(images.map((img) => {
      if (img.complete) {
        return img.decode?.().catch(() => undefined);
      }
      return new Promise<void>((resolve) => {
        img.addEventListener('load', () => resolve(), { once: true });
        img.addEventListener('error', () => resolve(), { once: true });
      });
    }));
  }
}

Assign the API response as text, for example with HttpClient configured for responseType: 'text':

this.http.get('/api/content', { responseType: 'text' }).subscribe(html => {
  this.apiHtml = html;
});

Clicking the button after assignment gives Angular a deterministic point at which the element exists. If capture must happen automatically, schedule it after the value is assigned and Angular has rendered the update, then await images and fonts as shown above. A lifecycle hook alone does not guarantee that asynchronously fetched content has appeared.

Safely render API HTML

Use the normal binding

[innerHTML]="apiHtml" places the string in Angular’s HTML security context. Angular sanitizes untrusted values and removes or neutralizes dangerous markup. Keep the server contract narrow: allow only the tags, attributes, styles and URLs the application actually needs.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Do not bypass sanitization casually

Do not call DomSanitizer.bypassSecurityTrustHtml() for an API value merely to make a style appear. Angular documents that bypassing security with attacker-controlled data can expose the application to cross-site scripting. If users can influence the API response, sanitize it at the trust boundary and reject scripts, event-handler attributes such as onclick, dangerous URL schemes and unexpected resource loads.

Why direct DOM writes are a poor fit

Writing element.innerHTML = apiHtml bypasses Angular’s normal template safeguards and makes it harder to reason about updates and trust. Use a ViewChild only to identify the already-bound capture element; let Angular perform the binding.

Make the captured image match the rendered content

Wait for images and fonts

An image element can exist before its network request or decoding has completed. Capture after img.complete/img.decode() and document.fonts.ready. If a remote image fails, the sample resolves and captures the remaining content; you can instead show an error or abort when missing assets are unacceptable.

Choose the capture dimensions

windowWidth and windowHeight are set to the element’s scroll dimensions so content below the fold is included. Give the capture element an explicit background and stable width. For a fixed social-card size, set CSS dimensions and pass those dimensions instead of the full scroll size.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Control pixel density

scale: window.devicePixelRatio produces sharper output on high-density displays but increases canvas memory and export time. For large documents, use a lower scale or a fixed value such as 1. A very large element can exceed browser canvas limits and produce blank or truncated output; split the content or render it on a server in that case.

Understand CSS fidelity

html2canvas supports many common CSS properties but reconstructs them rather than asking the browser for a bitmap. Unsupported or partially supported effects can change. Test gradients, filters, complex blend modes, pseudo-elements, sticky positioning and custom fonts in the browsers you support.

Cross-origin images and iframes

useCORS: true works only when the image server sends a permissive CORS header. Without it, the canvas can become tainted and JavaScript cannot read or export it. Put assets behind a controlled same-origin proxy or inline approved images as data URLs. Do not set allowTaint: true when the result must be read, downloaded or uploaded.

Cross-origin iframes cannot be reconstructed by html2canvas. Replace them with data fetched through your own origin, capture the iframe separately if you control it, or use a real browser automation service that can navigate the page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Export, download or upload the result

Display or download a PNG

const dataUrl = canvas.toDataURL('image/png');
this.imageUrl = dataUrl;

const link = document.createElement('a');
link.href = dataUrl;
link.download = 'api-content.png';
link.click();

toDataURL is convenient for previews and small files, but it keeps the entire image as a base64 string in memory.

Prefer a Blob for larger files

canvas.toBlob((blob) => {
  if (!blob) return;
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.download = 'api-content.png';
  link.click();
  URL.revokeObjectURL(url);
}, 'image/png');

A Blob is a better hand-off for uploads. Send it with FormData rather than converting it to base64 first.

JPEG and WebP

const jpeg = canvas.toDataURL('image/jpeg', 0.9);
canvas.toBlob(blob => { /* upload blob */ }, 'image/webp', 0.85);

JPEG discards transparency and introduces compression artifacts. PNG preserves transparency and sharp text; WebP can reduce size when your consumers support it.

Automatic capture after an API update

If the image should be generated immediately after the response arrives, assign apiHtml, then queue the capture after Angular’s render pass. In newer Angular applications, use an Angular render-safe callback; otherwise a queued microtask or change-detection-aware scheduling step can be used, followed by the explicit image and font waits. Do not call html2canvas in the same synchronous statement that changes apiHtml, because the old DOM may still be present.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshooting

The output is blank or cut off

  • Check that the capture element has non-zero width and height when the call runs.
  • Wait for Angular’s update, images and fonts.
  • Reduce scale or split an exceptionally large element to stay within browser canvas dimensions.

Images are missing or the canvas cannot be exported

  • Confirm the image response includes an appropriate CORS header.
  • Use a same-origin proxy or data URLs for approved assets.
  • Keep allowTaint false when exporting.

Styles differ from the page

  • Verify that the stylesheets and web fonts have loaded before capture.
  • Replace unsupported CSS effects with simpler, supported properties.
  • Capture the element with its intended computed dimensions and background.

API markup appears as text or is missing

  • Request the endpoint with responseType: 'text', not JSON.
  • Bind the returned string to [innerHTML] and confirm that the value is assigned before capture.
  • Inspect sanitized output; Angular may remove unsafe tags, attributes or URLs by design.

Angular throws a security warning

Remove an unnecessary bypassSecurityTrustHtml call. Validate and sanitize the content at the trust boundary instead of suppressing the warning.

Server-side rendering fails

html2canvas requires browser APIs such as the DOM, canvas and image loading. Guard browser-only code in an application that uses SSR, and use Puppeteer or Playwright when the image must be generated on the server.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Client-side html2canvas or a browser renderer?

Requirement Angular plus html2canvas Headless browser renderer
Where it runs In a user’s browser Server or automation worker
Rendering model Reconstructs supported DOM and CSS Captures a real browser page
Cross-origin iframes Not supported Can navigate and capture according to browser permissions
Best fit Interactive previews and user-triggered exports Scheduled, server-side or pixel-sensitive images
Main costs Browser memory, CORS setup and client CPU Browser infrastructure, queueing and request control

Or skip the browser setup

ScreenshotNeo returns a PNG, JPEG, WebP or PDF from one GET request, so your Angular app can request an image instead of reconstructing the API HTML in the client. It accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and whether it was billed. Its MCP server provides take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients.

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

See the ScreenshotNeo documentation for request options. The service includes full-page lazy-image loading, CSS-selector element capture, dark mode, device presets and custom viewports, retina scale, PDF paper and page controls, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen-TTL caching, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification. Parameter names used by other screenshot APIs also work, which can simplify migration.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan, and yearly billing provides two months free. Sign up for the free ScreenshotNeo plan and use the 1,000 monthly screenshots without adding a card.

Practical checklist

  • Request the API response as text.
  • Bind it with sanitized [innerHTML].
  • Keep scripts, event handlers and unsafe URLs out of accepted markup.
  • Capture only after Angular has rendered and required images and fonts are ready.
  • Use CORS-enabled or same-origin images; never rely on a tainted canvas for export.
  • Set dimensions and scale deliberately, especially for long content.
  • Choose toDataURL for a quick preview and toBlob for larger downloads or uploads.
  • Use a real browser renderer for SSR, cross-origin iframes or pixel-accurate server output.

Frequently Asked Questions

Can I convert an HTML string to an image without displaying it to the user?

Yes. Render it in an off-screen or visually hidden capture element, keep it in the DOM long enough for layout and assets to load, then call html2canvas. Do not use display:none, because an element with no layout cannot produce a useful canvas.

Why does sanitization remove part of my API response?

Angular removes markup it considers unsafe. Treat that as a signal to narrow and validate the server contract, rather than bypassing sanitization; only explicitly trusted, reviewed content should be allowed through a security bypass.

Is a canvas image automatically available as a file?

No. A canvas is an in-memory object. Export it with toDataURL or toBlob, then create a download or upload the resulting data.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.