Blog Content Sync
Use markdown files in content/blog to create and update multilingual blog posts in the normal database-backed blog system.
Use markdown files in content/blog to create and update multilingual blog posts in the normal database-backed blog system.
Imported posts:
- become regular
blog_postsrecords - show up in the existing Filament blog admin
- can still be read, filtered, edited, published, archived, and translated in the UI
- keep categories and tags in the normal
blog_categories/blog_tagstables
Important:
- file-managed posts can be edited in Admin, but the next
blog:sync-contentrun can overwrite those synced fields - posts created manually in Admin are not touched by the sync command
- categories and tags are shared across locales, not localized per language
Folder Structure
Each article family lives in its own folder. Each locale is one markdown file named after the locale code.
content/blog/
stripe-vs-paddle/
en.md
de.md
fr.md
billing/launch-checklist/
en.md
es.md
Rules:
- the folder path is the stable article family key
- the filename without
.mdmust be a supported locale fromconfig/saas.php - every folder can contain one file per locale
- nested article folders are allowed
- renaming a folder or moving a file changes the source key/path seen by the importer
If you rename or remove markdown files, re-run the sync with --archive-missing so old imported posts are archived safely.
Markdown File Contract
Every markdown file must start with YAML front matter wrapped in ---.
Required front matter:
title
Optional front matter:
slugIf omitted, the importer generates it fromtitle.excerptauthor_emailMust match an existing user email. If omitted, the command falls back to the first admin user, or the--author=option. The public byline, title, avatar, and bio shown on the frontend come from that user's public author profile in Admin > Users.categoryCreated automatically if it does not exist yet.tagsYAML list or comma-separated string. Tags are created automatically if they do not exist yet.statusdraft,published, orarchived. Defaults todraft.published_atmeta_titlemeta_descriptionfeatured_imageStore a public disk path such asblog-images/stripe-vs-paddle.png.
Example:
---
title: Stripe vs Paddle for SaaS Billing
slug: stripe-vs-paddle-for-saas-billing
excerpt: Practical comparison for SaaS founders.
author_email: admin@example.com
category: Billing
tags:
- Stripe
- Paddle
- SaaS
status: published
published_at: 2026-03-21 09:00:00
meta_title: Stripe vs Paddle for SaaS Billing
meta_description: Compare Stripe and Paddle for subscriptions, tax, and global SaaS sales.
featured_image: blog-images/stripe-vs-paddle.png
---
# Stripe vs Paddle for SaaS Billing
Write the full article in markdown here.
Sync Command
Preview changes without writing to the database:
php artisan blog:sync-content --dry-run
Run the real sync:
php artisan blog:sync-content
Archive imported posts whose source files no longer exist:
php artisan blog:sync-content --archive-missing
Use a custom root path:
php artisan blog:sync-content --path=content/blog
Provide a fallback author when files omit author_email:
php artisan blog:sync-content --author=admin@example.com
What The Sync Does
For each markdown file, the importer:
- validates the folder structure, locale filename, and front matter
- groups locale variants from the same folder into one translation family
- creates or reuses categories and tags from front matter
- creates or updates the matching
blog_postsrecord - stores both
body_markdownand renderedbody_html - marks the post as markdown-managed so Admin can show where it came from
The importer does not modify manually created posts unless they explicitly share the same markdown source tracking fields, which the UI does not set.
Admin Workflow
After import, the posts appear in the normal Admin blog resource.
That means you can still:
- create manual posts in Admin
- edit imported posts in Admin
- manage categories and tags in Admin
- publish or archive imported posts in Admin
- manage public blog bylines from the selected author user profile in Admin > Users
The key constraint is ownership:
- manual posts stay manual
- markdown-managed posts stay tied to their source files
- future sync runs update markdown-managed posts again