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

Use the API that creates the request. In Puppeteer, call page.setExtraHTTPHeaders() for headers on every request initiated by a page, inspect outgoing values with request.headers(), or intercept requests when only selected URLs should change. In Angular, pass headers to an individual HttpClient call, or register a functional interceptor for shared behavior. Puppeteer page traffic and Angular HttpClient traffic are separate layers; configuring one does not configure the other.

Choose the request-producing layer first

Before changing a header, identify which code actually sends the HTTP request. A navigation, image, script, fetch, or XHR initiated by a browser page is controlled by Puppeteer. A call such as this.http.get() is produced by Angular’s HttpClient. A header added in one layer will not automatically appear on requests created independently in the other.

Need Use Scope
Add headers to all requests from a Puppeteer page page.setExtraHTTPHeaders() Every request initiated by that page
Inspect headers associated with a Puppeteer request request.headers() in a page.on('request') listener One observed request at a time
Change only matching Puppeteer requests Request interception and request.continue({ headers }) Conditional or per-request
Add a header to one Angular call The call’s headers option That request only
Apply shared or conditional Angular behavior A functional interceptor registered with provideHttpClient(withInterceptors(...)) Requests passing through that client configuration

Set headers on every Puppeteer page request

Call setExtraHTTPHeaders before navigation or other page activity. It accepts a Record<string, string> and returns a promise, so await it. Every value must be a string.

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();

await page.setExtraHTTPHeaders({
  'x-client-id': 'demo',
  authorization: 'Bearer example-token',
});

await page.goto('https://example.com');
await browser.close();

Puppeteer lowercases header names. HTTP header names are case-insensitive, so this normally does not change their meaning. The method is not a way to preserve a particular header order, and it should not be presented as a guarantee that a header is sent only to one origin. If a credential must be limited to selected destinations, use interception with an explicit URL check instead.

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

Read request headers in Puppeteer

Listen for requests and print the URL together with the headers exposed by Puppeteer’s request object:

page.on('request', request => {
  console.log(request.url(), request.headers());
});

HTTPRequest.headers() returns an object whose header names are lowercase. This is the request representation exposed to Puppeteer. It is useful for confirming what the automation layer prepared, but it does not prove what a remote server ultimately received. For that question, compare server-side logs or an appropriate network trace.

Install the listener before the action you want to diagnose. For example:

page.on('request', request => {
  if (request.url().includes('/api/')) {
    console.log({ url: request.url(), headers: request.headers() });
  }
});

await page.goto('https://example.com/dashboard');

Change headers only for selected Puppeteer requests

Use request interception when a page-wide header would be too broad. Interception must be enabled before calling request.continue() with overrides.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.setRequestInterception(true);

page.on('request', request => {
  const headers = {
    ...request.headers(),
    'x-client-id': 'demo',
  };

  void request.continue({ headers });
});

The spread preserves the headers Puppeteer already exposed, while the later property replaces or adds x-client-id. The same override object can remove a header by assigning undefined, as supported by Puppeteer’s interception API.

Once interception is enabled, every intercepted request must be resolved by continuing, responding, or aborting it. If a listener forgets to resolve even one request, page activity can stall. Keep the handler synchronous where possible, and make URL tests explicit when credentials or special headers are involved:

await page.setRequestInterception(true);

page.on('request', request => {
  const url = request.url();
  if (url.startsWith('https://api.example.com/')) {
    void request.continue({
      headers: {
        ...request.headers(),
        authorization: 'Bearer example-token',
      },
    });
    return;
  }

  void request.continue();
});

This pattern makes the default path visible and prevents unrelated assets from receiving an API credential.

Set headers on one Angular HttpClient request

For a single call, pass a plain object in the request options:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
this.http.get<Config>('/api/config', {
  headers: { 'X-Debug-Level': 'verbose' },
});

Construct HttpHeaders when you need to build or reuse a set of values. HttpHeaders is immutable: methods such as set and append return a new instance. Assign the returned value rather than expecting the original object to change.

import { HttpHeaders } from '@angular/common/http';

const baseHeaders = new HttpHeaders().set('X-Debug-Level', 'minimal');
const requestHeaders = baseHeaders.set('X-Debug-Level', 'verbose');

this.http.get<Config>('/api/config', {
  headers: requestHeaders,
});

Use set when one value should replace an existing value. Use append when the request should contain an additional value for that header. In either case, retain the returned HttpHeaders instance.

Use a functional Angular interceptor for shared or conditional headers

An interceptor is appropriate for cross-cutting behavior such as a client identifier, authentication, or logging. Angular’s current guidance uses functional interceptors. The interceptor receives an immutable request, clones it with the updated headers, and passes the clone to the next handler.

import {
  HttpHandlerFn,
  HttpRequest,
  HttpEvent,
  provideHttpClient,
  withInterceptors,
} from '@angular/common/http';
import { Observable } from 'rxjs';

export function clientIdInterceptor(
  req: HttpRequest<unknown>,
  next: HttpHandlerFn,
): Observable<HttpEvent<unknown>> {
  const updated = req.clone({
    headers: req.headers.set('X-Client-Id', 'demo'),
  });
  return next(updated);
}

