Skip to main content

How to Add Comments in Markdown

Markdown has no comment syntax, so there are two workarounds — and they hide your text to different depths. This guide covers both, which one actually keeps the text out of the published HTML, and the blank-line rule that makes comments leak onto the page.

Short answer

Use an HTML comment: <!-- your note -->. It works nearly everywhere and spans multiple lines. If the text must not appear in the generated HTML either, use an unused link label — [//]: # (your note) — with a blank line above and below it. In MDX, neither works; use {/* your note */}.

What “Hidden” Actually Means

Both methods hide text from the rendered page, and most guides stop there. But there are three different places your text can survive, and the two methods differ on the middle one. Picking the right method is entirely a question of which row you care about.

Where a Markdown comment remains readable, by method
Readable where?<!-- -->[//]: #
On the rendered pageNeither is visible to a reader of the page.NoNo
In the generated HTML sourceMost renderers pass HTML comments straight through. GitHub is the exception - its sanitizer drops comment nodes.Usually yesNo
In the raw .md fileAlways. Click Raw on GitHub, clone the repo, or open the file and it is right there.YesYes
A comment is never a secret. The bottom row is the one that matters: no method removes the text from the file. API keys, passwords, and internal notes about people do not belong in a Markdown comment, however well hidden the rendered page looks.

Method 1: HTML Comments

Markdown lets raw HTML through, so an HTML comment is a comment in Markdown too. This is the method to reach for by default: it is the most widely supported, it reads clearly to anyone who has written HTML, and it is the only one that spans multiple lines in a single construct.

A note on its own line

Markdown

Visible paragraph.

<!-- This note never appears on the page. -->

Another visible paragraph.

Preview

Visible paragraph.

Another visible paragraph.

Inline, in the middle of a sentence

Markdown

The build takes <!-- roughly --> two minutes.

Preview

The build takes two minutes.

The catch: the comment is still in the HTML the renderer produces

Markdown

Visible paragraph.

<!-- This note never appears on the page. -->

Another visible paragraph.

HTML output

<p>Visible paragraph.</p>
<!-- This note never appears on the page. -->
<p>Another visible paragraph.</p>
Invisible is not the same as absent. Nothing shows on the page, but the text is one View Source away on any site that publishes rendered Markdown. GitHub happens to strip comment nodes during sanitization, so READMEs and issues are clean — but a blog built with a static site generator usually ships them.

Commenting Out Multiple Lines

To park a whole draft section, wrap it in one HTML comment. Markdown inside <!-- --> is never parsed, so a commented-out heading does not become a heading and a commented-out list does not become a list — the entire block is skipped.

A whole block, headings and lists included

Markdown

<!--
## Draft section

This whole block is commented out, **formatting and all**.

- including
- this list
-->

Only this line renders.

Preview

Only this line renders.

The link-label method has no multi-line form, so you repeat it per line. Consecutive lines are fine — they do not need blank lines between them, only around the group as a whole.

One label per line

Markdown

[//]: # (First note.)
[//]: # (Second note.)
[//]: # (Third note - no blank lines needed between them.)

Visible text.

Preview

Visible text.

MDX, Docusaurus, Next.js and Astro

MDX parses your document as JSX, and <!-- is not valid there. An HTML comment is not ignored, and it does not render — it fails the build outright. Use a JavaScript comment inside braces instead.

Build error
<!-- This throws: Unexpected character "!" (U+0021) -->
Correct
{/* This is the only comment syntax MDX accepts. */}

<Callout>MDX content here.</Callout>
This catches people migrating a .md file to .mdx: content that rendered fine for years suddenly refuses to compile with Unexpected character “!” (U+0021). The fix is a find-and-replace of every <!-- --> to {/* */}.

Obsidian's Native %% Comments

Obsidian is the one popular Markdown tool that added a real comment syntax rather than leaving people to work around the gap. Wrap text in %% and it is shown in Editing view and hidden in Reading view. It works inline and across multiple lines.

Obsidian only
%% This whole line is an Obsidian comment. %%

Text with an %%inline%% comment in the middle.

%%
A block comment
spanning several lines.
%%
It does not travel. Outside Obsidian, nothing understands %% and the percent signs render as literal text. If the vault is ever published or pushed to GitHub, use HTML comments instead.

Common Mistakes

Four of these five make the comment appear on the page — the failure mode is always the same, because a link label that does not parse as a link label is just a line of text.

Broken

Some text here.
[//]: # (my comment)
More text here.

Fixed

Some text here.

[//]: # (my comment)

More text here.
This is the single most common reason a comment shows up on the page. A link label is a block-level construct, so it only counts as one when it starts its own block. Pressed up against a paragraph, it is swallowed as ordinary text and printed verbatim. Blank lines above and below are required.

Broken

[//]: # (my comment) and then more

Fixed

[//]: # (my comment)

and then more
Nothing may follow the closing parenthesis on the same line. A link label definition owns its whole line; add one character after it and the parser gives up and treats the entire line as a paragraph.

Broken

[//]: # (see the docs (page 4) for context)

Fixed

[//]: # (see the docs [page 4] for context)
The text in parentheses is parsed as a link title, and an unescaped inner parenthesis closes it early. The rest of the line then fails to parse and the whole comment renders literally. Use brackets, escape the parens as \( and \), or switch to the double-quoted form.

Broken

Some text.

    [//]: # (my comment)

More text.

Fixed

Some text.

[//]: # (my comment)

More text.
Four leading spaces turn any line into an indented code block, so the comment is not just visible - it is displayed in a monospace box as if it were sample code. Watch for this when pasting a comment into an already-indented list item.

Broken

<!-- API key for staging: sk_live_abc123 -->

Fixed

<!-- Staging credentials live in the team vault. -->
A comment is hidden from the rendered page, never from the file. Anyone who can click Raw on GitHub, clone the repo, or read the document source can read it. Treat everything you write in Markdown as public.

Quick Reference

Markdown comment syntax variants and where each applies
SyntaxWhere it appliesIn HTML output?
<!-- note -->Almost everywhere; multi-line and inlineUsually kept
[//]: # (note)CommonMark, GFM; own block onlyRemoved
[comment]: # (note)Same - any unused label worksRemoved
[//]: <> (note)Same, with an empty destinationRemoved
[//]: # "note"Same, double-quoted title formRemoved
{/* note */}MDX only - Docusaurus, Next.js, AstroRemoved
%% note %%Obsidian only; inline and blockRemoved

Platform Support

Comment support tracks how much HTML a renderer allows. Document tools allow enough. Chat apps allow none, which is why there is no way to hide text in a Discord or Slack message.

Markdown comment support by platform
PlatformSupported?Notes
GitHub / GitLabYesBoth methods work in READMEs, issues, PRs, and wikis. The sanitizer drops comment nodes, so they do not even reach the rendered page source - but the raw file is still public.
CommonMark / GFMYesHTML comments pass through into the HTML output. Unused link labels are discarded entirely, which is what makes the [//]: # trick leave no trace.
MDX (Docusaurus, Next.js, Astro)PartialOnly {/* comment */} works. An HTML comment is a hard build error: Unexpected character "!" (U+0021).
ObsidianYesHas its own native %%comment%% syntax that works inline and across lines. HTML comments work too.
VS Code previewYesBoth methods behave as in CommonMark. Ctrl+/ (Cmd+/) inserts an HTML comment.
Jupyter / R MarkdownYesHTML comments are hidden in rendered notebooks and knitted output alike.
Jekyll / Hugo / EleventyYesBoth work. Template comments ({% comment %}, {{/* */}}) strip earlier, at build time.
NotionPartialPasted HTML comments are dropped on import. Notion's own comments are a UI feature, not syntax.
RedditNoHTML is escaped, so <!-- --> shows up literally. Unused link labels are still discarded.
Discord / SlackNoNo HTML and no link labels. There is no way to hide text in a message.

Frequently Asked Questions

How do you do a comment in Markdown?

Markdown has no comment syntax of its own, so you use one of two workarounds. An HTML comment, <!-- like this -->, is the most widely supported and is what most people mean by a Markdown comment. The alternative is an unused link label: a line reading [//]: # (your note), with a blank line above and below it. Both are hidden from the rendered page.

How do I comment out multiple lines in Markdown?

Use a single HTML comment that spans the lines. Put <!-- on its own line before the block and --> on its own line after it, and everything in between is skipped, including headings, lists, and bold text. With the link-label method there is no multi-line form, so you write one [//]: # (line) per line - consecutive lines are fine and do not need blank lines between them.

What is the difference between an HTML comment and the [//]: # trick?

An HTML comment is passed through into the generated HTML in most renderers, so the text is readable in the page source even though it is invisible on screen. An unused link label is discarded by the parser and leaves no trace in the output at all. Use the HTML comment for notes to collaborators, and the link label when the text must not reach the published HTML.

Are Markdown comments really hidden?

Only from the rendered page. The comment is still in the .md file, so anyone who can read the file can read the comment - clicking Raw on GitHub is enough. Never put credentials, API keys, or anything sensitive in a Markdown comment.

Why is my Markdown comment showing up as text?

Almost always a missing blank line. The [//]: # (comment) form is a block-level construct, so it needs a blank line before and after it; if it sits directly under a paragraph it is absorbed into that paragraph and printed verbatim. The other common causes are text after the closing parenthesis, an unescaped parenthesis inside the comment, and four leading spaces, which turn the line into a code block.

Do HTML comments work in MDX?

No. MDX parses the document as JSX, where <!-- is not valid, so an HTML comment is a build error: Unexpected character "!" (U+0021). Use the JavaScript form in braces instead: {/* your comment */}. This applies to Docusaurus, Next.js MDX pages, Astro .mdx files, and anything else on the MDX pipeline.

Does Obsidian have a comment syntax?

Yes, and it is the one Markdown tool with a real native one. Wrap text in %% to comment it out: %%hidden%%. It works inline in the middle of a sentence and as a block across several lines. Obsidian comments are visible in Editing view and hidden in Reading view. HTML comments also work if you need the file to stay portable.

How do I comment out a heading or a list in Markdown?

Wrap the whole block in an HTML comment. Markdown inside <!-- --> is never parsed, so a commented-out ## heading does not become a heading and a commented-out list does not become a list - the entire block is skipped. This is the usual way to park a draft section without deleting it.

Can I put a comment inside a table or a list?

An HTML comment works inside a table cell and inside a list item. The link-label form works inside a list item and inside a blockquote, but it must still start its own block, so indent it to match the item and leave blank lines around it. Neither form works inside a fenced code block, where everything is shown as written.

Why does [comment]: # sometimes turn into a link?

Because it really is a link definition, not a comment. If the same label appears in the text later - writing [//] or [comment] in brackets somewhere - the parser matches the two and renders a real link, with your note exposed in its title attribute on hover. Pick a label you would never write in prose to avoid it.

Is there an official comment syntax in CommonMark?

No. Comments have been proposed on the CommonMark forum repeatedly and none has been adopted, which is why every method on this page is a workaround built out of some other feature. The HTML comment is the closest thing to a standard because HTML passthrough is part of the spec.

Do comments affect how AI tools read a Markdown file?

Usually not in the way people expect. A model reading the raw file - which is how coding agents read AGENTS.md, llms.txt, and README files - sees the comment text like any other line. Comments hide content from human readers of the rendered page, not from anything processing the source.