skip to Main Content

I work on a pretty old angular project, we started working on it on 2.0 release, and upgraded it release after release. We’re on 4.3 for now

Now, the project is very complex, with a lot of features, and a lot of (old) peer dependencies, not maintained anymore for some of them.

I tried to implement angular universal on this project, to improve SEO, but I come accross errors one after another, and it looks like there’s no end at this.

So my questions are :

  • is there a way to implement angular universal on old project, without refactoring everything ?
  • if no, is there a way to implement angular universal only on a part of the project, like on statical-non-complex pages ?

All answer and hints are welcome !

2

Answers


  1. Implementing Angular universal on old project can be really, really painful :

    • You use vanilla javascript => it can’t compile
    • You use a peer dep that uses vanilla javascript => it can’t compile, and there is a lot of old deps coded this way

    I have to implement it on a old project too, and, like you, I had a lot of compilation errors. So I decided to split my app between two parts, two projects :

    • The angular old-dependent part, with complex code/feature
    • The static pages that needs to be SEO friendly => and, good news, this is what brings you the most SEO juice

    The bad part is that the 2 projects are independent from each others, so you can’t use things like localStorage, routerLink etc. But they’re connected to the same API, so you can always share data between them

    Technically, I did it like this :

    1. Creating a new app-universal folder, with the app-universal.module.ts
    2. Importing what I needed from the initial project (like some helpers/interface/services)
    3. Building my statics pages, with SEO friendly content
    4. Implementing Angular universal on the project, thanks to this guide : Angular Universal guide
    5. Changing the <base href=""> of the simplified app to <base href="/content">
    6. Creating 3 projects in my angular-cli.json:

     "apps": [
    {
      "name": "app",
      "root": "src",
      "outDir": "dist",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "index.html",
      "main": "app/main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      ...
    },
    {
      "name": "universal",
      "root": "src",
      "outDir": "dist-universal",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "app-universal/index.html",
      "main": "app-universal/main.ts",
      "polyfills": "polyfills.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.app.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app-universal",
      "...
    },
    {
      "name": "server",
      "platform": "server",
      "root": "src",
      "outDir": "src/app-universal/dist-universal-server",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "app-universal/index.html",
      "main": "app-universal/main.server.ts",
      "test": "test.ts",
      "tsconfig": "app-universal/tsconfig.server.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app-universal",
      ...
    }
    ],
    
    1. Adding build command shortcuts on my package.json :

    "scripts": {
      "prebuild-server": "ng build --prod --aot --app server && ngc -p src/app-universal/tsconfig.server.json",
      "build-server": "ts-node src/server.ts",
      ...
    },
    

    and running npm run build-server to compile your simplified app and render it with universal.

    1. Using Apache Location and ReverseProxy on my server to launch my main app on the / path, and my simplified app on /content or /blog or /whatever path :

    In the /etc/apache2/site-availables/your-project.conf file (on the <VirtualHost:.80> block, after DocumentRoot for example):

      ProxyRequests Off
      ProxyPreserveHost On
      ProxyVia Full
      <Proxy *>
        Require all granted
      </Proxy>
      <Location /content>
        ProxyPass http://127.0.0.1:4000
        ProxyPassReverse http://1127.0.0.1:4000
      </Location>
    

    And then you can use pm2 to keep your Node.js application up in the background: How To Set Up a Node.js Application for Production on Ubuntu 16.04

    And that waq done. I had split my project into two sub-project independent from each-other and run them on the same domain, with all the /content/* url SEO friendly

    To help you pass trough current universal errors : Angular with universal does not work

    Login or Signup to reply.
  2. Nowadays there is one command which will make life a lot easier for you:

    ng add @nguniversal/express-engine --clientProject <project-name>
    

    You can read more about it here:

    https://angular.io/guide/universal

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search