Project Overview

A personal website at franco.international that publishes selected content from this private Obsidian vault to the web. Showcases CV, class notes, projects, book reviews, and other public-facing content while keeping the private vault completely separate and secure.

Inspiration

  • Steph Ango’s approach: Separate vault for website with different structure than private vault
  • ewan.my: Digital garden built with Quartz, featuring interconnected notes, graph view, and Obsidian Bases rendering
  • Quartz static site generator: Purpose-built for publishing Obsidian vaults as static websites

Architecture

Two-Vault System

This separation ensures: private vault structure stays intact, website has different organization optimized for web, zero risk of exposing private notes, and different structures for different audiences.

Publishing Flow

  1. Mark notes with publish: true in private vault
  2. Run node scripts/publish.mjs from website repo (dry-run by default)
  3. Script transforms notes (strips private properties, removes .base embeds, strips “)
  4. Run with --execute to publish, preview locally, then push
  5. GitHub Pages auto-deploys on push to main

Content to Publish

  • CV and about page
  • Selected ETH class notes (post-processed atomic notes, not raw class notes)
  • Public project notes (coding, research)
  • Book notes and reviews
  • Selected media notes (movies, etc.)
  • Public research notes

Technology Stack

Website Features

  • Obsidian wikilinks and backlinks
  • Local + global graph view (conditional: full on homepage, local on other pages)
  • Full-text search
  • Responsive design
  • Cupertino-inspired theme with Inter font and custom blue accent RGB(50, 130, 247)
  • Floating controls island (bottom-left): dark mode toggle + reader mode
  • Scroll buttons (bottom-right): top/bottom navigation
  • Reader mode with persistent state and smooth fade transitions
  • Explorer sidebar (desktop collapse disabled, TOC collapse kept)
  • Broken wikilinks rendered as plain text (no dead-link 404s)
  • Date display: created date + last updated date + reading time
  • Tags hidden from published pages

Website Content Structure

content/
  about/         # CV and about page
  projects/      # Project notes (coding, research, etc.)
  notes/         # General notes and clippings
  books/         # Book notes and reviews
  media/         # Movie notes
  eth/           # ETH class notes (mirrors vault folder structure)
  attachments/   # Images and media files

Each section has an index.md landing page.

Publishing System

Publishing Properties

  • publish: true — Required. Marks note for publication
  • web-path — Optional. Explicit destination folder (e.g., about, projects/coding). Auto-populated on first publish
  • web-title — Optional. Different title on website (becomes title in published frontmatter)
  • “ — Obsidian comments for inline redaction (invisible in Obsidian reading mode, stripped during publishing)

Routing Rules (first match wins)

  1. Explicit web-path property → use literally
  2. File in ETH/ → mirror folder structure under eth/ (slugified)
  3. Tag books or area [[media/books/Books|Books]]books/
  4. Tag movies or area [[media/movies/Movies|Movies]]media/
  5. Tag project/business or area Projectsprojects/
  6. Tag clippingsnotes/
  7. Fallback → notes/

Script Commands

node scripts/publish.mjs                  # Dry-run (default)
node scripts/publish.mjs --execute        # Publish + commit + preview + push
node scripts/publish.mjs --clean          # Remove all script-created files
node scripts/publish.mjs --verify         # Check published files match source

Content Transformations

During publishing, the script:

  • Strips private frontmatter: people, collections, expenses, projects, related, space, packing list, groups, attachments
  • Keeps public frontmatter: created, tags, title, status, url, author, year, genre, rating, language, topics, areas, aliases, description, coordinates
  • Removes .base embed lines (!*.base*)
  • Removes orphaned headings (headings with no content before next heading)
  • Strips “ Obsidian comments
  • Applies web-titletitle override
  • Strips wikilink syntax from remaining properties (TopicTopic)
  • Formats dates as YYYY-MM-DD strings
  • Copies referenced attachments to content/attachments/
  • Extracts property wikilinks and appends as hidden markdown for backlink generation (pure markdown, not HTML, so Quartz processes them)

Safety Features

  • Dry-run by default — must pass --execute to write anything
  • Manifest tracking (.publish-manifest.json, gitignored) — only touches files the script created
  • Change detection — skips unchanged files for clean git diffs
  • Orphan detection — removes files whose source no longer has publish: true
  • Preview before push — starts local Quartz server + auto-opens browser for review
  • Web-path writeback — auto-populates routing metadata back to source notes in private vault

Progress

Phase 1: Setup ✅

  • Install Quartz locally
  • Initialize Quartz project
  • Create public GitHub repository
  • Purchase franco.international domain
  • Document project in private vault
  • Update CLAUDE.md with publishing workflow

Phase 2: Website Design ✅

  • Configure Quartz theme (Cupertino-inspired, Inter fonts, custom colors)
  • Floating controls island with dark mode + reader mode
  • Scroll buttons for navigation
  • Reader mode with persistent state
  • Conditional graph view (full on homepage, local on other pages)
  • Create section index pages (about, projects, notes, books, media, eth)

