A Simple Guide to Managing and Publishing Articles with Obsidian
Obsidian is a great writing environment because posts are just plain Markdown files. To publish them to a website, you need a way to (a) get those files into a static site generator (SSG) like Astro, Hugo, Jekyll, or Eleventy, and (b) deploy the result. This guide covers the three workflows that actually work in practice — pick whichever matches how much control you want.
Pick your workflow
- Option A — Git submodule (recommended for devs): keep content in its own Git repo and pull it into your site repo as a submodule. Best balance of simplicity and control.
- Option B — Vault-in-repo + auto-export: Obsidian vault lives inside the site repo; a pre-commit hook converts Obsidian Markdown to “plain” Markdown the SSG understands. Best if you want zero manual steps.
- Option C — Publishing plugin: an Obsidian community plugin (Enveloppe, Hugo Publish, Digital Garden, etc.) pushes selected notes to a target repo or platform. Best if you don’t want to touch Git at all.
Prerequisites (all options)
- Obsidian installed, with a vault.
- A GitHub (or GitLab) account.
- A static site generator project (Astro, Hugo, Jekyll, Eleventy, Next.js, etc.).
- A host that auto-builds on push: Cloudflare Pages, Netlify, Vercel, or GitHub Pages.
Option A — Git submodule workflow
This is the approach Bryan Hogan describes for Astro, and it generalizes to any SSG.
1. Create a content folder and turn it into a repo. Put your posts (e.g. blog/) and assets (e.g. blog-assets/) in one folder, then:
git init
git add .
git commit -m "initial content"
git remote add origin <your-content-repo-url>
git push -u origin main
2. Open that folder as a vault in Obsidian. Install the community plugin Git (formerly obsidian-git). It will pick up the existing remote — set a backup interval (e.g. 5 minutes) so commits + pushes happen automatically as you write.
3. Add the content repo as a submodule of your site repo. From the site repo root:
git submodule add <your-content-repo-url> src/content
git add . && git commit -m "add content submodule" && git push
The path (src/content here) should match where your SSG expects content — Astro uses src/content/, Hugo uses content/, Jekyll uses _posts/, etc.
4. Make the build pull the submodule. Submodules aren’t fetched by default on most hosts.
- Cloudflare Pages: works out of the box.
- Netlify / Vercel: enable “submodules” or set
GIT_SUBMODULE_STRATEGY=recursive. - DigitalOcean App Platform: change your build command to
git submodule update --init --recursive && npm install && npm run build. If SSH fails, switch the submodule URL to HTTPS by editing.gitmodules, then rungit submodule sync. - When cloning later: use
git clone --recurse-submodules <url>, or rungit submodule update --init --recursiveif you forgot.
5. (Optional) One-button push from VS Code. Bryan’s tip: install the Tasks extension and add a tasks.json + a small script that commits/pushes the submodule and then the parent repo in one click. Saves the round-trip of committing twice for every change.
Option B — Vault-in-repo with auto-export (Jacob Kaplan-Moss’s pattern)
If you want “write in Obsidian, see it on the web in 5 minutes” with no manual steps:
1. Put the vault inside the site repo at e.g. vault/. Point Obsidian at that folder.
2. Install the Git community plugin with auto-commit and auto-push enabled. Set Advanced → Custom base path: .. so it commits at the parent repo level, not the vault.
3. Add a pre-commit hook (use Husky or any hook manager) that converts your vault to the SSG’s expected layout. For Hugo:
rm -rf content/*
obsidian-export vault/ content/ --frontmatter always
git add -A content/
obsidian-export strips Obsidian-specific syntax (wikilinks, etc.) and adds empty frontmatter so the SSG doesn’t choke. For Astro you can usually skip this step if you avoid wikilinks; for Hugo with nested sections you may also need a tiny script to create missing _index.md files.
4. Point your host at the repo. Every Obsidian auto-commit fires the hook, pushes, and triggers a fresh build.
Option C — Publishing plugin (no Git knowledge needed)
If you don’t want to deal with submodules or hooks, an Obsidian plugin can push selected notes for you. Add publish: true (or similar) to a note’s frontmatter and the plugin handles the rest.
- Enveloppe — publishes notes to a GitHub repo; converts wikilinks; handles deletions. Works with Hugo, Jekyll, MkDocs.
- Hugo Publish — Hugo-specific; converts internal links and image paths, writes YAML headers automatically.
- Digital Garden — opinionated end-to-end (GitHub + Vercel) for a personal “garden” site.
- Quartz / Kiln — separate SSGs designed specifically for Obsidian vaults, preserving wikilinks, callouts, canvas, etc. Closest free alternatives to paid Obsidian Publish.
Trade-off: less flexible than rolling your own, but no Git commands.
Practical tips that apply to all three
- Frontmatter: use Obsidian’s Properties UI to set
title,date,tags,draft, etc. The Templater plugin can stamp consistent frontmatter on new notes. - Drafts: add
draft: true(Hugo) orpublished: false(Astro content collections) — most SSGs will skip them. - Images: keep them in a sibling folder (
blog-assets/) committed alongside posts so links don’t break. - Wikilinks (
[[link]]): Astro and Hugo don’t render these natively. Either avoid them in posts, or use a converter (obsidian-export, Enveloppe, or a remark plugin). - Preview locally: run the SSG’s dev server (
astro dev,hugo server, etc.) while writing if you want a live preview beyond Obsidian’s.
Which should you pick?
- Comfortable with Git and want clean separation: Option A.
- Want fully automatic “save = deploy” and don’t mind a build hook: Option B.
- Want to avoid Git entirely: Option C.