Markdown to Confluence
Convert Markdown to Confluence Wiki Markup. Handles headings, code blocks, tables, links, lists, and Confluence macros.
Markdown to Confluence Wiki Markup
Confluence uses Atlassian Wiki Markup — similar to Jira but with additional macro support. Notable differences from Jira: code blocks use {code:language=javascript}, and blockquotes become the {info} macro. Confluence also supports {note}, {warning}, and {tip} macros for callout boxes.
Built and maintained by Meet Shah · Last updated
What this tool is used for
- Moving documentation from a repository into a Confluence space.
- Converting release notes for an internal wiki page.
- Adapting a README for a Confluence page that mirrors it.
- Producing wiki markup from a source maintained in Markdown.
- Finding out which Confluence macros a page needs before pasting anything in.
How it works in practice
A worked example
A backend developer is moving the local-setup section of a service's README into the team's Confluence space, and the numbered steps, the code block and the config table all have to survive the trip.
## Local setup Needs **Node 24** and the `db` container. 1. Copy `.env.example` to `.env` 2. Start the stack: ```bash docker compose up -d db npm run dev ``` | Variable | Default | Notes | |---|---|---| | `PORT` | 3000 | API port | | `DB_URL` | _none_ | **Required** | > **Heads up:** `npm run seed` wipes the database. Deploys: see the [release runbook](https://wiki.example.com/display/OPS/release_runbook).
h2. Local setup
Needs *Node 24* and the {{db}} container.
# Copy {{.env.example}} to {{.env}}
# Start the stack:
{code:language=bash}
docker compose up -d db
npm run dev
{code}
|| Variable || Default || Notes ||
| {{PORT}} | 3000 | API port |
| {{DB_URL}} | _none_ | *Required* |
{info}
*Heads up:* {{npm run seed}} wipes the database.
{info}
Deploys: see the [release runbook|https://wiki.example.com/display/OPS/release_runbook].Nearly every line changed, and two characters swapped meanings on the way. In Markdown a hash opens a heading and a single asterisk means italics; in wiki markup a hash opens a numbered item and a single asterisk means bold, which is why the steps come out as # lines and Node 24 sits between single asterisks. The fence becomes a code macro that carries bash as its language, the table's separator row disappears because header cells are marked with double pipes instead, and the quote turns into an info panel. The link keeps its underscore: URLs are set aside before the emphasis rules run, so release_runbook is never read as italics.
The edge case that catches people
Quotes are recognised by two characters, a greater-than sign followed by a space, and the blank line that separates two paragraphs inside a quote is usually written as a bare > with nothing after it. That line fails the test, so the quote closes there, the > is written out as literal text, and the next line opens a fresh quote: a two-paragraph warning arrives as two {info} panels with a stray > between them. Typing a single space after that lone > keeps both paragraphs in one panel, separated by an empty line.
When not to use this tool
It converts line by line with pattern rules rather than parsing the document, which suits a page you will paste once and then maintain in Confluence. Anything whose meaning depends on neighbouring lines comes through wrong or as plain text: a list item continued on the next line, a table written without outer pipes, a sub-list indented four spaces, which lands two levels deeper instead of one. If the Markdown stays the source of truth in a repository, a one-off conversion is also a fork, and every later edit means converting and pasting again; publishing from the repository through Confluence's REST API keeps a single copy. For long documents, pandoc's jira writer is a real parser that targets the same markup.
Frequently Asked Questions
- Which Confluence syntax does this produce?
- Wiki markup — h1. headings, {code} and {info} macros — not the XHTML storage format the API uses. In Confluence Cloud you paste it via the editor's markup insertion rather than typing it into the page, because the editor stores XHTML and only converts markup on the way in.
- Why do blockquotes become an info panel?
- Because Confluence's own quote styling is barely visible, while {info} renders the recognisable blue callout that most documentation uses for exactly the notes people write as blockquotes. Swap it for {note} or {warning} if the tone calls for it — the macros are interchangeable.
- Are code fences preserved with their language?
- Yes — a fenced block becomes {code:language} and keeps the hint, so Confluence applies syntax highlighting. Fences without a language become a plain {code} block, which still renders as monospace with the surrounding frame.
- Why did bold and italic behave oddly in older versions?
- Because the inline conversion emitted bold as *x* and then ran an italic pass over the result, which rewrote every bold into _x_. Inline handling is now shared with the Slack and Jira converters and applies each rule once, so bold stays bold.
- What Markdown will not survive?
- Anything with no wiki equivalent: HTML blocks, footnotes, task lists and reference-style links. Tables, headings, lists, code, quotes and inline emphasis all convert. Check nested lists in particular — indentation rules differ, and deep nesting is where the two formats diverge most.
Common errors and gotchas
- Expecting code fences to convert cleanly, since Confluence uses a macro rather than a fence.
- Assuming heading syntax matches, when Confluence uses h1. through h6. notation.
- Losing table formatting, where Confluence uses double pipes for header cells.
- Overlooking that Confluence's newer editor may not accept wiki markup at all.
- Leaving raw HTML in place, which Confluence usually strips or renders as text.