Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn
Bob at Genuitec
Virtual evangelist at large. The face of Genuitec often appearing in graphics. Pen-name for our more shy writers of content.

We will be creating a blog using Angular 5, and Firebase in a 3 part series – our app will allow for easy creation and publishing of blog posts. A normal Angular application executes in the browser, rendering pages in the DOM in response to user actions. In order to improve the user experience, we want to render the pages server side and send the generated static content to the client side. The technology that allows us to do this is Angular Universal. Angular Universal generates static application pages on the server through a process called server-side rendering (SSR). It can generate and serve those pages in response to requests from browsers. It can also pre-generate pages as HTML files that you serve later.

Now, why would you want something like this? Fundamentally, the fact that JavaScript is not involved in a pre-generated page, makes it render faster – your application’s first page shows up faster, it’s easier for web crawlers (better SEO), and it works better on low-powered devices or on slower connections.

We would recommend that you follow the tutorial step by step, copying snippets from the article into a project you create. This will help you understand both the tool as well as Angular Universal concepts better. However, the final source is also available on GitHub.

New Angular Project

If you don’t already have Angular IDE, please download and install it before starting this tutorial.

Open Angular IDE, and from the top menu select File, then New, then Angular Project. In the New Angular Project wizard, enter FireBlog as the project name, 1.6.5 as the Angular CLI version, and you can choose whatever Node and NPM versions you wish, or stick with the defaults. Click Next, then click Finish.

app-w-firebase-new-project

Project Module Directories

Our project is a simple blog built with Angular, which will use FireBase for authentication and as a database. In this project we will use at least two modules to organize our code:

  • Editor Module: This module will provide functionality authors to create and modify content for the blog.
  • Reader Module: This module will provide functionality for users who come to the blog to read an interact.
Do you need a full-stack IDE that can cover both your back-end and front-end needs? Ready to go beyond what Eclipse has to offer? Try our fullstack MyEclipse IDE, which will rock your world.

Components for Editor Module

We need at least two components for the editor module:

  • EditorPostsComponent to show the title, published status and other summary details for a list of all blog posts in the application.
  • EditorPostComponent to show the details for a single post and allows us to edit this single post.

In the top menu select File > New > Component, in the New Component dialog, enter /FireBlog/src/app/modules/editor/components as Source Folder and editor-posts as element name, and click Finish. Also create a new component in /FireBlog/src/app/modules/editor/components with element name editor-post, click Finish.

create-appw-with-firebase-new-component

The Editor Module

For our Editor Module we will need two classes, EditorModule – which will be our feature module, and EditorRoutingModule – which will configure the routing for EditorModule.

  1. In the project explorer, right click on the editor folder.
  2. In the pop up menu select New > Class.
  3. In the ‘New Typescript Class’ wizard, enter EditorModule as class name, and editor.module.ts as file name, then click Finish.
  4. Repeat steps 1 and 2.
  5. In the ‘New Typescript Class’ wizard, enter EditorRoutingModule as class name, and editor-routing.module.ts as file name, then click Finish.

EditorRoutingModule

Update the content of src/app/modules/editor/editor-routing.module.ts:

The Angular Router enables navigation from one view to the next as users perform application tasks. In EditorRoutingModule, we are setting up 3 child routes:

  • /posts to render a view of all post titles and some metadata like published status, author, etc.
  • /post/:id to render a view that allows editors to make changes to a single post.

EditorModule

Update the content of src/app/modules/editor/editor.module.ts:

In EditorModule we import EditorRoutingModule and include it among the imports for NgModuleEditorModule. We also import EditorPostsComponent, and  EditorPostComponent, which we add to the declarations for NgModule EditorModule.

Components for Reader Module

We need at least two components for the reader module:

  • ReaderPostsComponent to show title, published status and other summary details for a list of published blog posts in the application.
  • ReaderPostComponent for the read only view for a single post.

Create two components with element names reader-posts and reader-postusing FireBlog/src/app/modules/reader/components as the Source folder.

The Reader Module

For our Editor Module we will need two classes, ReaderModule which will be our feature module, and ReaderRoutingModule which will configure the routing for ReaderModule.

  1. In the project explorer, right click on the reader folder
  2. In the pop up menu select New > Class
  3. In the ‘New Typescript Class’ wizard, enter ReaderModule as class name, and reader.module.ts as file name, then click Finish.
  4. Repeat steps 1 and 2
  5. In the ‘New Typescript Class’ wizard, enter ReaderRoutingModule as class name, and reader-routing.module.ts as file name, and then click Finish.

Reader Routing Module

Update the content of src/app/modules/reader/reader-routing.module.ts:

Similar to EditorRoutingModule, we set up an NgModule ReaderRoutingModule, to configure routing for views to be used by readers on the site, we just have two routes, the empty path which will render ReaderPostsComponent to show a list of posts available on the blog, and post/:id to read a particular blog post.

Reader Module

Update the content of src/app/modules/reader/reader.module.ts:

In ReaderModule, we import ReaderRoutingModule and add it to the imports for NgModule, then we import ReaderPostsComponent, ReaderPostComponent and add them to the declarations.

Routing Module for AppModule

We will create a routing module for our AppModule, but before that lets create a 404 page component. Let’s follow these steps:

  1. Right click on the app folder and select New > Component.
  2. Change the Source Folder to /FireBlog/src/app/components
  3. Enter page-not-found as the element name and then click Finish.

Now let us create a routing module for AppModule:

  1. Right click on the app folder in the project explorer.
  2. In the pop up menu select New > Class.
  3. In the ‘New Typescript Class’ wizard, enter AppRoutingModule as class name, and app-routing.module.ts as file name.

