[{"data":1,"prerenderedAt":59},["Reactive",2],{"blog-post-markdown-comments-across-platforms":3},{"slug":4,"title":5,"description":6,"excerpt":7,"date":8,"category":9,"author":10,"keywords":11,"readingMinutes":12,"html":13,"headings":14,"tools":31,"related":33},"markdown-comments-across-platforms","Markdown Comments Across Platforms: Hidden, Stripped, or Still Sitting in Your HTML?","HTML comments in Markdown don't behave the same way everywhere. See which platforms actually remove them, which just hide them from rendering, and why that distinction matters for anything sensitive.","If you've read our guide to adding comments in Markdown, you already know the syntax: wrap text in \u003C!-- --> and it won't show up in the rendered output. That part is simple and it's the same…","2026-09-18","Tutorial","Matthew Rathbone","markdown comments, html comments markdown, markdown hidden text, jekyll comment tag, markdown comments github, markdown comments confluence, markdown comments notion",8,"\u003Cp>If you&#39;ve read our \u003Ca href=\"/blog/how-to-add-comments-in-markdown\">guide to adding comments in Markdown\u003C/a>, you already know the syntax: wrap text in \u003Ccode>&lt;!-- --&gt;\u003C/code> and it won&#39;t show up in the rendered output. That part is simple and it&#39;s the same everywhere.\u003C/p>\n\u003Cp>What isn&#39;t the same everywhere is what &quot;won&#39;t show up&quot; actually means. On some platforms, an HTML comment is truly deleted before the page is ever generated — it never exists in the shipped output at all. On others, it&#39;s just told not to \u003Cem>display\u003C/em>, while the literal text sits right there in the page&#39;s HTML source, visible to anyone who right-clicks and chooses &quot;View Page Source.&quot; And on a few platforms, the comment doesn&#39;t get hidden at all — it gets stripped so aggressively that the whole thing, syntax and content, just vanishes on import.\u003C/p>\n\u003Cp>Those are three genuinely different outcomes, and mixing them up is how internal notes end up leaking, or how a &quot;hidden&quot; TODO turns into a paragraph of literal \u003Ccode>&lt;!--\u003C/code> characters on a live page. This guide walks through what actually happens, platform by platform.\u003C/p>\n\u003Ch2 id=\"the-distinction-that-matters-removed-vs-hidden\">The distinction that matters: removed vs. hidden\u003C/h2>\n\u003Cp>Before the platform tour, it&#39;s worth naming the core difference explicitly, because it&#39;s the thing most comment tutorials skip.\u003C/p>\n\u003Cp>\u003Cstrong>Removed at build time\u003C/strong> means the comment&#39;s content never makes it into the file that gets served to a browser. If you view the page source, it&#39;s simply not there. This is what you want for anything you&#39;d be embarrassed to have a curious visitor stumble across — draft pricing, internal reviewer names, &quot;don&#39;t publish this until legal signs off,&quot; that kind of thing.\u003C/p>\n\u003Cp>\u003Cstrong>Hidden at render time\u003C/strong> means the comment&#39;s content \u003Cem>is\u003C/em> in the HTML that gets served — it&#39;s just wrapped in \u003Ccode>&lt;!-- --&gt;\u003C/code>, which browsers know not to display. A regular visitor won&#39;t see it in the rendered page. Anyone who opens dev tools or view-source will see it immediately, in plain text.\u003C/p>\n\u003Cp>Standard HTML comments (\u003Ccode>&lt;!-- like this --&gt;\u003C/code>) are almost always the second kind, not the first. That&#39;s true no matter what Markdown processor you&#39;re using, because Markdown itself doesn&#39;t do anything special with HTML comments — it passes them through untouched, and it&#39;s the browser, not Markdown, that decides not to render them visually. The confusion comes from platforms that layer a \u003Cem>build system\u003C/em> on top of Markdown, because some of those build systems have their own, separate comment syntax that behaves differently. More on that below.\u003C/p>\n\u003Ch2 id=\"platform-by-platform-behavior\">Platform-by-platform behavior\u003C/h2>\n\u003Ch3 id=\"github--repo-files-vs-issuesprs\">GitHub — repo files vs. Issues/PRs\u003C/h3>\n\u003Cp>In a rendered file (a README, a wiki page, anything under a repo&#39;s Markdown rendering), HTML comments are hidden-not-removed: view the raw file (\u003Ccode>?raw=true\u003C/code> or the &quot;Raw&quot; button) and the comment text is right there. This is expected and fine for a public repo, since anyone can already read your whole file&#39;s raw source anyway — there&#39;s no secret being kept from anyone.\u003C/p>\n\u003Cp>Issues and pull requests behave the same way but get used differently in practice: GitHub&#39;s own issue and PR templates use HTML comments as instructional placeholder text (\u003Ccode>&lt;!-- Please describe the change and link any related issues --&gt;\u003C/code>). Once submitted, that instructional text is hidden in the rendered comment, exactly as designed — but it&#39;s still sitting in the issue body&#39;s raw Markdown, retrievable via the API or an &quot;Edit&quot; click. Don&#39;t put anything in a PR template comment you wouldn&#39;t want a bot or a scraper reading back to you later.\u003C/p>\n\u003Ch3 id=\"gitlab\">GitLab\u003C/h3>\n\u003Cp>Functionally identical to GitHub for both files and merge request descriptions — HTML comments hide in rendered view, remain fully present in the raw Markdown. GitLab also uses the same instructional-placeholder-comment pattern in its default MR templates.\u003C/p>\n\u003Ch3 id=\"npm-and-pypi-package-pages\">npm and PyPI package pages\u003C/h3>\n\u003Cp>Both npmjs.com and pypi.org render your \u003Ccode>README.md\u003C/code> for the package listing page using largely the same rendering assumptions as GitHub. HTML comments are hidden from the rendered listing but present in the page&#39;s HTML source — worth remembering if your README&#39;s HTML comments contain anything like internal build notes or unpublished feature flags.\u003C/p>\n\u003Ch3 id=\"jekyll-this-sites-own-engine--and-why-its-a-special-case\">Jekyll (this site&#39;s own engine) — and why it&#39;s a special case\u003C/h3>\n\u003Cp>This is where the removed-vs-hidden distinction stops being theoretical, because Jekyll gives you \u003Cem>both\u003C/em> options, and they&#39;re not interchangeable.\u003C/p>\n\u003Cp>A plain HTML comment in a Jekyll post behaves like everywhere else — hidden from the rendered page, present in the shipped HTML:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-markdown\">&lt;!-- This survives the build and sits in the final HTML, just invisible --&gt;\n\u003C/code>\u003C/pre>\u003Cp>But Jekyll&#39;s Liquid templating layer also has its own comment tag, and it works completely differently:\u003C/p>\n\u003Cpre>\u003Ccode class=\"hljs language-liquid\">{% comment %}\nThis text is deleted during the build. It never appears\nanywhere in the generated _site output, not even in the source.\n{% endcomment %}\n\u003C/code>\u003C/pre>\u003Cp>\u003Ccode>{% comment %}...{% endcomment %}\u003C/code> content is stripped by Jekyll itself, before the HTML is ever written to disk. That&#39;s the actual &quot;removed at build time&quot; behavior — genuinely useful for author-only notes you don&#39;t want in your Git-hosted output at all, as opposed to notes you&#39;re fine with a curious reader finding in view-source.\u003C/p>\n\u003Cp>The catch: \u003Ccode>{% comment %}\u003C/code> only works in files Jekyll actually processes through Liquid (posts and pages with front matter). It does nothing useful inside a fenced code block meant to \u003Cem>display\u003C/em> Liquid syntax as an example — in fact, unescaped \u003Ccode>{% %}\u003C/code> or \u003Ccode>{{ }}\u003C/code> inside a code sample is exactly the class of bug we&#39;ve written about \u003Ca href=\"/blog/why-your-markdown-isnt-rendering\">in our own troubleshooting guide\u003C/a>, where Jekyll tries to execute what you meant as illustrative text.\u003C/p>\n\u003Ch3 id=\"hugo\">Hugo\u003C/h3>\n\u003Cp>Hugo has the same two-tier structure as Jekyll, just with different names. Plain HTML comments behave like everywhere else: hidden, not removed. Hugo templates additionally support Go template comments (\u003Ccode>{{/* like this */}}\u003C/code>) for \u003Ccode>.html\u003C/code> layout files, which are stripped at build time — but that syntax is a layout-file feature, not something you write inside your Markdown content itself. If you&#39;re commenting inside a Markdown post body on a Hugo site, you&#39;re almost always using the plain HTML form, which means: hidden, not removed.\u003C/p>\n\u003Ch3 id=\"mkdocs-docusaurus-and-other-static-site-generators\">MkDocs, Docusaurus, and other static-site generators\u003C/h3>\n\u003Cp>These follow the same general rule as Jekyll and Hugo&#39;s content layer: they pass HTML comments through to the rendered HTML untouched. The comment is hidden visually but present in source. Docusaurus (React/MDX-based) is worth a specific flag: because MDX treats \u003Ccode>{\u003C/code> as the start of a JavaScript expression, curly-brace syntax in prose can trigger build errors in ways plain Jekyll/Hugo content doesn&#39;t — a separate gotcha from the comment-visibility question, but one that trips up the same audience.\u003C/p>\n\u003Ch3 id=\"confluence\">Confluence\u003C/h3>\n\u003Cp>Confluence doesn&#39;t render Markdown to HTML the way the platforms above do — it converts to its own storage format, and as \u003Ca href=\"/blog/markdown-in-confluence-what-works\">our Confluence guide\u003C/a> documents, raw HTML gets stripped or escaped on import rather than preserved. In practice, that means an HTML comment pasted into Confluence&#39;s \u003Ccode>/markdown\u003C/code> panel usually doesn&#39;t survive as a hidden comment at all — it&#39;s either dropped entirely or shows up as literal, visible \u003Ccode>&lt;!--\u003C/code> text, depending on the import path. If you need a genuinely hidden internal note in Confluence, use a real Confluence feature built for it (an inline comment, or the \u003Ccode>{noformat}\u003C/code>/expand macros) rather than relying on Markdown syntax that the platform was never built to honor.\u003C/p>\n\u003Ch3 id=\"notion\">Notion\u003C/h3>\n\u003Cp>Notion strips raw HTML entirely on import, and that includes comment syntax — it&#39;s not a &quot;hidden but present&quot; situation, it&#39;s a &quot;gone&quot; situation, per \u003Ca href=\"/blog/markdown-for-notion-what-actually-works\">our Notion compatibility guide\u003C/a>. If you need a genuinely invisible internal note inside a Notion page, Notion&#39;s own commenting feature (select text, add a comment) is the tool for that job, not an HTML comment carried over from a Markdown file.\u003C/p>\n\u003Ch3 id=\"obsidian\">Obsidian\u003C/h3>\n\u003Cp>Obsidian is the one platform on this list where &quot;hidden vs. removed&quot; barely applies, because there&#39;s no build/publish step by default — you&#39;re just looking at your own local file. In Reading view, an HTML comment is hidden the same way it would be in a browser. In Source/Live Preview mode, you see it as plain text, since you&#39;re literally looking at the file. Nothing is ever removed; it&#39;s your file, sitting on your disk, exactly as you typed it, until you delete it yourself.\u003C/p>\n\u003Ch3 id=\"vs-code-markdown-preview\">VS Code Markdown Preview\u003C/h3>\n\u003Cp>The simplest case on this list: the built-in preview pane hides HTML comments, the editor pane shows them, because you&#39;re editing a plain local file and the preview is just a live render of it — no build step, no publish step, nothing gets removed.\u003C/p>\n\u003Ch2 id=\"quick-reference\">Quick reference\u003C/h2>\n\u003Cdiv class=\"table-responsive\">\u003Ctable class=\"table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Platform / context\u003C/th>\n\u003Cth>HTML comment behavior\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\u003Ctr>\n\u003Ctd>GitHub (files, Issues, PRs)\u003C/td>\n\u003Ctd>Hidden in render, present in raw source\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>GitLab (files, MRs)\u003C/td>\n\u003Ctd>Hidden in render, present in raw source\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>npm / PyPI README\u003C/td>\n\u003Ctd>Hidden in render, present in page source\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Jekyll — \u003Ccode>&lt;!-- --&gt;\u003C/code>\u003C/td>\n\u003Ctd>Hidden in render, present in shipped HTML\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Jekyll — \u003Ccode>{% comment %}\u003C/code>\u003C/td>\n\u003Ctd>Removed entirely at build time\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Hugo — \u003Ccode>&lt;!-- --&gt;\u003C/code> in content\u003C/td>\n\u003Ctd>Hidden in render, present in shipped HTML\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Hugo — \u003Ccode>{{/* */}}\u003C/code> in layouts\u003C/td>\n\u003Ctd>Removed entirely at build time\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>MkDocs / Docusaurus\u003C/td>\n\u003Ctd>Hidden in render, present in shipped HTML\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Confluence\u003C/td>\n\u003Ctd>Usually dropped or shown literally — not reliably hidden\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Notion\u003C/td>\n\u003Ctd>Stripped entirely on import\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Obsidian\u003C/td>\n\u003Ctd>Nothing removed — visible in Source mode, hidden in Reading view\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>VS Code preview\u003C/td>\n\u003Ctd>Hidden in preview pane, visible in editor pane\u003C/td>\n\u003C/tr>\n\u003C/tbody>\u003C/table>\u003C/div>\n\u003Ch2 id=\"what-this-means-in-practice\">What this means in practice\u003C/h2>\n\u003Cp>Two practical takeaways follow directly from the table above.\u003C/p>\n\u003Cp>\u003Cstrong>Never treat an HTML comment as a privacy or security boundary.\u003C/strong> On the majority of platforms here, &quot;hidden&quot; means &quot;not displayed,&quot; not &quot;not present.&quot; Anything sensitive — API keys, internal pricing, a note about a security issue you haven&#39;t disclosed yet — needs to actually not be in the file at all, or needs to live somewhere with real access control. If you&#39;re publishing through Jekyll or Hugo specifically and want a note that genuinely never reaches the output, use the templating engine&#39;s own comment tag (\u003Ccode>{% comment %}\u003C/code> or \u003Ccode>{{/* */}}\u003C/code>), not a plain HTML comment.\u003C/p>\n\u003Cp>\u003Cstrong>Don&#39;t assume a comment will survive a platform migration.\u003C/strong> If you&#39;re moving content from a Git-based Markdown workflow into Confluence or Notion, any HTML comments you were relying on for editorial notes, TODOs, or draft flags will very likely not make the trip — either they&#39;ll vanish silently or, worse, show up as visible clutter. Strip them out (or convert them to that platform&#39;s native commenting feature) before you migrate, rather than after someone notices.\u003C/p>\n\u003Cp>You can test any of this yourself before committing to a workflow: paste Markdown containing comments into the \u003Ca href=\"/tools/markdown-editor\">Markdown Live Preview Editor\u003C/a> and check both the rendered pane and the raw output. It won&#39;t simulate a Confluence or Notion import, but it will immediately confirm the base case — hidden in render, present in source — that every platform above starts from before adding its own quirks on top.\u003C/p>\n\u003Ch2 id=\"related-reading\">Related reading\u003C/h2>\n\u003Cul>\n\u003Cli>\u003Ca href=\"/blog/how-to-add-comments-in-markdown\">How to Add Comments in Markdown\u003C/a> — the syntax fundamentals this guide builds on\u003C/li>\n\u003Cli>\u003Ca href=\"/blog/why-your-markdown-isnt-rendering\">Why Your Markdown Isn&#39;t Rendering\u003C/a> — troubleshooting for when template syntax gets executed instead of displayed\u003C/li>\n\u003Cli>\u003Ca href=\"/blog/markdown-in-confluence-what-works\">Markdown in Confluence: What Actually Works\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"/blog/markdown-for-notion-what-actually-works\">Markdown for Notion: What Actually Works and What Doesn&#39;t\u003C/a>\u003C/li>\n\u003Cli>\u003Ca href=\"/blog/markdown-platform-compatibility-guide\">Markdown Across Platforms: The Compatibility Guide\u003C/a>\u003C/li>\n\u003C/ul>\n",[15,19,22,25,28],{"id":16,"text":17,"level":18},"the-distinction-that-matters-removed-vs-hidden","The distinction that matters: removed vs. hidden",2,{"id":20,"text":21,"level":18},"platform-by-platform-behavior","Platform-by-platform behavior",{"id":23,"text":24,"level":18},"quick-reference","Quick reference",{"id":26,"text":27,"level":18},"what-this-means-in-practice","What this means in practice",{"id":29,"text":30,"level":18},"related-reading","Related reading",[32],"markdown-editor",[34,43,52],{"slug":35,"title":36,"description":37,"excerpt":38,"date":39,"category":40,"author":41,"keywords":42,"readingMinutes":12},"markdown-callouts-admonitions-across-platforms","Markdown Callouts and Admonitions Across Platforms: What Actually Renders","GitHub's > [!NOTE] alert syntax, Obsidian's callouts, and MkDocs's admonition extension all look like variations on a theme — but they're three genuinely different syntaxes that mostly don't cross-render. Here's what works where.","Type > [!NOTE] into a Markdown file and on GitHub you get a styled, icon-prefixed callout box. Paste that exact same text into a plain CommonMark renderer, a Jekyll site with no plugin, or an…","2026-08-28","workflows","Matt Rathbone","markdown callouts, github alerts, obsidian callouts, mkdocs admonitions, docusaurus admonitions, markdown warning box across platforms",{"slug":44,"title":45,"description":46,"excerpt":47,"date":48,"category":49,"author":10,"keywords":50,"readingMinutes":51},"markdown-footnotes-across-platforms","Markdown Footnotes Across Platforms: Where They Actually Render","GitHub, GitLab, Obsidian, and this very blog render [^1] footnotes natively — Notion, Slack, Jira, and Confluence don't support them at all. A platform-by-platform reference for where footnote syntax actually works.","Footnote syntax — a reference marker like [^1] in the body text, paired with a definition [^1]: The actual note. elsewhere in the document — looks the same everywhere you write it. Whether it…","2026-09-25","Reference","markdown footnotes across platforms, github footnotes, gitlab footnotes, notion footnotes, obsidian footnotes support",5,{"slug":53,"title":54,"description":55,"excerpt":56,"date":57,"category":40,"author":41,"keywords":58,"readingMinutes":12},"markdown-image-sizing-alignment-across-platforms","Markdown Image Sizing and Alignment Across Platforms: What Actually Works","Wrapping an image in a sized, centered \u003Cimg> tag works great in GitHub — but paste that same Markdown into Notion or Slack and the HTML just vanishes. Here's which platforms honor inline HTML for images, which have their own separate syntax, and which need attachments instead.","Standard Markdown's image syntax — — has no way to control size or alignment. There's no width=, no center, nothing. So the moment you need a smaller image, or one centered on the page instead of…","2026-09-04","markdown image size, markdown image alignment, resize image markdown, center image markdown, obsidian image size, notion image markdown, markdown image html platforms",1792184947062]