Nuxt, Meet Disqus
Tags: nuxt, javascript, vue, disqus
Published: 2020-04-14 04:44:52

This article is part of a series on my experiences with Nuxt.js that I built into the [nuxt-toolkit](https://github.com/overscore-media/nuxt-toolkit) by [OverScore Media](https://overscore.media) {% github https://github.com/overscore-media/nuxt-toolkit no-readme %}

See a live example at https://nuxt-toolkit.overscore.media! :]

-----

Hey everybody! I hope you're doing well. You probably already know why you're here. If not, Nuxt is a Vue-based JS framework for building websites/web apps, and Disqus is a commenting system for blogs/websites.

Plug these together, and you get a pretty powerful duo, IMO. In we go!

{% github https://github.com/ktquez/vue-disqus no-readme %}

## Installation Process

### Save as a Dependency
`yarn add vue-disqus` or `npm install --save vue-disqus`. 

### Make a Plugin

Create a file in the `~/plugins` folder of your Nuxt app. I named mine `disqus.js`. (Can you guess why? Can ya?) It should look like this:

```js
import Vue from 'vue'
import VueDisqus from 'vue-disqus'

Vue.use(VueDisqus)
```

Next, import said plugin in your `nuxt.config.js` like so:

```js
// ...
plugins: [
  // Thanks https://dev.to/thelearneer for
  // pointing out that this shouldn't be in client mode
  '~/plugins/disqus',
],
// ...
```

In the words of Lyle from the Animal Crossing series, "Bang! Boom!"

![Lyle from Animal Crossing meme](https://i.kym-cdn.com/photos/images/newsfeed/001/264/640/439.jpg)

### Make it a Component

Now, you can do a ton with this power, but here's a rather grounded example that I used when I built https://botinabox.ca: (As I write this, I just noticed that my implementation on that site just broke. Oh well, I'll get around to fixing it, but it's probably my fault and unrelated to the way I setup the component...)

```vue
<!-- ~/components/Comments.vue -->
<template>
  <v-layout class="comment-box">
    <v-container>
      <vue-disqus
        v-if="metadata"
        shortname="botinabox"
        :identifier="`botinabox-${metadata.title}`"
        :url="`https://botinabox.ca/tutorials/${metadata.url}`"
      ></vue-disqus>
    </v-container>
  </v-layout>
</template>

<script>
export default {
  computed: {
    metadata () {
      const metadata = this.$store.state.tutorials.slice()

      const tutorialMeta = metadata.filter((tutorial) => {
        return `/tutorials/${tutorial.url}` === this.$route.path
      })[0]

      return tutorialMeta
    }
  }
}
</script>
```

Now, don't get overwhelmed by this. I'll break it down for you. First, notice the `<vue-disqus>` component amidst a couple of Vuetify components. That's the real kicker here, functionality wise. The `shortname` is super important; it's your site name when you sign up for Disqus at https://disqus.com/admin/. It all should be fairly straightforward. (I also recommend setting up a Comment Policy, but that's outside the scope of this article. Not that I'm known to be one to stay on scope, but you know....)

The `v-if="metadata"` is because I had some issues when I navigated to another page if the comment box was visible, so making it conditionally-visible solved my problem. The `:identifier` is for different pages - in this case I had it set up with my tutorials, so each tutorial is on a different page and has its own metadata (stored in Vuex, but again that's out of scope). Point is, IMO you'll need at the very least `shortname`, `:identifier`, and `:url` to make it worth it. You don't have to worry about the stuff in the `computed:` block, though; it's just how I actually used this component. Also, I do recommend conditional rendering with a `v-if`, if you can find a suitable condition.

In any case, that's how I made Disqus work in my Nuxt site. It works pretty well IMO (and Disqus has a white and dark theme, so you can change to match your site).

I realize some of you reading this may have some qualms about using Disqus (why are you reading this, then, I guess is a good question, but whatever). I get it; personally I think it can be a bit sketchy, and I'm not a big fan of how they use comment data, but when I find a better solution I'll publish another one of these tutorials on how to use it with Nuxt. For now, though, this is the best I got. Hope this was all helpful.