How to create a Newsletter feedback form using React and Supabase
Gbadebo ifedayo
Posted on March 1, 2023
Businesses are looking for new ways to connect with their customers as more and more customers prefer online communication channels. Allowing clients to provide their information and receive regular updates and promotional offers via email is an excellent solution. This does not only enables companies to stay in touch with their clients, but additionally enables businesses to precisely target their marketing campaigns and customize their messaging. This article will offer a step-by-step tutorial on how to create an app that allows users to sign up to receive feedback.
Pre-requisites for this project
Latest version of Node.js installed
Knowledge of React and React hooks
A Supabase account, you can create one here
You can find the repo for this project on Github, a live demo of the app is hosted on vercel.
Setting up the project
First, create a new react app by running the following in the terminal:
npx create-react-app react-feedback-form
After that, run the following to install React Router in the project:
npm install react-router-dom@5.3.3
Next, integrate the Supabase client library into your project using the following:
npm install @supabase/supabase-js
Running npm start
will launch the project on the local development server at http://localhost:3000/ in our browser.
Setting up our database in Supabase
What is Supabase?
Supabase is a cloud-based platform that provides a real-time database and API for online and mobile apps. It allows for simple database setup, administration, and scaling while providing a user-friendly interface for data management and visualization. Supabase also provides features such as authentication, authorization, and secure access control to keep data safe and secure.
To get started, create an account in Supabase here.
Next, navigate to the All projects tab where you should see this page and click the New project button the project as shown below.
Note that the project is named react-feedback-form, feel free to name it any name that deems fit.
Navigate to the table editor tab, where you will construct a table to store the database information.
The table used for this project will contain 5 columns:
An
id
which is included in every table by default and assigns an unique key for our data in a chronological ordername
,email
,company
,role
columns which accepts a text input and has a null default value
After setting your parameters, go ahead and save the table and it is ready to go.
When you click on the newly created table in the table editor tab, the following should appear:
Constructing our components
After setting up the database, navigate to the src
directory of your React app and create a components
folder to store all the app's components.
Interacting with the Database
You can locate the Project URL and Project API key, which are needed to operate your database, on the API tab in Settings. Don’t share your Supabase Key or Supabase URL as they’re sensitive credentials., so we create a .env
file in your project's root directory to store our it here in a REACT_APP_SUPABASE_ANON_KEY
variable.
Next, in supabaseclient.js
we input the following:
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = 'https://dbyqqbijztrdgdzysseg.supabase.co' //project URL
const supabaseKey = process.env.REACT_APP_SUPABASE_ANON_KEY //API key stored in the .env file
export const supabase = createClient(supabaseUrl, supabaseKey) //interact with the database using the URL and API key
Next up, create the Form
component which collects the information to be stored in the database.
import React,{useState} from 'react'
import {useHistory} from 'react-router-dom'
import { supabase } from './supabaseclient'
import logo from '../images/logo.png'
function Form(){
const [name,setName]=useState('')
const [email,setEmail]=useState('')
const [company,setCompany]=useState('')
const [role,setRole]=useState('')
const history=useHistory() //assign history function to a variable
async function handleSubmit(e){ //function to be carried out when form is submitted
e.preventDefault()
await supabase.from('feedback form').insert([ //insert values into database
{name: {name},
email:{email},
company:{company},
role:{role}}
]).then((res)=>{ //function to be carried out if action is successful
console.log('success');
console.log(res)
history.push('/success')} //changes page url to render success component
,function(err){
console.log(err)
console.log('error')
history.push('/failure') //changes page url to render failure component
})
}
return(
<div className='form'>
<img src={logo}/>
<h1>Sign up for Feedback</h1>
<form onSubmit={handleSubmit}>
<input type='text' name='name' placeholder='Full Name' onChange={(e)=>{setName(e.target.value)}}/>
<input type='email' name='email' placeholder='Email' onChange={(e)=>{setEmail(e.target.value)}}/>
<input type='text' name='company' placeholder='Company' onChange={(e)=>{setCompany(e.target.value)}}/>
<input type='text' name='role' placeholder='Role' onChange={(e)=>{setRole(e.target.value)}}/>
<input type='submit' value='Submit' className='submit'/>
</form>
</div>
)
}
export default Form
React, useState
, and useHistory
are imported first in the code above. useHistory
is used in this project to render the Success and Failure component by manipulating the browser URL; the supabase component is then imported after that and useState
is used to store the values inputed in the form.
Four text areas on the form are used to collect the following information -- Name, Email, Company, and Role. Submitting the form invokes the handleSubmit
function, awaits the values entered in the form to be uploaded to the database, and then display the subsequent page based on whether the information was successful or not through the use of an async
function.
Styling the app
After successfully creating the Form
component which is the major part of the app, style the app in App.css
.form{
width: 40%;
background-color: rgb(205, 174, 143);
margin: auto;
padding: 20px;
box-sizing: border-box;
border-radius: 25px;
box-shadow: 0px 0px 15px grey;
}
.form img{
width: 30%;
margin: auto;
display: block;
}
.form h1{
text-align: center;
margin-bottom: 30px;
color: rgb(54, 46, 46);
}
.form form input{
width: 80%;
display: block;
height: 40px;
border-radius: 20px;
box-sizing: border-box;
padding: 10px;
border: none;
outline: none;
box-shadow: 0px 0px 5px grey;
margin: auto;
margin-bottom: 15px;
}
.form .submit{
width: unset;
font-size: 18px;
height: unset;
padding: 15px 50px;
cursor: pointer;
background-color: rgb(220, 192, 81);
border-radius: 25px;
transition: background-color,color 0.3s ;
color: black;
font-weight: 700;
}
.form .submit:hover {
background-color: rgb(218, 142, 66);
color: white;
}
Defining the Success and Failure component
Input the following code into the success component:
import React from "react";
import {Link} from "react-router-dom" //import Link element which is used to navigate the app
function Success(){
return(
<div className="success">
<h2>SUCCESSFUL!</h2>
<p>Congratulations, you have sucessfully signed up. Have a nice day!</p>
<Link to='/' className="link">Go Back</Link> //React Router Link to return to home page
</div>
)
}
export default Success
Next up, style the success component
The following is the code for the failure component:
import React from "react";
import {Link} from "react-router-dom"
function Failure(){
return(
<div className="failure">
<h2>FAILED!</h2>
<p>Sorry, there was a problem while trying to sign up.</p>
<Link to='/' className="link">Retry</Link> //React Router Link to return to home page
</div>
)
}
export default Failure
Thus far, you have successfully developed an operational form as well as success and failure components that will be shown in response to the outcomes of the query to the database. To navigate the pages of the Feedback Form app, the React Router is u.
import React from 'react';
import './App.css';
import {BrowserRouter as Router,Route} from 'react-router-dom'
import Form from './components/form';
import Success from './components/sucess';
import Failure from './components/failure';
function App() {
return (
<div>
<Router>
<Route exact path='/'><Form/></Route>
<Route path='/success'><Success/></Route>
<Route path='/failure'><Failure/></Route>
</Router>
</div>
)
}
export default App;
In the code above, first Router
is imported which serves as a parent element for all other elements. A Route
changes the page to a component when it's path matches that of the page's URL.
Here's is what a live version of the app looks like:
Conclusion
In conclusion, creating an app that allows customers to sign up for emails is a powerful tool for businesses looking to improve their customer engagement and retention rates. This article demonstrates how to make use of Supabase and React Hooks to accomplish this goal.
Posted on March 1, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.