Skip to main content

Foundations

info

This page covers the foundational setup: Obsidian vault creation, iCloud sync, the plugin stack, and the split repository approach for publishing.

Personal Data Hub series

  1. Personal Data Hub
  2. Foundations - You are here
  3. Data pipelines
  4. QuickAdd scripts
  5. Chrome extensions
  6. Plugins

The couch problem

I finish most books on the couch, not at my desk. If logging a book meant walking to my computer, opening Obsidian, and filling in fields, I would never do it. I know myself too well.

Everything had to work on my iPhone. That single constraint shaped every decision that followed.

1. The iPhone constraint

iOS ruled out Node.js dependencies and desktop-only plugins. Every script had to use Obsidian's cross-platform APIs:

Instead ofUse
fetch()obsidian.requestUrl()
Node.js fsapp.vault.adapter
Node.js BufferArrayBuffer
path moduleString concatenation
require() / importCopy functions inline

I discovered these limitations the hard way. My first version of the book script worked perfectly on my Mac and failed silently on my phone. After rewriting it twice I documented the rules above so I would not make the same mistake again.

2. The sync problem

I wanted sync across devices without paying for Obsidian Sync. iCloud was the obvious choice as I already use it, but my existing vault had too many files. iCloud would stall for hours trying to sync build artifacts and node_modules.

The split repository approach

My solution was to split the vault into two GitLab repositories:

  1. Content repository (synced via iCloud) - markdown files, scripts, CSV imports
  2. Build repository - Docusaurus config, build scripts, deployment manifests

Commits to the content repository trigger the build pipeline via a GitLab trigger token.

# In content repo .gitlab-ci.yml
trigger-build:
stage: deploy
script:
- |
curl -X POST \
-F "token=$TRIGGER_TOKEN" \
-F "ref=main" \
"https://gitlab.com/api/v4/projects/$BUILD_PROJECT_ID/trigger/pipeline"
only:
- main

The iCloud vault gotcha

This one cost me an afternoon. The iPhone app creates its own iCloud directory and cannot read a vault already created by the Mac app.

I tried everything: recreating the vault, renaming folders, clearing caches. Nothing worked until I found the solution buried in a forum thread.

Solution: Create the vault on iPhone first, then open it on Mac. The iPhone app will create the correct iCloud directory structure.

I also encountered a bug where one Mac could see the vault but the other could not. Restarting iCloud Drive on the affected Mac resolved it.

3. The plugin stack

I started with twelve community plugins and removed them one by one. Most added complexity without solving my actual problems. After two weeks of testing I reduced them down to three:

PluginPurpose
GitVersion control, automatic commits and pushes
QuickAddCustom JavaScript scripts triggered by hotkey
Local REST APIChrome extensions can talk to Obsidian

Plus one I built myself: Calendar View with month, week, and list views. I built it because nothing existed that let me see shows, books, health and workouts together on a calendar. More on that in the Plugins page.

What surprised me was how little I actually needed. Three community plugins and one custom one. The rest is just JavaScript running inside Obsidian.

4. Folder structure

The scripts expect and create this structure:

vault/
├── .obsidian/
│ ├── quickadd-secrets.json # API keys
│ ├── book-import-progress-*.json # Book import progress
│ ├── health-import-progress.json # Health import progress
│ └── workout-import-progress.json # Workout import progress
├── books/
│ ├── books/ # Book notes
│ └── covers/ # Cover images
├── health/
│ ├── daily/ # Daily health notes
│ └── workouts/ # Individual workout notes
├── shows/
│ ├── movies/ # Movie notes
│ ├── series/ # Series and episode notes
│ ├── watched/ # Watch log entries
│ └── covers/ # Show cover images
├── csv-imports/ # CSV source files
│ ├── books/
│ ├── emby/
│ ├── prime/
│ └── health/
├── scripts/active/ # QuickAdd scripts
├── People/ # Author notes
├── Genres/ # Genre notes
├── Sources/ # Streaming service notes
├── Stores/ # Purchase store notes
├── Formats/ # Book format notes
└── WorkoutTypes/ # Workout type notes

5. API keys

Store API keys in .obsidian/quickadd-secrets.json:

{
"googleBooksApiKey": "your_google_books_api_key",
"tmdbApiKey": "your_tmdb_api_key",
"embyServerUrl": "http://your-emby-server:8096",
"embyApiKey": "your_emby_api_key",
"embyUserId": "your_emby_user_id"
}

Load with loadSecrets(app) in scripts. This file should be in .gitignore.


Next: Data pipelines covers how to get your scattered data into CSV format ready for import.