What we are going to use:
- Angular 5+
- AngularFire Lite ( ⚡️ Lightweight Angular Firebase API wrapper)
Why AngularFire Lite not AngularFire2 ?
AngularFire Lite is the very first and currently the only library that supports server side rendering out of the box for both Firestore and the Realtime Database plus other features over the Angularfire2 library like Storage , Observable based Transactions & Batched Writes and Cloud Messaging.
Quick story about the name: it was called “AngularFire Lite” simply because it is around 50% lighter than Angularfire2 and unlike the confusing 2 number in the name of the official library it chose simply to match the Angular versions so it’s currently in version 5.
take a look at the library repo to get started: Here
Step 1: Install decencies and generate a new Angular CLI project:
reminder: install nodejs from here and the Angular CLI using this command:
npm i @angluar/cli
then generate a new project:
ng new AngularFireLiteSSR
finally install the following decencies which we are going to use for server side rendering:
npm i @angular/platform-server @nguniversal/module-map-ngfactory-loader ts-loader
Step 2: Install AngularFire Lite and Firebase:
change directory to the project directory and install both packages : Angularfire Lite and Firebase
cd AngularFireLiteSSRnpm i angularfire-lite firebase
Step 3: Create a new Firebase project and get its credentials
open your browser and navigate to : https://console.firebase.google.com
click `Add Project` write your project name and then `Create Project`:
then to get your project credentials click `Add Firebase to your web app`
copy only the
Step 4: Save Firebase credentials in your Angular project
open the file called
environment.prod.ts in your favorite editor of choice located under
src/environments/environment.ts and paste that config object we got from the Firebase console inside your environment object and do the same for the file called
Step 5: Setup AngularFire Lite and Universal compatibility
Open your root module which is called
app.module.ts and import AngularFireLite and pass it the config object we store in the environment file.
To make the
AppModule Universal compatible we should call the
BrowserModule.withServerTransition and pass it an appId of your choice so your module looks just like this:
Step 6: Creating the server module and exporting it
Create a new module inside
src/app and call it
app.server.module.ts and it should import your core module followed by the
ServerModule from the
@angular/platform-server package (order is important).
We added the Map Loader Module here to support lazy loading module on the server side.
⚠️ it’s important to import
ServerTransferStateModule as it’s required by AngularFire Lite to do its magic which offers us a flicker free transition when the Angular app bootstraps. Freaking Awesome!! 😮 👌
to export the server module create a new file called
main.server.ts inside your
/src folder and just add the following export statement:
Step 7: creating a tsconfig for the Universal bundle
Simply copy the tsconfig file that the Angular CLI generates called
tsconfig.app.json located in your
/src folder and name the new file
We only need to do a couple of things here
- change the module target: from
commonjswhich node will use.
- add the
angularcompilerOptionsto tell the compiler about its entry module which is the
AppServerModuleand here we use the hash symbol in the path to reach the actual class.
Step 8: Configure the Angular CLI to build our server side App
Open the file called
.angular-cli.json located in the root of your project which is the file that configures the Angular CLI and how it builds our app.
However, if you take a look at the
apps array you will only see when entry inside it which tells the Angular CLI how to build our client side app when you simply run
ng build .
We need add a new object to the apps array to tell the Angular CLI how to compile our server side app. So your
apps array should look something like this:
in the first entry, we need just to modify the
dist/browser so it will store our client side app bundle there.
in the second app entry we give it a name
ssr then we tell the CLI that the platform we are targeting is the server and our Universal bundle should appear under
dist/server . We also point it to the tsconfig we created for the server and the main server file.
Step 9: Spinning up an Express Server and Using Webpack
I won’t go here into details but basically here we are creating an express server to serve our server side app locally.
So create a
server.ts file in the root of your project file and a
webpack.server.config.js to package the
ts file using the
ts-loader we installed earlier
Step 10: NPM script to bundle and serve the app
now all we have to do is just add an npm script to save us the time of writing a long command to build our app using the CLI , pack our
server.ts file using Webpack and finally run it with node
package.json file add the following command to your
"universal": "ng build --prod && ng build --prod --app ssr --output-hashing=false && webpack --config webpack.server.config.js --progress --colors && node dist/server.js"
finally using AngularFire Lite
we are just going to do something simple in here just print some data from Firestore in header tag but stay tuned as I am going to release new step by step guide to build production ready beautiful apps with AngularFire Lite and if you don’t want to miss those valuable tutorials you can subscribe in here.
if you add document under and name it `hello` with a field called `firestore` and a value `Hello Firestore from AngularFire Lite`
you can retrieve it simply in you
app.component.ts by doing the following:
- you import AngularFireLiteFirestore and you inject it in the constructor
- you reference it in you
ngOnIntlifecycle hook and call the read method
- finally, subscribe in the component or the template using the
asyncpipe to retrieve the data
here an example of using multiple features of the AngularFire Lite library which includes the Realtime Database, Firestore (reads and batched writes) and authentication (just remember to set your read and write permissions in your Firebase dashboard to true just for testing only).
and here is the template:
Enjoy Server Side Goodness! 😮
Now all you have to do is just to run
npm run universal
then open http://localhost:5000/ and your data should appear as you store it in your Realtime Database or Firestore and the cool thing is when you hit view source you can see the actual HTML displayed just like this:
you can now enjoy :
🔎 SEO benefits and social media thumbnails on shared content
😎📃 Faster loading time* (first render / first meaningful paint)
Feeling lazy? clone the AngularFire Lite demo repo
If you are feeling a little lazy you can clone the AngularFire Lite demo from Github by visiting the repo: Here
What about rendering with Firebase Cloud Functions and firebase hosting?
This article is one of a series of articles and I will definitely cover that but I just wanted to start with core principles of server side rendering and demonstrating that AngularFire Lite actually let Angular Universal renders our HTML using the data stored on the Firebase realtime database or firestore unlike Angularfire2 which throws an error. More to come in the rest of the articles so you better don’t miss those by subscribing here to get notified.
Best courses to invest in — fastest path to Fullstack
Don’t waste your time searching for pieces of content scattered on the internet and stop being cheap! You think you’re saving money and making a good deal by digging deep in google search and YouTube looking for tutorials but believe me, you are paying a high price by wasting your time doing so!
I really recommend you get one of the most popular courses by Wes Bos in the areas you lack the most experience in. Nothing beats an up-to-date and well thought out course. Here is a list of his best selling courses that you should consider
Become an Angular Master
The best course to take in order to familiarizes yourself with the entire Angular ecosystem as you will use popular libraries in building an entire application (includes state management using NgRx too):