Angular SEO with SSR don't show component

Viewed 343

I have a problem with a SPA page. I'm using SSR but my index.html (when i show sourcecode [Crtl+U]) don't show my title and meta description updates when i go to another component, because index is always pre-rendered in server, and i need this new data in source code.

Also i need to show in sourcecode, the code of the next component beyond index.html.

Is possible?

server.ts

(global as any).WebSocket = require('ws');
(global as any).XMLHttpRequest = require('xhr2');

import 'zone.js/dist/zone-node';
import { enableProdMode } from '@angular/core';
// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

import * as express from 'express';
import { join } from 'path';
import * as cookieParser from 'cookie-parser';

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/singapur-frontend-web');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main');

app.use( cookieParser() );

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
    bootstrap: AppServerModuleNgFactory,
    providers: [
        provideModuleMap(LAZY_MODULE_MAP)
    ]
}));

app.set('view engine', 'html');
app.set('views', DIST_FOLDER);

// app.get('/', (req, res, next) => {
//  const cookie = req.cookies;
//  for (const prop in cookie) {
//      if (!cookie.hasOwnProperty(prop)) {
//          continue;
//      }
//      res.cookie(prop, '', { expires: new Date( 0 ) });
//  }
//  next();
// });

app.get('*.well-known/**', ( req, res ) => {
    res.sendFile( join( DIST_FOLDER, '/.well-known/assetlinks.json' ) );
});

// Serve static files from /browser
app.get('*.*', express.static(DIST_FOLDER, {
    maxAge: '1y'
}));

app.get(['/chat/**', '/profile'], (req, res) => {
    res.sendFile(join(DIST_FOLDER, 'index.html'));
});

// All regular routes use the Universal engine
app.get('*', (req, res) => {
    res.render('index', {
        req,
        res,
        providers: [
            {
                provide: 'REQUEST',
                useValue: (req)
            },
            {
                provide: 'RESPONSE',
                useValue: (res)
            }
        ]
    });
});

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

package.json

