For debugging purposes, you can provide an Angular HttpInteceptor that logs time of every http request made by the Angular app. Btw. it can also indicate if the response was already sent to the client by the ExpressJS engine (e.g. due to a SSR request timeout).
See the example implementation:
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { Inject, InjectionToken, Optional } from '@angular/core';
import { RESPONSE } from '@nguniversal/express-engine/tokens';
import { Response } from 'express';
export class LoggingInterceptor implements HttpInterceptor {
constructor(@Optional() @Inject(RESPONSE) private response: Response) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const started = Date.now();
return next.handle(request).pipe(
tap(
_event => {
console.log(
`Request for ${request.urlWithParams} took ${Date.now() - started} ms. ` +
`Was ExpressJS Response already sent?: ${this.response?.headersSent}`
);
},
_error => {
console.log(
`Request for ${request.urlWithParams} failed after ${Date.now() - started} ms. ` +
`Was ExpressJS Response already sent?: ${this.response?.headersSent}`
);
}
)
);
}
}
Explanation:
- we inject
RESPONSE InjectionToken from @nguniversal/express-engine/tokens
- the
RESPONSE object has a type of Response from ExpressJS. Please mind to write: import {Response} from 'express'. Otherwise the global type Response of Node.js will be implicitly used, which would be incorrect
- We inject
RESPONSE with @Optional() decorator as it is not available in the browser, but only in SSR
- we lookup the property
this.response.headersSent, which indicates whether the ExpressJS already sent a response to a client. For more, see docs of ExpressJS Response.headersSent
Note: If you want to also console.log the URL of the currently rendered page in SSR, you can inject WindowRef from @spartacus/core and log it’s property windowRef.location.href.