Complete Guide to Markdown Tags: Inline Tags and Front Matter Tags

When people talk about Markdown tags, the first reaction is usually "isn't that a blog-only feature?" Fair point — John Gruber's original Markdown spec didn't include tags at all [^1]. But as Markdown has become the go-to format for managing notes, writing blogs, and maintaining documentation, tags have become essential. You need some way to organize hundreds of articles by topic.

This article covers everything about Markdown tags: how to write inline tags (#tag), how to use the tags field in Front Matter, what the differences are across platforms, and how to pick good tag names.

Markdown Tags Quick Reference

Here's an overview table for quick lookup. Each type is explained in detail below.

Tag TypeSyntaxUse CaseTypical Platform
Inline tag#tagnameTag anywhere in textObsidian, Logseq
Nested tag#parent/childOrganize tags hierarchicallyObsidian
Front Matter listtags: [a, b]Article-level metadataJekyll, Hugo, VitePress
Front Matter multilinetags: + - aSame, for many tagsSame
Front Matter stringtags: a b cSpace-separated (Jekyll only)Jekyll

Key insight: Markdown tags are not part of the original spec. They're implemented by individual tools (static site generators, note-taking apps), so syntax and behavior vary across platforms. Let's break them down into two categories.

Inline Tags: Tag as You Write

Inline tags are #tagname written directly in the Markdown body. They look like social media hashtags, but functionally they're for categorizing notes.

Obsidian Inline Tags

Obsidian has the most mature inline tag support. Write #tagname anywhere in your text and Obsidian automatically recognizes it, showing it in the left tag panel [^2].

Learned the basics of Markdown syntax today #markdown
This note is related to JavaScript #javascript

A few detail rules:

  1. Must be preceded by a space or start of linethis is#tag won't be recognized, this is #tag will
  2. Cannot be followed immediately by regular text#tagtext only recognizes #tag (space marks the end)
  3. No spaces allowed#my tag only recognizes #my; use #my_tag or #my-tag instead
  4. Case-insensitive#Markdown and #markdown are the same tag
  5. Numbers are allowed#2026plan is valid, but pure numbers like #123 may not work in some versions

Nested Tags: Organize with Slashes

Obsidian supports nested tags using /, essentially creating a folder structure for your tags [^2]:

#inbox/to-read
#inbox/to-process
#project/frontend
#project/backend

In the tag panel, #inbox will show to-read and to-process as collapsible sub-tags. Searching for #inbox also matches all child tags. This is incredibly useful once you have many tags — a flat list of hundreds of tags is impossible to navigate.

There's no hard limit on nesting depth, but in practice two to three levels is enough. Going deeper just adds management overhead.

Limitations of Inline Tags

The biggest issue with inline tags is tool dependency. The #tag syntax means nothing to static site generators like Jekyll or Hugo — they only read metadata from Front Matter. On GitHub, #tag would be rendered as an H1 heading.

So if you use Obsidian for note-taking, inline tags are convenient. But if your files will be published to a blog or GitHub, you'll still need Front Matter tags.

Front Matter Tags: Categorize in Metadata

Front Matter tags are the tags field written in the YAML header, used to tag the entire article. This is the approach supported by most static site generators and tools.

YAML List Syntax

Two equivalent formats — pick whichever you prefer:

Inline style (for a small number of tags):

---
title: Markdown Tags Guide
tags: [markdown, tags, tutorial]
---

Multiline style (for many tags):

---
title: Markdown Tags Guide
tags:
  - markdown
  - tags
  - tutorial
---

I personally prefer the multiline style because adding or removing tags produces cleaner Git diffs — you won't have an entire array changed in one line.

Jekyll's Space-Separated Syntax

Jekyll has a unique way of writing tags — as a space-separated string [^3]:

---
title: My Article
tags: markdown tags tutorial
---

Only Jekyll understands this format. Hugo, Hexo, and VitePress all require array syntax. From my testing, Jekyll also correctly parses the array format tags: [a, b], so using arrays in Jekyll projects works fine and has better cross-platform compatibility.

Hugo's Multi-Format Support

Hugo is one of the few static site generators that supports three front matter formats [^4]:

---
title: My Article
tags: [markdown, tags]
---
# TOML
+++
title = "My Article"
tags = ["markdown", "tags"]
+++
# JSON (rarely used)
{
  "title": "My Article",
  "tags": ["markdown", "tags"]
}

In all three formats, Hugo treats tags as a taxonomy, automatically generating tag pages like /tags/markdown/.

Combining Both Tag Types in Obsidian

Obsidian is unique — it supports both inline tags and Front Matter tags, and merges them into the same system [^2]. Whether you write #javascript in the body or tags: [javascript] in the front matter, Obsidian groups them under the same javascript entry in the tag panel.

So how should you choose between the two? My approach:

  • Front Matter tags for article-level classification — what this article "is about", like tags: [tutorial, markdown, frontend]
  • Inline tags for paragraph-level markers — what this section "involves", like #review-later #important #bug

The benefit of this split: Front Matter tags are great for batch searching "all tutorial articles", while inline tags help you quickly locate "which paragraphs are marked as important" while reading.

Markdown Tag Naming Rules

Regardless of which tag format you use, there are some universal rules for naming. These are lessons I learned the hard way.

Allowed Characters

CharacterInline TagsFront Matter TagsNotes
Chinese charactersObsidian supports Chinese tags perfectly
English letters
Numbers
Underscore _Used as space replacement
Hyphen -
Slash /✅ (Obsidian)Used for nested hierarchy in inline tags
Space✅ (with quotes)Inline tags break at spaces
#✅ (with quotes)Conflicts with inline tag prefix

Naming Tips

Keep it short — a tag is not a description. Two to four words is plenty. #frontend beats #frontend-development-tech-stack any day.

Be consistent — use either all Chinese (#前端) or all English (#frontend). Mixing makes the tag panel messy. I used to mix #javascript and #前端, and when I wanted to find all frontend-related notes, they were scattered across two different tags.

Avoid synonyms#js and #javascript are two different tags. Pick one and stick with it. You can delete the less-used one from the tag panel — Obsidian will remind you which notes used it.

Platform Comparison for Markdown Tags

A single table showing tag support across platforms:

FeatureObsidianJekyllHugoHexoMkDocs Material
Inline tags
Nested tags✅ (paid)
Front Matter tags
Auto tag pages
YAML array format
TOML format
Tag panel/indexPlugin neededPlugin needed

One point that confuses people: the difference between tags and categories. In Hexo and Jekyll, categories are hierarchical (an article belongs to one category chain), while tags are flat (an article can have multiple tags) [^3]. Obsidian doesn't make this distinction — it only has tags.

Frequently Asked Questions

What's the difference between tags and keywords in Front Matter?

tags are classification labels used to organize content, typically displayed as clickable tag links on a website. keywords are SEO keywords written in the HTML meta tag and not shown on the page. Some themes use tags as SEO keywords too, but semantically they're different things.

What if I have too many tags?

Tag sprawl is a real problem. Once I was organizing my notes and found over 200 tags in the panel, half of which had only been used once. Here's what I did:

  1. Merge synonyms — combined #js, #JS, and #javascript into #javascript
  2. Remove low-frequency tags — tags used only 1-2 times were either merged into broader tags or deleted
  3. Replace flat tags with nested tags — changed #css #css-animation #css-layout to #css/animation #css/layout

The goal is to keep tags under 50, with each tag linked to at least 3 articles.

What about the conflict between inline tags and Markdown headings?

In standard Markdown, lines starting with # are H1 headings. So #tag would be rendered as a heading on GitHub or GitLab, not a tag. Only note-taking tools like Obsidian and Logseq treat #word in the body as a tag.

If your Markdown files need to work across multiple platforms, keep inline tags for Obsidian only and use Front Matter tags for anything you're publishing.

Honestly, the syntax itself is just a few lines, but the gotchas are all in the details. Figure out which platform your files will end up on, pick the right tag format, and stick to consistent naming habits. Your tag system will actually help you instead of adding chaos.

References

[^1]: John Gruber, Markdown: Syntax, Daring Fireball — The original Markdown spec does not define tags [^2]: Obsidian Help, Tags, help.obsidian.md — Official Obsidian tag documentation [^3]: Jekyll Documentation, Front Matter Defaults, jekyllrb.com — How Jekyll handles tags and categories [^4]: Hugo Documentation, Front Matter, gohugo.io — Hugo's three front matter formats and taxonomies support