Angular DevTools
On this page ▾
Every HttpClient call made while rendering on the server and in the browser. Fault injection, hydration stats and the TransferState payload, in one tab.

SSR & HTTP

The SSR & HTTP tab shows the HTTP calls your app makes during server rendering and in the browser. It also shows the hydration result and the TransferState payload, and it can inject faults into requests. Pick the page at the top. The tab shows that page's data.

Setup

The timeline and fault rules need the interceptor. The hydration warnings need the provider. Add both to the app config, with withNgDevtools() before your own interceptors:

// src/app/app.config.ts
import {ApplicationConfig} from '@angular/core';
import {provideHttpClient, withFetch, withInterceptors} from '@angular/common/http';
import {provideNgDevtoolsHttp, withNgDevtools} from '@santoshyadavdev/ng-devtools/http';
import {authInterceptor} from './auth.interceptor';

export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(withFetch(), withNgDevtools(), withInterceptors([authInterceptor])),
    provideNgDevtoolsHttp(),
  ],
};
Put withNgDevtools() before your own interceptors. Then it records requests as the app makes them, and fault rules apply before anything else. The full setup is in the SSR & HTTP guide.

SSR must run in the same Node process as the devtools server, such as the Express server with the hub mounted, or the Vite dev server with the plugin. The overlay must be loaded, because client calls, hydration and the payload reach the tab through it.

What it shows

HTTP timeline

Every HttpClient request, tagged SSR or Client. Each row shows the method, the URL, the page that made it, the status, the time, and notes:

  • transfer cache: the TransferState cache answered it. A client request counts as a hit only when its method, response type, URL, body and params match the entry Angular stored.
  • delayed N ms: a fault rule held it back.
  • mocked: a fault rule answered it with a status below 400.
  • faulted: a fault rule failed it with a status of 400 or more.
  • rule: the pattern of the fault rule that matched it.

A request that was unsubscribed before its response, for example by switchMap, a route change or a destroyed component, shows cancelled as its status. ERR marks a request that failed without a status, such as when the browser is offline or CORS blocks it.

Click a row for a response preview. The preview opens under the timeline and takes focus. Close or Escape returns focus to the row. A long timeline scrolls inside its own box. The timeline shows the page's client calls and the SSR calls made while rendering its first URL. Clear timeline empties it.

Fault injection

Add a rule with these fields:

  • URL pattern: a substring, or a glob where * matches anything. /api/* matches both relative and absolute URLs.
  • Method: any, or one method.
  • Apply on: SSR + client, SSR only, or client only.
  • Status: None, or a status from the list. The list has the standard 2xx to 5xx statuses, plus 499 (nginx) and 520 to 524 (Cloudflare). Type the code, for example 503, to jump to it.
  • Delay (ms) up to 10000, and an optional JSON body.

A status of 400 or more fails the request with an HttpErrorResponse. A lower status returns the body as a mocked response. A body with the status on None returns it with status 200. A stored rule with a status outside the list loses that status, and is dropped when nothing else is left to change. A rule with only a delay passes the request through, later. A rule needs a status, a delay or a body, so Add rule stays off until it has one. The form clears after each added rule. The first enabled rule that matches wins.

The body follows the request's responseType. A json request gets the parsed JSON (or the raw string when it does not parse) with content-type: application/json. A text request gets the string with text/plain. A blob request gets a Blob, and an arraybuffer request an ArrayBuffer, both with application/octet-stream. The same value is the error of an injected failure.

Hydration

  • Whether hydration is on.
  • Hydrated components and nodes, skipped components, and incremental defer blocks.
  • DOM nodes hydrated and skipped, and ngSkipHydration hosts.
  • Mismatched components, with the expected and actual DOM.
  • The hydration warnings (NG05xx) Angular logged in the browser.

TransferState payload

Each entry in the page's {APP_ID}-state script, with its size. The tab decodes HttpClient and Analog cache entries to status, URL and body. It labels __nghData__ and __nghDeferData__ as hydration annotations, and Analog server function results seeded during server rendering by function name.

Where the data comes from

The interceptor on the server hands SSR calls to the devtools through the shared Node process. The overlay reports client calls, hydration stats and the payload. Fault rules live on the devtools server, which sends them to every page.

What each part needs

Part Needs
HTTP timeline withNgDevtools() and the overlay.
Fault injection withNgDevtools().
Hydration stats The overlay.
Hydration warnings provideNgDevtoolsHttp().
TransferState payload The overlay, on a server-rendered page.

Development builds

The interceptor works in development builds only. In production it passes requests through untouched.

How to use it

Test an error state

Enter the URL pattern, pick Client only, and pick 500 Internal Server Error as the status. Click Add rule. Trigger the request. The row is marked faulted. Your error handling runs against a real HttpErrorResponse. Click Remove when you are done.

Test a slow API

Enter the URL pattern, leave the status on None and the body empty, and set a delay, for example 3000 ms. Click Add rule. The request still reaches the API, only later. Its row is marked delayed 3000 ms.

Check that TransferState works

Use a route with RenderMode.Server. Each GET should show an SSR row, and a Client row marked transfer cache. The matching entry should appear in TransferState payload.

Agent tools

There is no dedicated tool for this tab. Agents read its data with the devframe_state_read tool and the ng-devtools:http key. See Resources.

Two router tools cover related ground:

Tool What it does
ng-devtools:explain-render-mode Which render mode a URL gets, from *.routes.server.ts.
ng-devtools:explain-navigation Each navigation's story, including the HTTP requests it made.

Limits and gotchas

Request URLs, page URLs and error messages are redacted like router URLs. Response previews and TransferState values reach the devtools server as they are. Don't expose the dev server beyond localhost. See Security.

Prerendered routes make no requests

Routes prerendered at build time make no requests at runtime and ignore SSR rules. For pages you want to test this way, use RenderMode.Server in app.routes.server.ts.

SSR mocks are not transferred

The devtools don't write SSR mocks to TransferState, so the browser requests the URL again. To mock both, apply the rule on SSR + client.

When rules apply

Client rules apply right away. SSR rules apply from the next page load, so the panel asks for a reload only when a rule applies on SSR. The page also keeps client rules in sessionStorage, so they apply on reload before the overlay connects. Rules live in the memory of the server process. They survive a Vite restart in the same process, such as after a config edit, and the SSR & HTTP tab keeps showing them. A new process starts with none.

If the http inspector or actions.http is off, the server clears its rules when it starts. The overlay removes the stored client rules when it connects with the http inspector off, so requests made before it connects on that load can still fail.

Timeline and rule caps

The timeline keeps the last 200 SSR calls in total, and the last 200 client calls of each page. Set both with limits.httpCalls. Once older calls are dropped, the timeline says how many and which limit to raise. You can add up to 50 fault rules. At 50, Add rule stays off until you remove one.

FAQ

SSR runs in a different process from the devtools, or the route is prerendered. Mount the hub in the same server, and use RenderMode.Server. provideNgDevtoolsHttp() is missing from the app providers. Client calls live in the page, so a reload clears them. SSR calls stay until Clear timeline or a server restart.

Where to next

The providers, their order, and the server setup. Mount the hub in server.ts. HTTP requests per navigation, and render modes. What is redacted, and what is not.