Update the content of src/app/app-routing.module.ts:

In AppRoutingModule, we have configured our ReaderModule, which imports ReaderRoutingModule to handle urls without the editor prefix and we have configured EditorModule which imports EditorRoutingModule to handle urls with the editor prefix. For example fireblog-domain.tld/post/1 will be routed through ReaderRoutingModule, while fireblog-domain.tld/editor/post/1 will be routed through EditorRoutingModule.

Now let us update the content of src/app/app.module.ts, and import AppRoutingModule and add it to our imports, also checking to ensure PageNotFoundComponent is in the declarations array.

Add Bootstrap CSS

Update src/index.html by using a link tag in the document head to include Bootstrap 4 from maxcdn. The file content becomes

Layout

We will update src/app/app.component.html, to add a simple navigation bar and create a sidebar and a content area:

Now let’s update src/app/modules/editor/components/editor-posts/editor-posts.component.html with placeholder text, the full functionality will be implemented in the next post in this series:

Also update src/app/modules/reader/components/reader-posts/reader-posts.component.html:

Server Side Rendering

So far we’ve been setting up our app, just like we would any regular Angular application. We’re now moving on to the Universal part of this tutorial, setting up Angular Universal.

Install dependencies

In order to implement server side rendering, we need to install some additional dependencies. Open a new terminal session in the Terminal+ view, ensuring that the FireBlog project is selected there. Enter the following commands:

The root AppModule

Open file src/app/app.module.ts and find the BrowserModule import in the NgModule metadata. Replace that import with this one:

This will add fire-blog to the style-names of server-rendered pages, so they can be differentiated from the regular styles – these will be removed when the client application takes over.

Create an app.server.module.ts file in the src/app/ directory with the following AppServerModule code:

Create a main.server.ts file in the src directory with the following code. Note you can right click the src folder, and use File > New > TypeScript Source File to create this file.

Create a server.ts file in the project’s root directory and add the following code:

This looks complex, but what it’s doing is responding to HTTP requests from clients – serving HTML pages, styles, images, etc. It could even respond to data requests.

Note: This sample server is not secure – please do not use it, as-is, in production!

Create a tsconfig.server.json file in the project’s src directory to configure TypeScript and AOT compilation of the universal app.

This is the TypeScript configuration for Universal.

Create a webpack.server.config.js file in the project’s root directory with the following code.

This Webpack configuration transpiles the server, which is a TypeScript application, to JavaScript.

Update apps section of .angular-cli.json – this file can be found in the project’s root folder.

Note: If you don’t see the .angular-cli.json file, you need to disable a resource filter from the View’s menu, as shown below. You can alternatively open the file using File > Open.
disable-dot-filter


Build and Run with Universal

Now that you’ve created the TypeScript and Webpack config files, you can build and run the Universal application.

First add the build and serve commands to the scripts section of the package.json:

Build Universal

From Terminal+, type

npm run build:universal

Serve Universal

After building the application, start the server.

npm run serve:universal

The console window should say

Node server listening on http://localhost:4000

Open a browser to http://localhost:4000/.

Serve the App without Server Side Rendering

In the Server window right click on FireBlog and click the green icon with label Start Server:

app-w-firebase-without-server-side-rendering

Demo

Now we have our project running in two modes

Both versions should look like the image below:

app-w-firebase-demo

Disable JavaScript

In order to see the difference between the two versions, let us go ahead and disable JavaScript in our browser. We are using Google Chrome, so we will check the disable JavaScript option in the settings of developer tools.

app-w-firebase-disable-js

Now we will see that the regular Angular project running displays a blank screen, while the server side rendered version shows the rendered page even with JavaScript disabled.

app-w-firebase-js-disabled

app-w-firebase-server-side-rendered-with-js-disabled

Conclusion

With server-side rendering we can ensure that search engines, browsers with JavaScript disabled, or browsers without JavaScript can still access our site content. In the next article we will add the markdown editor for our authoring posts on our blog, and in the final article we will set up Firebase for authentication and persisting data to remote storage.

Related Posts

Creating Twitter Clone Using HTML, CSS, jQuery In this project, we are going to create a Twitter clone using HTML, CSS and jQuery only. We will create the Registration screen and Twitter wall, where you can post tweets up to 250 characters in length. You can also retweet and like the tweets. However, since we are not using any server and database, nothing will persist. As soon as you reload the...
A Day with Dani: Eclipse Plugin for Awesome Worksp... DevStyle Rescued My Workspace!As a new developer working in Eclipse, nothing was worse than doing a project and looking at an outdated, plain workspace. It was boring, and took away from the excitement and learning these projects had to offer. This was an IDE I would be using almost every day, so when I learned about the DevStyle plugin for Eclipse...
Happy Holidays – from Our Family to Yours! It’s that time of the year again - the time to enjoy a break from the everyday duties, accompanied by our loved ones! At Genuitec we would like to wish you a wonderful holiday season filled with great times and awesome food! We already got our party hats out (as you can see)! Our U.S. offices will be closed on December 25th and 26th, as well as Jan...
30% off sale, including Angular IDE and more! Step away from the leftovers and come take advantage of our Cyber Monday sale for Angular IDE, Webclipse, MyEclipse and more!   Thanksgiving is a great time for getting together with family, but perhaps more importantly, it’s about the SALES!  Whether it’s Buen Fin or Cyber Monday, we all love a bargain. Now is the time to get the software you alwa...

Posted on Jan 24th 2018