DEV Community

Kiran Krishnan
Kiran Krishnan

Posted on • Edited on

HelpUp: Knowledge Base / Help Center Builder

What I built

HelpUp - A simple knowledge base builder. It helps you build a knowledge base for your customer support team. It is a self-hosted solution that you can deploy on your own infrastructure. It is built using Next.js, Supabase and MongoDB.

Category Submission

Search No More: Build an application with full-text search capabilities using MongoDB Atlas and Atlas Search

App Link

https://helpup.vercel.app/

Demo HelpCenter for a E-commerce Store

Screenshots

Image description

Image description

Image description

Backend
Watch demo

Frontend
Watch demo

Description

HelpUp is a simple knowledge base builder. It helps you build a knowledge base for your customer support team. You can add as many workspaces as you want. Each workspace has its own set of articles. You can group articles into collections. You can search articles by title, content.

Here are some of the features of the app.

  • Create an account
  • Create and manage workspaces
  • Create and manage collections
  • Create and manage articles
  • Customize the landing page of the help center
  • Search articles by title and content
  • Autocomplete search title
  • Highlight search term in the article content
  • Allow users to share feedback on the article

Link to Source Code

Github

Permissive License

MIT

How I built it

I built the app using Next.js, Supabase, and MongoDB. I used MongoDB Atlas to store and query the data.

Let's take a look at the important parts of the app.

Search articles

I created a MongoDB Atlas Search Index searchArticles to search the articles. I used the following mapping for the index.

{
  "mappings": {
    "dynamic": false,
    "fields": {
      "contentText": {
        "type": "string"
      },
      "title": {
        "type": "string"
      },
      "workspaceId": {
        "type": "objectId"
      }
    }
  },
  "storedSource": {
    "include": ["workspaceId"]
  }
}
Enter fullscreen mode Exit fullscreen mode

Then created a Atlas Function to search the articles. It is a simple function that takes the searchTerm and workspaceId as input and returns the search results. Here is the code for the function.

exports = function ({ query, headers, body }, response) {
  const { searchTerm, workspaceId } = query;

  const docs = context.services
    .get("mongodb-atlas")
    .db("helpup")
    .collection("Article")
    .aggregate([
      {
        $search: {
          index: "searchArticles",
          compound: {
            must: [
              {
                text: {
                  query: searchTerm,
                  path: ["title", "contentText"],
                },
              },
            ],
            filter: [
              {
                equals: {
                  value: new BSON.ObjectId(workspaceId),
                  path: "workspaceId",
                },
              },
            ],
          },
        },
      },
      {
        $project: {
          _id: 0,
          title: 1,
          slug: 1,
          contentText: 1,
          updatedAt: 1,
        },
      },
    ]);

  return docs;
};
Enter fullscreen mode Exit fullscreen mode

Then I created a HTTPS Endpoint /searchArticles to call the above Atlas Function. I called this endpoint from Next.js getServerSideProps function to get the search results. Here is the code to invoke the endpoint.

const url = new URL(`${process.env.NEXT_PUBLIC_ATLAS_APP_URL}/searchArticles`);

url.searchParams.set("searchTerm", searchTerm);
url.searchParams.set("workspaceId", workspaceId);

const response = await fetch(url, {
  method: "GET",
  headers: {
    "Content-Type": "application/json",
  },
});

const articles = await response.json();
Enter fullscreen mode Exit fullscreen mode

Autocomplete search

I created another MongoDB Atlas Search Index autocompleteArticles to autocomplete the search title. I used the following mapping for the index.

{
  "mappings": {
    "dynamic": false,
    "fields": {
      "title": {
        "type": "autocomplete"
      },
      "workspaceId": {
        "type": "objectId"
      }
    }
  },
  "storedSource": {
    "include": [
      "workspaceId"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Created a new Atlas Function to autocomplete the search title. It is a simple function that takes the searchTerm and workspaceId as input and returns the search results.

exports = function ({ query, headers, body }, response) {
  const { searchTerm, workspaceId } = query;

  const docs = context.services
    .get("mongodb-atlas")
    .db("helpup")
    .collection("Article")
    .aggregate([
      {
        $search: {
          index: "autocompleteArticles",
          compound: {
            must: [
              {
                autocomplete: {
                  query: searchTerm,
                  path: "title",
                },
              },
            ],
            filter: [
              {
                equals: {
                  value: new BSON.ObjectId(workspaceId),
                  path: "workspaceId",
                },
              },
            ],
          },
        },
      },
      {
        $project: {
          _id: 0,
          title: 1,
          slug: 1,
          contentText: 1,
          updatedAt: 1,
        },
      },
    ]);

  return docs;
};
Enter fullscreen mode Exit fullscreen mode

I created another HTTPS Endpoint /autocompleteArticles to call the above Atlas Function. I called this endpoint from the client-side to get the autocomplete search results.

Here is the link to the search and autocomplete code

Top comments (0)