Build & Deploy a Site with Hugo & Firebase

Build & Deploy a Site with Hugo & Firebase

It’s not uncommon to find content creators who choose to have their content on personal blogs/websites. Usually, a go-to solution would be to use a CMS (Content Management System) like WordPress or Wix.

However, building a web application with any of these technologies is restrictive due to their monolithic design (tight coupling between client and server). It’s harder to manage and scale these kinds of applications. Some of the likely drawbacks of these CMS applications include:

  • Tight coupling between components (making it harder to test components individually).

  • Large and complicated codebase: Making it hard for collaboration.

  • Less reusability.

  • It does not follow the SRP (Single Responsibility Principle).


Jamstack to the rescue

With the rise of Jamstack, building web applications that are fast, lighter, decoupled, and easily maintainable is just a couple of tools away. If you’re wondering what Jamstack is all about, I’ve written a practical guide here to get you started:

With Jamstack, we can use Static Site Generators like Hugo to generate and deploy a site on a CDN like Firebase Hosting Service or Netlify.


What you’ll need

Hugo

Hugo is a popular open-source static site generator that helps us quickly scaffold simple websites.

Installation (Mac)

To get Hugo installed on your Mac Operating System, you must ensure you have Homebrew installed. Homebrew is a package manager for macOS and Linux.

If you do not already have Homebrew installed, you can install it on macOS with a single command. Open up your terminal and paste this:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

Once the installation is complete, you should be able to access the brew CLI. Verify that you have Homebrew installed by typing: brew

image

From here, you can easily install the Hugo CLI with Brew using this command:

brew install hugo

That’s about all you need to install Hugo on your macOS.

Installation (Windows)

The Binary installation is perhaps the easiest way to install Hugo CLI on your system. You can download the appropriate version for your platform from Hugo Releases. Once downloaded, you need to unzip and install it. The binary can be run from anywhere, so you won’t need to install it in a global location.

Chocolatey

Chocolatey is the package manager for Windows operating systems, the same way you have Homebrew for macOS. You can find the installation guide here:

Once installed, you can simply install Hugo with this command:

choco install hugo -confirm

Installation (Linux)

You can also use the binary installation to get Hugo on your Linux machine. Alternatively, you can install Hugo with Snap.

First, you need to install the Snap CLI tool.

    sudo apt update
sudo apt install snapd
snap install hugo

Great! Now, you should have Hugo installed on your system. Next, we need to create a Firebase account (if you don’t already have one).

Firebase

Head over here and create an account. Once you’re logged in, you’ll need to create a new Firebase project.

image

Give your project a name like so:

image

We do not need to enable Google Analytics for this project, so you can comfortably turn that off:

image

Grab a coffee while your project is being generated. ☕️


image

Your project should be ready now. Click “Continue” to proceed to your Firebase dashboard.

Firebase offers a handful of services that help you build and deploy mobile and web applications easily. One such service is the Firebase hosting service. This is the service we will be using.

Firebase CLI

Now that you have your Firebase account set up and have successfully created a Firebase project, we can proceed to install the Firebase CLI. This command-line interface allows us to perform certain Firebase actions from our machine via the terminal.

  • Windows: Download the latest binary for Firebase tools here

  • macOS / Linux: For macOS or Linux users, you can run the auto-install script. The script will automatically detect your operating system and install the latest Firebase CLI release.

curl -sL https://firebase.tools | bash

Via NPM

It is also possible to install Firebase CLI via NPM (Node Package Manager) if you already have Node installed.

npm install -g firebase-tools

Once the installation is successful, you should have the Firebase command available from your terminal.

image


Generate Hugo Site

Next, we need to generate our site with Hugo CLI. Open up your terminal/command prompt and type:

hugo new site site_name

You can decide to give your site whatever name you wish. A new folder will be created with the name you specified.

image

Hugo CLI scaffolds a project directory structure with empty subfolders; let’s take a closer look at the generated folder structure.

I’ll open up the application in VSCode. From the terminal, you can type:

code .

image

The folders above should be empty when generated. Let’s break down what each folder serves.

Most of the information about folder structure can be found here.

  • Archetypes: In Hugo, front matters are metadata that holds tiny information about our site content (date, title, draft). Archetypes contain custom preconfigured front matters.

  • Content: All content for your website lives inside this directory. Each top-level folder in Hugo is considered a content section. For example, if your site has three main sections — blog, articles and tutorials—you will have three directories at content/blog, content/articlesand content/tutorials .

  • Data: This directory is used to hold configuration files used by Hugo when generating your website. You can write configurations in JSON, YAML, or TOML.

  • Layout: This folder is used to store templates in the form of “.html” files that specify how views of your content will be rendered into a static website.

  • Static: Stores all the static content: images, CSS, JavaScript, etc.


