How To Password Protect A Hugo Site

February 19, 2017

In this tutorial, we'll add a login page to our Hugo site using the Aerobatic password-protect plugin. No servers. No dynos. No hassles. Just a few lines of code and your login page will be live.

Create a login.html

Create a login.html page in the /static directory where Hugo will pass through whatever is in that directory into your built assets.

You can style your login page however you want. What's essential is that the form markup needs to be decorated with the aerobatic-password attribute in the input as shown below.

<!DOCTYPE html>
<html lang="en">
  <head> </head>
  <body class="body">
    <div class="container">
      <div class="content center">
        <!-- login form -->
        <h6 class="error" id="password-error" style="color:red"><strong></strong></h6>
        <form method="POST">
          <label for="password">Password</label>
          <input class="button-primary" type="submit" value="Submit" />
        <!-- /form -->
    <!-- /container -->
    <!-- JS -->
      if (/fail=1/.test( {
        document.getElementById('password-error').innerHTML = 'Incorrect Password';

Create Aerobatic site

Assuming you've already installed the aerobatic-cli, from the command line, enter the following to associate your Hugo site with Aerobatic:

$ aero create

Edit aerobatic.yml

This is where you'll take advantage of Aerobatic's built-in password-protect plugin. In the root of your Hugo site, open up the newly created aerobatic.yml file and edit like so:

# Aerobatic website manifest
  - name: password-protect
      password: $SITE_PASSWORD
      loginPage: login.html
      maxFailures: 5
      failureWindow: 600
      lockoutDuration: 600
        - '/css/*.css'
        - '/js/*.js'
        - '/img/*.jpg'
  - name: webpage

You'll notice here a couple of things. The first is that we have an environment variable called $SITE_PASSWORD. The second thing you probably noticed is that we're telling the password-protect plugin to not protect a few files, namely some CSS, JS, and JPG files. That's so they can load on the login.html page and not get a 401 error before the password has been entered.

Create environment variable

Using the CLI, create an environment variable called SITE_PASSWORD. In this example we are using the value "aerobatic".

$ aero env --name SITE_PASSWORD --value aerobatic

Set up Bitbucket Pipelines Continuous Deployment

At this point you could just type aero deploy -d public to deploy your Hugo site. However, in this case, we're going to use Bitbucket Pipelines to set up a nice continuous deployment flow. Make sure you enable Bitbucket Pipelines in your repo, and here's what your bitbucket-pipelines.yml file might look like (you may have noticed we're using Aerobatic's custom docker image for Hugo:

image: aerobatic/hugo
      - step:
            - git clone themes/hugo-geo
            - hugo --theme=hugo-geo --baseURL ""
            - aero deploy --directory public

Push your changes

Either from the command line, or with a tool like Sourcetreee, push the changes to your Jekyll repository. e.g.

git add --all
git commit -m "Added a login page"
git push origin master


That's it! Your Hugo site is now password protected with a branded login page. In this example, we've added protection to the whole site, but you can also add it to specific folders. For example, maybe your landing page is open to everyone, but you want your /post content to be password protected. That's all possible with the password-protect plugin.

Additionally, maybe you want to handle the 401 error with a custom error page if the user incorrectly enters their credentials. Again, all possible with the Aerobatic custom-errors plugin.

The demo Hugo site can be found at and the source code is on Bitbucket.