In this tutorial, we will guide you step by step through the process of creating a contact form using AWS SES
(Simple Email Service), AWS Amplify
, NodeJS Lambda
, DynamoDB
, UI components generated by Amplify Studio
, and deploying it to a Next.js
app hosted on GitHub with fully automated deployment. See video here.
Prerequisites
Before we begin, make sure you have the following prerequisites:
- An
AWS account
with appropriate permissions to create resources -
AWS CLI
andAmplify CLI
installed and configured on your development machine - Basic knowledge of
AWS services
,Next.js
, andGitHub
Step 1: Set up AWS SES
1. Login to the AWS Management Console and navigate to the AWS SES
service.
2. Follow the instructions to verify your domain and set up email sending and receiving permissions.
3. Once your domain is verified, note down the ARN (Amazon Resource Name) of the verified domain.
Step 2: Host Next.js project with AWS Amplify
1. Create a Next.js project by running the following command:
$ npx create-next-app@latest
2. Create a GitHub repository for your project, commit and push changes to remote.
3. Initialize an Amplify project with the following command:
$ amplify init
4. Add hosting with Amplify CLI and select Continuous deployment (Git-based deployments)
when prompted:
$ amplify add hosting
Note: There is a more detailed blog explaining this step here
Step 3: Create Data Model using AWS Amplify Studio
1. Launch Amplify Studio by going to the AWS console and selecting backend environments
under the Amplify service, then selecting the Amplify App we set up in the previous step.
2. Once in Amplify Studio, select Data Modeling. Click on Add model
and enter ContactForm
as the table name. Select the following field names:
- Field name: id, Type: ID!
- Field name: Name, Type: String
- Field name: Email, Type: AWSEmail
- Field name: Subject, Type: String
- Field name: Message, Type: String
3. Finally, click on
save and deploy
.
Step 4: Create a Lambda Node.js Trigger
1. In the Amplify Studio UI, select Local setup instructions
on the top right corner and copy the pull command instruction.
2. Open a command line under the root of your Next.js project and copy and paste the pull command.
3. After the pull command has been completed, run the amplify add function
command. When prompted, select the following options:
- Capability:
Lambda function (serverless function)
- Lambda function name:
SendContactInfo
- Runtime:
NodeJS
- Function template:
Lambda trigger
- Event source to associate:
Amazon DynamoDB Stream
- DynamoDB event source:
Use API category graphql @model backed DynamoDB table(s)
- Advanced setting:
Environment variables configuration
(Add VERIFIED_EMAIL environment key and value)
4. After adding the function with the Amplify CLI, you can edit the NodeJS lambda source file
.
const AWS = require('aws-sdk')
const ses = new AWS.SES
const verified_email = process.env.VERIFIED_EMAIL
exports.handler = async (event) => {
for (const record of event.Records) {
if (record.eventName === 'INSERT'){
const contactName = record.dynamodb.NewImage.Name.S
const contactEmail = record.dynamodb.NewImage.Email.S
const contactMessage = record.dynamodb.NewImage.Message.S
const contactSubject = record.dynamodb.NewImage.Subject.S
const bodyData = '<br/><b>Contact Name</b>: ' + contactName +
'<br/><b>Contact Email</b>: ' + contactEmail +
'<br/><b>Message</b>: ' + contactMessage
await ses.sendEmail({
Destination: {
ToAddresses: [verified_email],
},
Source: verified_email,
Message: {
Subject: { Data: contactSubject },
Body: {
Html: {
Charset: "UTF-8",
Data: bodyData
},
},
},
}).promise()
}
return { status: 'email sent'}
}
return Promise.resolve('Successfully processed DynamoDB record');
};
5. Make sure to add the environment variable verified_email
. You can do this by running amplify update function
and selecting Environment variable configuration
under Available Advance settings
. Alternatively, you can hardcode the value in the following code line:
const verified_email = process.env.VERIFIED_EMAIL
6. Change the cloudformation template
for the lambda to have the permission to use the AWS SES service to be able to send emails.
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"ses:SendEmail"
],
"Effect": "Allow",
"Resource": {
"Fn::Sub": [
"arn:aws:ses:${region}:${account}:identity/albac.dev",
{
"region": {
"Ref": "AWS::Region"
},
"account": {
"Ref": "AWS::AccountId"
}
}
]
}
},
7. To save changes on the cloud, run amplify push
.
Step 5: Using generated UI Contact by Amplify Studio
1. The command amplify pull
executed in Step 4
has synced the UI components from Amplify Studio and saved them locally. You can run this command again if necessary.
2. Let's start by creating a client component that will wrap the Theme provider from Amplify Studio.
'use client';
import React, { ReactNode } from 'react';
import { Amplify } from 'aws-amplify';
import awsconfig from '@/src/aws-exports';
import { ThemeProvider, defaultDarkModeOverride } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
Amplify.configure(awsconfig);
export default function AmplifyUITheme(props: {children: ReactNode}){
const theme = {
name: 'my-theme',
overrides: [defaultDarkModeOverride],
};
return (
<ThemeProvider theme={theme} colorMode="system" >
{props.children}
</ThemeProvider>
)
}
3. Then create another [client component](https://github.com/albac/amplify-contactform/blob/main/app/custom
contact.tsx) that will call the ContactFormCreateForm
generated by Amplify and wrap it with the AmplifyUITheme
component.
...
import ContactFormCreateForm from '@/src/ui-components/ContactFormCreateForm';
import AmplifyUITheme from './amplifyuitheme';
...
<AmplifyUITheme>
<ContactFormCreateForm
onSuccess={() => setShowModal(false)}
backgroundColor="neutral.40"
borderRadius="6px"
width="40rem"
/>
</AmplifyUITheme>
4. Optionally, you can also add a Modal component and use useState
and useEffect
to trigger the modal.
...
const [showModal, setShowModal] = useState(false)
useEffect(() => {
const onKeyPress = (e: KeyboardEvent) => {
if (e.key === "Escape") setShowModal(false);
};
window.addEventListener("keydown", onKeyPress);
return () => window.removeEventListener("keydown", onKeyPress);
},[setShowModal])
return(
<>
<button onClick={() => setShowModal(true)} >
Contact me
</button>
{showModal ? (
<Modal>
...
Note: For this, we have used one of the best, but at the same time easy to use, modal components by another author. You can check his blog here.
Congratulations! You have successfully created a contact form using AWS SES, AWS Amplify Studio, and AWS Amplify, and deployed it to a Next.js app hosted on GitHub with fully automated deployment.
The final result will look something like this:
Conclusion
In this tutorial, we walked through the process of creating a contact form using AWS SES
, AWS Amplify Studio
, and NodeJS Lambda
. We started by setting up AWS SES and hosting a Next.js project with AWS Amplify. Then, we created a data model using AWS Amplify Studio and set up a Lambda Node.js trigger to handle the form submissions and send emails using AWS SES.
We also utilized the UI components
generated by Amplify Studio
to create a user-friendly contact form interface. Finally, we deployed the Next.js app
to GitHub
with automated deployment.
Feel free to customize and enhance the contact form and the overall application according to your specific requirements. Happy coding!
Happy coding!
References
- Video: https://www.tiktok.com/@albac.dev/video/7254586286583909678?_r=1&_t=8dxw7Ytz88M
- GitHub Code: https://github.com/albac/amplify-contactform/
- Amplify UI Theme Provider: https://ui.docs.amplify.aws/react/theming/theme-provider
- Modal Blog Component: https://codewitholgun.com/how-to-create-a-modal-with-reactjs-and-style-it-with-tailwindcss
Top comments (0)