In Angular <19 I used such code to specify the providers:
// All regular routes use the Angular engine
server.get('**', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
commonEngine
.render({
bootstrap,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: distFolder,
providers: [
{ provide: APP_BASE_HREF, useValue: baseUrl },
{ provide: RESPONSE, useValue: res },
{ provide: REQUEST, useValue: req },
],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
but in Angular 19 there is another structure:
app.use('/**', (req, res, next) => {
angularApp
.handle(req)
.then((response) =>
response ? writeResponseToNodeResponse(response, res) : next(),
)
.catch(next);
});
I have tried to add the providers array in the second parameter of handle()
method, but it did not work for me.
I need to set providers for the REQUEST
token, which should be the req
object
In Angular <19 I used such code to specify the providers:
// All regular routes use the Angular engine
server.get('**', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
commonEngine
.render({
bootstrap,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: distFolder,
providers: [
{ provide: APP_BASE_HREF, useValue: baseUrl },
{ provide: RESPONSE, useValue: res },
{ provide: REQUEST, useValue: req },
],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
but in Angular 19 there is another structure:
app.use('/**', (req, res, next) => {
angularApp
.handle(req)
.then((response) =>
response ? writeResponseToNodeResponse(response, res) : next(),
)
.catch(next);
});
I have tried to add the providers array in the second parameter of handle()
method, but it did not work for me.
I need to set providers for the REQUEST
token, which should be the req
object
2 Answers
Reset to default 6In v19 those token are set for you automatically by the framework.
In your app, you'll pull them from '@angular/core'
import { Component, inject REQUEST, } from '@angular/core';
@Component({...})
export class AppComponent {
constructor() {
const request = inject(REQUEST, { optional: true });
}
}
Make sure to inject is with optional: true
as this token will not be available in every context.
I have a working demo you can check: https://github/jeanmeche/ssr-v19
Additional note : If you want to inject custom tokens from your node server and provide them to your angular v19 app, you can use REQUEST_CONTEXT from @angular/core
.
server.ts
app.use('/**', (req, res, next) => {
angularApp
.handle(req, {
context: { foo: 'bar' },
})
.then((response) =>
response ? writeResponseToNodeResponse(response, res) : next(),
)
.catch(next);
});
Then use TransferState
API to get your data in the browser.
const CONTEXT_KEY = makeStateKey<any>('context');
@Injectable({
providedIn: 'root',
})
export class ServerContextService {
constructor(
) {
const transferState = inject(TransferState);
const CONTEXT_TOKEN:any = inject(REQUEST_CONTEXT, { optional: true });
if(CONTEXT_TOKEN) {
transferState.set(CONTEXT_KEY, CONTEXT_TOKEN);
}
this.transfered = transferState.get(CONTEXT_KEY, {});
}
transfered: any;
}