Skip to content

Using Shortcodes in Markdown ​

Shortcodes are simple snippets that let you embed complex functionality into your Markdown documents without writing HTML or complex code. They're commonly used in static site generators.

What are Shortcodes? ​

Shortcodes are placeholders that get replaced with rendered content during the build process. They typically look like this:

markdown
&#123;&#123;< shortcode-name param1="value1" >&#125;&#125;

or

&#123;&#123;% shortcode-name %&#125;&#125;
Content here
&#123;&#123;% /shortcode-name %&#125;&#125;

Common Shortcode Syntax Formats ​

Hugo Syntax ​

markdown
<!-- Self-closing -->
&#123;&#123;< youtube id="dQw4w9WgXcQ" >&#125;&#125;

<!-- With content -->
&#123;&#123;% note type="warning" %&#125;&#125;
This is important information!
&#123;&#123;% /note %&#125;&#125;

Jekyll/Liquid Syntax ​

markdown
{% youtube "dQw4w9WgXcQ" %}

{% highlight javascript %}
console.log("Hello World");
{% endhighlight %}

Gatsby/MDX Components ​

markdown
<YouTube videoId="dQw4w9WgXcQ" />

<Note type="warning">
  This is important information!
</Note>

Built-in Shortcodes ​

Hugo Built-in Shortcodes ​

Figure/Image ​

markdown
&#123;&#123;< figure src="/images/sunset.jpg" 
           title="Beautiful Sunset"
           caption="Taken in California"
           alt="Sunset over ocean"
           width="800" >&#125;&#125;

YouTube ​

markdown
&#123;&#123;< youtube dQw4w9WgXcQ >&#125;&#125;

<!-- With parameters -->
&#123;&#123;< youtube id="dQw4w9WgXcQ" autoplay="true" >&#125;&#125;

Twitter ​

markdown
&#123;&#123;< twitter user="github" id="1234567890" >&#125;&#125;

Instagram ​

markdown
&#123;&#123;< instagram BWNjjyYFxVx >&#125;&#125;

Gist ​

markdown
&#123;&#123;< gist username 0123456789abcdef >&#125;&#125;

Jekyll Built-in Tags ​

Highlight Code ​

markdown
{% highlight ruby linenos %}
def hello
  puts "Hello World"
end
{% endhighlight %}

Include Files ​

markdown
{% include header.html %}

{% include_relative ../shared/footer.html %}
markdown
{% post_url 2024-01-15-my-post %}

{% link _posts/2024-01-15-my-post.md %}

Creating Custom Shortcodes ​

Hugo Custom Shortcodes ​

Create a file in layouts/shortcodes/button.html:

html
<a href="&#123;&#123; .Get "url" &#125;&#125;" class="button &#123;&#123; .Get "style" &#125;&#125;">
  &#123;&#123; .Inner &#125;&#125;
</a>

Usage:

markdown
&#123;&#123;< button url="/docs" style="primary" >&#125;&#125;
Read Documentation
&#123;&#123;< /button >&#125;&#125;

More Complex Example ​

layouts/shortcodes/callout.html:

html
&#123;&#123; $type := .Get "type" | default "info" &#125;&#125;
<div class="callout callout-&#123;&#123; $type &#125;&#125;">
  <div class="callout-title">
    &#123;&#123; with .Get "title" &#125;&#125;&#123;&#123; . &#125;&#125;&#123;&#123; end &#125;&#125;
  </div>
  <div class="callout-content">
    &#123;&#123; .Inner | markdownify &#125;&#125;
  </div>
</div>

Usage:

markdown
&#123;&#123;% callout type="warning" title="Important" %&#125;&#125;
This is a **warning** message with *Markdown* support.
&#123;&#123;% /callout %&#125;&#125;

Jekyll Custom Tag ​

Create a plugin in _plugins/custom_tag.rb:

