How to implement real-time data sync in your Next.js app with Appwrite Cloud
Tags: nextjs, database
Published: 2023-06-21 09:47:22

## Introduction

[Appwrite](https://appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog) is an open-source backend-as-a-service platform that provides developers with all the core APIs to build web, mobile, and flutter applications. Appwrite can be integrated directly with your client app or used behind or alongside your custom backend.

[Appwrite Cloud](https://cloud.appwrite.io/login?utm_source=hackmamba&utm_medium=hackmamba-blog) is an extension of the open-source version of Appwrite. It comes with all the services included in the open-source version but now with fully managed service and minimum friction. 

This tutorial demonstrates how to implement real-time data sync using Next.js, Appwrite Cloud, and [Pink Design](https://pink.appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog).

## GitHub

Check out the complete source code [here](https://github.com/obinnadtq/appwrite-data-sync).

## Prerequisites 

To follow along with this tutorial, you should have a working knowledge of the following:

- React, Next.js, and CSS
- An Appwrite cloud account

You can request access to Appwrite Cloud [here](https://cloud.appwrite.io/login?utm_source=hackmamba&utm_medium=hackmamba-blog).

## Creating a Next.js project

Open a terminal and run this in the command line to scaffold a Next.js app.  

```powershell
npx create-next-app data-sync
```

Next, go to the project directory and start the development server on `localhost:3000` with the commands below.  

```powershell
cd data-sync && npm run dev
```


## Installing dependencies 

**Installing Pink Design**
Pink Design is an open-source system from Appwrite used to build consistent and reusable user interfaces. It enhances collaboration, development experience, and accessibility.

To install Pink Design, open a terminal in the project directory and run the following command: 

```powershell
npm install @appwrite.io/pink
```

Next, update the `src/pages/_app.js` file with the required CSS and icons library from Pink Design.

```javascript
import '@appwrite.io/pink';
import '@appwrite.io/pink-icons';
    
export default function App({ Component, pageProps }) {
   return <Component {...pageProps} />
}
```

**Installing Appwrite**
To use Appwrite, install the Appwrite client-side SDK for web applications using the command below.

```powershell
npm install appwrite
```

## Building the UI

The UI will be a page showing a list of student data and the total number of students.
To build the UI, create an `src/components` folder; in the folder, create a `TotalStudents.jsx` file to display the number of students.

```javascript
import React from "react";

const TotalStudents = ({students}) => {
        return (
            <div className="card u-flex u-flex-vertical u-cross-center">
                <div className='u-flex u-cross-center'>
                    <p
                        className='icon-user'
                        style=`{{ marginRight: '15px' }}`
                    ></p>
                    <h5 className='u-bold'>Total students</h5>
                </div>
                <h1
                    className='u-bold'
                    style=`{{ fontSize: '80px', color: '#5D5FEF' }}
                >
                    {students.length}
                </h1>
            </div>
        )
    }
export default TotalStudents;
```

The code above uses Pink Design’s Card, Flex, and Display elements to style the page. Also, displaying the number of students is done by passing the `students` props to the component.

Then import the `TotalStudents.jsx` component into `src/pages/index.js` which looks like this.

```javascript
import Head from 'next/head'
import TotalStudents from '@/components/TotalStudents'

const data = [
      {
          "firstName": "Peter",
          "lastName": "Dunk",
          "nationality": "British",
          "age": 21
      },
      {
          "firstName": "Obinna",
          "lastName": "Hilary",
          "nationality": "Nigerian",
          "age": 22
      }
    ];

export default function Home() {
      return (
        <>
          <Head>
            <title>Student data</title>
          </Head>
          <div>
            <h1 class="heading-level-1 u-text-center">Student Data</h1>
            <TotalStudents students={data}/>
          </div>
        </>
      )
    }
```

An array is used to store the students’ data for now. It will be fetched later from Appwrite in the subsequent sessions.

Next, create a component `src/components/StudentData.jsx` to display the student data. 

```javascript
import React from "react";

const StudentData = ({ students }) => {
      return (
        <div>
          <table class="table">
            <thead class="table-thead">
              <tr class="table-row">
                <th class="table-thead-col"><span class="eyebrow-heading-3">Serial No.</span></th>
                <th class="table-thead-col">
                  <span class="eyebrow-heading-3">First Name</span>
                </th>
                <th class="table-thead-col">
                  <span class="eyebrow-heading-3">Last Name</span>
                </th>
                <th class="table-thead-col">
                  <span class="eyebrow-heading-3">Nationality</span>
                </th>
                <th class="table-thead-col">
                  <span class="eyebrow-heading-3">Age</span>
                </th>
              </tr>
            </thead>
            <tbody class="table-tbody">
              {students && students.map((student, i) => {
                return (
                  <tr class="table-row">
                    <td class="table-col" data-title="SerialNo">
                      <div class="u-inline-flex u-cross-center u-gap-12">
                        <span class="text u-break-word u-line-height-1-5">{i + 1}</span>
                      </div>
                    </td>
                    <td class="table-col" data-title="FirstName">
                      <div><span class="text">{student.firstName}</span></div>
                    </td>
                    <td class="table-col" data-title="LastName">
                      <span class="text">{student.lastName}</span>
                    </td>
                    <td class="table-col" data-title="Nationality">
                      <span class="text">{student.nationality}</span>
                    </td>
                    <td class="table-col" data-title="Age">
                      <span class="text">{student.age}</span>
                    </td>
                  </tr>
                )
              })}
            </tbody>
          </table>
        </div>
      )
    }
export default StudentData;
```

The code above uses Pink Design’s Table element to create a table for displaying student data.

## Creating an Appwrite Cloud project

Log in to your Appwrite cloud account to create a new project. The project name is `Data-sync` in this tutorial.

![Creating an Appwrite project](https://paper-attachments.dropboxusercontent.com/s_01199E6AC508A62EFD62ABD1C9B18BE74062C7E2200DE314AA841710EF863E0A_1687290042540_Screenshot+2023-06-20+at+21.10.51.png)

## Creating the database, collection, and attributes

Create a database for the project after creating the project. Navigate to the `Databases` tab and click the `Create database` button. Enter the name `student_data` as the database name and click the `Create` button.

![Creating a Database](https://paper-attachments.dropboxusercontent.com/s_01199E6AC508A62EFD62ABD1C9B18BE74062C7E2200DE314AA841710EF863E0A_1687290138095_image.png)


Next, create a collection for storing the student data. Click the `Create collection` button and enter `student_data_collection` as the collection name.

![Creating a collection](https://paper-attachments.dropboxusercontent.com/s_01199E6AC508A62EFD62ABD1C9B18BE74062C7E2200DE314AA841710EF863E0A_1687290312275_image.png)


After creating the collection, create the attributes representing the database’s data fields. To create them, click the `Create Attribute` button. For this tutorial, the attributes include the following:

| Attribute Key | Attribute type | Size | Required | Default Value |
| ------------- | -------------- | ---- | -------- | ------------- |
| firstName     | String         | 225  | Yes      | -             |
| lastName      | String         | 225  | Yes      | -             |
| nationality   | String         | 225  | Yes      | -             |
| age           | Integer        | -    | Yes      | -             |

![Creating attributes](https://paper-attachments.dropboxusercontent.com/s_01199E6AC508A62EFD62ABD1C9B18BE74062C7E2200DE314AA841710EF863E0A_1687290686483_image.png)


Next, update the `student_data_collection` permission in order to manage who can access the collection. To do this, click the `Settings`  tab and click `Any`. Select the permissions and click the `Update` button.

![Updating permissions](https://paper-attachments.dropboxusercontent.com/s_01199E6AC508A62EFD62ABD1C9B18BE74062C7E2200DE314AA841710EF863E0A_1687290731234_image.png)


Lastly, add sample data to the database to be displayed in the Next.js application.

![Creating documents](https://paper-attachments.dropboxusercontent.com/s_01199E6AC508A62EFD62ABD1C9B18BE74062C7E2200DE314AA841710EF863E0A_1687290776980_image.png)

## Integrating Appwrite Cloud into the Next.js project

To integrate Appwrite into the UI, create a `src/components/appwriteInit.js` file. The file should look like this.

```javascript
import { Client, Databases } from 'appwrite';

const PROJECT_ID = 'project Id';
const DATABASE_ID = 'database Id';
const COLLECTION_ID = 'collection Id';
const client = new Client();
const databases = new Databases(client);

client.setEndpoint('https://cloud.appwrite.io/v1').setProject(PROJECT_ID);
export const getStudentDataFromDb = () =>
        databases.listDocuments(DATABASE_ID, COLLECTION_ID);
```
    

The code above does the following:

- Imports `Client` and `Databases` from Appwrite.
- Instantiates the `Client` and `Databases` objects.
- Uses the client object to set the endpoint and project.
- Fetches the data from the Appwrite cloud database.

Next, update `src/pages/index.js` . At this point, it looks like this.

```javascript
import Head from 'next/head'
import TotalStudents from '@/components/TotalStudents'
import StudentData from '@/components/StudentData'
import { useEffect, useState } from 'react'
import { getStudentDataFromDb } from '@/components/appwriteInit'

export default function Home() {
      const [data, setData] = useState([])
        useEffect(() => {
       studentData()
      }, [data])
    
     const studentData = () => {
        getStudentDataFromDb()
        .then((res) => setData(res.documents))
        .catch((err) => console.log(err))
      };
      return (
        <>
          <Head>
            <title>Student data</title>
          </Head>
          <div>
            <h1 class="heading-level-1 u-text-center">Student Data</h1>
            <TotalStudents students={data}/>
          </div>
          <StudentData students={data}/>
        </>
      )
    }
```
The code above imports the `getStudentDataFromDb` function and passes the result as props into the child components.

At this point, the UI looks like this.

![Initial UI](https://paper-attachments.dropboxusercontent.com/s_01199E6AC508A62EFD62ABD1C9B18BE74062C7E2200DE314AA841710EF863E0A_1681857481139_Screenshot+2023-04-19+at+00.37.23.png)


To show the real-data sync, update the database with a new document, and it should update the UI in real-time.

![Real-time update](https://paper-attachments.dropboxusercontent.com/s_01199E6AC508A62EFD62ABD1C9B18BE74062C7E2200DE314AA841710EF863E0A_1681857648050_Screenshot+2023-04-19+at+00.39.56.png)

## Conclusion

This tutorial showed how to implement real-time data sync using Appwrite Cloud. It also showed how to integrate Appwrite’s Pink Design into your project.

## Resources
- [Appwrite](https://appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Appwrite Cloud](https://appwrite.io/cloud?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Appwrite Pink Design](https://pink.appwrite.io/?utm_source=hackmamba&utm_medium=hackmamba-blog)