DEV Community

Cover image for How to Build A Video Player with timeline comments using Appwrite & Cloudinary in Next.js
Chidi Eze for Hackmamba

Posted on

How to Build A Video Player with timeline comments using Appwrite & Cloudinary in Next.js

Timeline comments allow viewers to add comments or notes to specific points in a video, providing additional context or information about what is happening on screen. This feature enhances the viewer's experience, facilitates collaboration and engagement, improves accessibility, and provides valuable data insights for creators.

This article discusses building a video player with timeline comments using Appwrite storage, the Cloudinary video player, and Next.js.

Appwrite is an open-source backend server that provides a range of APIs and SDKs to help developers build web and mobile applications. It offers user authentication, database management, file storage, and more features.

Cloudinary is a cloud-based image and video management platform that provides developers with tools for storing, manipulating, optimizing, and delivering images and videos on their websites or applications.

Next.js is a popular open-source React-based framework for building web applications. It provides a range of features, such as server-side rendering, static site generation, and automatic code splitting.

Check out the GitHub repository to quickly get started:


To fully grasp the concepts presented in this tutorial, the following are required:

  • Basic understanding of JavaScript and React
  • Cloudinary account and at least one video uploaded to the media library (Create a free account here)

Getting started

Log in to Cloudinary, navigate to the “Dashboard” page, and copy the cloud name.

Next, navigate to the Media Library tab, select a video, or click the Upload button to upload a video. Grab the video's id and keep it safe; we need it later.


Creating a Next.js application

First, let’s run the following command in the terminal to create a new Next.js application:

    npx create-next-app with-tailwindcss video-comments
Enter fullscreen mode Exit fullscreen mode

The command above creates a starter Next.js application and adds tailwind CSS to the application with the with-tailwindcss flag in the video-comments folder.

Next, navigate to the project directory and start the application with the following commands:

    cd video-comments #navigate into the project directory
    npm run dev #start the dev server
Enter fullscreen mode Exit fullscreen mode

Building the video player and the comments section

First, clean up the index.js file in the pages folder and update it with the following snippet:

    import { useEffect, useState, useRef } from "react";
    const Home = () => {
      const videoRef = useRef();
      const cloudinaryRef = useRef();
      const playerRef = useRef();

      useEffect(() => {
        if (cloudinaryRef.current) return;
        cloudinaryRef.current = window.cloudinary;
        playerRef.current = cloudinaryRef.current.videoPlayer(videoRef.current, {
          cloud_name: "kizmelvin",
          secure: true,
      return (
        <div className=" flex min-h-screen  justify-around py-2">
          {/* Video player */}
          <section className="flex w-8/12 flex-col items-center justify-center px-10 text-center">
            <div className="w-full">
                className="cld-video-player cld-fluid "
    export default Home;
Enter fullscreen mode Exit fullscreen mode

In the snippet above:

  • We created some references, instantiated a Cloudinary instance in the useEffect() function, and passed our cloud name.
  • In the return function, we returned a video tag, passed ref and id properties, and set the data-cld-public-id property to the video ID we obtained from Cloudinary.

In the browser, the application should like the image below:


Creating the comments section

Let’s create an input to collect user comments and buttons to submit and cancel the process.

Next, let’s update the index.js with the following snippet:

In the snippet above, we:

  • Created state constants using the useState hook.
  • Created the openComment() function to pause the video and grab the current playing time.
  • In the return function, we rendered a Comment button, an input field for the comment, a Submit button to save the comment to Appwrite, and a Cancel button to terminate the process. image-demo

Integrating Appwrite for comments storage

Now it’s time to integrate Appwrite into our application to handle the video timeline comments.

First, log in to the Appwrite cloud or create an account. Check out this article on how to set up an Appwrite instance locally.

After successfully signing in, click on the + Create project button, choose a name for the project, and click the Create button.


After creating the project, navigate to the database tab, click the +Create database button, name the database, and click the create button to continue.


Next, grab the database ID and keep it handy. Click the +Create collection button, name the collection, and click the Create button to continue.


On the next screen, grab the collection ID and save it. Navigate to the attributes tab, click the +Create collection” button and the prompts, and create a name, comment, and videoTime attribute.


Finally, click the Settings button in the bottom-left corner and grab the project ID and the API Endpoint; we’ll need them to set up the Appwrite instance.


Back in the code editor, run the following command to install Appwrite, uuid, and dotenv npm packages:

    npm install appwrite uuidv4 dotenv #install the packages
Enter fullscreen mode Exit fullscreen mode

Next, create a .env.local file in the root directory of the project and save the Appwrite credentials like the below:

Enter fullscreen mode Exit fullscreen mode

Let’s create a helper folder in the root directory and create a Utils.js file with the following snippet:

    import { Client, Databases } from "appwrite";
    import { v4 as uuidv4 } from "uuid";

    //Initializing Appwrite
    export const client = new Client();
    const dataB = new Databases(client);

    //Saving Comments to Appwrite Database

    export const saveComments = async (details) => {
      try {
        await dataB.createDocument(
            comment: `${details.comment}`,
            videoTime: `${details.videoTime}`,
            name: `${}`,
      } catch (error) {

    //Fetching comments from Appwrite Database

    export const listComments = ({ setComments }) => {
      const promise = dataB.listDocuments(
        (response) => setComments(response.documents),
        (error) => console.log(error)
Enter fullscreen mode Exit fullscreen mode

In the snippet above, we did the following:

  • Created a new Client and two Database instances and passed the project_id to the client.
  • Created the saveComment function to save the video time and the user comment to the Appwrite database.
  • Created the listComments function to get the list of comments from Appwrite and update our comment state.

Now in the index.js file, let’s grab the details from our user; update the index.js file with the following snippet:

In the above snippet, we:

  • Imported saveComments and listComments functions from the Utils.js file and created the details object.
  • Called the saveComments() in the handleSubmit() function and passed the details object to it.
  • Created a button to view and hide the comments, looped through the comment state, and displayed the comments.

The complete code of the index.js file can be found in this Github Gist.

Now, we have a functional video player with timeline commenting functionality in the browser.



Building a video player with timeline comments is a great way to enhance user experience and engagement. By leveraging the power of these technologies, we created a seamless and interactive video playback experience that allows users to leave comments and feedback at specific points in the video timeline. So, to take your website to the next level, consider implementing a video player with timeline comments using Appwrite and Cloudinary in Next.js.


These resources might be helpful:

Top comments (0)