Add Contact Form in Hugo Site

Create a lambda function to send the contact message

  • Setup SES and verify sender email address
  • Create an IAM role for lambda with policy details below
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ses:SendEmail",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}
  • Create the lambda function
const aws = require("aws-sdk");
const ses = new aws.SES({ region: "ap-southeast-2" });
exports.handler = async function (event) {
  console.log('EVENT: ', event)
	// Extract the properties from the event body
	try {
     const { senderEmail, senderName, message } = JSON.parse(event.body)

    const params = {
      Destination: {
        ToAddresses: ["[email protected]"],
      },
  		// Interpolate the data in the strings to send
      Message: {
        Body: {
          Text: { 
              Data: `You just got a message from ${senderName} - ${senderEmail}:
              ${message}` 
          },
        },
        Subject: { Data: `Message from ${senderName}` },
      },
      Source: "[email protected]",
    };
  
    return ses.sendEmail(params).promise();
	}
	catch (err) {
	  console.log("error on parse message body: " + err.message)
	  context.fail("error: "+ err.message)
	}
};
  • Setup API Gateway and configure it as trigger for the lambda function

  • Update the API endpoint in the html code

Create a shortcode with Html contact form

  • Create layouts/shortcodes/form-contact.html with content below
<form id="contact-form">
    <div class="form-group row">
        <label for="name" class="col-4 col-form-label">Name</label>
        <div class="col-8">
            <div class="input-group">
                <div class="input-group-addon">
                    <i class="fa fa-user"></i>
                </div>
                <input id="name" name="name" placeholder="Please enter your name" type="text" required="required"
                    class="form-control">
            </div>
        </div>
    </div>
    <div class="form-group row">
        <label for="email" class="col-4 col-form-label">E-mail address</label>
        <div class="col-8">
            <div class="input-group">
                <div class="input-group-addon">
                    <i class="fa fa-envelope"></i>
                </div>
                <input id="email" name="email" placeholder="Your e-mail address" type="text" required="required"
                    class="form-control">
            </div>
        </div>
    </div>
    <div class="form-group row">
        <label for="message" class="col-4 col-form-label">Message</label>
        <div class="col-8">
            <textarea id="message" name="message" cols="40" rows="10" required="required"
                class="form-control"></textarea>
        </div>
    </div>
    <div class="form-group row">
        <div class="offset-4 col-8">
            <button name="submit" type="submit" class="btn btn-primary">Send</button>
        </div>
        <div>
            <p id="result-text"></p>
        </div>
    </div>
</form>
<script>
    const form = document.querySelector("form");
    form.addEventListener("submit", (event) => {
        // prevent the form submit from refreshing the page
        event.preventDefault();

        const { name, email, message } = event.target;

        // Use your API endpoint URL you copied from the previous step
        const endpoint = "https://api.example.com/sendContactEmail";
        // We use JSON.stringify here so the data can be sent as a string via HTTP
        const body = JSON.stringify({
            senderName: name.value,
            senderEmail: email.value,
            message: message.value
        });
        const requestOptions = {
            method: "POST",
            body
        };

        fetch(endpoint, requestOptions)
            .then((response) => {
                if (!response.ok) throw new Error("Error in fetch");
                return response.json();
            })
            .then((response) => {
                document.getElementById("result-text").innerText =
                    "Email sent successfully!";
            })
            .catch((error) => {
                document.getElementById("result-text").innerText =
                    "An unkown error occured.";
            });
    });

</script>

Use the contact form shortcode

  • create a Contact.md file under content folder with details below
You can contact me here!

{{< form-contact >}}
  • Test out the form with some details, and an email with the filled message should be sent to the configured email

Reference