Front-End Web & Mobile

Add a GraphQL API to your Hugo site with AWS Amplify

This post was written by Tom Moore, Solutions Architect at AWS

Hugo is a very popular web framework for developing static web sites. The AWS Amplify console provides an easy way for you to host your Hugo web site with an automated CI/CD Pipeline built for you. This Blog post will help users to extend their Hugo web sites hosted in the Amplify console with back end services like AppSync that are built using the Amplify tool chain.

By following the steps outlined in this blog post you will be able to host data stored in Amazon AppSync on your Hugo web site.

Prerequisites

Install NodeJS and Node Package Manager (NPM)

You can install NodeJS and NPM on MacOS or Linux by using either Homebrew, or Node Version Manager (NVM.) Windows users can download and install the package published at: https://nodejs.org/

Setting up the Amplify tools

Instructions for installing and configuring the Amplify Command Line tools can be found here: https://aws-amplify.github.io/docs/

Under Getting Started. These instructions will walk you through the process of setting up an AWS Account along with installing and configuring the AWS Amplify command line tools. Once you are done with the first two steps, return to this post. You do not need follow the instructions in section 3, “Build your app”.

Install Hugo

In order to build a Hugo website, you will need to install the Hugo tool chain. Instructions for installing Hugo can be found here: https://gohugo.io/getting-started/installing/

Install Git

This project will require interacting with git source control. You should install a git client, and make sure you have access to Git credentials via HTTPS or SSH. This lab blog post assumes a basic level of familiarity with how to use git.

Setting up source control

In order to use the Amplify Console later in this process, we will need to have access to a source control repository. This repository will serve as the repository for the Amplify CI/CD pipeline.

  • In the AWS Console, select the Code Commit service.
  • From code commit, select Repositories.

  • Click on the Create Repository button on the right-hand side.

In the create repository dialog, provide a Repository name, and optionally a description. For this sample the repository is called “hugosample”. If you use a different name, you will need to use that wherever the instructions call for your repository name.

Once your repository has been created, the Code Commit console provides instructions for downloading and configuring your git client to access Code Commit. The console also provides a way of getting access to the clone URL for the repository.

Cloning your repository

On your local development machine use your git client to clone your repository to a local folder.

git clone {Repository URL copied from above.}

You will receive the following warning, but you will have a new directory created that matches the name of the repository that you created in Code Commit.

Creating your Hugo site

The Hugo command line will create your new website via the command line. Unfortunately, the Hugo command line insists on creating the new site in a sub folder, which is not ideal for our purposes. Use the following commands from the command line in order to generate a new Hugo website, and move all the files to the base of your repository.

