Reputation: 548
I have an angular6 universal application, I am integrating ng-simple-slideshow for the image slider, it's building successful, but while running: npm run serve: SSR giving below error: please suggest some solution.thanks
ReferenceError: window is not defined
at F:\new_trd_back_up\dist\server.js:247023:8032
at vt (F:\new_trd_back_up\dist\server.js:246852:163)
at Object.module.exports (F:\new_trd_back_up\dist\server.js:246852:177)
at __webpack_require__ (F:\new_trd_back_up\dist\server.js:20:30)
at Object.jspdf (F:\new_trd_back_up\dist\server.js:87271:18)
at __webpack_require__ (F:\new_trd_back_up\dist\server.js:59361:30)
at Object../src/app/presentation/presentation.component.ts (F:\new_trd_back_up\dist\server.js:81159:13)
at __webpack_require__ (F:\new_trd_back_up\dist\server.js:59361:30)
at Object../src/app/presentation/presentation.component.ngfactory.js (F:\new_trd_back_up\dist\server.js:81046:11)
at __webpack_require__ (F:\new_trd_back_up\dist\server.js:59361:30)
Upvotes: 6
Views: 7670
Reputation: 1093
Edit: This answer and question are wrong from the root, Angular uses Domino these days anyways and you should use Injection or Guards, for further explanation, read the manual.
This also can be solved by using Dominos.
Add this to 'server.ts':
const domino = require('domino');
const fs = require('fs');
const path = require('path');
const template = fs.readFileSync(path.join(__dirname, '.', 'dist', 'index.html')).toString();
const win = domino.createWindow(template);
global['window'] = win;
global['document'] = win.document;
Ticket's issue and suggestion on Github
Upvotes: 3
Reputation: 10512
With NestJS you can it by simply applying the applyDomino
, like so:
import { AngularUniversalModule, applyDomino } from '@nestjs/ng-universal';
import { join } from 'path';
import { Module } from '@nestjs/common';
// Get working directory of client bundle.
const BROWSER_DIR = join(process.cwd(), 'dist/apps/browser');
applyDomino(global, join(BROWSER_DIR, 'index.html')); // Mock document, window etc.
@Module({
imports: [
AngularUniversalModule.forRoot({
bundle: require('./../functions/dist/apps/server/main'), // Bundle is created dynamically during build process.
liveReload: true,
viewsPath: BROWSER_DIR
})
]
})
export class AppNestModule {}
Edit: after upgrading from Angular 8
to Angular 10
it stopped working, which you can realise based on #451. As of now, the raw domino
has to be used in such a form (server.ts
):
import { createWindow } from 'domino';
import { join } from 'path';
const indexHtml = join(
process.cwd(),
'dist/apps/browser/index2.html'
);
const win = createWindow(indexHtml);
// Polyfills
(global as any).window = win;
(global as any).document = win.document;
(global as any).navigator = win.navigator;
import { ApplicationModule } from './app.module'; // IMPORTANT: MUST be placed AFTER all the code above
More detailed answer #830 (comment).
Upvotes: 2
Reputation: 786
"window is not defined" came from 3rd party library which accessing window variable.
You should wrapping your code with browser check condition
HTML:
<ng-container *ngIf="isBrowser">
<!-- In my case, ngx-siema & ngx-slcik -->
<ngx-siema></ngx-siema>
</ng-container>
TS:
import { PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
isBrowser;
constructor(@Inject(PLATFORM_ID) private platformId) {
this.isBrowser = isPlatformBrowser(platformId);
}
if (this.isBrowser) {
// put your code which is access window variable
}
A good example of usage could be found here.
Upvotes: 2