Velo Tutorial: Sending an Email on Form Submission
6 min read
Visit the Velo by Wix website to onboard and continue learning.
There are many instances when you want to send an email each time a form is submitted. In this article, we demonstrate how to build 2 types of forms that send an email. We start by setting up a form that sends an email to a specific email address each time the form is submitted successfully. Then we modify our code so that an email confirmation is sent to the address of any site visitor who fills out the form.
To send an email when a form is submitted we use the following:
To send an email when a form is submitted we use the following:
- Velo custom form
- SendGrid 3rd party service for sending emails
- Secrets Manager to store the API key and the sender's email
- Two backend functions to call a 3rd party service to send an email
- Event handler that runs when the dataset saves a new item and calls the backend functions
Note
This tutorial uses the Fetch API to connect with the SendGrid 3rd party service. You can also use the SendGrid npm package to connect with SendGrid.
Create a SendGrid Account
Note
You can use any email delivery service you like. The same overall concepts will apply. However, you will have to modify the code to fit your email delivery service's API.
To use the SendGrid service on your Wix site, you'll need to create a SendGrid account. The email address you verify in the account will be the sender address for the emails you send from your Wix site.
Once you've created an account, do the following:
- In the SendGrid site, navigate to the left menu.
- Go to Settings > Sender Authentication and verify your email address.
- Go to Settings > API Keys and generate an API key.
- Copy the key from your dashboard and store it in the Secrets Manager in your Wix site (see the next step).
Important:
Using SendGrid to send emails from certain email providers may not work as expected. For example, see this notification about sending from Gmail addresses.
Store Secrets in the Secrets Manager
For security purposes, it's best to store sensitive content such as API keys in the Secrets Manager.
- In the Velo Sidebar, select the Developer Tools
tab.
- Under the Security section, select Secrets Manager.
- In the top right, click Store Secret.
- Store both your SendGrid API key and the verified email address associated with your SendGrid account in a single secret. The secret should look like this:
- Make sure to name the secret: sendGridSecret.
- Replace <my-sendgrid-api-key> with the value of your API key surrounded by quotation marks.
- Replace <my-verified-sender-email> with your email address surrounded by quotes.
- Your secret value will look something like this:
1{
2 "key": "AB.CdPEfg1HIJk-LMnoPq2R3s.T4uVwxyZAbcd567eF8fghIjKL9mN",
3 "senderEmail": "janedoe@example.com"
4}
5. Click Save.
Later you'll use the Secrets API to extract the secret and use it securely in your code.
Later you'll use the Secrets API to extract the secret and use it securely in your code.
Create a Form
We created an input form consisting of input elements and a submit button. Each input element is connected to a field in a dataset and the button is connected to the same dataset with the Submit action.
In this example, we use a simple form with the following input elements:
In this example, we use a simple form with the following input elements:

