Search code examples
node.jsangularserver-side-rendering

render using Server Side Rendering is infinitely loading


I implemented nguniversal in my Angular 14 app which use :

{
  "name": "cosycorse",
  "version": "0.0.0",
  "overrides": {
    "autoprefixer": "10.4.5"
  },
  "scripts": {
    "ng": "ng",
    "start": "ng serve --proxy-config proxy.conf.json",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "dev:ssr": "ng run cosycorse:serve-ssr",
    "serve:ssr": "node dist/cosycorse/server/main.js",
    "build:ssr": "ng build && ng run cosycorse:server",
    "prerender": "ng run cosycorse:prerender"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^14.1.3",
    "@angular/cdk": "^14.1.3",
    "@angular/common": "^14.1.3",
    "@angular/compiler": "^14.1.3",
    "@angular/core": "^14.1.3",
    "@angular/flex-layout": "^14.0.0-beta.41",
    "@angular/forms": "^14.1.3",
    "@angular/material": "^14.2.7",
    "@angular/platform-browser": "^14.3.0",
    "@angular/platform-browser-dynamic": "^14.1.3",
    "@angular/platform-server": "^14.3.0",
    "@angular/router": "^14.1.3",
    "@asymmetrik/ngx-leaflet": "^14.0.1",
    "@fortawesome/fontawesome-free": "^6.2.0",
    "@geoapify/geocoder-autocomplete": "^1.1.2",
    "@kolkov/ngx-gallery": "^2.0.1",
    "@material-ui/pickers": "^3.3.10",
    "@nguniversal/express-engine": "^14.2.3",
    "@ngx-translate/core": "^14.0.0",
    "@ngx-translate/http-loader": "^7.0.0",
    "@stripe/stripe-js": "^1.42.1",
    "@types/crypto-js": "^4.1.1",
    "body-parser": "^1.20.2",
    "bootstrap": "^5.2.0",
    "cookie-parser": "^1.4.6",
    "cors": "^2.8.5",
    "crypto-js": "^4.1.1",
    "express": "^4.15.2",
    "leaflet": "^1.7.1",
    "ngx-cookie-service": "^14.0.1",
    "ngx-dropzone": "^3.1.0",
    "ngx-material-timepicker": "^5.5.2",
    "ngx-owl-carousel-o": "^14.0.1",
    "rxjs": "~6.6.0",
    "stripe": "^10.15.0",
    "sweetalert2": "^11.4.8",
    "tslib": "^2.0.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^14.1.3",
    "@angular/cli": "^14.2.0",
    "@angular/compiler-cli": "^14.1.3",
    "@nguniversal/builders": "^14.2.3",
    "@types/express": "^4.17.0",
    "@types/jasmine": "~3.6.0",
    "@types/leaflet": "^1.5.19",
    "@types/morgan": "^1.9.4",
    "@types/node": "^12.20.55",
    "jasmine-core": "~4.0.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.1.0",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "~1.7.0",
    "typescript": "~4.6.4"
  }
}

When I try to load my index in SSR, it never rendering, I keep having the loader on my browser tab without any errors.

I've use the ngx-translate implementation described here : https://andremonteiro.pt/ngx-translate-angular-universal-ssr/

And the problem persists.

I think the problem is with i18n but don't know what to do.

There is no errors in me server console.

server.ts:

import 'zone.js/node';

import { APP_BASE_HREF } from '@angular/common';
import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { existsSync } from 'fs';
import { join } from 'path';

import { AppServerModule } from './src/main.server';
import { createProxyMiddleware } from 'http-proxy-middleware';
import * as cors from 'cors';

// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
  const server = express();
  const distFolder = join(process.cwd(), 'dist/cosycorse/browser');
  const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
  // Our Universal express-engine (found @ https://github.com/angular/universal/tree/main/modules/express-engine)
  server.engine('html', ngExpressEngine({
    bootstrap: AppServerModule,
  }));
  //sslRootCAs.addFile(join(__dirname, '../../server/ssl/cert.pem')).inject();
  server.use(cors());

  server.set('view engine', 'html');
  server.set('views', distFolder);

  server.use('/a*', createProxyMiddleware({
    target: 'https://localhost',
    changeOrigin: true,
    secure: false
  }));

  // Example Express Rest API endpoints
  // server.get('/api/**', (req, res) => { });
  // Serve static files from /browser
  server.get('*.*', express.static(distFolder, {
    maxAge: '1y'
  }));

  // All regular routes use the Universal engine
  server.get('*', (req, res) => {
    console.log('render : '+req.url)
    res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
  });

  return server;
}

function run(): void {
  const port = process.env['PORT'] || 4000;

  // Start up the Node server
  const server = app();
  server.listen(port, () => {
    console.log(`Node Express server listening on http://localhost:${port}`);
  });
}

// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
  run();
}

export * from './src/main.server';

app.server.module.ts:

import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { FlexLayoutServerModule } from '@angular/flex-layout/server';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { translateServerLoaderFactory } from './translate-server.loader';
import { TransferState } from '@angular/platform-browser';


@NgModule({
  imports: [
    AppModule,
    ServerModule,
    FlexLayoutServerModule,
    TranslateModule.forRoot({
      loader: {
        provide: TranslateLoader,
        useFactory: translateServerLoaderFactory,
        deps: [TransferState]
      }
    })
  ],
  bootstrap: [AppComponent],
})
export class AppServerModule {}

Result in browser


Solution

  • I found my problem, this is using CookieService:

    in my app.component :

    this.cookieService.check(this.title)