Confluence Page Publisher

approved

by Gibran

Publish notes to Confluence pages using frontmatter bindings and custom Markdown conversion. - This plugin has not been manually reviewed by Obsidian staff.

★ 2 stars↓ 104 downloadsUpdated 23d agoMIT

Confluence Page Publisher

Release Desktop License Issues

A one-way publisher for turning Obsidian notes into Confluence pages.


📖 Table of Contents

Obsidian plugin that publishes your notes to Confluence as Confluence Storage XHTML, with frontmatter page binding, attachment uploads, diagram rendering, automatic bound-note links, and content-hash based skips.

Install

From Obsidian

When the plugin is listed in the Obsidian community plugin browser:

Settings > Community plugins > Browse > Search Confluence Page Publisher > Install > Enable

Manual

  1. Download main.js, manifest.json, and styles.css from the latest release

  2. Create folder:

    /path/to/your-vault/.obsidian/plugins/confluence-page-publisher/
    
  3. Copy the 3 files into that folder

  4. Restart Obsidian

  5. Settings > Community plugins > Enable "Confluence Page Publisher"

BRAT

  1. Install BRAT

  2. Open BRAT settings

  3. Add beta plugin:

    gibranbadrul/obsidian-confluence-page
    
  4. Enable "Confluence Page Publisher"

Usage

Bind a note to a Confluence page with frontmatter:

---
confluence_url: "https://example.atlassian.net/wiki/spaces/DOC/pages/123456/My+Page"
---

Then publish it:

Command Palette > Publish current note

The plugin converts the note to Confluence Storage XHTML, uploads local attachments, updates the Confluence page, and writes publish metadata back to the note.

After a successful publishing, the note frontmatter will look like this:

---
confluence_url: "https://example.atlassian.net/wiki/spaces/DOC/pages/123456/My+Page"
confluence_page_id: "123456"
confluence_last_published_at: "2026-07-07T10:30:00.000Z"
confluence_content_hash: "d3f91cb44f6c8a6d72c640adbc18e870f1aa0031"
confluence_attachments:
  "123456":
    image.png:
      hash: "38ab93050f81a0c93d8166150ed8540a47f2748d"
      id: "att987654"
---

Create a new child page

Use confluence_parent_url when the note should create a new page under an existing Confluence container.

Parent page example:

---
confluence_url:
confluence_parent_url: "https://example.atlassian.net/wiki/spaces/DOC/pages/100/Parent+Page"
confluence_title: "New Child Page"
---

On Confluence Cloud, the parent may also be a folder URL:

---
confluence_url:
confluence_parent_url: "https://example.atlassian.net/wiki/spaces/DOC/folder/200/Documentation"
confluence_title: "New Folder Page"
---

For a parent page, the plugin creates the new page directly beneath that page. For a Cloud folder, it creates the page in the folder's space and then moves it into the folder.

Folder parent URLs are supported only when Confluence type is set to Cloud. Confluence Server / Data Center requires a parent page URL.

After the first successful creation, the plugin writes the resolved page URL and ID into the note. Future publishes update that same page directly.

Trigger publishing

MethodBehavior
Command Palette > Publish current notePublishes the active note
Command Palette > Publish all bound notesPublishes every note with Confluence frontmatter
Ribbon iconPublishes all bound notes
Editor right-clickOpens a Confluence submenu for publishing and ignore helpers
File tree right-click on notePublishes a bound note or inserts frontmatter into an unbound note
File tree right-click on folderPublishes bound notes under that folder recursively

Helper commands

CommandBehavior
Insert Confluence frontmatter into current noteAdds the publisher frontmatter fields
Create bound noteCreates a note already bound to a Confluence page URL
Add ignore line macroMarks the current line or selected lines as excluded
Add ignore block macroWraps the selection in a block excluded from Confluence output
Add table of contents macroInserts a marker that renders as a Confluence table of contents
Export storage preview of current noteWrites example.preview.xml with generated Storage XHTML
Validate credentialsChecks the current Confluence connection

Frontmatter

Existing page

---
confluence_url: "https://example.atlassian.net/wiki/spaces/DOC/pages/123456/My+Page"
---

New child page

---
confluence_url:
confluence_parent_url: "https://example.atlassian.net/wiki/spaces/DOC/pages/100/Parent+Page"
---

Full template

---
confluence_url:
confluence_parent_url:
confluence_title:
confluence_page_id:
confluence_last_published_at:
confluence_content_hash:
---
FieldDescription
confluence_urlTarget Confluence page URL
confluence_parent_urlParent page URL, or Confluence Cloud folder URL, used for first-time page creation
confluence_titleOptional Confluence page title override
confluence_page_idResolved Confluence page ID
confluence_last_published_atLast successful publish timestamp
confluence_content_hashContent hash used to skip unchanged notes
confluence_attachmentsPer-page attachment cache used to skip unchanged uploads

The attachment cache is grouped by Confluence page ID so attachment metadata is not reused accidentally when the note is rebound to another page. Existing flat attachment metadata is migrated when a target page ID is available.

Creating a root page directly from a space key is planned. New pages currently require an existing parent page, or a folder when using Confluence Cloud.

What gets converted

ElementOutput
YAML frontmatterRemoved from the published body
Headings H1-H6Confluence headings
ParagraphsConfluence paragraphs
Bold, italic, bold italicRich text formatting
StrikethroughRich text formatting
Inline codeInline code
Standard linksConfluence links
Plain URLsLinkified URLs
Ordered listsOrdered lists
Unordered listsBullet lists
Nested listsNested lists
BlockquotesBlockquotes
TablesTables
Horizontal rulesHorizontal rules
Fenced code blocksConfluence code macros
Code block languagePreserved when available
Indented code blocksConfluence code macros
Obsidian wikilinksConfluence link when the target note is bound; readable text otherwise
Obsidian wikilink aliasesSame resolution with the alias used as link text
Obsidian calloutsSee Callouts for details
Local Markdown imagesConfluence attachments
Obsidian image embedsConfluence attachments
Remote imagesRemote image URLs
Image alt textPreserved when available
Image size / align / border modifiersSee Image attributes for details
Mermaid blocksRendered image attachment when enabled
PlantUML blocksRendered image attachment when enabled
Internal MacrosSee Internal macros for details

Not converted yet

ElementCurrent behavior
HighlightKept as plain text
Task listsKept as text markers
Heading/block wikilinksResolve the target page when bound, but do not preserve the heading or block anchor
Non-image file embedsUploaded, but richer attachment rendering is planned
FootnotesKept as plain text
Math / LaTeXKept as plain text
TagsKept as text; Confluence labels are planned
Note transclusionNot inlined yet
Raw HTMLEscaped / not executed, except <details> — see <details> blocks
Definition listsKept as regular text
Supplementary emojiReplaced with stable placeholders for Confluence compatibility

Internal macros

Confluence Page Publisher supports a few internal comment macros. These macros are only used by the plugin before publishing. They are not sent to Confluence.

ScopeBehaviorUI helper
Single lineRemoves the whole line from the published outputYes, via Add ignore line macro
BlockRemoves everything between the start and end markers from the published outputYes, via Add ignore block macro
TOCInserts a Confluence table of contents macroYes, via Add table of contents macro

Image attributes

Add cpp--prefixed modifiers after a | to resize, align, wrap, border, or caption an image — works on Obsidian embeds (![[image.png|...]]) and Markdown images (![...](image.png)), stack as many as you want in any order. The cpp- prefix keeps them from clashing with other plugins that read the same | segment (some use bare numbers for resizing), and from accidentally matching real alt text.

Editor toolbar

Click an image alone on its own line (e.g. ![[image.png]]) in the editor and a toolbar shows up below it — no need to type the syntax by hand. Align, wrap, and border toggle are buttons; Color / Size open a dropdown for border thickness/color; Image Size and Alt text & Caption open a small panel (Apply/Enter to commit, Cancel/Escape to discard). Move the cursor off the line and it disappears. Toggle it off in Settings → Interface → Show image attributes toolbar.

![[diagram.png|A caption describing the diagram|cpp-w-300|cpp-h-200|cpp-border-bold|cpp-center]]
ModifierExampleResult
Width|cpp-w-300ac:width="300"
Height|cpp-h-200ac:height="200"
Width and height|cpp-w-300|cpp-h-200ac:width="300" ac:height="200"
Alignment|cpp-left, |cpp-center, |cpp-rightac:align="..."
Wrap|cpp-left|cpp-wrap, |cpp-right|cpp-wrapac:align="..." + ac:layout="wrap-left"/"wrap-right"
Border|cpp-borderac:border="true"
Border thickness|cpp-border-subtle, |cpp-border-medium, |cpp-border-boldac:border="true" + Confluence Cloud border thickness (see caveat below)
Border color|cpp-border-color-light, |cpp-border-color-medium, |cpp-border-color-darkac:border="true" + Confluence Cloud border color (see caveat below)
Caption|cpp-caption:A visible caption<ac:caption> child element (see caveat below)
Combined|cpp-w-300|cpp-h-200|cpp-border-bold|cpp-rightall of the above together

Callouts

Obsidian callouts (> [!type] Title) become Confluence structured macros. Most types map to the similarly-named panel:

Callout type(s)Confluence panel
note, info, tip, hintInfo
warning, caution, attentionWarning
danger, error, failure, bugNote
success, check, doneTip
anything elseInfo (default)

Collapsible callouts

Fold any callout with Obsidian's own -/+ marker and it becomes a collapsible expand section instead of a panel, regardless of type — Confluence's colored panels have no collapse option, only its expand macro does, so foldability always wins:

> [!note]- Click to expand
> Hidden details — lists, code blocks, anything goes.
<ac:structured-macro ac:name="expand">
  <ac:parameter ac:name="title">Click to expand</ac:parameter>
  <ac:rich-text-body>Hidden details — lists, code blocks, anything goes.</ac:rich-text-body>
</ac:structured-macro>

The type still picks the icon/color when a callout isn't folded; fold it and that's traded away for a plain expand toggle instead. This isn't limited to a specific type — [!warning]-, [!tip]+, even an unrecognized type like [!quote]-, all produce the same expand section. The title line (Click to expand) becomes a real ac:parameter, same as <details><summary> below, so it stays visible on the toggle while the section is collapsed.

<details> blocks

<details><summary>Title</summary>...</details> also becomes an expand macro — each tag alone on its own line, <summary> optional:

<details>
<summary>Click to expand</summary>

Hidden text, lists, or code blocks go here.

</details>
<ac:structured-macro ac:name="expand">
  <ac:parameter ac:name="title">Click to expand</ac:parameter>
  <ac:rich-text-body>Hidden text, lists, or code blocks go here.</ac:rich-text-body>
</ac:structured-macro>

Same title behavior as a folded callout above — the body is parsed as ordinary Markdown, not treated as opaque HTML.

This is the one deliberate exception to "raw HTML is escaped, not executed" (see What gets converted) — <details> specifically is recognized and converted, nothing else is. It works for publishing regardless of how the note looks in Obsidian itself: Obsidian's own renderer doesn't parse Markdown inside raw HTML blocks by default, so a note with unrendered lists/code inside a <details> fold is a known Obsidian limitation, not something this plugin can fix. Install a community plugin such as Details Markdown if you also want that content to render properly while reading the note in Obsidian — either way, publishing to Confluence produces the same expand macro.

Attachment publishing

When local attachment uploads are enabled, the publisher:

  1. Resolves local Markdown images and Obsidian embeds from the vault
  2. Calculates a content hash for each attachment
  3. Reuses unchanged attachment metadata from confluence_attachments
  4. Updates changed attachments using the cached attachment ID when possible
  5. Falls back to filename lookup and Confluence's create-or-update endpoint when the direct update fails

Common image formats, including SVG (image/svg+xml), are supported. The fallback update flow is useful for Confluence instances that reject a direct attachment-data update for some file types.

Attachment filenames must be unique within a published page because Confluence addresses page attachments by filename.

Diagram rendering

Mermaid and PlantUML rendering is optional.

SourceBehavior
MermaidSends the diagram source to a Kroki-compatible endpoint and uploads the rendered image
PlantUMLSends the diagram source to a PlantUML server and uploads the rendered image

Default render services:

SettingDefault
Mermaid render service URLhttps://kroki.io/mermaid/png
PlantUML server URLhttps://www.plantuml.com/plantuml

For private documentation, use a self-hosted Kroki or PlantUML service.

Settings

Settings > Community plugins > Confluence Page Publisher > Settings

Setting areaDescription
Connection profileBase URL, auth type, account, token secret
Page defaultsTemplate folder, title property, auto-install template
Publishing scopeScan folders and ignore patterns
Publishing metadataFrontmatter field mapping
Publishing assetsAttachment upload toggle and max file size
Content conversionMermaid and PlantUML rendering options
InterfaceStatus bar, notices, and the image attributes toolbar

