Server Side Render an Angular CLI Project with Angular Universal

InstructorBram Borggreve

Share this video with your friends

Send Tweet

In this lesson we will add Server Side Rendering to our application using Angular Universal. We'll build a simple Express application and see how Angular Universal builds and renders our app on the server.

Since Angular CLI v6 we can simple run ng generate universal --clientProject store, where store is the name of our app.

In angular.json in the architect.server object we define a configurations object, to make sure the correct environment gets copied on a production build.

To make Angular Universal with lazy loaded modules we need to add the ModuleMapLoaderModule to AppServerModule, which we get after installing @nguniversal/module-map-ngfactory-loader from npm.

npm install --save @nguniversal/module-map-ngfactory-loader @nguniversal/express-engine

In the project root we implement a server.ts and define our simple express server.

When we run the new server we see that the app gets rendered before it hits the browser.

Stepan
~ 6 years ago

If you try to run final version of your code example there is no ssr-html in it. is it expected behavior? and it looks like SW is the cause of the problem.

saiteja
~ 6 years ago

I'm getting this error - "You must pass in a NgModule or NgModuleFactory to be bootstrapped"

Brent Mitchell
~ 6 years ago

I can only get this running if I pass the module option via the start script in package.json:

"start": "ts-node -O '{\"module\": \"commonjs\"}' ./server",

Otherwise I get a "SyntaxError: Unexpected token *" regarding the "import * as express from 'express'" statement in server.ts.

I copied my "tsconfig.server.json" from the git repository for this lesson so it has the following line in the compilerOptions:

"module": "commonjs"

but it doesn't seem to do anything.

I'm running Node version v10.9.0.

I'm wondering why I have to pass the module option the way I'm doing it?

Nicholas Murray
~ 6 years ago

I've followed along with this tutorial and for some reason it does not render the server side version of the app - it remains the same as before, I've cloned and ran the version in github and it also does not render the server side version. Is there some step that I am missing?

Kristy Mae Almuete
~ 6 years ago

It runs perfectly on my side by running these commands:

$ git clone --single-branch -b lesson-10 https://github.com/eggheadio-projects/egghead-course-SEO-friendly-PWA-with-angular-universal angular-seo

$ cd angular-seo

$ npm install

$ npm run build

$ npm start

Then, the application runs at http://localhost:8080 same content as on the demo.

Nicholas Murray
~ 6 years ago

Hi Kristy,

so it does, I must have taken a mis-step somewhere.

Thanks for your response!

Kevin Clark
~ 6 years ago

I did not get lesson-10 tag running. It seems like there is already code dependent on now.sh embedded in that version in environments/environment.prod.ts

Bram Borggreveinstructor
~ 6 years ago

I did not get lesson-10 tag running. It seems like there is already code dependent on now.sh embedded in that version in environments/environment.prod.ts

Not sure if I follow, the value of apiUrl in environments/environment.prod.ts should be unrelated, it's just where the production API is found.

Kevin Clark
~ 6 years ago

Sorry. When you checkout the tag of lesson-10, there is code in environments/environment.prod.ts points to the now.sh urls. Running 'npm run build' and then npm start will use external APIs on now.sh

Bram Borggreveinstructor
~ 6 years ago

Sorry. When you checkout the tag of lesson-10, there is code in environments/environment.prod.ts points to the now.sh urls. Running 'npm run build' and then npm start will use external APIs on now.sh

That's intentional. When running a production build we generally want to connect it to an API that is hosted online, and not on our local machines.

However, you can replace that value with any other URL that works best for you!

Kevin Clark
~ 6 years ago

I added to the package.json

"build:local": "ng build store && ng run store:server",

and ran npm audit fix which changed the package.json to use "protractor": "^5.4.2"

Works now as changes to the lesson-10 tag without using now.sh