Plugins
Docsy loads some of its optional JavaScript features, and any script you add, as
plugins: entries under params.docsy.plugins in your site configuration.
Configure Docsy’s plugins
| Plugin | What it does (Default / Loads on) | Learn more |
|---|---|---|
click-to-copy | Adds a copy button to code blocks (On, but off under Prism, which has its own / Every page) | Copy to clipboard |
tabpane-persist | Remembers the selected tab across pages (On / Every page (why)) | tabpane |
markmap | Renders markmap code blocks as mind maps (Off / Pages with a markmap code block) | Activating MarkMap support |
To turn a plugin off, set its enable field to false:
[params.docsy.plugins.click-to-copy]
enable = falseparams:
docsy:
plugins:
click-to-copy:
enable: false{
"params": {
"docsy": {
"plugins": { "click-to-copy": { "enable": false } }
}
}
}Configuration reference
Docsy’s own plugins are declared in the theme’s hugo.yaml;
your entries merge over them by name and field (Configuration § Theme
defaults). The schema defines each entry’s keys, required fields,
types, defaults, and syntactic patterns:
type: map
entries:
'plugins':
type: map # nonempty
key: # plugin name
type: string # coerced, lowercased
pattern: ^[a-z0-9_-]+$
reservedSuffix: _docsy-shim
value:
type: map
entries:
'defer': { type: bool, default: false } # coerced; adds `defer` to the script tag
'enable': { type: bool, required: true } # coerced
'version':
type: string # coerced
pattern: ^[0-9A-Za-z.+-]+$
- Fields are optional unless marked
required: true. {}for a theme plugin keeps every inherited field, includingenable.enableis off forfalse,"false", and0, and on for any other value;deferis on fortrue,"true", and1, and off for any other value. The string forms exist for environment overrides.
For guidance on using version, see
Dependency versions.
Warnings
Every registry shape warning carries the id docsy-config (to silence one, see
Configuration § Configuration warnings):
- An unknown field is ignored and the rest of the entry applies.
- A name the schema’s pattern rejects or that ends in its reserved suffix, a scalar entry, or an entry missing a required field drops the whole entry.
- A
params.docsyorparams.docsy.pluginsthat is not a map empties the registry, Docsy’s own plugins and their deprecated aliases included.plugins: {}keeps them; a valuelessplugins:is null and drops them. - An empty registry after configuration merging warns; a registry with all entries disabled is valid.
- An enabled name with no script file (Plugin files) is a
different fault: it warns
docsy-plugin-missing(a disabled entry is never looked up).
version validation applies to entries not already dropped by the shape guards,
including disabled entries. An exact X.Y.Z passes without a version warning;
another value matching the schema’s pattern, such as latest, warns under
NAME-floating-version, where NAME is the entry’s name. An empty or
malformed value fails the build and skips the entry before its companion runs.
For why Docsy pins versions, see Pinned script-dependency versions.
Add a custom script
For a script that should load at the end of every page, register it as a plugin;
for markup in <head>, inline snippets, or third-party tags, use the head and
body hooks instead.
- Save the script as
assets/js/plugins/NAME.js, withNAMEin lowercase. - Register it under
params.docsy.plugins(configuration reference):
[params.docsy.plugins.NAME]
enable = trueparams:
docsy:
plugins:
NAME:
enable: true{
"params": {
"docsy": {
"plugins": { "NAME": { "enable": true } }
}
}
}Plugin files
A project file shadows the theme’s of the same name, which is how you replace one of Docsy’s plugins, its companions, or its shim.
| File | Contract |
|---|---|
assets/js/plugins/NAME.js | Required. Built on its own with js.Build. |
layouts/_partials/scripts/plugins/NAME.html | Optional companion partial for vendored libraries, markup, or configuration; receives (dict "Page" PAGE "Plugin" ENTRY). |
assets/scss/plugins/NAME.scss | Optional companion stylesheet, through the Sass pipeline. |
layouts/_partials/scripts/plugins/NAME_docsy-shim.html | Optional shim partial; adjust a plugin per page. |
Companions emit before the script (why). Script and stylesheet tags carry subresource integrity in every environment. Entry keys reach templates lowercase (Configuration § Key spelling).
Adjust a plugin per page
A shim adjusts a plugin’s registry entry for each page before the plugin
loads. Add one for your own plugin, or for one of Docsy’s. Two of Docsy’s
plugins ship a shim, markmap and click-to-copy: your file replaces it, gate,
Prism guard, and deprecated-parameter handling included, so start from a copy of
the theme’s file, in scripts/plugins/.
Create layouts/_partials/scripts/plugins/NAME_docsy-shim.html, with the
plugin’s registry name as NAME (shim contract):
{{ $entry := .Plugin -}}
{{ if not (.Page.Store.Get "hasMyFeature") -}}
{{ $entry = merge $entry (dict "enable" false) -}}
{{ end -}}
{{ return $entry -}}
That shim loads the plugin only on pages that use it: a render hook of yours
sets the flag with .Page.Store.Set where the feature’s markup appears. Before
relying on a flag, read
Page flags in included content.
Dependency versions
The entry’s version selects a plugin dependency version. The companion partial
determines which dependency it refers to. The field does not automatically
identify the version of the plugin script itself or the Docsy theme.
For a custom plugin with a configurable dependency, set version on its
registry entry and read .Plugin.version in the companion partial. Use that
value to select the dependency’s code, for example in a build-time fetch URL.
Declaring version does not fetch code automatically. Omit the field if the
plugin has no dependency version to configure.
The entry’s version is not passed to the plugin script. For a working example
and instructions for overriding a theme-provided pin, see MarkMap
version.
Security
- Pin third-party dependencies on the entry’s
version, neverlatest. - Vendor build-time fetches and serve them with SRI.
- Use no loader that pulls unpinned secondary code, which SRI on the loader can’t cover.
- Load remote code only on pages that use it: gate the plugin with a shim.
Page flags in included content
Some plugins load only on pages that need them: Docsy’s markmap render hook
sets a page flag whenever a page has a markmap code block, and the plugin
ships where the flag is set. A flag counts only when it lands on the page whose
output the plugin is emitted into.
- A render hook runs in the context of the page being rendered, so a
markmapblock in content pulled in through.RenderShortcodesflags the page that includes it. - A shortcode runs in the context of the page whose file contains it, so a shortcode in included content would flag the included page, and the including page would never see the flag.
- Content pulled in through
.Contentflags the included page in both cases.
That is why Docsy ships tabpane-persist ungated, on every page: tabpanes come
from a shortcode. For MarkMap’s authoring paths and the remedy, see When a
MarkMap doesn’t render.
Feedback
Cette page est-elle utile?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.