Written by: Geoffrey Callaghan

Creating a JAMstack-friendly Contact Page

Creating A Jamstack-Friendly Contact Page

Creating a JAMstack-friendly contact page involves building a static page with a form, handling form submissions using client-side JavaScript, and processing the submissions with serverless functions or an API. Here’s a step-by-step guide to create such a page using Hugo, Netlify Functions, and JavaScript.

Step 1: Set Up Your Hugo Site

If you haven’t already, create a Hugo site:

hugo new site my-jamstack-site
cd my-jamstack-site

Step 2: Install a Theme

Install a Hugo theme. For this example, we’ll use the Ananke theme:

git init
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke
echo 'theme = "ananke"' >> config.toml

Step 3: Create the Contact Page

Create a new contact page:

hugo new contact.md

Edit the content/contact.md file to add a form:

title: "Contact"
draft: false

# Contact Us

<form id="contact-form">
  <label for="name">Name:</label>
  <input type="text" id="name" name="name" required>
  <label for="email">Email:</label>
  <input type="email" id="email" name="email" required>
  <label for="message">Message:</label>
  <textarea id="message" name="message" required></textarea>
  <button type="submit">Submit</button>

<div id="form-response"></div>

document.getElementById('contact-form').addEventListener('submit', async (event) => {
  const formData = new FormData(event.target);
  const responseElement = document.getElementById('form-response');
  responseElement.textContent = 'Submitting...';

  try {
    const response = await fetch('/.netlify/functions/submit-form', {
      method: 'POST',
      body: JSON.stringify(Object.fromEntries(formData)),
      headers: { 'Content-Type': 'application/json' },

    if (response.ok) {
      responseElement.textContent = 'Form submitted successfully!';
    } else {
      responseElement.textContent = 'Form submission failed. Please try again.';
  } catch (error) {
    responseElement.textContent = 'An error occurred. Please try again.';

Step 4: Add Serverless Function

Create a directory for Netlify functions in the root of your Hugo site:

mkdir -p netlify/functions

Create a function to handle form submissions in netlify/functions/submit-form.js:

// netlify/functions/submit-form.js
exports.handler = async (event, context) => {
  const data = JSON.parse(event.body);

  // Process form data (e.g., send email, save to database)
  // This example simply logs the data and returns a success response
  console.log('Form data received:', data);

  return {
    statusCode: 200,
    body: JSON.stringify({ message: 'Form submitted successfully!' }),

Step 5: Configure Netlify

  1. Deploy the Site: Deploy your site to Netlify. If you haven’t already done so, you can link your repository to Netlify and set up continuous deployment.

  2. Netlify Functions: Ensure that Netlify Functions are enabled for your site. Netlify will automatically detect the netlify/functions directory and deploy the functions.

Step 6: Test the Contact Form

Run the Hugo server locally to test your contact form:

hugo server

Open your browser and navigate to http://localhost:1313/contact/ to test the form submission. When deployed to Netlify, the form data will be handled by the serverless function.


  1. Create the Contact Page: Use Hugo to create a new page with a contact form.
  2. Client-Side Form Handling: Use JavaScript to handle form submissions and send data to the serverless function.
  3. Serverless Function: Implement a serverless function (e.g., with Netlify Functions) to process form data.
  4. Deploy: Deploy your site to a platform like Netlify to handle the form submissions and serverless functions.

By following these steps, you can create a JAMstack-friendly contact page that leverages the benefits of static site generation and serverless architecture for efficient and scalable form handling.