title: “Quartz v4 + Deployment” date: 2026-04-14 tags:

  • quartz
  • self-hosted

CouchDB + couch-sync · Overview


Quartz v4

Quartz is a static site generator built for Obsidian-style markdown. Wikilinks, backlinks, graph views, tags, and full-text search work out of the box.

Configuration: quartz.config.ts

const config: QuartzConfig = {
  configuration: {
    pageTitle: "Shivam's Notes",
    baseUrl: "obsidian.myui.in",
    analytics: { provider: "plausible" },
  },
  plugins: {
    transformers: [
      Plugin.FrontMatter(),
      Plugin.ObsidianFlavoredMarkdown(),  // wikilinks, callouts, embeds
      Plugin.SyntaxHighlighting(),
      Plugin.TableOfContents(),
      Plugin.Latex(),
      Plugin.CreatedModifiedDate(),
      Plugin.Description(),
    ],
    filters: [
      Plugin.RemoveDrafts(),             // excludes draft:true or publish:false
    ],
    emitters: [
      Plugin.ContentPage(),
      Plugin.TagPage(),
      Plugin.FolderPage(),
      Plugin.ContentIndex({ enableRSS: true, enableSitemap: true }),
      Plugin.CustomOgImages(),
    ],
  },
}

Layout: quartz.layout.ts

Quartz separates layout into left sidebar, right sidebar, and beforeBody. For content pages on this site:

export const defaultContentPageLayout: PageLayout = {
  beforeBody: [ArticleTitle(), ContentMeta()],
  left: [PageTitle(), Flex([Search(), Darkmode()]), Graph()],
  right: [DesktopOnly(TableOfContents())],
}

Graph() sits in the left sidebar — every wikilink between notes becomes an edge, and you can see the connected cluster of this series directly while reading.


Building the Site

cd /root/projects/obsidian
npx quartz build

Quartz reads all .md files from content/, transforms them through the plugin pipeline, and writes the static site to public/. The build is fast (~1 second for a small vault) and incremental.

couch-sync triggers this command automatically with a 2-second debounce on every file change.


Serving with nginx

server {
    listen 80;
    server_name obsidian.myui.in;
    root /root/projects/obsidian/public;
    index index.html;
 
    location / {
        try_files $uri $uri/ $uri.html =404;
    }
}

nginx serves public/ statically. Every Quartz build is immediately live — there’s no upload or deploy step. The VPS disk is the “CDN”.


End-to-End Flow

  1. Edit a note in Obsidian → obsidian-livesync pushes encrypted chunks to CouchDB.
  2. CouchDB emits a change on the _changes feed.
  3. couch-sync writes a .md file to content/ and schedules a rebuild.
  4. Quartz compiles content/ into public/.
  5. nginx serves the update instantly.

Total latency: ~5–10 seconds from saving in Obsidian to live on the web.


Lessons & Gotchas

E2E encryptionobsidian-livesync’s encryption means couch-sync cannot read note content; extracted_text is always empty. Disable encryption, or run a decryption step, to get content flowing.

Hardcoded credentials — couch-sync ships with admin:admin. Always replace and use environment variables in production.

RemoveDrafts — any note with draft: true or publish: false in frontmatter is silently excluded from the build. Check frontmatter first if a page isn’t appearing.

Sequence file — deleting .seq forces couch-sync to replay the entire change history. Safe but slow on large vaults.


CouchDB + couch-sync · Back to overview