// In application providers:
provideHttpClient(withInterceptors([clientIdInterceptor]));

HttpRequest is immutable too. Calling req.headers.set(...) alone does not alter the request; the cloned request must be sent to next. Scope an authentication interceptor so credentials are not attached indiscriminately to unrelated destinations.

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.

Conditionally add a header

Check the request before cloning it. Requests that do not match should pass through unchanged:

export function apiTokenInterceptor(
  req: HttpRequest<unknown>,
  next: HttpHandlerFn,
): Observable<HttpEvent<unknown>> {
  if (!req.url.startsWith('/api/')) {
    return next(req);
  }

  return next(req.clone({
    headers: req.headers.set('Authorization', 'Bearer example-token'),
  }));
}

Observe response events in an interceptor

The value returned by next(req) is an observable of HTTP events. If you need to inspect response fields, transform that observable and check for the final response event rather than treating every event as a completed response:

import {
  HttpEventType,
  HttpHandlerFn,
  HttpRequest,
} from '@angular/common/http';
import { tap } from 'rxjs/operators';

export function loggingInterceptor(req, next) {
  return next(req).pipe(
    tap(event => {
      if (event.type === HttpEventType.Response) {
        console.log('status:', event.status);
        console.log('response headers:', event.headers);
      }
    }),
  );
}

How to decide between the alternatives

Question Recommended choice Reason
Should every request from this page carry the value? setExtraHTTPHeaders One page-level configuration covers page-initiated traffic.
Should only API calls or a URL pattern carry it? Puppeteer interception The handler can inspect the URL and override selected requests.
Is the request a one-off Angular call? HttpClient options The scope is explicit at the call site.
Is the behavior shared across Angular calls? Functional interceptor One registered policy can clone matching requests consistently.
Do you need to know what a server received? Server logs or a network trace Puppeteer’s request object shows the automation-layer representation, not server-side receipt.

Troubleshooting headers that are missing or wrong

The header is absent from a Puppeteer request

  • Confirm that await page.setExtraHTTPHeaders(...) ran before goto or the action that created the request.
  • Verify that every value is a string.
  • Check whether the request came from a different page or from application code outside the Puppeteer page.
  • Remember that names are exposed in lowercase when you inspect them.

Interception causes the page to hang

With interception enabled, resolve every request. Add a default request.continue() path, and ensure asynchronous logic cannot exit without continuing, responding, or aborting.

The server does not see the value you logged

request.headers() reports the headers associated with Puppeteer’s request object. Compare the value with server-side logs or a network trace when receipt, redirects, proxies, or other network layers matter.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
The SQL Programming Language: .
  • Used Book in Good Condition

An Angular header change has no effect

  • When using HttpHeaders, assign the object returned by set or append.
  • When using an interceptor, clone the request and pass the clone to next.
  • Verify that the interceptor is registered through provideHttpClient(withInterceptors([...])).
  • Check that the request is actually made by Angular HttpClient, rather than by an unrelated browser or third-party client.

A credential is sent too broadly

Replace a page-wide Puppeteer header with URL-checked interception, or narrow an Angular interceptor to the API paths that require it. Avoid treating either global mechanism as origin filtering.

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

Operational notes for reliable automation and applications

  • Configure Puppeteer headers before navigation so the first request follows the intended policy.
  • Use page-wide headers only for values that are safe across that page’s traffic; interception adds control but requires a resolution path for every request.
  • Keep inspection listeners focused on the URLs or events you need to diagnose so logs remain usable.
  • In Angular, keep one-call headers near the call site and reserve interceptors for genuinely shared rules.
  • Treat header values as secrets when they contain authorization data. Do not print tokens in logs or attach them to unrelated destinations.
  • Because Angular request and header objects are immutable, code that reassigns returned instances is easier to reason about than code that relies on mutation.

Or skip the browser setup

If your actual goal is to capture a page after setting custom headers, ScreenshotNeo provides a website screenshot API and MCP server. Its request options include custom headers, cookies, user agents, and authorization, so you can send the page context without building Puppeteer interception yourself.

One GET request returns an image or PDF. The cURL example below saves a WebP screenshot; see the ScreenshotNeo documentation for the complete parameter list.

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

Equivalent Python call

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)

Equivalent Node.js call

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

ScreenshotNeo accepts consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and whether the shot was billed. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. There is a free allowance of 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 screenshots. Sign up for the free ScreenshotNeo plan to try the call.

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

FAQ

Can I preserve the capitalization or order of Puppeteer headers?

Puppeteer lowercases header names and does not guarantee outgoing header order. Since header names are case-insensitive, applications should not depend on either detail.

Does an Angular interceptor change requests made by Puppeteer?

No. An Angular interceptor handles requests sent through that Angular application’s HttpClient. Puppeteer controls browser-page requests; choose the layer that creates the traffic.

What is the safest way to verify a header reached the server?

Use server-side logs or an appropriate network trace. Puppeteer’s request.headers() is an automation-side view and is not proof of server receipt.

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.

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