How to build a Hugo (Jamstack) website!

In this post I’ll walk you through what I did to build Quidel’s QuickStart website, built with Hugo and Azure services, located at located at https://quickStart.quidel.com.

What’s this QuickStart site all about?

I built and released this site in August of 2020. The project required a very quick build and release timeline to support customers who would soon receive Quidel FDA emergency approved diagnostic products during the SARS Covid-19 pandemic.

Specifically, the reason we built the site was to act as an easy to follow step by step guide for the near-consumer market to be able to quickly get up and running with Quidel’s Sofia 2 analyzer and start testing.

In the past Quidel had focused on Physician office labs and hospitals use their products so this was a little bit of a different challenge.

Here’s a screenshot of the home page:

Home page of quickstart.quidel.com

What did this website need to do?

The main technical requirements for the project included being able to

  • Scale up to high traffic loads
  • Load very quickly
  • Being mobile responsive (and looking very professional)
  • Eventually have multi-language support
  • Being launched soon (within a week!)

How I approached the build

I wanted to get away from having to manage a tech stack like LAMP (WordPress or Drupal) and the infrastructure to support it.

So I decided to go with a statically built website hosted on a CDN. Some call this the Jamstack.

Using a CDN (Content Delivery Networks) offers virtual infinite scalability for staticaly delivered content (HTML, CSS, JavaScript). And offers reduced maintenance and worry around will the site have exposure to back-end code (PHP) or database vulnerabilities.

Which Static Site Generators were best for the job?

I looked at a few different popular static site generators: Jekyll, Hugo, Next.js and Gatsby.

I started playing with Gatsby mostly because of all the buzz surrounding it being a hot technology and is using React and GraphQL. However I found it was cumbersome to setup (needed additional components for things like Google Analytics and multi-language support) and had 40+ second build times each time I wanted to first build the site on my local host.

I then settled on using Hugo because of it’s fast build times (~1 or less than 1 second) and it is very simple to get a site up and running and configured / customized without needing to install additional components.

Hugo, a framework for building static websites

The Docsy theme turned out to be fanstastic!

I choose to use the Docsy theme (lots of other Hugo themes are available) to run on top of Hugo:

  • Came with some very useful pre-built styling for buttons and sections.
  • Just works with Google Analytics. Plug in the code and you are good. There is a flag Hugo provides I am using to turn of or off analytics code being compiled into the web site files for when I want to deploy to prod vs to the test environment. This is super cool because I didn’t want to track analytics for people testing the site.
  • Had multi-language support built in. Fantastic, as we did end up adding multi-language support later on after first release.
  • Included image auto-manipulation (something the Go language appears to do very well). Meaning images I uploaded into Hugo (for example I uploaded a large image with the intent of it being a background image to display in a particular bootstrap block) were automatically transformed into multi-device friendly background images so the site looked very professional without me having to really do much image work!
  • Had nice site search capabilities built in – I chose just to have Google provide the site search. But there were out of the box options to use a third party service or use a pre-compiled JavaScript powered index of the site.

What about the site content?

I ended up taking the Sofia 2 package insert and translating that into a web friendly format using Markdown.

By the way here’s a quick into show some things you can do with Markdown and here’s how it works in a nutshell:

Markdown flowchart
Image credit markdownguide.org

Where the Markdown app in the above image represents Hugo as it compiles markdown into HTML.

Hugo loves Markdown

With Hugo, everything uses markdow. There is a main settings file but outside of that markdown controls the site configuration). Including the navigation and how pages fit into the navigation. It took a little getting used to at first.

And turns out markdown files (pages) in Hugo are sort of like entries in a database. So when you instruct Hugo to build your site it queries those pages (like a database) to then build the navigation and put pages where they need to go.

A little different from WordPress for example that is using a relational mysql database.

Local host editing with Hugo is blazing fast

When you tell Hugo to build your site you can use this command

hugo serve

And it will generate something like this

And in my case, means Hugo built the site in 892 ms (less than a second) and is now serving the site on my localhost http://localhost:1313/. And browsing to that location I can navigate and experience the site as if it were deployed to the internet.

Making a change to any markdown file and saving that file results in Hugo re-building the site very quickly (in under a second) and those changes are also then reflected in the localhost site.

And the ability for me to quickly see changes in the site was key to the process of polishing the site and making it look great in a short amount of time.

I built and deployed the site to Azure CDN using Azure Pipelines

The site was setup to build and deploy through Azure DevOps (Pipelines). In other words, I could do a commit on my local host, send that to Azure DevOps Repos (or at least do a Pull request from my branch into the Main branch), which would kick off a build via the build pipeline. The build would just end up being all the built HTML/CSS/JavaScript files. Then that completed build kicks off a release pipeline to send the build to Azure CDN.

The hosting infrastructure

I setup the dev, test and prod environments in Azure using resource groups to logically group things together.

For each environment, I used an Azure storage account (Blob storage) as the file hosting for the website files (that’s where the release pipeline was pointed to) and then setup Azure CDN endpoint to auto-refresh from Blob storage (the release pipeline also needed to tell the CDN to clear and refresh from Blob storage).

Treating websites like a software product

It was a fun experience to set all that up and see it working 🙂

Getting away from the traditional web server, database, PHP stack that a lot of sites run on today was refreshing.

And having all code and content version controlled is an interesting way to manage websites that may begin to catch fire in the coming years. To me it makes a lot of sense to control content in this way vs having someone log into a production site to make changes – which just is asking for problems! Don’t edit in prod! 😉