Selectively publish parts of your notes. Flag blocks as public, then sync them into publish-ready copies, keeping secrets, drafts, and private content out of your published site.
Selectively publish parts of your notes. Flag blocks of any note as player-facing (public), then sync them into publish-ready copies for Obsidian Publish — the rest of the note never leaves your vault.
Built for Dungeon Masters who keep campaign notes and player handouts in one place, but just as useful for anyone publishing from a working vault: public docs with private margin notes, blog drafts with internal comments, shared team notes with personal context.
Flag content. Four ways, no syntax to remember:
pfn property (checkbox) at the top of the note, or run Toggle player-facing for entire note. Everything after the frontmatter publishes; the editor tints the whole note to show it.Under the hood the plugin wraps content in lightweight markers:
::pf
> [!quote] The note reads
> Dear Friends, my name is Azumi...
::/pf
Markers are standalone lines, so they wrap anything — callouts, nested callouts, tables, code blocks. They also work inside a callout (> ::pf) to flag part of one.
Markers stay invisible. In Live Preview they render as small "player-facing" pills with a tinted left border on the region (Realm Works style). In Reading view they're stripped entirely. Only Source mode shows raw markers.
Sync. Run Sync all player copies (ribbon eye icon or command palette). For each note with flagged content, the plugin writes a clean copy — flagged blocks only, markers stripped, publish: true — into a mirror folder (default _player/), preserving your folder structure. Stale copies are pruned automatically. Optional auto-sync on save in settings.
Publish. In Obsidian Publish, publish only the _player/ folder. Your master notes keep publish: false (or simply never get selected). Because filtering happens before upload, players cannot recover DM text from page source — unlike CSS/publish.js hiding, which only hides content client-side.
Player copies are tracked by the pfn-source property in their frontmatter, not by their path. Move or rename copies anywhere inside the player folder — build whatever structure your players should see — and future syncs update them in place. New copies start at the mirrored location; after that, layout is yours.
publish and pfn-source are managed.pfn-source are never touched or pruned — handy for player-only index pages.pfn-source automatically, so your layout survives vault reorganizations.pfn-source property is the sync connection, so the new name sticks — and links in other player notes display the copy's player-facing name, never the original DM-side note name (unless you wrote an explicit alias).Inside player copies, wikilinks are rewritten:
_player/ copy (display text preserved, #heading anchors kept).pf; markers are ::pf / ::/pf._player.> [!note] ...) in the region so it renders as a callout for players.pfn-source frontmatter key in each player copy points back at the original note.::pf flags everything to the end of the note.npm install
npm run build # production build -> main.js
npm run dev # watch mode
npm test # parser unit tests
Install by copying manifest.json, main.js, and styles.css into <vault>/.obsidian/plugins/player-facing-notes/.