Build a Contact form with Nextjs and Slack webhooks

Roger Stringer • May 04, 2021

2 min read

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.

Tagged in: #Code
Like this blog post? Share it on twitter!

Subscribe to the newsletter

Subscribe to the newsletter to stay up to date with web development, tech, articles, writing and much more!

No spam!! I will send you at most one mail per month if that.