{
    "name": "-------------------",
    "version": "0.0.2-SNAPSHOT",
    "scripts": {
        "ng": "ng",
        "start": "npm run serve:ssr",
        "start:local": "ng serve",
        "build": "ng build",
        "build:qa": "ng build -c qa",
        "build:pre": "ng build -c pre",
        "build:pro": "ng build --prod",
        "deploy:qa": "npm run build:qa && npm run build:ssr && gcloud app deploy qa.app.yaml",
        "deploy:pre": "npm run build:pre && npm run build:ssr && gcloud app deploy",
        "deploy:pro": "npm run build:pro && npm run build:ssr && gcloud app deploy",
        "docker:build:prod": "cd docker && docker-compose build --build-arg app_env=production && npm run docker:export",
        "docker:build:pre": "cd docker && docker-compose build --build-arg app_env=pre && npm run docker:export",
        "docker:build:qa": "cd docker && docker-compose build --build-arg app_env=qa && npm run docker:export",
        "docker:export": "docker export leroy_merlin > docker/container.tgz",
        "test": "ng test --browsers=Chrome",
        "test:ci": "ng test --no-watch --no-progress --browsers=PhantomJS",
        "lint": "ng lint",
        "e2e": "ng e2e",
        "build:ssr": "ng run frontend-web:server:production && npm run compile:server",
        "compile:server": "webpack --config webpack.server.config.js --progress --colors",
        "serve:ssr": "node dist/server"
    },
    "publishConfig": {
        "registry": "-----------------------"
    },
    "dependencies": {
        "@angular/animations": "^7.2.13",
        "@angular/cdk": "^7.3.7",
        "@angular/common": "^7.2.13",
        "@angular/compiler": "^7.2.13",
        "@angular/core": "^7.2.13",
        "@angular/fire": "^5.2.1",
        "@angular/flex-layout": "^7.0.0-beta.24",
        "@angular/forms": "^7.2.13",
        "@angular/http": "^7.2.13",
        "@angular/material": "^7.3.7",
        "@angular/platform-browser": "^7.2.13",
        "@angular/platform-browser-dynamic": "^7.2.13",
        "@angular/platform-server": "^7.2.13",
        "@angular/router": "^7.2.13",
        "@ngrx/effects": "^7.4.0",
        "@ngrx/router-store": "^7.4.0",
        "@ngrx/store": "^7.4.0",
        "@ngrx/store-devtools": "^7.4.0",
        "@nguniversal/common": "^8.1.1",
        "@nguniversal/express-engine": "^7.1.1",
        "@nguniversal/module-map-ngfactory-loader": "0.0.0",
        "@ngx-translate/core": "^11.0.1",
        "@ngx-translate/http-loader": "^4.0.0",
        "@nicky-lenaers/ngx-scroll-to": "^2.0.0",
        "@singapur/add-credit-card": "^1.0.166",
        "@singapur/alerts": "^1.0.166",
        "@singapur/autocomplete": "^1.0.166",
        "@singapur/banner": "^1.0.166",
        "@singapur/block-services": "^1.0.166",
        "@singapur/block-text-image": "^1.0.166",
        "@singapur/breadcrumb": "^1.0.166",
        "@singapur/calculator": "^1.0.166",
        "@singapur/card-add-item": "^1.0.166",
        "@singapur/card-configurator-service": "^1.0.166",
        "@singapur/card-container": "^1.0.166",
        "@singapur/card-description": "^1.0.166",
        "@singapur/card-img": "^1.0.166",
        "@singapur/card-img-opinion": "^1.0.166",
        "@singapur/card-opinion": "^1.0.166",
        "@singapur/card-prof": "^1.0.166",
        "@singapur/card-profile-detail": "^1.0.166",
        "@singapur/card-static": "^1.0.166",
        "@singapur/card-tabs": "^1.0.166",
        "@singapur/card-title": "^1.0.166",
        "@singapur/chat": "^1.0.166",
        "@singapur/cookies": "^1.0.166",
        "@singapur/dialog": "^1.0.166",
        "@singapur/footer": "^1.0.166",
        "@singapur/grid": "^1.0.166",
        "@singapur/header": "^1.0.166",
        "@singapur/includes-excludes": "^1.0.166",
        "@singapur/input-password": "^1.0.166",
        "@singapur/menu-lateral": "^1.0.166",
        "@singapur/opinion-module": "^1.0.166",
        "@singapur/professionals": "^1.0.166",
        "@singapur/sass": "^1.0.166",
        "@singapur/spinner": "^1.0.166",
        "@singapur/stepper": "^1.0.166",
        "angular-star-rating": "^4.0.0-beta.3",
        "cache": "^2.1.0",
        "classlist.js": "^1.1.20150312",
        "core-js": "^2.5.4",
        "css-star-rating": "^1.2.4",
        "express": "^4.15.2",
        "firebase": "^6.2.0",
        "hammerjs": "^2.0.8",
        "lodash": "^4.17.11",
        "moment": "^2.24.0",
        "ngx-indexed-db": "^2.0.8",
        "ngx-page-scroll": "^6.0.0-beta.1",
        "ngx-page-scroll-core": "^6.0.0-beta.1",
        "ngx-universal-cookies": "^8.0.1",
        "rxjs": "^6.4.0",
        "rxjs-compat": "^6.4.0",
        "verify": "^0.1.2",
        "web-animations-js": "^2.3.1",
        "zone.js": "^0.9.0"
    },
    "devDependencies": {
        "@angular-devkit/build-angular": "^0.13.8",
        "@angular/cli": "^7.3.8",
        "@angular/compiler-cli": "^7.2.13",
        "@angular/language-service": "^7.2.13",
        "@types/jasmine": "^3.3.12",
        "@types/jasminewd2": "~2.0.3",
        "@types/node": "^11.13.20",
        "bufferutil": "^4.0.1",
        "codelyzer": "^5.0.0",
        "cookie-parser": "^1.4.4",
        "express": "^4.16.4",
        "jasmine-core": "^3.4.0",
        "jasmine-spec-reporter": "^4.2.1",
        "karma": "^4.1.0",
        "karma-chrome-launcher": "^2.2.0",
        "karma-cli": "^2.0.0",
        "karma-coverage-istanbul-reporter": "~2.0.1",
        "karma-jasmine": "^2.0.1",
        "karma-jasmine-html-reporter": "^1.4.0",
        "karma-phantomjs-launcher": "^1.0.4",
        "karma-sonarqube-unit-reporter": "0.0.18",
        "morgan": "^1.9.1",
        "node-sass": "^4.12.0",
        "phantomjs-prebuilt": "^2.1.16",
        "protractor": "^5.4.2",
        "sass-rem": "^2.0.1",
        "ts-loader": "^5.2.0",
        "ts-node": "~7.0.0",
        "tslint": "^5.16.0",
        "tslint-sonarts": "^1.9.0",
        "typescript": "~3.2.2",
        "utf-8-validate": "^5.0.2",
        "webpack-cli": "^3.1.0",
        "ws": "^7.1.2",
        "xhr2": "^0.2.0"
    }
}
0 Answers
Related