Adding Comments to Metalsmith
Comments are the vital part of communication with the audience. It fits for a lot type of websites starting from blogs finishing with e-commerce. Metalsmith is a static site generator, that means (in most cases) that developer doesn’t want to have a database and other back-end infrastructure to implement commenting functionality. But it not says that you can’t add it.
Some services provide commenting widgets as a service in web. The most widely-used and famous of them – Disqus. With it, you will not care about a lot of complicated things related to comments. So what they offer to you:
- Commenting widget
- Real-time comments updates
- Comments counter widget
- Spam filtering
- Moderation tool
- Design adapting to your website
- Media resources support
The site registration is pretty simple, just visit Disqus webpage and follow the instructions.
Integrate with Metalsmith
Metalsmith was created as flexible as possible, and it has a little core functionality. Any additional feature could be implemented as a plugin. So to simplify Disqus integration I created plugin – metalsmith-disqus
.
Installation
The installation process is pretty simple, just run the command in your terminal:
npm install --save-dev metalsmith-disqus
Plug into Metalsmith build
The plugin needs HTML markup to be already generated for its work because it will look for elements with configured class names and add Disqus scripts, meta tags to your page. So you need to place it after markdown files are processed, for example after metalsmith-layouts
plugin:
const Metalsmith = require('metalsmith');
const layouts = require('metalsmith-layouts');
const disqus = require('metalsmith-disqus');
Metalsmith(__dirname)
...
.use(layouts())
.use(disqus({
siteurl: 'my-site.com',
shortname: 'my-site'
}));
Required options
You need to specify two required configuration options – siteurl
and shortname
. siteurl
– needed to generate absolute URL for your pages. That is required for proper Disqus widget configuration. shortname
is the same name that you received during website registration in Disqus admin. Disqus gives the links to widgets based on your shortname sub-domain. All other options are optional, if not specified plugin will use defaults.
Optional configuration
path
- Metalsmith metadata key to finding your page relative path. It is used to generate absolute URL to the page, using path
and siteurl
. If you are using metalsmith-permalinks
plugin you could leave it as default value – 'path’, this plugin adds path
property to your content. Otherwise, you may pass own front matter key to the configuration:
Metalsmith(__dirname)
...
.use(disqus({
siteurl: 'my-site.com',
shortname: 'my-site',
path: 'alias' // Used `alias` property to find page path.
}));
path
- Metalsmith metadata key to finding your page title that will be used in comments widget configuration. Default value – 'title’. You may pass own front matter key to the configuration:
Metalsmith(__dirname)
...
.use(disqus({
siteurl: 'my-site.com',
shortname: 'my-site',
title: 'label' // Used `label` property to find page title.
}));
identifier
- Metalsmith metadata key to finding your page property from which plugin will generate the unique value. This value will be used in Disqus to define content page unique id. It will help Disqus to add the same commenting widget to all content instances, that may have few aliases, for example, the page may be available by few URLs or under different network protocols. Default value – 'title’, metalsmith-disqus
will take the content title and sluglify it. You may pass own front matter key to the configuration:
Metalsmith(__dirname)
...
.use(disqus({
siteurl: 'my-site.com',
shortname: 'my-site',
identifier: 'uuid' // Used `uuid` property to generate unique id.
}));
counterSelector
- a string that represents CSS class name selector for counter widget container. By default plugin is looking for .disqus-comment-count
elements in markup. Then it will add Disqus identifiers to HTML elements, so disqus widget will know what comments amount to insert inside which of them. Now only selectors starting with class name definition works.
Widgets insertion
There are two widgets possible to use from Disqus – the commenting widget and comments counter. To use comments widgets just add comments: true
to content front matter data:
---
title: Hello World
comments: true
---
But wouldn’t be enough, you need to add HTML container for Disqus comments inside your page template with id disqus_thread
, if you’re using handlebars as template engine it may look like this:
{{#if comments }}
<section id="disqus_thread">section>
{{/if}}
The same manipulations needed for comments count widget, just enable comments-counter: true
in metadata and add a container to insert text with some comments. The difference is that for the container you should use the class name disqus-comment-count
(configured by default) or specify any CSS class with counterSelector
option. Also, you need to render property to that is used as identifier
in your settings (title
by default) inside data-disqus-key
attribute. This data-attribute in necessary to insert correct counter to proper content:
---
title: My page
comments-counter: true
---
{{#if comments }}
<span class="disqus-comment-count" data-disqus-key="{{title}}">span>
{{/if}}
Performance optimizations
As a bonus, the plugin can prefetch Disqus DNS and preload scripts by simple parameters in YAML front matter. Adding disqus-dns-prefetch: true
will add line tag that will tell the browser to start resolving disqus hosts earlier to decrease library loading time. Other parameters: disqus-prefetch-widget: true
and disqus-prefetch-counter: true
will force modern browsers to start loading scripts before they are requested by the user.
Let’s imagine real project situation when you have a page(s) with listings of content that have comments, and if you add disqus-prefetch-widget: true
to this pages, while user is discovering this content, modern browsers could load commenting widget script. Then after the transition to the content page, widget JavaScript will be already in place. You can check this feature support here. It is cost nothing to add it, and it will not affect unsupported browsers.
Let’s keep in touch
If you have any issues or any ideas regarding new features, please leave them here.