How I made my blog cheap to host, customizable, and lightning-fast. -Part 2

Part 1: Setting up Our Headless CMS and Azure DevOps
Part 2: Building out our Angular Site — You are here
Part 3: Meet Scully, our Static Site Generator
Part 4: Hosting on the Cheap
Part 5: Build and Deploy with Azure DevOps

Antique letterpress letter blocks
photo credit: Patrick Fore

In Part 1, I laid out the stack from source control to release pipeline. We also set up a couple of accounts we’ll need for our CMS and Source Control. Now let’s get to the fun stuff.

We’re going to build an Angular site here, but you could swap out your framework of choice if you’d like. The key is that you can hook up a Static Site Generator to it. We’ll use Scully, but I don’t see any reason you couldn't use Hugo or Gatsby or any of the others out there.

The Site

I put an extremely basic site together to prove out this concept. I’ve posted it over at Github. Feel free to do whatever you want with this site. I’ll likely port back some features to it as I build them out for my personal blog and welcome any you might want to add. I should say upfront though that at this point it is hardly a blog. Just a site with an unstyled list of posts and an equally unstyled display of title/body.

If you want to skip this section you can just grab the code from Github and move to Part 3. The site is pretty simple, but there are a couple of things worth mentioning:

There is an interceptor that catches all requests to the Squidex API and tacks on an authentication header.

I added dotenv to keep the environment variables out of git. This is described a bit in the readme, but basically, you create .env.[prod/dev] files with your variables, and on npm start or npm build, it will regenerate your environment.ts files.

Here’s how you can get started with it:

Pull site down from github

create .env.dev and .env.prod files in root

fill those files out per the .env.example file in the repo with details from your squidex client

run npm start

Still here? Let’s build a website.

First, we need to create an angular site. Open up your favorite editor (It’s VS Code right?) and if you’re new to angular run this:

npm install -g @angular/cli

Then run this (You can name the project anything)

ng new my-rad-project

You’ll get asked a few questions. We want it strict. We want routing. You can pick the styles (I use SCSS).

Create our Components

We’re going to need a couple of components:

  • list of blog posts
  • individual blog post
  • navigation
  • home page

We can create these with the following terminal commands:

ng g c components/blog
ng g c components/blog-post
ng g c components/nav-bar
ng g c components/home

Moving Around

Let’s get some routing set up so we can navigate to these components. Open the file /app-routing.module.ts. We’re going to modify the routes variable to map 3 routes:

const routes: Routes = [
{path: 'blog', component: BlogComponent},
{path: 'blog/:postSlug', component: BlogPostComponent},
{path: '', component: HomeComponent},
];

When you put your cursor on a component name, you can press ‘Ctrl + .’ then enter to import that component.

Finally, let's go into the /app.component.html file and replace all the contents with

<app-nav-bar></app-nav-bar>
<router-outlet></router-outlet>

If your server stopped running you can start it again and you should see a page that says “nav bar works!” and “home works!”.

Let’s add links to our nav bar control so we can check out the work we’re going to do on our blogs component. Replace the nav bar file with this:

Get our Data from Squidex

Since we’re using TypeScript we need to start with our models. These interfaces will define the structure of the objects we’re bringing back from the CMS. We’ll create a “models” folder and add these interfaces:

Now we have the structure, we can create a service to fetch the data. Run the following command in the terminal:

ng g s services/contentBackend

Fill the file with the code below. It just makes a call out to the Squidex URL that gives us back a list of all of our posts.

Adding Authentication

Awesome. Now we can pull in our posts, right? Not quite... We still have to handle authentication with Squidex. Good news though, we’re just going to do this once. First we need to create a “services” folder, and add the following file to it, call it “squidex.config.ts”

Then we need to provide all of the environment variables. We do that in our environment.ts file:

Next, run this command:

ng g interceptor services/contentAuth

This will generate an “interceptor” file. We’ll use this to catch every request going out to the Squidex API and tack on an authentication header before sending it. Here’s how we do it. This code is lightly modified from the official Squidex sample blog. You can find the original here.

Then we’ll need to add the interceptor and the config to the providers section of our App Module.

providers: [
{ provide: SquidexConfig, useValue: DefaultSquidexConfig},
{ provide: HTTP_INTERCEPTORS, useClass: ContentAuthInterceptor, multi: true}
]

Now we should be able to make a call and get data from Squidex. Let’s try it!

Listing our Blog Posts

We’ve got to have a way for users to go from post to post. We’re going to create a list of every published post and just link each one. To do this, we’ll edit the blog component we created earlier. Modify the Html and .ts files to look like this:

Now you should be able to run an ng serve -o and click the “blog” link in the nav to see any posts you have published in Squidex. Make an edit, come back and refresh, and things should update.

Display a Post

If you click the link on one of your published posts, you should have just seen: “blog-post works!”. What we need to do is fill out that component so that it reads the slug from the URL and displays the correct story. Here’s the content for both the Html and the .ts file.

Notice we’re calling a new method on our ContentBackendService. Let’s open that file and add the new method:

We did it. Now we can run the site again and click through to our blog post and see the title and body. We don’t have styles, or like ANY blog features, but we can see a list of posts and click through and read the post. If changes are made in the CMS, you’ll see them on the site when you change routes.

Ready to make it fast? Check out Part 3 and see how Scully can help. You may also want to commit at this point if you haven’t been doing so along the way.

< Part 1: Setting up Our Headless CMS and Azure DevOps

Part 3: Meet Scully, our Static Site Generator >

Full-stack developer, Dad. Passionate about clean code and constantly learning. Current interests: Angular, DevOps, Domain Driven Design, and birding.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store