Store landing-page leads without a backend server in Next.js
Tags: javascript, nextjs, tutorial, programming
Published: 2022-05-24 12:10:51

Lead generation landing pages help facilitate the user acquisition process and are usually created to collect a user’s personal information. With this information, a brand can decide to send resources or figure out their prospective customer’s demographic. Lead generation landing pages establish the initial contact point between our brand and a prospective customer.

## What we will be building

This post will discuss creating a landing page to collect and store a user’s contact information in a Next.js application. This application does not require a custom backend server.

**GitHub URL** 


https://github.com/Iheanacho-ai/appwrite-email-leads



## Prerequisites

To get the most out of this project, we require the following:

- A basic understanding of CSS, JavaScript, and React.js
- Docker Desktop is installed on the computer, run the `docker -v` command to verify if we have docker desktop installed, if not, install it from [here](https://www.docker.com/products/docker-desktop/) 
- An Appwrite instance running on our computer, check out the [this article](https://dev.to/hackmamba/create-a-local-appwrite-instance-in-3-steps-19n9?utm_source=hackmamba&utm_medium=hackmamba) to create a local Appwrite instance, we will use Appwrite’s powerful database service to handle storing email leads


## Setting up our Next.js app

[Next.js](https://nextjs.org/) is an open-source React framework that enables us to build server-side rendered static web applications.

To create our Next.js app, we navigate to our preferred directory and run the terminal command below: 

```bash
    npx create-next-app@latest
    # or
    yarn create next-app
```

After creating our app, we change the directory to the project and start a development server with:

```bash
    cd <name of our project>
    npm run dev
```

To see our app, we go to [http://localhost:3000](http://localhost:3000).


## Installing Appwrite

[Appwrite](https://appwrite.io/) is an open-source, end-to-end, back-end server solution that allows developers to build applications faster.

To use Appwrite in our Next.js application, we install the Appwrite client-side SDK for web applications.

```bash
    npm install appwrite
```
## Creating a new Appwrite project

During the creation of the Appwrite instance, we specified what hostname and port we see our console. The default value is [localhost:80](http://localhost/).

We go to [localhost:80](http://localhost/) and create a new account to see our console.

On our console, there is a **Create Project** button. Click on it to start a new project.

![Image upload](https://paper-attachments.dropbox.com/s_314B50E78D2533608F0DEE9BE97FEF3C5B7916B2F8CAC55559F4DCA3A07D86F6_1648400276700_Screenshot+64.png)

## 

Our project dashboard appears once we have created the project. At the top of the page, there is a **Settings** bar. Click the **Settings bar** to access the **Project ID** and **API Endpoint**.  


![Image upload](https://paper-attachments.dropbox.com/s_E9FCC16A09539977BBE06A1D26EB3F3E791D81AE781A5D221825A67EB9810FDF_1650006781387_Screenshot+101-2.png)


We copy the **Project ID** and **API Endpoint**, which we need to initialize the Appwrite Web SDK.


![Image upload](https://paper-attachments.dropbox.com/s_E9FCC16A09539977BBE06A1D26EB3F3E791D81AE781A5D221825A67EB9810FDF_1650009259617_Screenshot+102.png)


In our `index.js` file, we initialize a new Appwrite instance with the following.

```jsx
    import {Appwrite} from "appwrite";
    import {useEffect, useState } from "react";
    
    const Home = () => {
    
        // Init our Web SDK
        const sdk = new Appwrite();
        sdk
        .setEndpoint('http://localhost/v1') // our API Endpoint
        .setProject(projectID) // our project ID
        ;
    
        return(
          <div>Hello World!</div>
        )
    }
    
    export default Home;
```
## Creating the collection and attributes

In the Appwrite web [Console](http://localhost/console), we click on Database on the left side of the dashboard.

![Image upload](https://paper-attachments.dropbox.com/s_E9FCC16A09539977BBE06A1D26EB3F3E791D81AE781A5D221825A67EB9810FDF_1650006598971_Screenshot+104.png)


We create a collection in the database tab by clicking on the **Add Collection** button. This action redirects us to a **Permissions** page.

At the **Collection Level,** we want to assign a **Read Access** and **Write Access** with a **role:all** value. We can modify these permissions later to control who has access to read or write to our database.

![Image upload](https://paper-attachments.dropbox.com/s_E9FCC16A09539977BBE06A1D26EB3F3E791D81AE781A5D221825A67EB9810FDF_1650006579537_Screenshot+105.png)


On the right of the **Permissions** page, we copy the **Collection ID**, which we need to perform operations on the collection’s documents.

Next, we go to the **Attributes** tab to create the properties we want a document to have. 

![Image Upload](https://paper-attachments.dropbox.com/s_E9FCC16A09539977BBE06A1D26EB3F3E791D81AE781A5D221825A67EB9810FDF_1650009301207_Screenshot+106.png)


We create an **email** attribute of **emailAddress.**


![Image upload](https://paper-attachments.dropbox.com/s_E9FCC16A09539977BBE06A1D26EB3F3E791D81AE781A5D221825A67EB9810FDF_1650009362291_Screenshot+107.png)

## Creating our Landing page

In our `index.js` file, we create our landing page. This page consists of an `input` element that will allow users to input their email addresses to be stored in the database.

```jsx
    import {Appwrite} from "appwrite";
    import {useEffect, useState } from "react";
    
    const Home = () => {
    
        // Init our Web SDK
        const sdk = new Appwrite();
        sdk
        .setEndpoint('http://localhost/v1') // our API Endpoint
        .setProject(projectID) // our project ID
        ;
    
          return(
            <div className="home">
              <div className="title-container">
                  <h2>Orange Music</h2>
                  <p>Input your email address to get updates when we launch!</p>
                  <input 
                  type="text" 
                  />
                  <button type="button">Add email address</button>
              </div>
            </div>
      )
    }
    
    export default Home;
```
**NOTE:** **We use a button with a `type= button` to override the button’s default submit behavior.**

In our `global.css` file, we add these CSS styles to our landing page.

```jsx
    body{
        margin: 0;
        padding: 0;
    }

    .home{
        height: 100vh;
        display: flex;
        justify-content: center;
        align-items: center;
        text-align: center;
        background-image: url('https://res.cloudinary.com/amarachi-2812/image/upload/v1649445450/music-banner_zveuix.jpg');
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
    }

    .title-container h2{
        color: #fff;
        font-size: 32px;
    }

    .title-container p{
        color: rgba(255, 255, 255, 0.815);
        font-size: 18px;
        
    }

    .title-container input{
        outline: none;
        height: 30px;
        width: 250px;
        
    }

    .title-container button{
        height: 35px;
        background-color: #111;
        color: #fff;
        border: 1px solid #111;
        
    }
```
We can use any image link for our background image. However, in this tutorial, we use an image stored on [Cloudinary](https://cloudinary.com/?utm_source=hackmamba&utm_medium=blog&utm_campaign=nextjs-email-leads) because it is easier to apply transformations and optimize delivery. 
To understand how to upload images to Cloudinary, check out the [Cloudinary documentation](https://cloudinary.com/blog/automating_file_upload_and_sharing?utm_source=appwrite&utm_medium=affiliate&utm_term=hackmamba).

Here is our landing page:

![Image upload](https://paper-attachments.dropbox.com/s_E9FCC16A09539977BBE06A1D26EB3F3E791D81AE781A5D221825A67EB9810FDF_1650015651320_Screenshot+99-2.png)

## Adding input interaction with the database

Appwrite has a safety policy that insists we sign in to use the Appwrite features like **Database** and **Functions.** However, Appwrite allows us to work around that policy for simple projects like this by creating anonymous user sessions.

We create an anonymous user session in our `index.js` file once our application mounts using Appwrite's `createAnonymousSession` method.

```jsx
    import {Appwrite} from "appwrite";
    import {useEffect, useState } from "react";
    
    const Home = () => {
    
        // Init our Web SDK
        const sdk = new Appwrite();
        sdk
        .setEndpoint('http://localhost/v1') // our API Endpoint
        .setProject(projectID) // our project ID
        ;
    
        //creating an anonymous Session
        
        const createAnonymousSession = async() => {
          try{
            await sdk.account.createAnonymousSession();
          }catch(err){
            console.log(err)
          }
            
        }
        useEffect(()=> {
          createAnonymousSession()
        }, [])
    
        return(
          <div className="home">
            <div className="title-container">
              <h2>Orange Music</h2>
              <p>Input your email address to get updates when we launch!</p>
              <input 
              type="text" 
              />
              <button type="button">Add email address</button>
            </div>
          </div>
      )
    }
    
    export default Home;
```
Next, in our `index.js` file,  we create a state variable using React `useState` hook to hold the value of our email address `input` form.

```jsx
    // email state 
    const [emailAddress, setEmailAddress] = useState()
```
We then create a `handleEmailAddress` function in our `index.js` file to save the email addresses to the Appwrite database.

```jsx
    // handle email submission
    const handleEmailAddress = async () => {
      try {
        await sdk.database.createDocument(collectionID, 'unique()',{
          "emailAddress": emailAddress
        } )
        setEmailAddress('');
        alert("Email saved successfully!")
      } catch (error) {
        console.log(error)
        
      }
    }
```
In the code block above, the `handleEmailAddress` function does the following:

- Creates a new document in the database using Appwrite’s `createDocument` function, this function receives the collection ID we saved from the **Permissions** page, a **unique()** parameter that specifies that we want a dynamically created document ID, and attributes values as parameters
- Alerts us when we have successfully saved the document and then clears out the information in our `emailAddress` state variable
- Logs any error we encountered to our console

Next, we pass our state variable as a value to our `input` element and our `handleEmailAddress` function to our button's `onClick` event listener.

```jsx
    <div className="home">
      <div className="title-container">
        <h2>Orange Music</h2>
        <p>Input your email address to get updates when we launch!</p>
        <input 
        type="text" 
        value={emailAddress}
        onChange= {(e) => setEmailAddress(e.target.value)}
        />
        <button type="button" onClick={handleEmailAddress}>Add email address</button>
      </div>
    </div>
```
Here is how our `index.js` file looks.



[https://gist.github.com/Iheanacho-ai/c0b17efee282f5e2b280ac53fb2e8218](https://gist.github.com/Iheanacho-ai/c0b17efee282f5e2b280ac53fb2e8218)




![Image upload](https://paper-attachments.dropbox.com/s_E9FCC16A09539977BBE06A1D26EB3F3E791D81AE781A5D221825A67EB9810FDF_1650015887748_Screenshot+99-2.png)


Please input an email address to see it saved on the database.

![Image upload](https://paper-attachments.dropbox.com/s_E9FCC16A09539977BBE06A1D26EB3F3E791D81AE781A5D221825A67EB9810FDF_1650009400470_Screenshot+109.png)

## Conclusion

This article discussed using Appwrite to create data on the database. We created a simple lead generation page in a Next.js application. 

## Resources

Here are some resources that might be helpful:

- [Getting started with Appwrite for web](https://appwrite.io/docs/getting-started-for-web)
- [Database API](https://appwrite.io/docs/client/database)
- [What is Appwrite and How to use it Efficiently](https://appwrite.io/docs/getting-started-for-web)