admin 管理员组文章数量: 1184232
I have just created a simple Angular SSR application using Angular CLI: 18.2.12.
I am not using ngExpressEngine, but I am using @angular/platform-server
The application works fine with npm run build:ssr and npm run serve:ssr.
However, when I use built-in browser objects like localStorage, sessionStorage, window, location, document, or isBrowser, I encounter errors.
I understand that these objects are not accessible on the server.
In my application, these variables (e.g., localStorage and window) are used extensively. I tried using libraries like Domino and JSDOM, but they didn’t work properly.
I also referred to this post: Angular CLI - How to use window, document, or location in environment.ts.
Still, I couldn’t find a better solution.
Here is my server.ts file:
import 'zone.js/node';
import { renderModule } from '@angular/platform-server';
import express from 'express';
import { join } from 'path';
import AppServerModule from './src/main.server';
// import { readFileSync } from 'fs';
// import { JSDOM } from 'jsdom'
const app = express();
const PORT = process.env['PORT'] || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/angular-ssr-project/browser');
// Serve static files
app.use(express.static(join(DIST_FOLDER, 'browser'), {
maxAge: '1y',
index: false
}));
// Serve SSR page
app.get('*', (req, res) => {
renderModule(AppServerModule, {
document: '<app-root></app-root>',
url: req.url
}).then(html => {
res.send(html);
}).catch(err => {
console.error('SSR Rendering Error:', err);
res.status(500).send('Error during SSR rendering');
});
});
// Start the server
app.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`);
});
// const dom = new JSDOM('<!doctype html><html><body></body></html>');
// global['window'] = dom.window;
// global['document'] = dom.window.document;
// ...
// ...
// const template = readFileSync(join(DIST_FOLDER, 'index.html')).toString();
// const win = createWindow(template);
// global['window'] = win as any;
// global['document'] = win.document;
// global['navigator'] = win.navigator;
// ...
// ...
I have just created a simple Angular SSR application using Angular CLI: 18.2.12.
I am not using ngExpressEngine, but I am using @angular/platform-server
The application works fine with npm run build:ssr and npm run serve:ssr.
However, when I use built-in browser objects like localStorage, sessionStorage, window, location, document, or isBrowser, I encounter errors.
I understand that these objects are not accessible on the server.
In my application, these variables (e.g., localStorage and window) are used extensively. I tried using libraries like Domino and JSDOM, but they didn’t work properly.
I also referred to this post: Angular CLI - How to use window, document, or location in environment.ts.
Still, I couldn’t find a better solution.
Here is my server.ts file:
import 'zone.js/node';
import { renderModule } from '@angular/platform-server';
import express from 'express';
import { join } from 'path';
import AppServerModule from './src/main.server';
// import { readFileSync } from 'fs';
// import { JSDOM } from 'jsdom'
const app = express();
const PORT = process.env['PORT'] || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/angular-ssr-project/browser');
// Serve static files
app.use(express.static(join(DIST_FOLDER, 'browser'), {
maxAge: '1y',
index: false
}));
// Serve SSR page
app.get('*', (req, res) => {
renderModule(AppServerModule, {
document: '<app-root></app-root>',
url: req.url
}).then(html => {
res.send(html);
}).catch(err => {
console.error('SSR Rendering Error:', err);
res.status(500).send('Error during SSR rendering');
});
});
// Start the server
app.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`);
});
// const dom = new JSDOM('<!doctype html><html><body></body></html>');
// global['window'] = dom.window;
// global['document'] = dom.window.document;
// ...
// ...
// const template = readFileSync(join(DIST_FOLDER, 'index.html')).toString();
// const win = createWindow(template);
// global['window'] = win as any;
// global['document'] = win.document;
// global['navigator'] = win.navigator;
// ...
// ...
Share
Improve this question
edited Dec 4, 2024 at 13:04
Naren Murali
54.5k5 gold badges40 silver badges70 bronze badges
asked Dec 4, 2024 at 12:06
Kishan BholaKishan Bhola
412 bronze badges
1 Answer
Reset to default 0If you want you can import document inside angular using:
DOCUMENT
A DI Token representing the main rendering context. In a browser and SSR this is the DOM Document. When using SSR, that document is created by Domino.
export class SomeComponent {
document: DOCUMENT = inject(DOCUMENT);
...
Apart from this, we have the following techniques to bypass the errors arising from lack of localStorage, sessionStorage, document and window.
The below approach, does not do SSR, for the HTMLbut you can show a spinner to temporarily show until the proper screen loads.
@defer() {
} @placeholder { Loading... }
You can use isPlatformBrowser to conditionally execute code only on the browser.
import { inject, Inject, Injectable, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
...
...
platformId = inject(PLATFORM_ID);
...
...
ngOnInit () {
if(isPlatformBrowser(this.platformId)) {
const query = this.activatedRoute.snapshot.queryParams;
if (!query.code) {
this.router.navigate(['/auth/login']);
} else {
this.checkGoogleCodeAndRedirect(query);
}
}
}
You can also use afterNextRender to do the same. The code inside the callback executes only on the browser.
ngOnInit () {
afterNextRender(() => {
const query = this.activatedRoute.snapshot.queryParams;
if (!query.code) {
this.router.navigate(['/auth/login']);
} else {
this.checkGoogleCodeAndRedirect(query);
}
});
}
本文标签: javascriptHow to Use window Document location in angular SSR applicationStack Overflow
版权声明:本文标题:javascript - How to Use window, document, location in angular SSR application - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1736183328a1709477.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论