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 {}
I found my problem, this is using CookieService:
in my app.component :
this.cookieService.check(this.title)