Introduction
Appwrite 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 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.
GitHub
Check out the complete source code here.
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.
Creating a Next.js project
Open a terminal and run this in the command line to scaffold a Next.js app.
npx create-next-app data-sync
Next, go to the project directory and start the development server on localhost:3000
with the commands below.
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:
npm install @appwrite.io/pink
Next, update the src/pages/_app.js
file with the required CSS and icons library from Pink Design.
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.
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.
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)