Build a Contact form with Nextjs and Slack webhooks

Roger Stringer

Roger Stringer / May 04, 2021

2 min read––– views

For this form, I used react-hook-form which is a handy form library for building and validating forms. For the actual sending to Slack, I used axios.

yarn add react-hook-form axios

Then, create a file called pages/contact.js:

contact.js
import React from 'react';
import axios from 'axios';
import { useForm } from "react-hook-form";

export default function Contact() {
  const { register, handleSubmit, reset, formState: { errors } } = useForm();

  const onSubmit = async (data) => {
    const { name, email, message } = data;
    const webhookUrl = process.env.NEXT_PUBLIC_SLACK_WEBHOOK;
    const payload = {
      "text": `Name: ${name} \n${email} \n${message}`,
    }
    const res = await axios.post(webhookUrl, JSON.stringify(payload), {
        withCredentials: false,
        transformRequest: [(data, headers) => {
            delete headers.post["Content-Type"]
            return data
        }]
    })
    if (res.status === 200) {
        alert("Message sent")
        reset();
    } else {
        alert("There was an error.  Please try again later.")
    }
  }

  const resetForm = async (e) => {
    reset();
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
        <input
            aria-label="Your Name"
            type="text"
            id="name"
            name="name"
            required={true}
            {...register('name', { required: true})}
            placeholder="Your Name"
        />
        {errors.name && errors.name.type === "required" && <span>This is required</span>}
        <input
            aria-label="Your Email"
            type="email"
            id="email"
            name="email"
            required={true}
            {...register('email', { required: true})}
            placeholder="Your Email"
        />
        {errors.email && errors.email.type === "required" && <span>This is required</span>}
        <textarea
            aria-label="What did you want to talk about?"
            type="text"
            id="message"
            name="message"
            required={true}
            {...register('message', { required: true})}
            placeholder="What did you want to talk about?"
        />
        {errors.message && errors.message.type === "required" && <span>This is required</span>}
        <button type="submit">Send</button>
    </form>
  );
}

This example is pretty basic, you can add your own styling and other fields of course, but it works well, I let react-hook-forms do the validating and then I let it send via the axios post.

I store the webhook as an env variable called NEXT_PUBLIC_SLACK_WEBHOOK.

Posted in: #code