Using GitHub Discussions to Host My Astro Blog Comments and Reactions

Before writing this article, I've been using a custom comment section for my blog posts.
This involved setting up a database using PlanetScale and Prisma as the ORM, and a TRPC server to handle requests , which is a lot of work for a simple comments section.
Even then, it's not perfect, because I had to manually clean up spam comments (because I'm too lazy to add authentication :-D), I don't support replying to comments, and I get no response.

When I was reading a blog on the TkDodo website, I noticed that he uses GisCus in the comments section.
GisCus is based on GitHub discussions, so I've made this functionality available to me as part of the repository where I host the site.
Setup is very simple, on the GisCus website you select the repository you want to use and it generates a script for you to include in your website.
This looks like this:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-error-color)"><script
  </span><span style="color:var(--syntax-name-color)">src=</span><span style="color:var(--syntax-string-color)">"https://giscus.app/client.js"</span>
  <span style="color:var(--syntax-name-color)">data-repo=</span><span style="color:var(--syntax-string-color)">"[ENTER REPO HERE]"</span>
  <span style="color:var(--syntax-name-color)">data-repo-id=</span><span style="color:var(--syntax-string-color)">"[ENTER REPO ID HERE]"</span>
  <span style="color:var(--syntax-name-color)">data-category=</span><span style="color:var(--syntax-string-color)">"[ENTER CATEGORY NAME HERE]"</span>
  <span style="color:var(--syntax-name-color)">data-category-id=</span><span style="color:var(--syntax-string-color)">"[ENTER CATEGORY ID HERE]"</span>
  <span style="color:var(--syntax-name-color)">data-mapping=</span><span style="color:var(--syntax-string-color)">"pathname"</span>
  <span style="color:var(--syntax-name-color)">data-strict=</span><span style="color:var(--syntax-string-color)">"0"</span>
  <span style="color:var(--syntax-name-color)">data-reactions-enabled=</span><span style="color:var(--syntax-string-color)">"1"</span>
  <span style="color:var(--syntax-name-color)">data-emit-metadata=</span><span style="color:var(--syntax-string-color)">"0"</span>
  <span style="color:var(--syntax-name-color)">data-input-position=</span><span style="color:var(--syntax-string-color)">"bottom"</span>
  <span style="color:var(--syntax-name-color)">data-theme=</span><span style="color:var(--syntax-string-color)">"preferred_color_scheme"</span>
  <span style="color:var(--syntax-name-color)">data-lang=</span><span style="color:var(--syntax-string-color)">"en"</span>
  <span style="color:var(--syntax-name-color)">crossorigin=</span><span style="color:var(--syntax-string-color)">"anonymous"</span>
  <span style="color:var(--syntax-name-color)">async</span>
<span style="color:var(--syntax-error-color)">></script></span>
</code></span></span>

The blanks are automatically filled with repository name, repository id, category name and category id.
The only thing I've noticed is that with the default <script>tabs, clicking the "Sign in with GitHub" button refreshes the entire page and doesn't scroll down to the comments section.
For me this was annoying, so I decided to use GisCus React components instead .
The component is very easy to use, you just need to install it npm install @giscus/reactand then import it into your React components.
The props you need to pass to the component are the same as the data attributes in the script tag, but in camel case instead of kebab.

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-error-color)">*</span> <span style="color:var(--syntax-declaration-color)">as</span> <span style="color:var(--syntax-name-color)">React</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">react</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">;</span>
<span style="color:var(--syntax-declaration-color)">import</span> <span style="color:var(--syntax-name-color)">Giscus</span> <span style="color:var(--syntax-declaration-color)">from</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">@giscus/react</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">;</span>

<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">id</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-string-color)">inject-comments</span><span style="color:var(--syntax-string-color)">'</span><span style="color:var(--syntax-text-color)">;</span>

