Reputation: 19288
From the docs:
For example, your server-side page can't reference browser-only native objects such as window, document, navigator, or location. If you don't need these on the server-rendered page, you can side-step them with conditional logic. Alternatively, you can find an injectable Angular abstraction over the object you need such as Location or Document; it may substitute adequately for the specific API that you're calling. If Angular doesn't provide it, you can write your own abstraction that delegates to the browser API while in the browser and to a satisfactory alternative implementation while on the server.
It makes sense the server can't access browser objects. But it can be achievend:
Alternatively, you can find an injectable Angular abstraction over the object you need such as Location or Document; it may substitute adequately for the specific API that you're calling.
Next:
If Angular doesn't provide it, you can write your own abstraction that delegates to the browser API while in the browser and to a satisfactory alternative implementation while on the server.
Where can I find which ones Angular provides and how can I use them? I'm specificly looking for the navigator.
If navigator is not provided by Angular, how can I write my own abstraction?
Side node: I used ng add @nguniversal/express-engine --clientProject angular.io-example
to get started with ssr.
Upvotes: 0
Views: 3790
Reputation: 738
While I wouldn't recommend this approach, if you need the navigator
object in Angular Universal, you might want to check the Domino project.
Then, in your server.ts
file you would do something like this:
const template = readFileSync(join(DIST_FOLDER, 'index.html')).toString();
const win = domino.createWindow(template);
global['window'] = win;
global['Node'] = win.Node;
global['navigator'] = win.navigator;
global['Event'] = win.Event;
global['Event']['prototype'] = win.Event.prototype;
global['document'] = win.document;
And in the handler you could do:
app.engine('html', (_, options, callback) => {
renderModuleFactory(AppServerModuleNgFactory, {
// Our index.html
document: template,
url: options.req.url,
// DI so that we can get lazy-loading to work differently (since we need it to just instantly render it)
extraProviders: [
provideModuleMap(LAZY_MODULE_MAP)
]
}).then(html => {
callback(null, html);
});
});
See: https://mdbootstrap.com/angular/angular-universal/
Upvotes: 1