ruby
module Jekyll
  class CustomTag < Liquid::Tag
    def initialize(tag_name, params, tokens)
      super
      @params = params
    end

    def render(context)
      "<div class='custom-tag'>#{@params}</div>"
    end
  end
end

Liquid::Template.register_tag('custom', Jekyll::CustomTag)

Usage:

markdown
{% custom "My custom content" %}

Practical Shortcode Examples ​

Alert/Notice Boxes ​

markdown
&#123;&#123;% alert type="info" %&#125;&#125;
ℹ️ This is an informational message.
&#123;&#123;% /alert %&#125;&#125;

&#123;&#123;% alert type="warning" %&#125;&#125;
⚠️ This is a warning message.
&#123;&#123;% /alert %&#125;&#125;

&#123;&#123;% alert type="danger" %&#125;&#125;
🚨 This is a danger message.
&#123;&#123;% /alert %&#125;&#125;

Code Tabs ​

markdown
&#123;&#123;< tabs >&#125;&#125;
  &#123;&#123;< tab "JavaScript" >&#125;&#125;
  ```javascript
  console.log("Hello");

{{< /tab >}}

{{< tab "Python" >}}

python
print("Hello")

{{< /tab >}} {{< /tabs >}}


### Expandable Sections

```markdown
&#123;&#123;< expand "Click to expand" >&#125;&#125;
This content is hidden by default and can be expanded.

It can contain **any Markdown** including:
- Lists
- Code blocks
- Images
&#123;&#123;< /expand >&#125;&#125;

Embed External Content ​

markdown
<!-- CodePen -->
&#123;&#123;< codepen user="username" id="abcdefg" >&#125;&#125;

<!-- JSFiddle -->
&#123;&#123;< jsfiddle url="https://jsfiddle.net/username/abc123" >&#125;&#125;

<!-- CodeSandbox -->
&#123;&#123;< codesandbox id="abc123" >&#125;&#125;
markdown
&#123;&#123;< gallery >&#125;&#125;
  &#123;&#123;< img src="image1.jpg" caption="First image" >&#125;&#125;
  &#123;&#123;< img src="image2.jpg" caption="Second image" >&#125;&#125;
  &#123;&#123;< img src="image3.jpg" caption="Third image" >&#125;&#125;
&#123;&#123;< /gallery >&#125;&#125;

Table of Contents ​

markdown
&#123;&#123;< toc >&#125;&#125;

<!-- With options -->
&#123;&#123;< toc levels="2,3" >&#125;&#125;

Mermaid Diagrams ​

markdown
&#123;&#123;< mermaid >&#125;&#125;
graph TD;
    A-->B;
    A-->C;
    B-->D;
    C-->D;
&#123;&#123;< /mermaid >&#125;&#125;

Advanced Shortcode Patterns ​

Parameterized Shortcodes ​

markdown
<!-- Named parameters -->
&#123;&#123;< card title="My Title" 
         image="/images/card.jpg" 
         link="/read-more" 
         button="Learn More" >&#125;&#125;

<!-- Positional parameters -->
&#123;&#123;< youtube "dQw4w9WgXcQ" "16:9" >&#125;&#125;

Nested Shortcodes ​

markdown
&#123;&#123;< columns >&#125;&#125;
  &#123;&#123;< column size="6" >&#125;&#125;
    Left column content
  &#123;&#123;< /column >&#125;&#125;
  
  &#123;&#123;< column size="6" >&#125;&#125;
    Right column content
  &#123;&#123;< /column >&#125;&#125;
&#123;&#123;< /columns >&#125;&#125;

Conditional Rendering ​

Hugo example:

html
&#123;&#123; if .Get "show" &#125;&#125;
<div class="optional-content">
  &#123;&#123; .Inner &#125;&#125;
</div>
&#123;&#123; end &#125;&#125;

Accessing Page Variables ​

