HelpUp: Knowledge Base / Help Center Builder
Tags: atlashackathon22, nextjs, opensource, node
Published: 2022-12-07 19:18:29

## 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/](https://helpup.vercel.app/)

[Demo HelpCenter for a E-commerce Store](https://helpup.vercel.app/helpcenter/shop)

### Screenshots

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fx8l99pce3ger33won6v.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/geku3pgxgium0erj1t9f.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dzoi8rvbg7vxd9ik40mh.png)

**Backend**
[Watch demo](https://www.loom.com/share/bdf078d628a44190a7d43913b60266c5)

**Frontend**
[Watch demo](https://www.loom.com/share/3ed8a5bfb945461f9007470f05d3ba33)

### 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](https://github.com/devkiran/helpup)

### Permissive License

[MIT](https://github.com/devkiran/helpup/blob/main/LICENSE.md)

### 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.

```js
{
  "mappings": {
    "dynamic": false,
    "fields": {
      "contentText": {
        "type": "string"
      },
      "title": {
        "type": "string"
      },
      "workspaceId": {
        "type": "objectId"
      }
    }
  },
  "storedSource": {
    "include": ["workspaceId"]
  }
}
```

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.

```js
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;
};
```

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.

```js
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();
```

#### Autocomplete search

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

```js
{
  "mappings": {
    "dynamic": false,
    "fields": {
      "title": {
        "type": "autocomplete"
      },
      "workspaceId": {
        "type": "objectId"
      }
    }
  },
  "storedSource": {
    "include": [
      "workspaceId"
    ]
  }
}
```

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.

```js
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;
};
```

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](https://github.com/devkiran/helpup/blob/main/components/docs/ArticleSearchBar.tsx)