Rewriting angular-meteor.com in Angular Universal
Published: 2020-03-18 19:41:13

![](https://github.com/the-guild-org/oneblog/blob/master/img/704/1*ChqVouqofNoSwmgp_-Ytag.png?raw=true "angular-meteor.com is now a universal app!")

We recently finished re-writing and deploying our new [angular-meteor.com](https://angular-meteor.com/) website with completely new tooling using Angular Universal and our new tutorial infrastructure.


In this post, I’ll share our experience using Angular Universal, and introduce the tools that we created on top of it. We’ll write about (and open source) our new tutorial infrastructure in a following post, so stay tuned!

## TL;DR

Our former website was a dynamic app. We wanted to rewrite it into a static website because:

1.  It needed a server and hosting.
1.  We needed a lot of tooling in order to make it SEO compatible.
1.  It loaded slowly.

**We’re happy to say… The transition was successful!** Check it out and take a look at the new tutorials [here](https://angular-meteor.com/).


Here are the improvements this made possible:

-   The page loads much faster
-   No need for servers anymore, we use GitHub Pages

To accomplish this, we created a tool that takes various content types and renders it to any format we want:

-   Input sources — A unique markdown format for our tutorials and a JSDoc format.
-   Render targets — Our angular-meteor.com website, your own website or doc format, or a Medium post API.

# Converting input sources to render outputs

Our new tooling is capable of getting input sources from various content types and generating output in any format we like. Currently, we published it as a package, which includes:

-   Accepting [Markdown](https://github.com/Urigo/tutorial-infrastructure/blob/master/src/steps-templates-loader.ts#L28-L42) + [Git patch](https://github.com/Urigo/tutorial-infrastructure/blob/master/src/tutorials-registry-cache.ts#L54-L85) from our tutorial infrastructure.

-   Accepting [JSDoc](https://github.com/Urigo/tutorial-infrastructure/blob/master/src/api-load-resolve.ts#L20-L78).

-   Angular 2 [Components](https://github.com/Urigo/tutorial-infrastructure/blob/master/src/diffbox.component.ts) and [Directives](https://github.com/Urigo/tutorial-infrastructure/blob/master/src/tutorial-navigation.component.ts), and some utils functions that relate to Angular 2, including [tutorial -> route](https://github.com/Urigo/tutorial-infrastructure/blob/master/src/tutorial-routes.ts).

-   [Static website generator](https://github.com/Urigo/tutorial-infrastructure/blob/master/src/generate-static.ts) — think about this as a NgModule to HTML files converter.


# Tutorial as input

As part of the rewrite, we created a new tutorial infrastructure that we’ll talk about in a future post when we release a few more features. You can see it in action here — <https://angular-meteor.com/tutorials/whatsapp2/ionic/setup>


For the purpose of this post, the important thing to know about the infrastructure is that the code examples are being generated from a real app using real commits (inspired by Sashko Stubailo’s work [on the Meteor tutorial](https://blog.meteor.com/building-maintainable-step-by-step-tutorials-with-git-cdb6d77ea966#.lg32xh4c9)).


The infrastructure renders markdown files with links to the git commits, and we need to turn those into a diff-box components with the actual code that changed in the commit, like [here](https://angular-meteor.com/tutorials/whatsapp2/ionic/meteor-server-side#collections) for example.


# JSDoc as input

Let’s start again with the result of this section, so it will be simpler to understand: <https://angular-meteor.com/api/angular2-meteor/latest/Meteor-RxJS>


We want to use the JSDoc standard over our code ([example](https://github.com/Urigo/meteor-rxjs/blob/master/src/MeteorObservable.ts#L13-L24)), take this JSDoc definition, convert it into a standard markdown file, display it in our website, and finally expose it directly inside the repository of the package ([example](https://github.com/Urigo/meteor-rxjs/blob/master/docs/ObservableCollection.md)).


We wanted versioning because our API might change over time — that’s where Git comes to our aid. We also have a Git revision (commit id or tag) for each version of the package. That way, we can take a specific version of the file with it’s documentation from GitHub and generate the API reference for all of versions of the package and API docs.

# Components, Directives, and utils

The Angular 2 components and directives are meant to display results of the markdown docs together with the special Git patch handlers. This means it’s using a regular markdown parser with the small addition of DiffBox, a Component we wrote that displays the changes in each commit in a diff format (just like a diff view in GitHub).

Also, we have directives that are useful for: navigation, creating links, displaying a list of steps of the tutorial, links to download those steps (based on git commit) and more.

We also have a route generator for the tutorial, which means that, based on your tutorial definition, this util will generate your routes for the Angular router with all the required resolve phase that the infrastructure needs (load files from GitHub, format, convert and so on).

# Static HTML Generator

Our main output is our [angular-meteor.com](https://angular-meteor.com/) website. The utils wrap the sources with a beautiful design, custom pages and stylesheet, and then uses the last part of the infrastructure — the static page generator.


Using your application’s route definition (the generated tutorial routes, along with the custom pages you need), this tool loads the entire page (generated on the server side as we’re running in an Angular Universal environment) and saves it into a single HTML file that has no dependencies at all. The whole page is inside a single HTML file — no JS and no external CSS files!

Our next step is the deployment of this website, which is easy, because we are using an autonomous HTML files that every single HTTP server can serve. We chose GitHub Pages to host our website, so we don’t need any external server or hosting.

# The Result

We managed to accomplish all of our goals for the new website:

**We met our own needs:**


-   It’s easy to maintain because it uses the same GitHub repository that stores the actual tutorial code.
-   It’s super fast and because it loads only static HTML files.
-   Its hosting is simple (GitHub Pages) and it has no server-side at all.

**We created something that might be useful for others:**


-   Extensions to Angular Universal that can accept your own inputs and outputs.
-   Tools for rendering markdown from remote source with Angular Universal.

Check out the website and code! Maybe you can find some utils for generating routes of API docs, or expose Components and Directives that you can use later to enrich your own website.

We saw that the Angular team has started working on a new angular.io implementation and would love to help with our tools and experiences from doing very similar work on our own website.

Most importantly — enjoy the new [angular-meteor.com](https://angular-meteor.com/) :)


# Next steps for Angular-Meteor

In recent months, both Meteor and Angular have made huge leaps, so we have a lot of goodies to catch up on.

Our vision for the next version of Angular Meteor includes the following features:

-   Support for Angular CLI with [Meteor Client Bundler](https://blog.meteor.com/leverage-the-power-of-meteor-with-any-client-side-framework-bfb909141008) (already works).

-   The easiest way to do lazy load in Angular with [Meteor 1.5 (code splitting and dynamic imports without configuration)](https://blog.meteor.com/dynamic-imports-in-meteor-1-5-c6130419c3cd).

-   AOT out of the box.

But we want your help! If you’re interested in helping us tackle these exciting features, [contact us directly!](https://github.com/urigo)