Building a JAMstack site with Hugo and Azure Functions
Modern web development architecture:
Static site generators + JavaScript + Serverless = JAMstack
This blog post covers:
Hugo + jQuery + Azure Functions = JAMstack
This blog post is part of a series:
- Building a JAMstack site with Hugo and Azure Functions (this post)
- Managing content for a JAMstack site with Netlify CMS

The example used in this blog post is a site for jam recipes.
Example code:
Example site:
JAMstack
Modern web development architecture based on client-side JavaScript, reusable APIs, and prebuilt Markup.
Read all about it over at: https://jamstack.org
Three things are needed:
- JavaScript
- APIs
- Markup
In this blog post the JavaScript is written with jQuery, the APIs implemented with Azure Functions and the markup generated with Hugo.
Why?
- Better Performance
- Higher Security
- Cheaper, Easier Scaling
- Better Developer Experience
Static site generators is The Next Big Thing and it is used At Scale.
Hugo
A fast and modern static website engine
Hugo is a static site generator.
It’s the second most popular according to https://www.staticgen.com
Why Hugo?
- Extremely fast build times
- Runs on Windows and is easy to install
Scaffold a Hugo site:
hugo new site .

Add content:
hugo new recipe/apple-jam.md

Code
The code for the site:
Configuration for the Hugo site is done in config.toml:
- Uses the TOML format, located in the root folder
- The
baseURLpoints to where the site is hosted on GitHub Pages
Data:
- Uses the TOML format, located in the
datafolder - This example is for the API URLs invoked by the JavaScript
The HTML template for the header:
- HTML file located in the
layouts\partialsfolder - This example uses Bootstrap template with the Narrow jumbotron
- Custom CSS in
app.css, Bootstrap stylesheets from CDN - The
bodytag gets anidwith the current page template, will be used in the JavaScript - The navigation is populated by pages configured with
navigation = truein the front matter
The HTML template for the header:
- HTML file located in the
layouts\partialsfolder - Custom JS in
app.js, third-party scripts from CDN
Content:
- Uses the Markdown format with Front Matter
- This example is for the Apple Jam page
- The image and ingredients are stored as variables, available in templates via the Param method
Page Templates:
- HTML file located in a
layoutssubfolder - Reference the header and footer partials
- This example is for the recipe pages
- Data for the JavaScript is stored as attributes in a dedicated element
- The image and ingredients are accessed via the Param method
- The page markdown content is accessed with the
.Contentvariable
JavaScript:
- Located in the
staticfolder - This example uses jQuery
- The recipe page will
GETingredients from a Azure Function - The submit page will
POSTrecipes to a Azure Function
Hugo has a theming system, so you don’t have to implement all templates yourself.
Hugo Themes:
Run and Build
Hugo provides its own webserver which builds and serves the site:
hugo server

- In this example you can then browse
http://localhost:1313/jamstack/
Build the Hugo site:
hugo --destination ../../docs

- In this example the site is hosted by GitHub Pages from the
docsfolder in the git repo.
Troubleshoot the site generation with:
hugo --verbose
GitHub Pages
Get the site hosted on GitHub Pages by:
- Pushing the code to GitHub
- Configuring a publishing source for GitHub Pages
In this example the docs folder is used as publishing source:

Azure Functions
Azure Functions Core Tools is a command line tool for Azure Functions
The Azure Functions Core Tools provide a local development experience for creating, developing, testing, running, and debugging Azure Functions.
Create a function app:
func init

Create a function:
func function create

If you don’t like the terminal, take a look at Visual Studio 2017 Tools for Azure Functions
Code
The code for the API:
Configuration for a function is done in function.json:
- The
authLevelcan be set toanonymousin this example - The
routeandmethodsare important to know when invoking the function from the JavaScript
The actual function is implemented in run.csx:
- Uses the scriptcs format
- This example will return hard coded ingredients for the given recipe
Run
Run the functions locally:
func host start
When running the Hugo site against local functions, specify CORS origins:
func host start --cors http://localhost:1313

Deployment
Get the functions hosted on Azure by:
- Pushing the code to GitHub, Bitbucket or Visual Studio Team Services
- Log in to the Azure portal
- Create a function app
- Set up continuous deployment
In this example the Azure Functions code is located in the \src\api\ folder in the git repo.
Therefor deploying with custom script is needed:
.deployment:
- Run
deploy.cmdduring deployment
deploy.cmd:
- Copy files from the
\src\apifolder to the repository root
During deployment the logs look like this:

Configuration
Before the Hugo site and the JavaScript can invoke the Azure Functions, Cross-Origin Resource Sharing (CORS) needs to be configured.
In this example these origins are allowed:
https://hlaueriksson.github.iohttp://localhost:1313

Now the Hugo site can be configured to use these URLs:
https://jamstack.azurewebsites.net/api/Ingredients/{recipe}https://jamstack.azurewebsites.net/api/Recipe
Conclusion
- JAMstack is the modern web development architecture
- Static site generators is a big thing right now
- Hugo is fast and awesome
- jQuery is still useful
- Serverless is the next big thing
- Azure Functions is awesome