Skip to content

Migrate content layer to VaultCMS/Obsidian conventions#13

Merged
OzTamir merged 26 commits into
mainfrom
feat/vaultcms-migration
Jun 22, 2026
Merged

Migrate content layer to VaultCMS/Obsidian conventions#13
OzTamir merged 26 commits into
mainfrom
feat/vaultcms-migration

Conversation

@OzTamir

@OzTamir OzTamir commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Makes the blog editable in Obsidian via VaultCMS by adopting VaultCMS/Obsidian content conventions — while keeping the existing Astro 6 theme, URLs, Cloudflare deploy, and visual output the same. We did not adopt the astro-modular theme/stack.

What changed

  • Posts are now src/content/posts/<slug>/index.md (plain Markdown, folder name = slug = unchanged URL). No more .mdx + JSX component kit.
  • Images co-located in the post folder, referenced by basename (![alt](img.png)), still optimized to hashed /_astro/ (WebP + srcset; GIFs preserved).
  • Captions: an *emphasis* line immediately under an image → <figcaption> (may contain a [text](url) link). {wide} marker for the wide column. Implemented by src/plugins/remark-image-captions.mjs, replicating the old <Figure> output.
  • Video: ![[clip.mp4|poster=…|title=…]]; video + poster files live in public/<slug>/. Implemented by src/plugins/remark-video-embeds.mjs, replicating <Video>.
  • Tweets/Instagram: inline raw HTML (render on site; Obsidian-native auto-embed is a noted follow-up).
  • Frontmatter: date/description/image/imageAlt/imageCaption/tags: string[]/draft + SEO overrides (was pubDate/excerpt/featureImage/{slug,name} tags). Tag URL slug = slugify(name).
  • MDX component kit removed; its image resolver folded into src/utils/images.ts. Markdown-for-agents (Accept: text/markdown, /<slug>.md) simplified to serve the native body.
  • Remark plugins registered via the non-deprecated markdown.processor: unified({...}); Shiki nord preserved.
  • Docs rewritten (AGENTS.md, CLAUDE.md, docs/building-and-content.md).

Output preservation

  • All 42 post URLs unchanged; look, OG-card fallback, RSS, sitemap, llms.txt, dark mode all intact.
  • Only 2 tag URLs changed: Ghost's -2 duplicate slugs (home-assistant-2, 3d-printing-2) merged into their canonical tags — both 301-redirected in public/_redirects.
  • Accepted asset changes: image re-hashing; video URLs moved to public/<slug>/.

Verification

  • npm run check: 0 errors · npm run build: 130 pages · npm run check:links: 0 broken (2822 refs). Remark plugins covered by node --test.
  • npm run lhci runs in CI.

Not included (follow-ups)

  • VaultCMS Obsidian vault config (.obsidian/ + _bases/) — to be installed separately; the repo is already structurally VaultCMS-compatible.
  • Full Obsidian-native auto-embed plugin for Tweet/Instagram/YouTube.

🤖 Generated with Claude Code

OzTamir and others added 16 commits June 22, 2026 14:07
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-accept schema

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- git mv 19 images + 2 videos into src/content/posts/<slug>/
- wrote index.md with new frontmatter shape (date, tags as strings, image: featured.png)
- converted all <Figure>/<Video> to remark syntax; link-caption figure uses markdown image + emphasis (auto-linked URL in caption)
- expanded images.ts glob to cover co-located src/content/posts/**
- added resolveFeatureImagePath() to utils/images.ts; updated [slug].astro, rss.xml.ts, posts.json.ts, post-markdown.ts to prefix slug for bare-basename image paths
- videos served via public/<slug>/ (pipeline concern: remark video-embeds emits relative basenames, Astro doesn't auto-copy co-located mp4s to dist)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ved from public/)

Videos espresense-tracking-demo.mp4 and litter-box-sensor-demo.mp4 were
duplicated in src/content/posts/whose-turn-.../. Per convention, videos live
only in public/<slug>/, not in content. Post embeds are basename-only, so they
resolve to the served copies.

Verified: build passes, both videos render with video-card class in dist output.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d vars

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fold resolveImage/isGif globs from components/mdx/images.ts into
  src/utils/images.ts (kept legacy src/assets/content/images/** glob
  for site/ assets: icon, logo, avatar, og-default)
- Simplify post-markdown.ts: delete JSX-component rewriter (Figure/
  Video/Tweet/Instagram); posts are native .md, body served as-is
- Delete src/components/mdx/{Figure,Video,Tweet,Instagram}.astro,
  images.ts, media.ts
- Remove empty dirs: src/assets/content/images/posts, src/assets/content/media
- Build: 130 pages, 0 check errors, 0 broken links

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generate Cloudflare _redirects entries for Ghost -2 dedup slugs that
changed during the VaultCMS migration. Adds scripts/gen-tag-redirects.mjs
to extract legacy {slug, name} pairs from git history (rev 002941f) and
emit redirect lines where oldSlug !== slugify(name).

Result: 2 redirects added (/tag/3d-printing-2/ and /tag/home-assistant-2/).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Change "nor a image" to "nor an image" in OG fallback comment
- Mark MDX as "(compat)" in astro.config.mjs documentation

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 22, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
posts 37d615c Commit Preview URL

Branch Preview URL
Jun 22 2026, 02:40 PM

OzTamir and others added 10 commits June 22, 2026 16:42
Adds the VaultCMS vault (.obsidian config + bundled CMS plugins, _bases/Home.base,
_GUIDE.md) under src/content so the posts collection is editable in Obsidian.
Per-user workspace state (workspace.json/workspace-mobile.json) is gitignored via
**/ patterns that match the vault's actual src/content location.

