Angular Universal has always supported prerender, but setting it up was a little difficult. Recently, I was intrigued by Scully, a new static site generator on top of regular Angular. It allows you to use Angular in a JAM stack, and I was amazed. It have schematic, allowing to do ng add @scullyio/init
and it will add everything it needs to do its job. There are a couple of things that I didn't quite like, as for example you can't prerender the main index.html
. It was created with one goal in mind, and it does that very well, allow you to use Angular in a JAM site.
Angular to the rescue
As I said before, I try to use Angular Universal to do prerender likely a year ago. It did work, but much of the work had to be done by hand. And as we know, every code we write is likely to have errors. So, it was not as straightforward as it is now with Scully, but it does allow you some better flexibility.
So, I though to myself
It's been a year since I try that the last time, sure there a new easy way to do it.
Oh! Man, they are.
Universal Prerender
We are going to create a new Angular app, so you should have installed the latest LTS version of Node, currently Node 12.14.0. We are going to use npx
to execute the latest preview version of the Angular CLI, that's until Angular 9 gets released.
npx -p @angular/cli@next ng new static-app
Using that, we are saying to npx
it should download the latest version of Angular using the next
tag. Currently, 9-RC.7. Be sure to use routing, and select the style language you prefer. After that, you should have a new ready to go Angular application. Then, we use schematics to add the Angular Universal module in our project.
ng add @nguniversal/express-engine@next
Notice that we are also using the next
tag here because neither of them is stable yet. If you are like me, you can notice now several modified files since the latest git commit (the one Angular CLI does by default). This even setup some npm scripts now, one of those is prerender
.
There is only one more thing for you to do to use that command. Open angular.json
, and go to the new prerender build options, in projects.[your project name].architect.prerender
. You should see something like this:
"prerender": {
"builder": "@nguniversal/builders:prerender",
"options": {
"browserTarget": "static-app:build:production",
"serverTarget": "static-app:server:production",
"routes": [] // <-- Here you should put the routes you want to prender
},
"configurations": {
"production": {}
}
}
As the comment said, you have to put the routes you want to render right there. Right now, the application only has one route, so let's use that. Update the options.routes
to ["/"]
.
Run
npm run prerender
You should see now some buildings and some stuff. But the latest it's the most important part:
Prerendering 1 route(s) to ~~~\static-app\dist\static-app\browser
CREATE ~~~\static-app\dist\static-app\browser\index.html (27563 bytes)
Now, if you go to that folder, you will notice both, an index.html
file and an index.original.html
file. The first is the newly created file prerendered, and the later is the original index file of the application. Serve that folder with a static server such as http-server.
npx http-server
Now open that url in a browser, and better if you disable Javascript. You should see the same page that Angular shows by default, but instantly and also if you disable JS, without any usage of JS. This allows site crawlers to see your pages as your user would.
That's all folks!
I'm going to continue hacking with that but seems promising. I hope you enjoy the reading, and if you want to try it out, let me know in the comments how it went for you.
PS:
The prerender
script only worked for me in the latest version of Angular Universal. I don't know if that's going to change, but if it does, I'll update the entry with those changes.
Top comments (2)
Hi Michael,
Good morning!
Happy new year 2020!!!
Can you share code which you build with angular universal?
I need same functionality for SEO.
Thanks,
Pandian N.
Hi Pandian,
Happy new year. Good morning to you. It's 2 am where I live, so I'm no there yet. I don't know what you mean, that's all the steps it took me to do the prerender.