Going DeeperPro· 35 min read

HTTP Interceptors

An interceptor sits between your app and the server, touching every request and response — perfect for attaching tokens and handling errors in one place.

What you will learn

  • Explain what an interceptor does
  • Attach an auth header to every request
  • Handle server errors globally

One checkpoint for every request

Imagine every HTTP request your app makes has to pass through a single checkpoint on the way out, and every response passes through it on the way back. That checkpoint is an interceptor. Because every call goes through it, you write a rule once and it applies everywhere — no repeating yourself in every component.

The two most common jobs: (1) attach the login token to every outgoing request, and (2) catch errors from any response in one shared place. Modern Angular uses functional interceptors — just a function.

Attach a token to every request

Requests are immutable (you cannot change them directly), so you clone the request, add a header, and pass the copy along with next. The next function sends the request onward to the server.

An interceptor that adds an Authorization header
// auth.interceptor.ts
import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';
import { AuthService } from './auth.service';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const token = inject(AuthService).getToken();

  if (token) {
    const withAuth = req.clone({
      setHeaders: { Authorization: 'Bearer ' + token }
    });
    return next(withAuth);     // send the modified copy
  }
  return next(req);            // no token: send as-is
};

Note: Output: (No visible output — it changes requests silently.) Every outgoing request now carries Authorization: Bearer <token> if the user is logged in. We clone the request because requests cannot be edited in place, then next forwards it. You never add the header by hand again.

Register the interceptor

Tell Angular to use your interceptor when you provide HttpClient.

Wire the interceptor into HttpClient
// src/main.ts
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { authInterceptor } from './app/auth.interceptor';

bootstrapApplication(AppComponent, {
  providers: [
    provideHttpClient(withInterceptors([authInterceptor]))
  ]
});

Note: Output: (No visible output — setup only.) From now on every request made with HttpClient flows through authInterceptor first. You can list several interceptors; they run in order.

Handle errors in one place

You can also catch failures globally so you do not write error handling in every component. Use the catchError operator on the response stream.

A global error-handling interceptor
import { HttpInterceptorFn } from '@angular/common/http';
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';

export const errorInterceptor: HttpInterceptorFn = (req, next) => {
  return next(req).pipe(
    catchError(err => {
      console.error('Request failed:', err.status);
      return throwError(() => err);   // pass it on
    })
  );
};

Note: Output (when a request returns 500): Request failed: 500 Every failed response logs once here. You could instead show a toast, or redirect to login on a 401. Handling it centrally means components stay clean. throwError re-throws so the component can still react if it wants to.

Watch out: Do not put heavy logic inside an interceptor — it runs on every request. Keep it to small, cross-cutting concerns like headers, logging, and error handling.

Tip: A loading-spinner interceptor is a popular pattern: flip a shared “loading” signal on when a request starts and off when it finishes, so a spinner shows for any request app-wide automatically.

Q. Why must you clone the request before adding a header in an interceptor?

Answer: Angular HttpRequest objects are immutable. You clone the request with the new header and forward the copy with next(), leaving the original untouched.

✍️ Practice

  1. Write an interceptor that logs the URL of every outgoing request.
  2. Write an interceptor that adds a custom header like X-App-Version to every request.

🏠 Homework

  1. Build an auth interceptor that attaches a token plus an error interceptor that redirects to /login on a 401 response.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →