Gibran36 downloadsPublish notes to Confluence pages using frontmatter bindings and custom Markdown conversion.
A one-way publisher for turning Obsidian notes into Confluence pages.
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.
When the plugin is listed in the Obsidian community plugin browser:
Settings > Community plugins > Browse > Search Confluence Page Publisher > Install > Enable
Download main.js, manifest.json, and styles.css from the latest release
Create folder:
/path/to/your-vault/.obsidian/plugins/confluence-page-publisher/
Copy the 3 files into that folder
Restart Obsidian
Settings > Community plugins > Enable "Confluence Page Publisher"
Install BRAT
Open BRAT settings
Add beta plugin:
gibranbadrul/obsidian-confluence-page
Enable "Confluence Page Publisher"
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"
---
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.
| Method | Behavior |
|---|---|
| Command Palette > Publish current note | Publishes the active note |
| Command Palette > Publish all bound notes | Publishes every note with Confluence frontmatter |
| Ribbon icon | Publishes all bound notes |
| Editor right-click | Opens a Confluence submenu for publishing and ignore helpers |
| File tree right-click on note | Publishes a bound note or inserts frontmatter into an unbound note |
| File tree right-click on folder | Publishes bound notes under that folder recursively |
| Command | Behavior |
|---|---|
| Insert Confluence frontmatter into current note | Adds the publisher frontmatter fields |
| Create bound note | Creates a note already bound to a Confluence page URL |
| Add ignore line macro | Marks the current line or selected lines as excluded |
| Add ignore block macro | Wraps the selection in a block excluded from Confluence output |
| Export storage preview of current note | Writes example.preview.xml with generated Storage XHTML |
| Validate credentials | Checks the current Confluence connection |
---
confluence_url: "https://example.atlassian.net/wiki/spaces/DOC/pages/123456/My+Page"
---
---
confluence_url:
confluence_parent_url: "https://example.atlassian.net/wiki/spaces/DOC/pages/100/Parent+Page"
---
---
confluence_url:
confluence_parent_url:
confluence_title:
confluence_page_id:
confluence_last_published_at:
confluence_content_hash:
---
| Field | Description |
|---|---|
confluence_url |
Target Confluence page URL |
confluence_parent_url |
Parent page URL, or Confluence Cloud folder URL, used for first-time page creation |
confluence_title |
Optional Confluence page title override |
confluence_page_id |
Resolved Confluence page ID |
confluence_last_published_at |
Last successful publish timestamp |
confluence_content_hash |
Content hash used to skip unchanged notes |
confluence_attachments |
Per-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.
| Element | Output |
|---|---|
| YAML frontmatter | Removed from the published body |
| Headings H1-H6 | Confluence headings |
| Paragraphs | Confluence paragraphs |
| Bold, italic, bold italic | Rich text formatting |
| Strikethrough | Rich text formatting |
| Inline code | Inline code |
| Standard links | Confluence links |
| Plain URLs | Linkified URLs |
| Ordered lists | Ordered lists |
| Unordered lists | Bullet lists |
| Nested lists | Nested lists |
| Blockquotes | Blockquotes |
| Tables | Tables |
| Horizontal rules | Horizontal rules |
| Fenced code blocks | Confluence code macros |
| Code block language | Preserved when available |
| Indented code blocks | Confluence code macros |
| Obsidian wikilinks | Confluence link when the target note is bound; readable text otherwise |
| Obsidian wikilink aliases | Same resolution with the alias used as link text |
| Obsidian callouts | Confluence structured macros |
| Local Markdown images | Confluence attachments |
| Obsidian image embeds | Confluence attachments |
| Remote images | Remote image URLs |
| Image alt text | Preserved when available |
| Mermaid blocks | Rendered image attachment when enabled |
| PlantUML blocks | Rendered image attachment when enabled |
| Element | Current behavior |
|---|---|
| Highlight | Kept as plain text |
| Task lists | Kept as text markers |
| Heading/block wikilinks | Resolve the target page when bound, but do not preserve the heading or block anchor |
| Non-image file embeds | Uploaded, but richer attachment rendering is planned |
| Footnotes | Kept as plain text |
| Math / LaTeX | Kept as plain text |
| Tags | Kept as text; Confluence labels are planned |
| Note transclusion | Not inlined yet |
| Raw HTML | Escaped / not executed |
| Definition lists | Kept as regular text |
| Supplementary emoji | Replaced with stable placeholders for Confluence compatibility |
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.
| Scope | Behavior | UI helper |
|---|---|---|
| Single line | Removes the whole line from the published output | Yes, via Add ignore line macro |
| Block | Removes everything between the start and end markers from the published output | Yes, via Add ignore block macro |
When local attachment uploads are enabled, the publisher:
confluence_attachmentsCommon 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.
Mermaid and PlantUML rendering is optional.
| Source | Behavior |
|---|---|
| Mermaid | Sends the diagram source to a Kroki-compatible endpoint and uploads the rendered image |
| PlantUML | Sends the diagram source to a PlantUML server and uploads the rendered image |
Default render services:
| Setting | Default |
|---|---|
| Mermaid render service URL | https://kroki.io/mermaid/png |
| PlantUML server URL | https://www.plantuml.com/plantuml |
For private documentation, use a self-hosted Kroki or PlantUML service.
Settings > Community plugins > Confluence Page Publisher > Settings
| Setting area | Description |
|---|---|
| Connection profile | Base URL, auth type, account, token secret |
| Page defaults | Template folder, title property, auto-install template |
| Publishing scope | Scan folders and ignore patterns |
| Publishing metadata | Frontmatter field mapping |
| Publishing assets | Attachment upload toggle and max file size |
| Content conversion | Mermaid and PlantUML rendering options |
| Interface | Status bar and notices |
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.
Use Basic auth:
Account: your Atlassian email
Password / API token: Atlassian API token
Base URL usually looks like this:
https://example.atlassian.net/wiki
Use Bearer auth:
Password / API token: Personal Access Token
Base URL usually looks like this:
https://confluence.your-company.com
Use Basic auth:
Account: your username
Password / API token: your account password
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:
Confluence Page Publisher is a local Obsidian desktop plugin.
Here is what it does:
confluence_space_key is plannedgit clone https://github.com/gibranbadrul/obsidian-confluence-page.git
cd obsidian-confluence-page
bun install
Run:
make help
The main targets are:
| Target | Behavior |
|---|---|
make dev |
Starts the development build watcher |
make lint |
Runs ESLint |
make test |
Runs the unit test suite |
make check |
Runs lint, tests, and the production build |
make build |
Builds and validates the plugin files in dist/ |
make install |
Builds and installs the plugin into a local vault |
make uninstall |
Removes the plugin from the configured local vault |
make clean |
Removes generated build artifacts |
make build
The build must produce:
dist/main.js
dist/manifest.json
dist/styles.css
make dev
Run the complete local validation workflow:
make check
Individual checks are also available:
make lint
make test
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.
Use the same destination variable used during installation:
make uninstall OBSIDIAN_VAULT="/path/to/vault"
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