cd hugosample
hugo new site hugoSampleSite
mv hugoSampleSite/* ./
rmdir hugoSampleSite

Once you have the site constructed in the root directory of the repository, the only thing left to do is download and copy a Hugo theme into the theme directory of your site and configure it.

For this demo we will use the Hugo theme ‘Ananke’ which is available here: https://themes.gohugo.io/gohugo-theme-ananke/

For the purposes of this example I have downloaded a ZIP file of the theme, and added it to the theme directory in my hugo site.

Finally edit the config.toml file to configure Hugo to leverage the theme.

Make the hilighted change to the configuration file, telling Hugo to load the Ananke theme for your site.

Once you have made all the changes, save the configuration file.

Finally, you need to create a first content page for Hugo to display. From the command line type the following command:

hugo new _index.md

Then run the following command line to start your Hugo development server:

hugo Server

The Hugo server command will start a web server on the local machine, that allows you to browse the site for local testing. Using your browser browse to the address specified. (In this case it is http://localhost:1313/) You will see you skeleton Hugo site ready for customization.

Setting up Amplify Console

Now that we have a starting point for the website, we want to publish the site and set up the Amplify Console to host the website.

From the command line, use GIT to publish all of the changes to the project.

git add .
git commit -m “Initial checkin of site files.”
git push

Once your push is complete, you will receive a message similar to below:

Once your check in is completed, return to the AWS Console.

  • From the AWS Console, select AWS Amplify
  • Click on Connect App to create your new Amplify application and connect it to your source control.
  • From the source code selection option, choose AWS Code Commit as the location for your source control. Then click Continue.

  • From the Add repository branch dialog select the repository that you have used for the site. In this case ‘Hugosample’ and select the source control branch. In this case ‘master.’ Click Next.

For App build and test settings you will need to configure options for how your application will be handled by the CI/CD pipeline. Keep all of the default options on this dialog and click Next.

From the review screen, click Save and Deploy to have Amplify save your configuration and automatically deploy the first copy of your webpage.

Because this is a basic Hugo web page, the deployment process will not take long before the web page is available for the first viewing.

Once the deployment has been completed, you can click on the link the Amplify console to launch your web page and view it.

Depending on the theme you have used, and the way that the pages are configured your web site may or may not look the same as when it is being run locally. In order to fix any rendering issues, copy the URL that amplify uses for your web page, we will use that to update your Hugo template in the next stage.

Updating the Hugo configuration

After validating that the Amplify build and deployment has been successful. Copy the URL for the amplify site and use this up update the baseURL parameter in your Hugo config.toml file, and save your changes.

Adding NodeJS to the project

AWS Amplify leverages NodeJS for the automation features. In order to make use of Amplify in the website, we will need to add NodeJS to the deployment files.

From the command line, in the root of your site directory, use the following commands:

mkdir src
touch package.json webpack.config.js src/app.js

Using your text editor, add the following text to your package.json file:

{
  "name": "amplify-js-app",
  "version": "1.0.0",
  "description": "Amplify JavaScript Example",
  "dependencies": {
    "@aws-amplify/api": "latest",
    "@aws-amplify/pubsub": "latest",
    "hugo": "latest"
  },
  "devDependencies": {
    "webpack": "^4.17.1",
    "webpack-cli": "^3.1.0",
    "copy-webpack-plugin": "^4.5.2",
    "webpack-dev-server": "^3.1.5"
  },
  "scripts": {
    "start": "webpack && hugo server",
    "build": "webpack"
  }
}

From the command line run the following command:

npm install

This will download all of the node packages necessary for the application to work correctly.

Update your webpack.config.js file to the following:

const CopyWebpackPlugin = require('copy-webpack-plugin');
const webpack = require('webpack');
const path = require('path');

module.exports = {
    mode: 'development',
    entry: './src/app.js',
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'static/src')
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin()
    ]
};

Update your _index.md file to contain the following:

---
title: ""
date: 2020-01-31T15:55:43-05:00
draft: false
---

<div class="app-body">
    <button id="MutationEventButton">Add data</button>
    <div id="MutationResult"></div>
    <div id="QueryResult"></div>
    <div id="SubscriptionResult"></div>
</div>

<script src="src/main.bundle.js"></script>

You can now start your application locally by using the command

npm start

You should notice that the updated application has a new button called Add data

If you click this button, nothing will happen.

Updating your CI / CD Pipeline:

From the command line, use git to publish your local changes to the site:

git add .
git commit -m “Updating the UI changes.”
git push

Once the changes have been pushed, Amplify will automatically provision a new build environment, download your changes and publish an update to your web page.

Adding Amplify

From the command line in your website directory use the command to set up AWS Amplify in your project.:

amplify init

Accept the default for all options except:

  • Enter a name for the environment: dev
  • Type of application: Javascript
  • Javascript Framework: None

For the AWS Profile, choose Yes, and select either your default profile, or the profile you have created for AWS Amplify. Keep in mind that the profile you choose will need to have all necessary permissions to create and update your back end resources.

Adding AppSync

From the command line, use the command to add an AppSync API to the current project:

amplify add api
  • Choose GraphQL as the type of api.
  • Use the default provider name
  • Choose API key for the authorization type.
  • For the Key Description type ‘test’
  • For the number of days the key is valid, use the default of 7
  • For advanced settings, choose “No, I am done.”
  • For an Annotated GraphQL schema, choose No.
  • For guided schema creation, choose Y
  • Choose the default ‘Single Object’ option for the schema.
  • For do you want to edit the schema now, choose no.

Once completed, use the command to build out your back end for the application:

amplify push
  • As part of the push process, you will be asked if you want amplify to generate code for your GraphQL API. Choose Y for this, and choose the option for the code to be generated in Javascript.
  • Choose the default option for the pattern of GraphQL
  • Choose Y to generate and update all possible GraphQL operations.
  • Choose the default of 2 for the maximum statement depth.

The process of updating the back-end resources will take a few moments to complete.

Updating your website front end.

With the updates to the back end published, the front end of the application can now be updated to take advantage of the newly created services.

Update the app.js file to be the following:

import API, { graphqlOperation } from '@aws-amplify/api'
import PubSub from '@aws-amplify/pubsub';
import { createTodo } from './mutations'
import { listTodos } from './queries'

import awsconfig from './aws-exports';
API.configure(awsconfig);
PubSub.configure(awsconfig);

async function createNewTodo() {
  const todo = { name: "Use AppSync" , description: "Realtime and Offline"}
  return await API.graphql(graphqlOperation(createTodo, { input: todo }))
}

const MutationButton = document.getElementById('MutationEventButton');
const MutationResult = document.getElementById('MutationResult');
const QueryResult = document.getElementById('QueryResult');

MutationButton.addEventListener('click', (evt) => {
  MutationResult.innerHTML = `MUTATION RESULTS:`;
  createNewTodo().then( (evt) => {
    MutationResult.innerHTML += `<p>${evt.data.createTodo.name} - ${evt.data.createTodo.description}</p>`
  })
});

async function getData() {
  QueryResult.innerHTML = `QUERY RESULTS`;
  API.graphql(graphqlOperation(listTodos)).then((evt) => {
    evt.data.listTodos.items.map((todo, i) =>
    QueryResult.innerHTML += `<p>${todo.name} - ${todo.description}</p>`
    );
  })
}

getData();

Once the app.js file has been updated, save all your changes, and then restart your local web server by running:

npm start

With the new website running, you will be able to press the Add data button, and web page will push data into the back end via AppSync. When the web page refreshes, AppSync will automatically query the data in the backend database, and update the web page with the data from the back-end data source.

Updating your .gitignore file

By default, Amplify adds a line into your .gitignore file which causes git to not commit your aws-exports.js file. For this process, we need to remove this line form the file, so that the file is committed to your git repository.

 Deploying your update

Once you have made all the necessary changes, you can commit your changes to git and allow Amplify to build and deploy your web page complete with AppSync integration. Once the changes have been applied, you can view your application hosted in Amplify while connected to the back end.