The vault config lives outside src/content/posts/**, so the content glob does not
pick it up; build stays at 130 pages with no stray routes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
VaultCMS setup wizard configured the Obsidian plugins for this vault:
folder-based posts, link base path "/" (posts live at root), the
title/date/description/tags/image/draft property mappings, and the
new-post template. Updates plugin data.json files + _bases/Home.base.
Site build unaffected (130 pages, content glob excludes the vault).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ort)

Migration is complete, so drop what was only needed to get there:
- delete scripts/migrate-to-vaultcms.mjs and scripts/gen-tag-redirects.mjs
  (one-time codemod + redirect generator; their output is committed)
- remove the now-unused @astrojs/mdx integration + import, narrow the posts
  glob to **/*.md, and drop @astrojs/mdx from dependencies (no .mdx remain;
  remark plugins use @astrojs/markdown-remark, not mdx)

Build verified: astro check 0 errors/0 hints, 130 pages, links clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Removes the source-tree split: video files and their posters move from
public/<slug>/ back into the post folder (src/content/posts/<slug>/),
co-located with the post's images and index.md — one source of truth per
post. A new astro:build:done integration (copy-post-media) parses each
post's ![[...]] embeds and copies the referenced video + poster files into
dist/<slug>/, so they're still served at /<slug>/<file>. The split now
exists only in dist (build output), not in the repo.

Runs before strip-image-metadata so copied posters are EXIF-scrubbed.
Build verified: check 0 errors, 21 media files copied, 130 pages, links clean.
Docs (AGENTS.md, building-and-content.md) updated to the co-located convention.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A project-scoped skill (.claude/skills/creating-blog-posts) documenting the
mechanics of adding a post to this repo: folder-per-post index.md layout, the
frontmatter schema, co-located image/caption/video conventions, string tags,
build verification, and the real footguns (empty date strings, raw-HTML images,
draft not hiding posts). Defers prose/voice to the oz-skills:blog-post-writer
skill; covers everything needed to get a draft into the repo correctly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… blog

Swaps the bundled Oxygen theme for a custom "0xZ" theme so editing posts in
Obsidian looks like the live site. Palette + fonts are taken verbatim from
src/styles/global.css: gold accent (#997700 light / #ffd102 dark) on a
near-white / near-black surface, Mulish for text + extra-bold headings, IBM
Plex Mono for code. Defines .theme-light / .theme-dark blocks so the editor
follows the OS scheme like the blog does. appearance.json now points at 0xZ.

Theme lives in the vault (src/content/.obsidian), outside the posts glob, so
the site build is unaffected (130 pages, 0 errors).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
VaultCMS's onboarding guide is no longer needed now that the setup wizard has
been run and the vault is configured. It lives outside the posts glob, so the
build is unaffected (130 pages, 0 errors).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- README "At a glance": Content is now folder-based Markdown collections
  (editable in Obsidian via VaultCMS), images co-located; add a pointer to the
  creating-blog-posts skill.
- design-system.md: replace the "MDX component kit" section with the Markdown +
  remark-plugin model (remark-image-captions / remark-video-embeds), keeping the
  still-accurate rendered CSS-class docs; fix <Figure wide> -> {wide}.
- building-and-content.md: drop the stale "MDX (compat)" note (@astrojs/mdx removed).
- AGENTS.md: point "Adding content" at the creating-blog-posts skill; document the
  in-repo VaultCMS vault location and the 0xZ Obsidian theme.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The VaultCMS install committed the full third-party plugin bundles
(.obsidian/plugins/*/main.js + styles.css) — ~5.6 MB of code we don't maintain.
Gitignore the plugin code and untrack it, keeping only the small per-plugin
config (manifest.json + data.json, ~80 KB) so the vault stays documented and
re-installable via `npx create-vaultcms`. Files remain on disk, so local
Obsidian is unaffected.

Tracked plugin footprint: 5,691,368 -> 81,309 bytes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Since plugin code is no longer vendored, a fresh clone has the vault config but
not the plugin bundles. Document the one-time `npx create-vaultcms` restore step
(Obsidian-editing only; not needed to build/preview/deploy) in README, AGENTS.md,
and building-and-content.md. Also fixes the stale "config installed separately"
wording in building-and-content's Obsidian section.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@OzTamir OzTamir merged commit 6af7fa8 into main Jun 22, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant