Plugin to create block-level custom containers for markdown-it markdown parser


stars 🌟issues ⚠️updated 🛠created 🐣size 🏋️‍♀️
20Mar 6, 2021Aug 13, 2016Minified + gzip package size for @gerhobbelt/markdown-it-container in KB



Build Status NPM version Coverage Status

Plugin for creating block-level custom containers for markdown-it markdown parser.

v2.+ requires markdown-it v10.+, see changelog.

With this plugin you can create block containers like:

::: warning
*here be dragons*

.... and specify how they should be rendered. If no renderer defined, <div> with container name class will be created:

<div class="warning">
<em>here be dragons</em>

Markup is the same as for fenced code blocks. Difference is, that marker use another character and content is rendered as markdown markup.


node.js & bower:

$ npm install @gerhobbelt/markdown-it-container --save
$ bower install @gerhobbelt/markdown-it-container --save

browser (CDN):


// node.js
var md = require('@gerhobbelt/markdown-it')()
            .use(require('@gerhobbelt/markdown-it-container'), name [, options]);

// browser
var md =  window.markdownit()
            .use(window.markdownitContainer, name [, options]);


  • name - container name (mandatory)
  • options:
    • validate - optional, function to validate tail after opening marker, should return true on success.
    • render - optional, renderer function for opening/closing tokens.
    • content - optional, renderer function for the container content.
    • marker - optional (:), character/string to use in delimiter.
    • endMarker - optional (default: same as marker), character/string to use in terminating delimiter. Specify when the closing mark differs from the starting mark of your container.
    • minMarkerCount - optional (3), character/string repeated number to use in delimiter.


var options = {
  validate: function(params) {
    return params.trim().match(/^spoiler\s+(.*)$/);

  render: function (tokens, idx) {
    var m = tokens[idx].info.trim().match(/^spoiler\s+(.*)$/);

    if (tokens[idx].nesting === 1) {
      // opening tag
      return '<details><summary>' + md.utils.escapeHtml(m[1]) + '</summary>\n';

    } else {
      // closing tag
      return '</details>\n';

// node.js
var md = require('@gerhobbelt/markdown-it')();
md.use(require('@gerhobbelt/markdown-it-container'), 'spoiler', options);

// or browser
var md = window.markdownit();
md.use(window.markdownitContainer, 'spoiler', options);

console.log(md.render('::: spoiler click me\n*content*\n:::\n'));

// Output:
// <details><summary>click me</summary>
// <p><em>content</em></p>
// </details>

Example with markdown-it-attrs

You can use markdown-it-attrs syntax like '#my-id.my-class title="hello"'

var md = require('@gerhobbelt/markdown-it')();

  .use(require('@gerhobbelt/markdown-it-container'), 'decorate' , {
            validate: function(params) {
                return params.trim().match(/^(.*)$/);

            render: function (tokens, idx) {
                var m = tokens[idx].info.trim().match(/^(.*)$/);

                if (tokens[idx].nesting === 1) {
                    // opening tag
                    var fake=md.render('TMP_FOR_CONTAINER<!-- {'+ m[1]+'} -->')
                    return '<div '+ fake.substring(3,  fake.indexOf('>'))+'>\n';

                } else {
                    // closing tag
                    return '</div>\n';

console.log(md.render('::: #n.ok title=hello\nccc\n:::'));

// Output:
// <div id="n" class="ok" title="hello">
// <p>ccc</p>
// </div>



If you find any bugs or have a feature request, please open an issue on github!

The npm package download data comes from npm's download counts api and package details come from npms.io.