Understand how to connect front-end and backend to send email

In this article we will create an enquiry form in React and get that enquiry message through email.

We will be using create-react-app to initialize the project.

Create a new project by running

create-react-app contact-us-form

Once project is created, delete all files from src folder and create index.js, style.css and components folders inside the src folder

Also create a server folder along side the src folder

So your folder structure will look like this

Create Header.js and ContactForm.js inside src/components folder and add following contents in Header.js

Add following contents in ContactForm.js

We will be using react-bootstrap and bootstrap for styling our app so install it using

npm install react-bootstrap@1.0.0-beta.16 bootstrap@4.4.1

Add the following contents in src/style.css

Now we will add Header and ContactForm components and bootstrap and style css in src/index.js file

Now, If you run the app by executing npm start, you will see initial view of our app

Now, let’s add the contact form and get it rendered to the screen.

Here, we have added input text fields to get the data and each input field has added onInputChange handler.

Note that, Each input field has name property has to match with the state properties so we are able to use the same event handler for all the input fields and using ES6 dynamic object key syntax update the state value of each input field.

Also note that, we are using useState hook for working with state. If you are new to React Hooks, checkout this article to understand the basics of hooks.

Now, your app will look like this

Let’s now write code for sending email using Nodejs

Install express and axios library using

npm install express@4.17.1 axios@0.19.2

Create index.js inside the server folder and add following code.

Let’s understand what this code is doing.

1. On line 2, we are adding express library and line 3 we are creating the express app to handle the API requests

2. On line 9, we are creating post request handler for /send endpoint so when we make an API call from our React app to /send url, this handler will be executed

3. On line 13, we are starting the express server to listen to our requests on port 3030

4. On line 6, we are setting up json parser to handle the form data which we are sending as a json in post request from the enquiry form,

5. On line 7, we are telling express to serve all the files from the build folder which will be created when we run npm run build command. It will contain all our react code along with the index.html file.

This is important as we will be serving both react and nodejs apps on same port so we will not get CORS (Cross-Origin Resource Sharing) error which comes when application running on one port accesses application running on another port.

Now, add new scripts in package.json file

"start-server": "node server/index.js",
"start-app": "npm run build && npm run start-server"

So your package.json scripts section will look like this

Here in start-app script, we are running npm run build script first and then npm run start-server

So from terminal execute the following command

npm run start-app

This will create build folder with all of our react code and start the express server of server/index.js file so now both react and nodejs app is accessible on same 3030 port.

If you navigate to http://localhost:3030/ , you will see that our application still works.

Now let’s make an API request to the express server to send the enquiry form details to nodejs

Open src/ContactForm.js and import axios at the top

import axios from 'axios';

Declare new state to store the response from the API.

const [result, setResult] = useState(null);

and change sendEmail handler to this

const sendEmail = event => {
event.preventDefault();
axios
.post('/send', { ...state })
.then(response => {
setResult(response.data);
setState({ name: '', email: '', subject: '', message: '' });
})
.catch(() => {
setResult({ success: false, message: 'Something went wrong. Try again later'});
});

Your code will look like this now.

Here, we are making post request using axios and passing the form data as json object by spreading the state object using {...state} which is same as { name: name_value, email: email_value, subject: subject_value, message: message_value } and If the request is successful, we are clearing the entered data and calling the setResult function to set the state using API response. If the request is failed due to some error on server side, we are setting error object in the catch block.

Now, navigate to http://localhost:3030/ and fill up all the data and click submit button. Once you submit the form, you will see that the request goes to the server and you will be able to see the response in network tab.

Now, instead of sending back the request data from /send API, we will actually send the email and return the actual success or error message.

To send email, we will be using nodemailer npm package which is very popular for sending emails in Nodejs

Install it using

npm install nodemailer@6.4.3 --save-dev

We will be using gmail account to send email so login to your email account where you want to get all the enquiry mails and navigate HERE and allow non secure apps to access gmail.

As nodemailer will have access to your gmail account for sending email, don’t use your personal gmail account but create a new gmail account just for sending email.

Now, create a new file config.js inside server folder and add the following content.

Specifying email and password in the code, is not secure, so create a new .env(dotenv) file in the root of your project and create two new environment variables named email and password inside it

Your .dotenv file will look like this

Now to read those environment variables from .dotenv file, we need to use dotenv npm package

Install it using

npm install dotenv@8.2.0 --save-dev

Once installed, open server/config.js and import the dotenv package and call dotenv.config(); to get the environment variables.

Replace ‘abc@test.com’ with process.env.email and ‘password’ with process.env.password

Now, we will write code to send email.

Open server/index.js and import the transporter from config.js file at the top

const transporter = require('./config');

and replace your post request handler with following code.

Also include

const dotenv = require(‘dotenv’);
dotenv.config();

at the top of the file to read the environment variables.

so your final server/index.js code will look like this

Now at last, we will display the success or error message coming from the server on the UI.

Open src/components/ContactForm.js and in the render method display the message before the form tag inside the div

{result && (
<p className={`${result.success ? 'success' : 'error'}`}>
{result.message}
</p>
)}

So your final ContactForm.js file will look like this.

Now, you if you restart the application using npm run start-app and fill in all the details in the form and submit the form, you will see that, you will receive an email at the email address mentioned in .env file and form is cleared and success message is shown on the screen

If there is some error sending email like you entered wrong email or password in the .env file then you will see error on the UI

Complete Source Code: https://github.com/myogeshchavan97/contact-us-form

That’s it for today. Hope you learned something new today.