<span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-name-color)">Comments</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-text-color)">()</span> <span style="color:var(--syntax-error-color)">=></span> <span style="color:var(--syntax-text-color)">{</span>
  <span style="color:var(--syntax-declaration-color)">const</span> <span style="color:var(--syntax-text-color)">[</span><span style="color:var(--syntax-name-color)">mounted</span><span style="color:var(--syntax-text-color)">,</span> <span style="color:var(--syntax-name-color)">setMounted</span><span style="color:var(--syntax-text-color)">]</span> <span style="color:var(--syntax-error-color)">=</span> <span style="color:var(--syntax-name-color)">React</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">useState</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-declaration-color)">false</span><span style="color:var(--syntax-text-color)">);</span>

  <span style="color:var(--syntax-name-color)">React</span><span style="color:var(--syntax-text-color)">.</span><span style="color:var(--syntax-name-color)">useEffect</span><span style="color:var(--syntax-text-color)">(()</span> <span style="color:var(--syntax-error-color)">=></span> <span style="color:var(--syntax-text-color)">{</span>
    <span style="color:var(--syntax-name-color)">setMounted</span><span style="color:var(--syntax-text-color)">(</span><span style="color:var(--syntax-declaration-color)">true</span><span style="color:var(--syntax-text-color)">);</span>
  <span style="color:var(--syntax-text-color)">},</span> <span style="color:var(--syntax-text-color)">[]);</span>

  <span style="color:var(--syntax-declaration-color)">return</span> <span style="color:var(--syntax-text-color)">(</span>
    <span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-error-color)">div</span> <span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-string-color)">}</span><span style="color:var(--syntax-text-color)">></span>
      <span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">mounted</span> <span style="color:var(--syntax-text-color)">?</span> <span style="color:var(--syntax-text-color)">(</span>
        <span style="color:var(--syntax-text-color)"><</span><span style="color:var(--syntax-name-color)">Giscus</span>
          <span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">{</span><span style="color:var(--syntax-name-color)">id</span><span style="color:var(--syntax-string-color)">}</span>
          <span style="color:var(--syntax-name-color)">repo</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"[ENTER REPO HERE]"</span>
          <span style="color:var(--syntax-name-color)">repoId</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"[ENTER REPO ID HERE]"</span>
          <span style="color:var(--syntax-name-color)">category</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"[ENTER CATEGORY HERE]"</span>
          <span style="color:var(--syntax-name-color)">categoryId</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"[ENTER CATEGORY ID HERE]"</span>
          <span style="color:var(--syntax-name-color)">mapping</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"pathname"</span>
          <span style="color:var(--syntax-name-color)">reactionsEnabled</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"1"</span>
          <span style="color:var(--syntax-name-color)">emitMetadata</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"0"</span>
          <span style="color:var(--syntax-name-color)">inputPosition</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"top"</span>
          <span style="color:var(--syntax-name-color)">lang</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"en"</span>
          <span style="color:var(--syntax-name-color)">loading</span><span style="color:var(--syntax-text-color)">=</span><span style="color:var(--syntax-string-color)">"lazy"</span>
        <span style="color:var(--syntax-text-color)">/></span>
      <span style="color:var(--syntax-text-color)">)</span> <span style="color:var(--syntax-text-color)">:</span> <span style="color:var(--syntax-declaration-color)">null</span><span style="color:var(--syntax-string-color)">}</span>
    <span style="color:var(--syntax-text-color)"></</span><span style="color:var(--syntax-error-color)">div</span><span style="color:var(--syntax-text-color)">></span>
  <span style="color:var(--syntax-text-color)">);</span>
<span style="color:var(--syntax-text-color)">};</span>

<span style="color:var(--syntax-declaration-color)">export</span> <span style="color:var(--syntax-declaration-color)">default</span> <span style="color:var(--syntax-name-color)">Comments</span><span style="color:var(--syntax-text-color)">;</span>
</code></span></span>

In order to have this comments section on every blog I create, I updated my BlogLayout.astro(which I use to package all my blogs) files to include this component. Relevant section from that file:

<span style="color:var(--syntax-text-color)"><span style="color:var(--syntax-text-color)"><code><Comments client:idle />
</code></span></span>

You can see that I'm only loading components when the browser is idle using Astro's built-in client directives.

That's it!
A fully functional comment section for my blog posts, no database management or authentication required.
Hope it works for you too! The full code can be found on my GitHub
.

Guess you like

Origin blog.csdn.net/jascl/article/details/131322348