How to adjust markdown heading levels for confluence pages
- Step 1Get the page Markdown — Copy or export the Markdown destined for Confluence. Free handles up to 1 MB / 500,000 characters per file.
- Step 2Set delta to +1 — Enter
+1(the default) to demote the body one level so its top heading becomes##, leaving the H1 slot for Confluence's page title. - Step 3Run the demotion — Process the file. Recognized ATX headings demote in one pass; frontmatter and fenced code blocks are untouched.
- Step 4Confirm no body H1 remains — Verify the body no longer contains a
#heading so the imported page has a single H1 — the Confluence title. - Step 5Convert to wiki markup if needed — If your import path uses Atlassian wiki syntax (not Markdown), run the demoted output through md-to-jira to produce
h2./h3.wiki headings. - Step 6Import to Confluence — Paste or import the result. For newer Confluence that accepts Markdown directly, paste the demoted Markdown; for the wiki-markup path, paste the converted output.
Confluence import paths and what to run
Confluence renders the page title as H1 in every case. Pick the path that matches how you import.
| Import path | Demote (this tool)? | Convert with md-to-jira? | Result |
|---|---|---|---|
| Paste Markdown (newer Confluence) | Yes (delta +1) | No | Body nests under the page title; Markdown rendered natively |
| Insert → Markup → Wiki markup | Yes (delta +1) | Yes | h2./h3. wiki headings under the page title |
| Bulk page import via Markdown | Yes (delta +1) | Depends on importer | Single-H1 pages; check importer docs for syntax |
| Already body-starts-at-H2 source | No (delta 0) | Optional | No demotion needed; top is already ## |
Heading map for the +1 Confluence demotion
Each body heading drops one level so the page title fills the H1 role.
| Body before | Body after (delta +1) | Markdown before | Markdown after |
|---|---|---|---|
| H1 (body title) | H2 (section) | # | ## |
| H2 (section) | H3 (subsection) | ## | ### |
| H3 | H4 | ### | #### |
| H6 (deepest) | H6 (clamped) | ###### | ###### |
Output format clarification
This tool shifts levels only — it does not convert to Confluence wiki syntax. Use the right tool for each step.
| Task | Tool | Output |
|---|---|---|
| Demote heading levels | md-heading-shifter (this tool) | Markdown with shifted # levels |
| Convert to Atlassian wiki markup | md-to-jira | Jira/Confluence wiki syntax (h2., *bold*) |
| Generate a page TOC after shifting | md-toc-generator | Markdown with an inserted contents list |
Cookbook
Before/after demotions for Confluence imports. Run delta +1 so the page title owns the H1; convert to wiki markup separately if your path needs it.
Runbook with its own H1 imported to Confluence
Your runbook opens with # Incident Response. Confluence renders the page title as H1, so demote the body one level first.
Input: # Incident Response ## Detection ## Mitigation Output (delta = +1): ## Incident Response ### Detection ### Mitigation
Demote, then convert to wiki markup
For the wiki-markup import path, demote first, then run the result through md-to-jira. This shows the demoted Markdown that feeds the converter.
Input: # Architecture ## Services After demote (delta = +1): ## Architecture ### Services (then md-to-jira →) h2. Architecture h3. Services
Runbook with shell commands
A # stop the service comment inside a fenced block is preserved while the real headings demote — important for copy-paste-able runbooks.
Input: # Restart Procedure ```bash # stop the service systemctl stop app ``` Output (delta = +1): ## Restart Procedure ```bash # stop the service systemctl stop app ```
Frontmatter from a docs repo survives
If the page came from a docs repo with YAML frontmatter, it is split off and preserved while the body demotes.
Input: --- space: ENG labels: [oncall] --- # On-Call Guide ## Escalation Output (delta = +1): --- space: ENG labels: [oncall] --- ## On-Call Guide ### Escalation
Page that already starts at H2
If a page was authored starting at H2, no demotion is needed — a delta of 0 leaves it as-is so it does not over-nest under the Confluence title.
Input: ## Overview ### Details Output (delta = 0): ## Overview ### Details
Edge cases and what actually happens
Expecting wiki markup output
Not supportedThis tool outputs Markdown with shifted heading levels — it does not produce Confluence wiki syntax (h2., {code}). If your import path needs wiki markup, run the demoted Markdown through md-to-jira as a second step.
Page already starts at H2
ExpectedSome teams author Confluence-bound pages starting at ##. A +1 demotion there pushes sections to ### and over-nests them under the page title. Check the current top level and use delta 0 if the body already starts at H2.
Deepest sections at H6
ClampedHeadings at H6 stay at H6 on a +1 demote due to the min(6, ...) clamp. A page using both H5 and H6 will see the H5 merge into H6 — review long runbooks after demoting.
`#` comment inside a fenced block
PreservedRunbook code samples often contain # comment lines. Inside a ``` ``` fence these are copied verbatim and never demoted, so pasted commands stay correct.
Frontmatter present
PreservedYAML (---) or TOML (+++) frontmatter is split off and re-attached unchanged. Confluence ignores frontmatter on import, but it is preserved here so the source stays valid in your repo.
Setext (underline) heading
Not supportedUnderline-style headings are not recognized and will not demote, leaving a stray top-level heading after the body shifts. Convert to ATX # first with md-prettifier.
`#label` with no space
PreservedA hash glued to text is not a heading and is never demoted — so inline tags and code-like tokens survive untouched.
Anchor links between sections
PreservedAnchor slugs come from heading text, not level, so internal links keep resolving after demotion. Confluence rebuilds its own page anchors on import regardless.
Multiple H1s in the source
By designAll # H1s demote to ##. The tool does not warn about duplicate H1s; the uniform +1 simply removes every body H1, which is what a clean Confluence page needs.
Page over the tier character limit
RejectedFree caps a single file at 1 MB / 500,000 characters. Large knowledge-base pages are rejected up front; upgrade to Pro (10 MB / 5,000,000 characters) or split with md-splitter.
Frequently asked questions
How do I prepare Markdown headings for a Confluence import?
Set delta = +1 and run. That demotes the body one level so the Confluence page title (rendered as H1) is the only top-level heading, with your sections nesting beneath at H2 and below.
Does this tool output Confluence wiki markup?
No. It outputs Markdown with the heading levels shifted. If your import path needs Atlassian wiki syntax (h2., *bold*), run the demoted Markdown through md-to-jira as a separate step.
Why demote by one level for Confluence?
Confluence renders the page title as the page's H1. A body that also opens with # creates a duplicate top-level heading, which clutters the page outline. Demoting by one keeps a single H1 — the page title.
Should I also run the Jira/Confluence converter?
Only if your import path uses wiki markup. Newer Confluence accepts Markdown paste directly, so demote and paste. For the wiki-markup path, demote first, then convert with md-to-jira.
Will my frontmatter be preserved?
Yes. YAML and TOML frontmatter is split off and re-attached unchanged. Confluence ignores it on import, but keeping it preserves the source file's validity in your repo.
What about Confluence's heading limits?
Confluence supports H1-H6 like standard Markdown. This tool clamps at H6, so an H6 heading cannot demote further — it stays at H6.
Are code blocks in my runbook safe?
Yes. Lines inside fenced ``` blocks are copied verbatim, so #` comment lines in shell or config samples are never treated as headings or demoted.
What if my page already starts at H2?
Then it needs no demotion — use a delta of 0. A +1 demotion would over-nest your sections to ### under the page title. Check the current top level first.
Does it handle Setext (underline) headings?
No — only ATX # headings shift. Convert Setext headings to ATX first with md-prettifier so the whole page demotes consistently.
Can I batch-process many wiki pages?
No — one file per run. Process each page individually. To combine or split pages, see md-merger and md-splitter.
Will demoting break anchor links between pages?
No. Anchor slugs derive from heading text, not level, so links keep resolving. Confluence also rebuilds its own anchors on import.
What is the size limit per page?
Free allows 1 MB / 500,000 characters per file. Pro raises it to 10 MB / 5,000,000 characters, Pro-media to 50 MB / 20,000,000, and Developer to 500 MB with no character cap.
Privacy first
All Markdown processing runs locally in your browser using JavaScript. No file is ever uploaded to JAD Apps servers — only metadata counters are saved for signed-in dashboard stats.