Simple React Contact Form Without Back-End
When I was building my portfolio website with React, one of the most challenging issues I had was creating a working contact form without any back-end code. I wanted to share the solution I came up with to make it easier for anyone else who is trying to do something similar. (NOTE: This article has last been updated as of 11/2023)
Step 1 - Install Dependencies
I used EmailJS and React-Hook-Form to help me build my contact form. EmailJS will send the completed contact form to your email address. React-Hook-Form will assist in handling the form’s functionality.
Install these dependencies to your React project through Node Package Manager.
npm install @emailjs/browser
npm install react-hook-form
Step 2 - Set up Contact Form
I used Bootstrap to help me create my contact form. Here is what the code looks like at this point:
Step 3- Implement React-Hook-Form
This is the main bulk of the code that will get your contact form to work. React-Hook-Form makes it really easy to make your contact form functional. We will be using register, errors, handleSubmit, and reset methods from the useForm function. Register allows you apply validation rules to your form input. Custom errors will be used when form validation has failed. We will eventually implement EmailJS into our onSubmit function.
At this point, your contact form should be functioning properly. Once you click submit you should be able to view the correct values of the submitted form in your console.
Step 4- Set up EmailJS
Setting up EmailJS is a pretty simple and straightforward process.
- Head to https://www.emailjs.com/ and sign up for a free account.
- Click Add New Service and add the email account that you would like to use to send your contact form submissions with.
- Go to Email Templates and create a new template.
- Set your template to look like this:
Record your EmailJS credentials that will be used in your handle submit function. You will need your serviceID, templateID, templateParams, and publicKey.
- Your serviceID is the name of your email account and can be found on the email services tab of the site.
- Your templateID can be found on the email templates tab.
- Template params will be added to your component in the next step using the user’s input, so don’t worry about this right now.
- Your publicKey can be found in the Account tab.
Here is a link to the EmailJS documentation: https://www.emailjs.com/docs/sdk/send/
Step 5- Implement EmailJS
To implement EmailJS I recommend adding your serviceID, templateID, and publicKey to a .env file. From there we will add a try/catch inside of the onSubmit function. First we will set our template params then call EmailJS to send the form submission. Finally we will call our reset function to reset the form.
const onSubmit = async (data) => {
const { name, email, subject, message } = data;
try {
const templateParams = {
name,
email,
subject,
message
};
await emailjs.send(
process.env.REACT_APP_SERVICE_ID,
process.env.REACT_APP_TEMPLATE_ID,
templateParams,
process.env.REACT_APP_PUBLIC_KEY
);
reset();
} catch (e) {
console.log(e);
}
};
Step 6- Set up an alert and handle form submission
I created my own alert using bootstrap to notify a user when the contact form has successfully been submitted. I also disable the submit button when the form has been submitted so that users cant accidentily submit the form twice or cause other issues. This really improves the user experience of your site and is pretty simple to set up. Here is the necessary code to add:
import { useState } from 'react';
const [disabled, setDisabled] = useState(false);
const [alertInfo, setAlertInfo] = useState({
display: false,
message: '',
type: '',
});
// Shows alert message for form submission feedback
const toggleAlert = (message, type) => {
setAlertInfo({ display: true, message, type });
// Hide alert after 5 seconds
setTimeout(() => {
setAlertInfo({ display: false, message: '', type: '' });
}, 5000);
};
// Function called on submit that uses emailjs to send email of valid contact form
const onSubmit = async (data) => {
// Destrcture data object
const { name, email, subject, message } = data;
try {
// Disable form while processing submission
setDisabled(true);
// Define template params
const templateParams = {
name,
email,
subject,
message,
};
// Use emailjs to email contact form data
await emailjs.send(
process.env.REACT_APP_SERVICE_ID,
process.env.REACT_APP_TEMPLATE_ID,
templateParams,
process.env.REACT_APP_PUBLIC_KEY
);
// Display success alert
toggleAlert('Form submission was successful!', 'success');
} catch (e) {
console.error(e);
// Display error alert
toggleAlert('Uh oh. Something went wrong.', 'danger');
} finally {
// Re-enable form submission
setDisabled(false);
// Reset contact form fields after submission
reset();
}
};
{alertInfo.display && (
<div
className={`alert alert-${alertInfo.type} alert-dismissible mt-5`}
role='alert'
>
{alertInfo.message}
<button
type='button'
className='btn-close'
data-bs-dismiss='alert'
aria-label='Close'
onClick={() =>
setAlertInfo({ display: false, message: '', type: '' })
} // Clear the alert when close button is clicked
></button>
</div>
)}
Final Product
Now that you have a functioning contact form without any back-end code, add some CSS to style your form and make it look good. Here is what my final contact form looks like:
You can test my live contact form here: https://react-contact-form-01.netlify.app/
And view the code here: https://gist.github.com/ksentak/d39b1cccae95bbce50806e62af79793d