Type | ID | Usage |
---|---|---|
Input | nameInput | For entering a name |
Input | emailInput | For entering an email address |
Dropdown | sportDropdown | For entering a preferred sport |
Text Box | commentsInput | For entering comments |
Button | submitButton | For submitting the data |
Dataset | sportDataset | For connecting the elements |
Add Backend Functions
Next, in 2 backend files, we create 2 functions to call our 3rd party email delivery service.
The first function adds the API key, sender address, and receiver address to the raw email data it receives and calls the second backend function.
The first function adds the API key, sender address, and receiver address to the raw email data it receives and calls the second backend function.
1//email.jsw
2
3import {sendWithService} from 'backend/sendGrid';
4import wixSecretsBackend from 'wix-secrets-backend';
5
6export function sendEmail(subject, body) {
7 const sendGridSecret = JSON.parse(await wixSecretsBackend.getSecret('sendGridSecret'));
8 const key = sendGridSecret.key;
9 const sender = sendGridSecret.senderEmail;
10 const recipient = "some-email-address@some-domain.com";
11 return sendWithService(key, sender, recipient, subject, body);
12}
Important:
You need to modify this function to contain the email address you want to send to.
Notice that we import the sendWithService
function from a file named sendGrid
. This is in a second backend file. The sendWithService
function packages up all the data it receives in the format expected by the email delivery service's API and then makes a call to the API.
1//sendGrid.js
2
3import {fetch} from 'wix-fetch';
4
5export function sendWithService(key, sender, recipient, subject, body) {
6 const url = "https://api.sendgrid.com/api/mail.send.json";
7
8 const headers = {
9 "Authorization": "Bearer " + key,
10 "Content-Type": "application/x-www-form-urlencoded"
11 };
12
13 const data = `from=${sender}&to=${recipient}&subject=${subject}&text=${body}`;
14
15 const request = {
16 "method": "post",
17 "headers": headers,
18 "body": data
19 };
20
21 return fetch(url, request)
22 .then(response => response.json());
23}
Reminder:
This example uses SendGrid as its 3rd party email delivery service. If you are using SendGrid, you can copy and paste this module without modifying it. If you are using a different service, you need to write a similar module to meet the format expected by your service's API and import that module from the email.jsw module.
Add an Event Handler
Finally, in the Page Code on the same page as the form, we add an event handler that runs each time a new item is successfully submitted. The event handler takes the values from the form to create the subject and the body of the email. That information is then passed along to the backend functions we wrote above.
1import {sendEmail} from 'backend/email';
2
3$w.onReady(function () {
4 $w("#sportDataset").onAfterSave(sendFormData);
5});
6
7function sendFormData() {
8 const subject = `New Submission from ${$w("#nameInput").value}`;
9 const body = `Name: ${$w("#nameInput").value}
10 \rEmail: ${$w("#emailInput").value}
11 \rSport: ${$w("#sportDropdown").value}
12 \rComments: ${$w("#commentsInput").value}`;
13
14 sendEmail(subject, body)
15 .then(response => console.log(response));
16}
Note:
Our import statement assumes the backend web module was named email.jsw. Modify the import statement to reflect the name of your backend web module.
Modifying the Code
The code we wrote above sends an email to the same address each time the form is submitted. It can easily be used as a basis for other common situations. For example, we will now modify the code so that the site visitor submitting the form receives a confirmation email.
Create a Form
The form does not need to be modified in any way.
Add Backend Functions
We'll add another modified version of the sendEmail
function that does not always call the sendWithService
function with the same address. Instead, we want the new function to get the address of the recipient from the form.
In our new function, we need to add a parameter to the for the recipient's address. Since that address will be passed on to sendWithService
function, we no longer need the line that declared the hardcoded address we were using before.
So, with the new function added, our file now looks like this:
1//email.jsw
2
3import {sendWithService} from 'backend/sendGrid';
4import wixSecretsBackend from 'wix-secrets-backend';
5
6export function sendEmail(subject, body) {
7 const sendGridSecret = JSON.parse(await wixSecretsBackend.getSecret('sendGridSecret'));
8 const key = sendGridSecret.key;
9 const sender = sendGridSecret.senderEmail;
10 const recipient = "some-email-address@some-domain.com";
11 return sendWithService(key, sender, recipient, subject, body);
12}
13
14export function sendEmailWithRecipient(subject, body, recipient) {
15 const sendGridSecret = JSON.parse(await wixSecretsBackend.getSecret('sendGridSecret'));
16 const key = sendGridSecret.key;
17 const sender = sendGridSecret.senderEmail;
18 return sendWithService(key, sender, recipient, subject, body);
19}
Add an Event Handler
We also need to modify the frontend code so that it imports the new function and uses it to send the email, specifying who the recipient is.
1import {sendEmail, sendEmailWithRecipient} from 'backend/email';
2
3$w.onReady(function () {
4 $w("#sportDataset").onAfterSave(sendFormData);
5});
6
7function sendFormData() {
8 const subject = `New Submission from ${$w("#nameInput").value}`;
9 const body = `Name: ${$w("#nameInput").value}
10 \rEmail: ${$w("#emailInput").value}
11 \rSport: ${$w("#sportDropdown").value}
12 \rComments: ${$w("#commentsInput").value}`;
13 const recipient = $w("#emailInput").value;
14
15 sendEmailWithRecipient(subject, body, recipient)
16 .then(response => console.log(response));
17}
API List
The following APIs are used in the code in this article. To learn more, see the API Reference.
$w.Dropdown
- $w.Dropdown.value - Sets or gets a dropdown's value.
$w.TextBox
- $w.TextBox.value - Sets or gets a text box's value.
$w.TextInput
- $w.TextInput.value - Sets or gets a text input's value.
wix-dataset
- wix-dataset.onAfterSave( ) - Adds an event handler that runs just after a dataset save.
wix-fetch
- wix-fetch.fetch( ) - Retrieves a specified resource from the network using HTTP / HTTPS.
wix-secrets-backend
- wix-secrets-backend.getSecret() - Gets sensitive data such as API keys from secure storage.
Did this help?
|