Build a Web app using Next.js and Appwrite
Tags: react, nextjs, appwrite
Published: 2021-10-30 12:08:04

In this blog tutorial, we are going to build a web app Next.js and Appwrite from complete scratch.

Live Demo - [Made with Appwrite 💙](https://madewithappwrite.vercel.app/)
Github - [harisarang/madewithappwrite](https://github.com/harisarang/madewithappwrite)

## Step 1: ▶️ Initialize Appwrite and Create a Next.js project

I have used Digital ocean to host my Appwrite instance.(Feel free to explore other hosting options)

First create a droplet in digital ocean (min. 2GB RAM / 2vCPU),
![Digital Ocean](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6ma98obtapo5j2anz170.png)
To install appwrite execute the following command (make sure you have docker installed in the instance),

```bash
docker run -it --rm \
    --volume /var/run/docker.sock:/var/run/docker.sock \
    --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
    --entrypoint="install" \
    appwrite/appwrite:0.11.0
```
Use you IP address of your VM in browser to access your Appwrite console or you can add DNS "A record" pointing to your Droplet IP address and access the console using that domain.

![Appwrite Console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nvawbo48tupjrhl8ctvz.png)

Now, create you Next.js project using `create-next-app`
```bash
npx create-next-app -e with-tailwindcss madewithappwrite
```
And then install `appwrite` js package to your project.
```bash
npm install appwrite
```

## Step 2: 🔗 Connect you Next App with Appwrite

Create a new project in Appwrite console named `madewithappwrite`.

Then, register a new web platform in Appwrite. For development purpose add `localhost` and for production register a new web platform with the domain name.

![Platform 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e1dracp19ua8o20sl3mq.png)

![Platform 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tiynu0j47otyo3qe69n8.png)

For this project, I am going to use anonymous users instead of OAuth and email and password.

Now, use the api wrapper below 👇 to perform various operations with appwrite server. (You can also extend by adding various functions to it)

```js
// Create a new file under lib/appwrite.js
import { Appwrite } from "appwrite";

let api = {
  sdk: null,

  provider: () => {
    if (api.sdk) {
      return api.sdk;
    }
    let appwrite = new Appwrite();
    appwrite
      .setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_URL)
      .setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT);
    api.sdk = appwrite;
    return appwrite;
  },

  createSession: (email, password) => {
    return api.provider().account.createAnonymousSession();
  },

  deleteCurrentSession: () => {
    return api.provider().account.deleteSession("current");
  },

  createDocument: (collectionId, data, read, write) => {
    return api
      .provider()
      .database.createDocument(collectionId, data, read, write);
  },

  listDocuments: (collectionId) => {
    return api.provider().database.listDocuments(collectionId);
  },

  getDocument: (collectionId, documentId) => {
    return api.provider().database.getDocument(collectionId, documentId);
  },

  updateDocument: (collectionId, documentId, data, read, write) => {
    return api
      .provider()
      .database.updateDocument(collectionId, documentId, data, read, write);
  },

  deleteDocument: (collectionId, documentId) => {
    return api.provider().database.deleteDocument(collectionId, documentId);
  }
};

export default api;
```

Create a new file named `.env.local`,

```
NEXT_PUBLIC_APPWRITE_URL=http://<your-ip-address>/v1
NEXT_PUBLIC_APPWRITE_PROJECT=<your-project-id>
```

You can find you `project-id` in appwrite console under settings in your project

![Project ID](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/53ea38aaq2ucu5cmrwch.png)

Yay 🥳 ! You have successfully connected you Next App with Appwrite.


## Step 3: 👩‍💻 User Session management

For this project, I am going to use anonymous users (Feel free to explore other options too !)
You can explore other options [here](https://appwrite.io/docs/server/users) !

Now, create a anonymous user session when they land on your web app i.e. create new user under `pages/_app.js` using `useEffect` react hook.

```js
import "tailwindcss/tailwind.css";
import "../styles/global.css";
import Navbar from "../components/Navbar";
import Footer from "../components/Footer";
import { useEffect } from "react";
import api from "../lib/appwrite";

function MyApp({ Component, pageProps }) {
  useEffect(() => {
    api
      .createSession()
      .then((response) => {
        console.log(response);
      })
      .catch((err) => console.log(err));
  }, []);
  return (
    <div>
      <Navbar />
      <Component {...pageProps} />
      <Footer />
    </div>
  );
}

export default MyApp;
```

## Step 4: 🔁 Create and View posts from Appwrite

To create a post, first create a appwrite collection in the database.

Under `settings` in the collection add the following 👇 rules (columns in the database). Find out the collection details in [JSON here](https://gist.github.com/harisarang/bec50d062a4616e8cec9b062660f2df2)

![Collection rules](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0em67t7frq1m5tnkzgk2.png)

Create a form in you Next App and in the `onSumbit` part of the form call the `api.createDocument()` function

I have used [`react-hook-form`](npmjs.com/package/react-hook-form) to manage my form state.
```js
// pages/submit.js

const example_object = {
  title: "title",
  github: "github-url",
  desc: "Description",
  tags: "tags",
  url: "url-to-project",
  appwrite: "appwrite-tags",
  email: "email",
}

...
const updatePost = async (object) => {
    console.log(object);
    api
      .createDocument(
        process.env.NEXT_PUBLIC_APPWRITE_PROJECT_COLLECTION,
        object,
        ["*"],
        ["*"]
      )
      .then((response) => {
        console.log(response);
        console.log("Sumbitted project successfully");
        router.push("/");
      })
      .catch((err) => {
        console.log(err);
        console.log(
          "Unable to submit project to server."
        );
      });
  };
...
```
To retrieve the list projects from the collection use the `api.listDocuments()` from the wrapper. Now, under `pages/index.js` retrieve all the projects.

```jsx
// pages/index.js

...
  const [projects, setProjects] = useState([]);

  useEffect(() => {   
   api.listDocuments("collection-id")
      .then((response) => {
        console.log(response);
        setProjects([...response.documents.reverse()]);
      });
  }, []);

  return (
    <div>
      {projects.map((project) => {
         // Render a card component for the card here ...
      })}
    </div>
 );
```

That's a wrap !✊. Now, you have successfully 🏆 create web app using Next.js and Appwrite 🎉.