Authentication

Changes to the base URL, Confluence type, authentication type, account, or selected key-vault secret are applied to the publisher connection without requiring an Obsidian restart. Use Validate credentials after changing connection settings.

Atlassian Cloud

Use Basic auth:

Account: your Atlassian email
Password / API token: Atlassian API token

Base URL usually looks like this:

https://example.atlassian.net/wiki

Confluence Server / Data Center with PAT

Use Bearer auth:

Password / API token: Personal Access Token

Base URL usually looks like this:

https://confluence.your-company.com

Legacy Server account

Use Basic auth:

Account: your username
Password / API token: your account password

Storage preview

Use this command to inspect the generated Confluence Storage XHTML before publishing:

Command Palette > Export storage preview of current note

It writes:

example.preview.xml

Use this when:

  • A page does not render as expected in Confluence
  • An attachment does not appear
  • A callout or code block looks wrong
  • Mermaid or PlantUML falls back to source text
  • You want to debug the converter without updating Confluence

Privacy & network behavior

Confluence Page Publisher is a local Obsidian desktop plugin.

Here is what it does:

  • Reads selected notes from your vault. Only notes you publish, or notes inside a folder/all-bound publish operation, are processed.
  • Reads referenced local attachments. Local images and embeds are read so they can be uploaded to Confluence.
  • Sends content to your configured Confluence URL. Page content, page metadata, and attachments are sent to Confluence when you publish.
  • Uses your configured authentication method. Credentials are used only for Confluence API requests.
  • Uses Obsidian key vault when available. Tokens should be stored as Obsidian secrets instead of plain text.
  • May contact diagram render services. Mermaid and PlantUML source is sent to the configured render service only when diagram rendering is enabled.
  • Does not read your clipboard. Publishing does not depend on clipboard access.
  • Does not sync Confluence back into Obsidian. The flow is one-way: Obsidian to Confluence.
  • Enumerates vault file paths when needed. The plugin scans Markdown files to find notes with Confluence publishing frontmatter for publish-all and folder publishing. It may also enumerate files as a fallback when resolving local attachment links by filename.

Limitations

  • One-way publishing only
  • Confluence edits are not pulled back into Obsidian
  • New page creation requires an existing parent page URL, or a folder URL on Confluence Cloud
  • Root page creation from confluence_space_key is planned
  • Task lists, footnotes, math, tags-to-labels, and note transclusion are planned
  • Raw HTML is not executed, except <details> (see <details> blocks)
  • Mobile Obsidian is not supported

Development

Prerequisites

  • Bun
  • Git-cliff

Setup

git clone https://github.com/gibranbadrul/obsidian-confluence-page.git
cd obsidian-confluence-page
bun install

Available targets

Run:

make help

The main targets are:

TargetBehavior
make devStarts the development build watcher
make lintRuns ESLint
make testRuns the unit test suite
make checkRuns lint, tests, and the production build
make buildBuilds and validates the plugin files in dist/
make installBuilds and installs the plugin into a local vault
make uninstallRemoves the plugin from the configured local vault
make cleanRemoves generated build artifacts

Build

make build

The build must produce:

dist/main.js
dist/manifest.json
dist/styles.css

Development build

make dev

Quality checks

Run the complete local validation workflow:

make check

Individual checks are also available:

make lint
make test

Deploy to a local vault

Configure either the vault root:

make install OBSIDIAN_VAULT="/path/to/vault"

or the complete plugin directory:

make install \
  OBSIDIAN_PLUGIN_DIR="/path/to/vault/.obsidian/plugins/confluence-page-publisher"

The target builds the plugin and copies main.js, manifest.json, and styles.css into the destination. Restart Obsidian or reload the plugin after installation.

Uninstall from a local vault

Use the same destination variable used during installation:

make uninstall OBSIDIAN_VAULT="/path/to/vault"

Release

Use the release script with flags:

./scripts/release.sh --major
./scripts/release.sh --minor
./scripts/release.sh --patch
./scripts/release.sh --auto
./scripts/release.sh --version <semver>

Release candidate:

./scripts/release.sh --minor --rc

Example to push release commit and tag:

./scripts/release.sh --version <SEMVER> --push

The release workflow builds and attaches the required plugin files:

main.js
manifest.json
styles.css

License

MIT Zero Clause

For plugin developers

Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.