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.
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.
I'm getting this error - "You must pass in a NgModule or NgModuleFactory to be bootstrapped"
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?
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?
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.
Hi Kristy,
so it does, I must have taken a mis-step somewhere.
Thanks for your response!
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
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.
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
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!
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