| 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 deployRegister 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 SecretUpdate CMS config:
backend: name: github repo: owner/repo branch: main base_url: https://your-worker.workers.dev # ← Add this lineTest 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