html
<!-- In shortcode template -->
<div class="page-info">
  <h3>&#123;&#123; .Page.Title &#125;&#125;</h3>
  <p>Last modified: &#123;&#123; .Page.Lastmod &#125;&#125;</p>
  <p>Reading time: &#123;&#123; .Page.ReadingTime &#125;&#125; minutes</p>
</div>

Shortcode Best Practices ​

  1. Keep It Simple: Shortcodes should be easy to remember and use
  2. Clear Naming: Use descriptive names that indicate functionality
  3. Documentation: Document all parameters and usage examples
  4. Error Handling: Provide sensible defaults and handle missing parameters
  5. Performance: Avoid complex computations in frequently used shortcodes
  6. Accessibility: Ensure generated HTML is accessible
  7. Mobile Friendly: Test shortcodes on mobile devices

Common Use Cases ​

Documentation ​

markdown
<!-- API endpoint documentation -->
&#123;&#123;< api method="GET" path="/api/users" >&#125;&#125;
Returns a list of all users.
&#123;&#123;< /api >&#125;&#125;

<!-- Parameter documentation -->
&#123;&#123;< param name="userId" type="string" required="true" >&#125;&#125;
The unique identifier for the user.
&#123;&#123;< /param >&#125;&#125;

E-learning ​

markdown
<!-- Quiz questions -->
&#123;&#123;< quiz >&#125;&#125;
  &#123;&#123;< question "What is 2+2?" >&#125;&#125;
    &#123;&#123;< answer correct="true" >&#125;&#125;4&#123;&#123;< /answer >&#125;&#125;
    &#123;&#123;< answer >&#125;&#125;3&#123;&#123;< /answer >&#125;&#125;
    &#123;&#123;< answer >&#125;&#125;5&#123;&#123;< /answer >&#125;&#125;
  &#123;&#123;< /question >&#125;&#125;
&#123;&#123;< /quiz >&#125;&#125;

Product Showcase ​

markdown
&#123;&#123;< product-card
     name="Premium Widget"
     price="$99.99"
     image="/products/widget.jpg"
     rating="4.5"
     reviews="245" >&#125;&#125;

Shortcodes vs. Components ​

FeatureShortcodesReact Components
Build Time✅ Rendered at build❌ Runtime
Interactivity❌ Static✅ Dynamic
Learning Curve✅ Simple⚠️ Moderate
Flexibility⚠️ Limited✅ High
Performance✅ Fast⚠️ Depends on bundle

Migrating from HTML to Shortcodes ​

Before (Raw HTML) ​

markdown
<div class="alert alert-warning" role="alert">
  <h4 class="alert-heading">Warning!</h4>
  <p>This is a warning message.</p>
</div>

After (Shortcode) ​

markdown
&#123;&#123;% alert type="warning" title="Warning!" %&#125;&#125;
This is a warning message.
&#123;&#123;% /alert %&#125;&#125;

Debugging Shortcodes ​

Hugo Debug ​

html
<!-- In shortcode template -->
&#123;&#123; printf "%#v" . &#125;&#125;

<!-- Print all params -->
&#123;&#123; range $key, $value := .Params &#125;&#125;
  &#123;&#123; $key &#125;&#125;: &#123;&#123; $value &#125;&#125;
&#123;&#123; end &#125;&#125;

Jekyll Debug ​

ruby
def render(context)
  puts "Debug: #{@params.inspect}"
  # ... rest of code
end

Performance Considerations ​

  1. Caching: Cache expensive computations
  2. Lazy Loading: Defer non-critical content
  3. Minimize API Calls: Batch requests when possible
  4. Optimize Images: Use appropriate sizes and formats
  5. Code Splitting: Load JavaScript only when needed

Conclusion ​

Shortcodes provide a powerful way to extend Markdown with custom functionality while keeping content files clean and maintainable. They're an essential tool for building modern static sites and documentation systems.

Additional Resources ​

Built by www.markdownlang.com