Developing plug-ins for plug-ins extend your blog with additional features or customization for themes. Read Manton’s blog post for an introduction.

Plug-ins are like lightweight Hugo themes. They can provide all the templates needed for a custom theme, or they can provide just a couple templates, overriding any templates in a built-in design on applies the plug-in templates after the blog’s theme has been set up.

A plug-in needs to have at least one file — plugin.json — and it can have other files as needed. The plugin.json file describes the plug-in and what parameters or include files it needs.

If a plug-in has a config.json file, that file can have only the parameters a plug-in cares about. will first set up any default parameters, then apply the blog’s theme parameters, and then apply any extra parameters in the plug-ins configured for that blog.

The basic structure of plugin.json looks like this:

  "version": "1.0",
  "title": "My plug-in",
  "description": "1-2 sentences about what this plug-in offers.",
  "includes": [
  "fields": [
      "field": "params.photos_use_category",
      "label": "Use category",
      "placeholder": "Enter the category name to include photos from"
      "field": "params.photos_only_microblog",
      "label": "Only include short microblog posts (without a title)",
      "type": "boolean"

Only version, title, and description are required. uses the version number to tell the user that a newer version of the plug-in is available. Version numbers usually start at “1.0” and are incremented like “1.0.1” and “1.0.2” for small bug fixes, “1.1” for new features, and “2.0” for major upgrades.

The includes field is optional. If present, automatically adds link(CSS) or script (JavaScript) tags to the blog. The files references in includes should also be in the plug-in. You can add them as static files under the “static” folder in the plug-in.

For example, if you want to include a CSS file named “hello.css” in your plug-in, it would be stored at “static/hello.css” and referenced in includes with the path “/hello.css”.

If you include an html file, will load it as a Hugo partial. You can add those files in the “layouts/partials” folder in the plug-in. These partials are included inside the head tag of the blog, so they are useful for adding metatags or inline styles and JavaScript.

The fields field is also optional. If present, will build a settings screen for the plug-in. Fields can be of type “string”, “boolean”, or “integer”. For booleans, will use a checkbox. If you need to provide default values, set them in the config.json file.

Fields can override some Hugo variables, or add new parameters that are accessible from the plug-in or any other theme. To add your own parameters, use “params.” as the prefix for your field name.

Plug-ins can be developed and edited inside with the theme editor, so that you can test them before making them available in the plug-in directory for other users. On the Edit Custom Themes screen, click the “New Plug-in” button to get started.

Feels like there was another help article better suited for this info but I didn’t see it so here we go:

I believe the category cloud author updated his/her GitHub name. In any case, the listed link from the find plugins page likely ought to be updated to point here.

Oh, and if y’all know Lukas, I added some plausible analytics functionality to my site that would fit nicely within his plugin. A page not included in navigation for displaying a button to toggle exclusion of visits (necessary for browsers within which one cannot access the JavaScript console). It even worked inside Gluon when I left myself a link via post.

is there any way of injecting HTML code into Body End rather than Head @manton?
I’m trying to adapt Lukas’s Plausible Analytics code to Simple Analytics.
(as a matter of fact, it doesn’t seem to be injecting into at all, even into Head!)

I added in New Plugin in Edit Custom Themes as instructed:

Yes, if you name the template with a “.js” extension instead of “.html”, will include it at the bottom right before the closing “body” tag.

I’ve noticed this doesn’t work with the Cypress theme. I can get that fixed, but it should work most everywhere.

Thanks for prompt response @manton.

In the GH repo, I’ve changed to layouts/partials/sa.js
and updated the reference in plugin.json to sa.js.
(N.b. I changed filename to lowercase incase that was an issue).

Will look for it in Body End. I’m not confident though, because it didn’t even inject into Head before!

Also does it matter that it’s not technically Javascript? It’s technically HTML because the javascript is announced with a tag (also next line a tag which I’m not familiar with).

I’ve now noticed that the M.b plugin didn’t automatically update from the change to GitHub Master branch.

Is it not setup to automatically track GH @manton ?

Adriaan at Simple Analytics suggested to me to put the Javascript in a .js file and the tag (backup for folks who disable Javascript) in a .html file.
So I’ve done that change and re-added the GH repo to this time.

Let’s see if this one works!

@manton no code is injecting whatsoever!
Can you give me some test code to make a repo of just to check that I can inject a plugin?