Skip to main content

Plugins

Plugins are used to extend Doxicity’s functionality. For your convenience, a number of useful first-party plugins come out of the box. You can enable as many or as few as you’d like.

Activating Plugins

Plugins are imported and activated in your config file like this.

// doxicity.config.js
import myPlugin from './path/to/my-plugin.js';

export default {
  // ...
  plugins: [
    myPlugin({
      /* plugin options go here */
    })
  ]
};

Plugins are be executed in the same order they appear in the plugins array.

First-party Plugins

The following plugins ship with the official Doxicity package. This project is still young, so for now please see the source of each plugin (linked below) to see which config options are available. Additional third-party plugins will soon be found on npm .

  • activeLinks : Adds a custom class name to active links on the page.
  • anchorHeadings : Turns headings into deep-linkable anchors with unique ids.
  • codeFormatter : Runs the resulting HTML through JS Beautify to improve formatting and indentation.
  • codeHighlighter : Highlights code fields using Prism. All languages that Prism supports work by default. Highlighting is done at build time, so no JavaScript is shipped to the client.
  • copyCode : Adds a button to each code field that copies the code when clicked.
  • customTitle : Adds a custom prefix and/or suffix to each page’s <title>
  • externalLinks : Makes external links safe by adding rel="noopener noreferrer" and optionally opens them in a new window.
  • search : Adds a static search index and a customizable search client to your website.
  • smoothLinks : Makes in-page links scroll smoothly.
  • tableOfContents : Generates a table of contents. You can select which headings are selected and where the TOC gets rendered. Can be used multiple times per page.
  • tableScroll : Adds a wrapper around table elements, allowing them to scroll horizontally as needed on smaller screens.
  • typography : Converts regular quotes to smart quotes and other common typographical symbols such as en dash, em dash, ellipsis, and more.

Example usage:

// doxicity.config.js
import { activeLinks, anchorHeadings, highlightCode, search } from 'doxicity/dist/plugins/index.js';

export default {
  // ...
  plugins: [
    activeLinks({
      // plugin options go here
    }),
    anchorHeadings(),
    highlightCode(),
    search()
  ]
};

Writing Your Own Plugins

Some static site generators offer a ton of hooks for plugin authors to tap into. However, this usually results in confusion. For example, how does each hook affect rendering? What if a plugin runs too soon or too late? What if it only applies to markdown content and not the rest of the HTML? With so many hooks, it’s difficult to keep track of which plugins are doing what and when.

Doxicity simplifies this by offering a limited number of hooks and making it easy to mutate the entire page — not just the markdown content — with standard JavaScript methods. At the heart of Doxicity’s plugin API is the transform hook. It provides you with a Document object that you can mutate just like you would in a browser.

Plugin Hooks

The following hooks are currently available to plugin authors.

Name Description
transform Hooks into the DOM transform phase, allowing you to mutate each page’s document object before it gets turned into HTML. Use this for all types of DOM manipulation.
afterTransform Hooks into the page’s raw HTML string after all rendering and transformations are complete. Useful for running a formatter, such as Prettier, before publishing.
afterAll Runs after all pages have been published and all assets have been copied. Use this when you need to do something after all publishing steps have been completed.
scripts Global scripts required by the plugin. These will be injected into the website’s shared scripts file. If you need to inject page-specific scripts, use the transform hook instead. Only use standard, browser-ready JavaScript.
styles Global styles required by the plugin. These will be injected into the website’s shared styles file. If you need to inject page-specific styles, use the transform hook instead. Only use standard, browser-ready CSS.

Every Doxicity plugin must conform to the DoxicityPlugin interface. The interface is described in TypeScript, but you can write plugins in JavaScript as well. All hooks can be synchronous or asynchronous.

Example Plugin

Here’s a contrived example that prepends the text “Wow ” to every paragraph of every page. It also shows how you can append a script and stylesheet.

import type { DoxicityPlugin } from 'doxicity';

const wowPlugin: DoxicityPlugin = {
  // Give it a name for debugging purposes
  name: 'doxicity-wow-plugin',

  // Use the transform hook to manipulate the DOM
  transform: (doc, page) => {
    // doc - a document object that you can manipulate using standard JavaScript methods
    // page - contains info about the page that's currently being processed
    doc.querySelectorAll('p').forEach(p => {
      p.classList.add('wow');
      p.innerHTML = 'Wow ' + p.innerHTML;
    });
  },

  // Use the afterTransform hook to manipulate the page's HTML
  afterTransform: (html, page) => {
    // html - an HTML string that you can modify before returning
    // page - contains info about the page that's currently being processed
    return html;
  },

  // Use the afterAll hook to do things after publishing is complete
  afterAll: result => {
    // result.pages - contains a list of all pages that were published
    // result.assets - contains a list of all assets that were copied
  },

  // Add a shared script to wow developers
  scripts: config => {
    return `
      console.log('Wow!');
    `;
  },

  // Add some CSS to make it pop
  styles: config => {
    return `
      .wow {
        color: tomato;
      }
    `;
  }
};

export default wowPlugin;

This example might seem silly, but the important thing to note is that you have complete control over every page. You can change the template’s structure, add or remove things from the DOM, mutate existing elements, and more. A good starting point for aspiring plugin authors is to look at the plugin folder to see how some of the first-party plugins work.