Phase 3: Publishing Automation ✅

  • Define publish property system
  • Design routing rules
  • Create scripts/publish.mjs
  • Metadata transformation and content cleaning
  • Attachment handling
  • Manifest-based change detection and orphan cleanup
  • web-path writeback
  • Dry-run report and execute mode with preview

Phase 4: Deployment ✅

  • Configure GitHub Pages with custom domain
  • SSL certificate (automatic)
  • Cloudflare analytics
  • Broken wikilinks rendered as plain text (Quartz config)
  • Tags hidden from published pages
  • Date display: created date + last updated
  • Dark mode toggle only in floating island (removed from list page sidebar)

Phase 4.5: Metadata & UI Enhancements ✅

Custom Components:

  • FrontmatterProperties Component - Displays metadata in Obsidian-style collapsible panel
    • Obsidian-inspired design with gray background and fold icon
    • Shows 30+ property types (status, rating, author, genre, topics, dates, location, media metadata, etc.)
    • Privacy-aware: excludes people, areas, attachments, journal metrics
    • Wikilinks in properties render as clickable links (only to published notes)
    • Proper vertical alignment and spacing

Explorer Improvements:

  • Single-line note names with ellipsis overflow
  • Reduced font weight for files (folders stay bold)
  • Templates folder excluded from publishing

Table of Contents:

  • Collapsed by default with configurable option
  • No animation flicker on page load (no-transition class)
  • Smooth animations for user interactions

Backlinks:

  • Always visible in sidebar (shows “No backlinks found” when empty)
  • Positioned below graph and TOC in right sidebar
  • Property Backlinks Feature - Includes links from frontmatter properties in link graph
    • Extracts wikilinks from all frontmatter properties (e.g., books: Book Title)
    • Appends property links as hidden markdown after content (hidden with CSS)
    • Quartz’s link crawler processes the markdown wikilinks for backlink generation
    • Enables Obsidian-like behavior where property links create backlinks
    • CSS hides the property link section using :last-of-type selector on <hr>

Wikilink Resolution System:

  • Custom link transformation during publishing
    • Builds note title map (by filename, frontmatter title, and aliases)
    • Case-insensitive matching (like Obsidian)
    • Transforms Note TitleNote Title
    • Wikilinks to unpublished notes → plain text
    • Works in note content AND properties
  • Why custom solution needed: Quartz can’t handle different vault/website structures or Obsidian-style title matching
  • Proper URL generation with space-to-hyphen conversion

Property System Expansion:

  • Added 30+ properties: source, published, description, start/end dates, due dates, filming dates, categories, seasons, books, clippings, collections, trips, related, projects, countries, cities, coordinates, cast, director, producer, writer, duration, r-value, journal-index, areas
  • Smart property stripping: keep public metadata, remove private data (people, groups, attachments, journal metrics)
  • Date formatting: YYYY-MM-DD strings
  • Trimmed whitespace from array values
  • Areas property now published - Added to frontmatter display and included in published notes

Phase 5: Content Population (Paused — waiting for Bases feature)

  • Publish CV and about page
  • Publish exercise area
  • Add trips area
  • Publish health area
  • Select and publish class notes
  • Publish project notes
  • Publish book reviews
  • Publish select books, movies, and videos

