Set up Sveltia CMS - lightweight Git-backed CMS successor to Decap/Netlify CMS (300KB bundle, 270+ fixes). Framework-agnostic for Hugo, Jekyll, 11ty, Astro. Use when adding CMS to static sites, migrating from Decap CMS, or fixing OAuth, YAML parse, CORS/COOP errors.
Installation
Details
Usage
After installing, this skill will be available to your AI coding assistant.
Verify installation:
skills listSkill Instructions
name: sveltia-cms description: | Set up Sveltia CMS - the lightweight Git-backed CMS successor to Decap/Netlify CMS with 5x smaller bundle (300 KB), GraphQL performance, and 270+ fixed predecessor issues. Framework-agnostic for Hugo, Jekyll, 11ty, Gatsby, Astro.
Use when: adding CMS to static sites, migrating from Decap/Netlify CMS, enabling non-technical editors, or troubleshooting OAuth authentication failures, YAML parse errors, CORS/COOP policy problems, content not listing issues. allowed-tools: ['Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep']
Sveltia CMS Skill
Complete skill for integrating Sveltia CMS into static site projects.
Current Versions
- @sveltia/cms: 0.120.1 (November 2025)
- Status: Public Beta (v1.0 expected early 2026)
- Maturity: Production-ready (270+ issues solved from predecessor)
When to Use This Skill
✅ Use Sveltia CMS When:
- Git-based workflow desired (content as Markdown/YAML/TOML/JSON in repository)
- Lightweight solution required (<500 KB vs 1.5-2.6 MB for competitors)
- Migrating from Decap/Netlify CMS (drop-in replacement, change 1 line)
- Non-technical editors need access without Git knowledge
❌ Don't Use Sveltia CMS When:
- Real-time collaboration needed (multiple users editing simultaneously) - Use Sanity, Contentful, or TinaCMS instead
- Visual page building required (drag-and-drop) - Use Webflow, Builder.io instead
- React-specific visual editing needed - Use TinaCMS instead
Breaking Changes & Updates (v0.105.0+)
v0.120.0 (November 24, 2025) - Author Template Tags
New Feature: Hidden widget now supports author template tags:
{{author-email}}- Signed-in user's email{{author-login}}- Signed-in user's login name{{author-name}}- Signed-in user's display name
Usage:
fields:
- label: Author Email
name: author_email
widget: hidden
default: '{{author-email}}'
Commit message templates also support {{author-email}} tag.
v0.119.0 (November 16, 2025) - TOML Config Support
New Feature: Configuration files can now be written in TOML format (previously YAML-only).
Migration:
# admin/config.toml (NEW)
[backend]
name = "github"
repo = "owner/repo"
branch = "main"
media_folder = "static/images/uploads"
public_folder = "/images/uploads"
Recommendation: YAML is still preferred for better tooling support.
v0.118.0 (November 15, 2025) - TypeScript Breaking Change
BREAKING: Renamed SiteConfig export to CmsConfig for compatibility with Netlify/Decap CMS.
Migration:
// ❌ Old (v0.117.x)
import type { SiteConfig } from '@sveltia/cms';
// ✅ New (v0.118.0+)
import type { CmsConfig } from '@sveltia/cms';
const config: CmsConfig = {
backend: { name: 'github', repo: 'owner/repo' },
collections: [/* ... */],
};
Impact: TypeScript users only. Breaking change for type imports.
v0.117.0 (November 14, 2025) - Enhanced Validation
New Features:
- Exported
CmsConfigtype for direct TypeScript import - Enhanced config validation for collection names, field types, and relation references
- Better error messages for invalid configurations
v0.115.0 (November 5, 2025) - Field-Specific Media Folders
New Feature: Override media_folder at the field level (not just collection level).
Usage:
collections:
- name: posts
label: Blog Posts
folder: content/posts
media_folder: static/images/posts # Collection-level default
fields:
- label: Featured Image
name: image
widget: image
media_folder: static/images/featured # ← Field-level override
public_folder: /images/featured
- label: Author Avatar
name: avatar
widget: image
media_folder: static/images/avatars # ← Another override
public_folder: /images/avatars
Use case: Different media folders for different image types in same collection.
v0.113.5 (October 27, 2025) - Logo Deprecation
DEPRECATION: logo_url option is now deprecated. Migrate to logo.src.
Migration:
# ❌ Deprecated
logo_url: https://yourdomain.com/logo.svg
# ✅ New (v0.113.5+)
logo:
src: https://yourdomain.com/logo.svg
v0.105.0 (September 15, 2024) - Security Breaking Change
BREAKING: sanitize_preview default changed to true for Markdown widget (XSS prevention).
Impact:
- Before v0.105.0:
sanitize_preview: false(compatibility with Netlify/Decap CMS, but vulnerable to XSS) - After v0.105.0:
sanitize_preview: true(secure by default)
Migration:
collections:
- name: posts
fields:
- label: Body
name: body
widget: markdown
sanitize_preview: false # ← Add ONLY if you trust all CMS users
Recommendation: Keep default (true) unless disabling fixes broken preview AND you fully trust all CMS users.
Setup Pattern (Framework-Agnostic)
All frameworks follow the same pattern:
-
Create admin directory in public/static folder:
- Hugo:
static/admin/ - Jekyll:
admin/ - 11ty:
admin/(with passthrough copy) - Astro:
public/admin/ - Next.js:
public/admin/
- Hugo:
-
Create admin/index.html:
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Content Manager</title> </head> <body> <script src="https://unpkg.com/@sveltia/cms@0.120.1/dist/sveltia-cms.js" type="module"></script> </body> </html> -
Create admin/config.yml:
backend: name: github repo: owner/repo branch: main base_url: https://your-worker.workers.dev # OAuth proxy (required) media_folder: static/images/uploads # Framework-specific path public_folder: /images/uploads collections: - name: posts label: Blog Posts folder: content/posts create: true fields: - { label: 'Title', name: 'title', widget: 'string' } - { label: 'Date', name: 'date', widget: 'datetime' } - { label: 'Body', name: 'body', widget: 'markdown' } -
Access admin:
http://localhost:<port>/admin/
Framework-specific details: See templates/ directory for complete examples.
Authentication: Cloudflare Workers OAuth (Recommended)
Why Cloudflare Workers: Fastest, free tier available, works with any deployment platform.
Steps:
-
Deploy Worker:
git clone https://github.com/sveltia/sveltia-cms-auth cd sveltia-cms-auth npm install npx wrangler deploy -
Register OAuth App on GitHub:
- Go to https://github.com/settings/developers
- Click "New OAuth App"
- Authorization callback URL:
https://your-worker.workers.dev/callback - Save Client ID and Client Secret
-
Configure Worker Environment Variables:
npx wrangler secret put GITHUB_CLIENT_ID # Paste your Client ID npx wrangler secret put GITHUB_CLIENT_SECRET # Paste your Client Secret -
Update CMS config:
backend: name: github repo: owner/repo branch: main base_url: https://your-worker.workers.dev # ← Add this line -
Test authentication:
- Open
/admin/ - Click "Login with GitHub"
- Should redirect to GitHub → Authorize → Back to CMS
- Open
Alternative: Vercel serverless functions - See templates/vercel-serverless/
Common Errors & Solutions
This skill prevents 8 common errors encountered when setting up Sveltia CMS.
1. ❌ OAuth Authentication Failures
Error Message:
- "Error: Failed to authenticate"
- Redirect to
https://api.netlify.com/authinstead of GitHub login
Symptoms:
- Login button does nothing
- Authentication popup closes immediately
Causes:
- Missing
base_urlin backend config - Incorrect OAuth proxy URL
- Wrong GitHub OAuth callback URL
Solution:
Step 1: Verify config.yml has base_url:
backend:
name: github
repo: owner/repo
branch: main
base_url: https://your-worker.workers.dev # ← Must be present
Step 2: Check GitHub OAuth App callback:
- Should be:
https://your-worker.workers.dev/callback - NOT:
https://yourdomain.com/callback
Step 3: Test Worker directly:
curl https://your-worker.workers.dev/health
# Should return: {"status": "ok"}
2. ❌ TOML Front Matter Errors
Error Message:
- "Parse error: Invalid TOML"
- Files missing
+++delimiters
Symptoms:
- New files created by CMS don't parse in Hugo
- Content appears above body separator
Causes:
- Sveltia's TOML generation is buggy in beta
- Mixed TOML/YAML in same collection
Solution:
Use YAML instead of TOML (recommended):
collections:
- name: posts
folder: content/posts
format: yaml # or md (Markdown with YAML frontmatter)
# NOT: format: toml
If you must use TOML:
- Manually fix delimiters after CMS saves
- Use pre-commit hook to validate TOML
- Wait for beta fixes (track GitHub issues)
3. ❌ YAML Parse Errors
Error Message:
- "YAML parse error: Invalid YAML"
- "Error: Duplicate key 'field_name'"
Symptoms:
- Existing posts won't load in CMS
- CMS shows empty fields
Causes:
- Sveltia is stricter than Hugo/Jekyll about YAML formatting
- Incorrect indentation or smart quotes
Solution:
Step 1: Validate YAML:
pip install yamllint
find content -name "*.md" -exec yamllint {} \;
Step 2: Common fixes:
Problem: Smart quotes
# ❌ Bad - smart quotes from copy-paste
title: "Hello World" # Curly quotes
# ✅ Good - straight quotes
title: "Hello World" # Straight quotes
Step 3: Auto-fix with yamlfmt:
go install github.com/google/yamlfmt/cmd/yamlfmt@latest
find content -name "*.md" -exec yamlfmt {} \;
4. ❌ Content Not Listing in CMS
Error Message:
- "No entries found"
- "Failed to load entries"
Symptoms:
- Admin loads but shows no content
- Files exist in repository but CMS doesn't see them
Causes:
- Format mismatch (config expects TOML, files are YAML)
- Incorrect folder path
Solution:
Step 1: Verify folder path:
# Config says:
collections:
- name: posts
folder: content/posts # Expects files here
# Check actual location:
ls -la content/posts # Files must exist here
Step 2: Match format to actual files:
# If files are: content/posts/hello.md with YAML frontmatter
collections:
- name: posts
folder: content/posts
format: yaml # or md (same as yaml for .md files)
5. ❌ "SVELTIA is not defined" Error
Error Message:
- Console error:
Uncaught ReferenceError: SVELTIA is not defined
Symptoms:
- Admin page shows white screen
Causes:
- Missing
type="module"attribute
Solution:
Use correct script tag:
<!-- ✅ Correct -->
<script src="https://unpkg.com/@sveltia/cms/dist/sveltia-cms.js" type="module"></script>
<!-- ❌ Wrong - missing type="module" -->
<script src="https://unpkg.com/@sveltia/cms/dist/sveltia-cms.js"></script>
Use version pinning (recommended):
<script src="https://unpkg.com/@sveltia/cms@0.120.1/dist/sveltia-cms.js" type="module"></script>
6. ❌ 404 on /admin
Error Message:
- "404 Not Found" when visiting
/admin/
Symptoms:
- Works locally but not in production
Causes:
- Admin directory not in correct location for framework
Solution:
Framework-specific fixes:
Hugo: Files in static/ are automatically copied
Jekyll: Add to _config.yml:
include:
- admin
11ty: Add to .eleventy.js:
module.exports = function(eleventyConfig) {
eleventyConfig.addPassthroughCopy('admin');
};
Astro: Files in public/ are automatically copied
7. ❌ Images Not Uploading (HEIC Format)
Error Message:
- "Unsupported file format"
Symptoms:
- iPhone photos won't upload
Causes:
- HEIC format not supported by browsers
Solution:
On iPhone:
- Settings > Camera > Formats > Most Compatible
- This saves photos as JPEG instead of HEIC
Or enable image optimization:
media_libraries:
default:
config:
max_file_size: 10485760 # 10 MB
transformations:
raster_image:
format: webp # Auto-converts to WebP
quality: 85
8. ❌ CORS / COOP Policy Errors
Error Message:
- "Authentication Aborted"
- "Cross-Origin-Opener-Policy blocked"
Symptoms:
- OAuth popup opens then closes
Causes:
- Strict
Cross-Origin-Opener-Policyheader blocking OAuth
Solution:
Cloudflare Pages (_headers file):
/*
Cross-Origin-Opener-Policy: same-origin-allow-popups
# NOT: same-origin (this breaks OAuth)
Netlify (_headers file):
/*
Cross-Origin-Opener-Policy: same-origin-allow-popups
Vercel (vercel.json):
{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "Cross-Origin-Opener-Policy",
"value": "same-origin-allow-popups"
}
]
}
]
}
Migration from Decap CMS
Sveltia CMS is a drop-in replacement for Decap CMS.
Step 1: Update script tag (1 line change):
<!-- OLD: Decap CMS -->
<script src="https://unpkg.com/decap-cms@^3.0.0/dist/decap-cms.js"></script>
<!-- NEW: Sveltia CMS -->
<script src="https://unpkg.com/@sveltia/cms@0.120.1/dist/sveltia-cms.js" type="module"></script>
Step 2: Keep existing config.yml (no changes needed)
Step 3: Test locally (verify login, content listing, editing, saving)
That's it! Your content, collections, and workflows remain unchanged.
Not Supported:
- Git Gateway backend (for performance reasons)
- Azure backend (may be added later)
Workaround: Use Cloudflare Workers or Vercel OAuth proxy instead.
Bundled Resources
Templates
- hugo/ - Complete Hugo blog setup
- jekyll/ - Jekyll site configuration
- 11ty/ - Eleventy blog setup
- astro/ - Astro content collections
- cloudflare-workers/ - OAuth proxy implementation
- vercel-serverless/ - Vercel auth functions
- collections/ - Pre-built collection patterns
References
- common-errors.md - Extended error troubleshooting
- migration-from-decap.md - Complete migration guide
- cloudflare-auth-setup.md - Step-by-step OAuth setup
- config-reference.md - Full config.yml documentation
Scripts
- init-sveltia.sh - Automated setup for new projects
- deploy-cf-auth.sh - Deploy Cloudflare Workers OAuth
Official Documentation
- GitHub: https://github.com/sveltia/sveltia-cms
- OAuth Worker: https://github.com/sveltia/sveltia-cms-auth
- npm Package: https://www.npmjs.com/package/@sveltia/cms
- Discussions: https://github.com/sveltia/sveltia-cms/discussions
Token Efficiency
Estimated Savings: 65-70% (~6,300 tokens saved)
Without Skill (~9,500 tokens):
- Framework setup trial & error: 2,500 tokens
- OAuth configuration attempts: 2,500 tokens
- Error troubleshooting: 2,500 tokens
- Deployment configuration: 2,000 tokens
With Skill (~3,200 tokens):
- Skill loading (SKILL.md): 2,000 tokens
- Template selection: 400 tokens
- Project-specific adjustments: 800 tokens
Errors Prevented
This skill prevents 8 common errors (100% prevention rate):
- ✅ OAuth authentication failures
- ✅ TOML front matter generation bugs
- ✅ YAML parse errors (strict validation)
- ✅ Content not listing in CMS
- ✅ "SVELTIA is not defined" errors
- ✅ 404 on /admin page
- ✅ Image upload failures (HEIC format)
- ✅ CORS / COOP policy errors
Last Updated: 2025-11-28 Skill Version: 2.0.0 Sveltia CMS Version: 0.120.1 (Beta) Status: Production-ready, v1.0 GA expected early 2026
More by jezweb
View allSelf-hosted auth for TypeScript/Cloudflare Workers with social auth, 2FA, passkeys, organizations, RBAC, and 15+ plugins. Requires Drizzle ORM or Kysely for D1 (no direct adapter). Self-hosted alternative to Clerk/Auth.js. Use when: self-hosting auth on D1, building OAuth provider, multi-tenant SaaS, or troubleshooting D1 adapter errors, session caching, rate limits.
/review-skill - Skill Audit Command: Comprehensive skill documentation audit with automated checks and manual review phases.
Build rich text editors with Tiptap - headless editor framework with React and Tailwind v4. Covers SSR-safe setup, image uploads, prose styling, and collaborative editing. Use when creating blog editors, comment systems, or Notion-like apps, or troubleshooting SSR hydration errors, typography issues, or image upload problems.
Run LLMs and AI models on Cloudflare's GPU network with Workers AI. Includes Llama 4, Gemma 3, Mistral 3.1, Flux images, BGE embeddings, streaming, and AI Gateway. Handles 2025 breaking changes. Use when: implementing LLM inference, images, RAG, or troubleshooting AI_ERROR, rate limits, max_tokens, BGE pooling.
