Skip to content
Support me
Buy Me a Coffee
Contact me
hey@aiktb.dev @aiktb39 t.me/aiktb

How to Integrate Giscus Comments into VitePress

Why Choose Giscus

There are various external comment providers for integration with VitePress, such as Disqus, Gitalk, Utterances, Giscus. However, I recommend using Giscus for its superior features. Let's compare it with other providers.

ProviderHosting LocationAdaptive BackgroundStyle Design
DisqusDisqus ServerGood
GitalkGithub IssuesModerate
UtterancesGithub IssuesModerate
GiscusGithub DiscussionsGood

As shown in the table, Disqus and Utterances do not adapt well to background color. Gitalk uses Github Issues as the hosting location, but Giscus, utilizing Github Discussions, is a better choice. It prevents comments from mixing with actual project error reports, reducing unnecessary noise. Additionally, Giscus has better style design compared to Gitalk.

In summary, Giscus is the best choice for integrating with VitePress. Now, let's dive into the specifics.

Implementation Steps

Note that you don't need vitepress-plugin-comment-with-giscus. This doesn't even require 80 lines of code, and the code is so easy to understand that there isn't any need to introduce dependency for this.

Obtain Github Repo Parameters

First, follow the instructions on giscus.app to install the Giscus Github application and obtain key parameters: data-repo, data-repo-id, data-category, and data-category-id.

Coding

Next, create a new components/comments.vue component and configure your Layout.vue and index.ts files. Here is the code:

vue
<script setup lang="ts">
import { useData } from 'vitepress'

const { title } = useData()
</script>

<template>
  <div :key="title" class="giscus">
    <component
      :is="'script'"
      src="https://giscus.app/client.js"
      data-repo=" .......... "
      data-repo-id=" .......... "
      data-category=" .......... "
      data-category-id=" .......... "
      data-mapping="pathname"
      data-strict="0"
      data-reactions-enabled="1"
      data-emit-metadata="0"
      data-input-position="top"
      data-lang="en"
      data-theme="transparent_dark"
      data-loading="lazy"
      async
    />
  </div>
</template>
vue
<script setup lang="ts">
import DefaultTheme from 'vitepress/theme'

import Comments from './components/Comments.vue'

const { Layout } = DefaultTheme
</script>

<template>
  <Layout>
    <template #doc-after>
      <Comments />
    </template>
  </Layout>
</template>
typescript
import Layout from './Layout.vue'

export default {
  Layout,
}

Use VitePress built-in Layout slot to inject the Giscus comment section below all doc layout pages. It's a good starting point.

Use the transparent_dark theme, which adapts well to background color changes.

A few things to note:

  • Vue cannot directly use the <script /> tag in templates, so we use <component /> to simulate a <script /> tag.
  • The :key prop is essential; otherwise, due to Vue's component reusability strategy, you might encounter issues with the comment section not reloading when the page route changes.
  • <div class="giscus" /> is used for Giscus to position the comment section correctly. This ensures that when the :key changes, the Giscus comment section in the DOM is properly updated.
  • :key prop should not be on the <component /> because the <script /> tag doesn't represent the actual DOM corresponding to the Giscus comment section. Placing :key on the <script /> tag is meaningless.

You might see a warning and an error in the browser console saying "Discussion not found". This is expected behavior from Giscus, and it will disappear once a comment or reaction is added to create a corresponding discussion thread.

Removing Giscus on Specific Pages

Even though you can lock discussions to disable comments, for better page design, you might want to hide the Giscus comment section altogether on some pages.

To achieve this, introduce frontmatter in specific pages:

markdown
---
comments: false
---

Then, modify the existing code as follows:

vue
<script setup lang="ts">
import { useData } from 'vitepress'

const { frontmatter, title } = useData()
</script>

<template>
  <div v-if="frontmatter.comments !== false" :key="title" class="giscus">
    <component ...... ...... />
  </div>
</template>

For the same reasons discussed earlier, do not place v-if on the <component />; it won't work.

Conclusion

You can check the specific integration of Giscus with VitePress at the end of this article. It looks fantastic!