Paused until Quartz officially merges Bases support (PR #2292). Bases would significantly change how the website is navigated and structured, so it makes sense to wait before investing time in content organization.

Phase 6: Bases Integration (Waiting for Quartz PR #2292)

  • Quartz merges official Bases support (PR #2292)
  • Update Quartz to version with Bases
  • Test .base file rendering on website
  • Adapt publishing script to handle .base files (currently stripped)

Phase 7: Future Enhancements

  • Recently edited notes section (implemented on homepage, shows 5 most recent)
  • Created/modified date display (ContentMeta already shows both when different)
  • QuickAdd script for publishing from within Obsidian
  • Automated publishing via cron job or GitHub Action
  • Blog/essays section
  • Newsletter/RSS feed
  • Interactive elements (executable code blocks)
  • Dynamic content (trip maps, book rating visualizations)
  • Include emoji in note title

Inspiration & References

Eilleen’s Quartz Customizations

Website: quartz.eilleeenz.com GitHub: fanteastick/quartz-test Customization Log: Quartz-customization-log

Eilleen has created an extensively customized Quartz v4 site with many genius modifications. Key features to potentially adopt:

Implemented by her (Inspiration for Future):

  • RecentNotes Component: Shows recently edited notes with configurable options

    • Located in: quartz/components/RecentNotes.tsx
    • Configuration: limit, showTags, showDate, linkToMore, excludeTags, custom filter/sort
    • Position: afterBody section, uses OnlyFor wrapper to show on specific pages
    • Custom styling with decorative prefixes (”✿”) and separators (”₊⊹⊹₊”)
    • Example config: showDate: true, title: "Recently edited notes:", linkToMore: "All-files-chronologically-modified"
  • Created vs Modified Date Display: Smart date handling in ContentMeta

    • Shows created date always
    • Only shows modified date when it differs from created date
    • Uses _getDateCustom() helper with date comparison
    • Avoids redundant date display when dates are identical

Other Notable Customizations (for potential future implementation):

  • Image carousel with lightbox zoom functionality
  • Interactive image galleries (clickable)
  • Custom callout styling (Minimal theme aesthetics)
  • Spoiler/blurred text implementation
  • Floating buttons for graph access and random page navigation
  • Slug display on tag pages
  • Broken link differentiation (prevents navigation)
  • External link favicons
  • ABC.js music notation plugin
  • Text replacer transformer for markdown preprocessing
  • Password-protected page support

Why Reference Her Work: Eilleen’s implementation provides excellent examples of how to extend Quartz v4 with custom components and features while maintaining clean, maintainable code. Her customization log documents the technical approach for each feature.

Ewan’s Obsidian Database (Bases)

Website: ewan.my GitHub: gassandrid/ewan.my

Ewan built a custom Quartz implementation that renders Obsidian Bases (.base files) as interactive database views with tables, cards, lists, and maps. His implementation includes:

Key Features:

  • Database Views: Tables, cards, lists, and maps with live filtering and sorting
  • Query Engine: Full filter evaluation, property resolution, formula computation
  • Interactive Controls: View selector tabs, search bars, grouping, summaries
  • ~4,800 lines of TypeScript/SCSS: Transformer plugin, emitter plugin, query engine, type system, UI components

Contribution: Ewan contributed his Bases implementation upstream to Quartz as PR #2292. This is the feature we’re waiting for to properly display database views on the website.

Why Reference: Ewan’s work demonstrates how to build complex, data-driven components in Quartz. His implementation shows how to parse YAML schemas, evaluate filters, compute formulas, and render interactive views - all critical for Bases support.

Kepano’s Minimal Theme & Design Philosophy

Website: kepano.com GitHub: kepano/obsidian-minimal

Kepano is the creator of the Minimal theme for Obsidian and has extensive design philosophy around note-taking and personal knowledge management.

Design Principles:

  • Clean, distraction-free interfaces
  • Typography-first design
  • Thoughtful use of whitespace
  • Consistent visual hierarchy
  • Performance-focused (minimal CSS)

Notable Work:

  • Minimal Theme: Most popular Obsidian theme with extensive customization options
  • Design Writing: Essays on note-taking, design, and digital tools
  • Style Settings Plugin: Allows theme customization without editing CSS

Why Reference: Kepano’s design philosophy influences how we think about presenting knowledge on the web. His emphasis on readability, simplicity, and user control informs our approach to the website’s visual design and information architecture.

Bases Feature Research

Official Quartz Support (PR #2292)

Bases rendering is being added to Quartz as an official feature via PR #2292 (feat/bases branch). This is the same feature that powers ewan.my — Ewan contributed his implementation upstream.

  • PR opened: January 30, 2026
  • Status: Open, with unresolved review feedback (anchor normalization bugs, documentation gaps, unanswered maintainer questions)
  • Estimated timeline: Likely weeks to months — needs revision cycles before approval and merge
  • Staging preview: Available at the PR’s deploy preview URL

Decision: Wait for the official merge rather than porting Ewan’s custom implementation. This avoids maintaining a fork and ensures compatibility with future Quartz updates.

Ewan’s Implementation (Reference)

Ewan’s website (ewan.my) already renders .base files as interactive card/table views. His implementation is in his public Quartz fork and consists of ~4,800 lines of custom TypeScript/SCSS:

  • Transformer plugin (quartz/plugins/transformers/bases.ts): Parses .base YAML, handles inline base code blocks
  • Emitter plugin (quartz/plugins/emitters/base.tsx): Renders tables, cards, lists, and maps with filtering, sorting, grouping, and summaries
  • Query engine (quartz/util/base/query.ts): Full filter evaluation, property resolution, formula computation
  • Type system (quartz/util/base/types.ts): YAML schema parsing, view configurations
  • UI components: View selector tabs, search bar, map rendering, card grid layout

This code is now being contributed upstream as PR #2292, so porting it manually is unnecessary.

Key Decisions

Why Separate Vaults?

  • Private vault structure unchanged (no “Public/” folder)
  • Website has different organization optimized for web
  • Zero risk of exposing private notes
  • Different audiences: personal vault for me, website for public

Why Property-Based Publishing?

  • Fits existing vault’s property system
  • Granular control over what gets published
  • Customize titles/categorization for web (web-* properties)
  • No folder structure disruption

Why GitHub Pages?

  • Free hosting, zero maintenance, better uptime than self-hosting
  • Global CDN for international visitors
  • Automatic SSL with custom domain
  • $0 ongoing cost
  • Obsidian Rules - Core vault principles
  • Automation - Vault automation strategies

index