Now that we have a basic understanding of the folders that were generated, we can move on.

The Hugo CLI only generates a skeletal structure for you. It is void of theming and content (all the folders are empty). We, however, have a whirlpool of community themes we can install. Hugo themes can be installed as git submodules.

To install a Hugo theme from your terminal within your Hugo root project directory, type:

git init$ git submodule github_url

I’m going to install the Ananke theme:

image

First, we initialize our project folder as a git repository, then install the theme as a submodule.

git init
git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke

The Ananke theme would be cloned into the directory we specified (/themes/ananke/). Let’s take a look at what the theme directory contains.

image

There are two ways to get started using this theme:

  • Using the example content provided by the theme

  • Creating your content

Using the example content

In this case, from the theme directory structure, what we are interested in is the “exampleSite” subdirectory. It would serve as a template to get started quickly with some dummy content. Firstly, what you need to do is copy the content of the “exampleSite” directory into your root directory. You can either do this manually (CTRL + A & CTRL + C & CTRL + V 👴🏼)

or from the terminal:

cp -R ./themes/ananke/exampleSite/* ./

This would add some folders and files (about, post, _index.md) in your “content” folder in your root directory.

This copy would also replace your “config.toml” file. PS: This is a very crucial configuration file.

You need to edit the config.toml file to specify the correct theme name and theme directory so the Hugo CLI knows what and where to look.

theme = "ananke"themesDir = "./themes"

Once that’s done, you can save and start the Hugo server:

hugo server

image

You can navigate localhost:1313 to view your site.

image

The Hugo has support for live-reload, so you don’t need to reload pages when you make a change.

Let’s try changing the header text. Open “_index.md”; you should see the title front matter value:

image

Try changing it to “My Hugo Test Site” and check the site in your browser.

image

You can keep making changes and creating new pages/posts from here. You can check out the documentation to learn more about Hugo CLI.

Creating your content

You don’t need to copy the content of the example site directory in this case. Open the “config.toml” file in your project root directory, set the “theme” value to Ananke, and also set the theme directory.

theme = "ananke"
themesDir = "./themes"

Your configuration file should look something like this:

image

Once that’s done, you can create your first post/page using the Hugo CLI.

hugo new index.md

This command generates a new file called “index.MD” (markdown extension) in your contents directory. You can open this file and add some text.

image

Notice the front matter at the top (title, date, draft)

Save this file and spin up the Hugo server again.

hugo server -D

Notice here we have a -D flag as opposed to the first time we started the server. This flag enables drafts.

Draft? What does that mean?

When you have a newly generated page/post, it is automatically in drafts and will not be publicly available until you “publish” it ( in this case, set draft to “false”). If, however, you do not wish to publish just yet but would still like to work on the page and see your changes, you can start the Hugo server with the -D flag.

Note: All public pages should have the draft value set to false

Great! Now we have our Hugo site ready. Next step — deployment.


Deploying to Firebase

We need to first generate the static files for our site using the hugo command in the root directory.

This generates the static files for your website and copies them into the public/ directory by default, although you can customize the output directory in your site configuration by changing thepublishDir field (we won’t be doing that). From your terminal, type:

hugo

Once your static files have been generated, initialize Firebase from your root directory:

firebase init

You’ll be presented with options to choose from. These options are Firebase services; we’ll only be selecting the hosting service. Once you have the arrow on a service, press the spacebar to select it.

image

Next, we need to associate the project directory with a Firebase project (remember the project we created earlier from the Firebase web console? Yeah, that one). Choose “Use an existing project”:

image

You would be presented with a list of existing projects on Firebase. Navigate to the new project we created and select it.

image

Next, you’ll need to set your public directory (This is the directory from which Firebase would publish our site). Since we already know that Hugo CLI generates static files to the public directory, we can simply press the enter key (as Firebase uses “public” by default).

image

When asked whether to configure it as a single-page app, Choose No by typing N. If you’re asked whether to overwrite files in the public folder, just choose Yes for now.

image

Your Firebase setup should now be complete.

Next, we’ll regenerate our static files with Hugo CLI and then deploy with Firebase CLI. Type hugo from your terminal, then type firebase deploy.

hugo
firebase deploy

Your deployment should be successful at this point. Firebase generates a Hosting URL for your site as well. You can copy the URL and open it in the browser to view your site.

image

You can equally access the site from a firebaseapp.com subdomain.


Custom Domain (Extra)

If you want to go a step further and use a custom domain name for your site, the Firebase console has a section to add a custom domain. From the Firebase console, select Hosting:

image

Next, click on “Add Custom Domain” and go through the process of setting it up and verifying ownership.

Well, it’s been a long ride. Cheers if you made it this far.

You can find all the project files here:

Cheers ☕️