Claude Code Plugins

Community-maintained marketplace

Feedback
20
0

|

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name sveltia-cms
description Complete Sveltia CMS skill for lightweight, Git-backed content management. Sveltia is the modern successor to Decap/Netlify CMS with 5x smaller bundle (300 KB), faster GraphQL-based performance, and solves 260+ predecessor issues. Use this skill when setting up Git-based CMS for static sites (Hugo, Jekyll, 11ty, Gatsby, Astro, SvelteKit, Next.js), blogs, documentation sites, marketing sites, or migrating from Decap/Netlify CMS. Framework-agnostic with first-class i18n support and mobile-friendly editing interface. Prevents 8+ common errors including OAuth authentication failures, TOML formatting issues, YAML parse errors, CORS/COOP policy problems, content not listing, script loading errors, image upload failures, and deployment problems. Includes complete Cloudflare Workers OAuth proxy setup guide.
license MIT
allowed-tools Read, Write, Edit, Bash, Glob, Grep
metadata [object Object]

Sveltia CMS Skill

Complete skill for integrating Sveltia CMS into static site projects.


What is Sveltia CMS?

Sveltia CMS is a Git-based lightweight headless content management system built from scratch as the modern successor to Decap CMS (formerly Netlify CMS). It provides a fast, intuitive editing interface for content stored in Git repositories.

Key Features

  1. Lightweight & Fast

    • Bundle size: <500 KB (minified/brotlied) vs 1.5-2.6 MB for competitors
    • Built with Svelte compiler (no virtual DOM overhead)
    • Uses GraphQL APIs for instant content fetching
    • Relevance-based search across all content
  2. Modern User Experience

    • Intuitive admin interface with full viewport utilization
    • Dark mode support (follows system preferences)
    • Mobile and tablet optimized
    • Drag-and-drop file uploads with multiple file support
    • Real-time preview with instant updates
  3. Git-Native Architecture

    • Content stored as Markdown, MDX, YAML, TOML, or JSON
    • Full version control and change history
    • No vendor lock-in - content lives with code
    • Supports GitHub, GitLab, Gitea, Forgejo backends
  4. Framework-Agnostic

    • Served as vanilla JavaScript bundle
    • Works with Hugo, Jekyll, 11ty, Gatsby, Astro, Next.js, SvelteKit
    • No React, Vue, or framework runtime dependencies
    • Compatible with any static site generator
  5. First-Class Internationalization

    • Multiple language support built-in
    • One-click DeepL translation integration
    • Locale switching while editing
    • Flexible i18n structures (files, folders, single file)
  6. Built-In Image Optimization

    • Automatic WebP conversion
    • Client-side resizing and optimization
    • SVG optimization support
    • Configurable quality and dimensions

Current Versions

  • @sveltia/cms: 0.113.5 (October 2025)
  • Status: Public Beta (v1.0 expected early 2026)
  • Maturity: Production-ready (265+ issues solved from predecessor)

When to Use This Skill

✅ Use Sveltia CMS When:

  1. Building Static Sites

    • Hugo blogs and documentation
    • Jekyll sites and GitHub Pages
    • 11ty (Eleventy) projects
    • Gatsby marketing sites
    • Astro content-heavy sites
  2. Non-Technical Editors Need Access

    • Marketing teams managing pages
    • Authors writing blog posts
    • Content teams without Git knowledge
    • Clients needing easy content updates
  3. Git-Based Workflow Desired

    • Content versioning through Git
    • Content review through pull requests
    • Content lives with code in repository
    • CI/CD integration for deployments
  4. Lightweight Solution Required

    • Performance-sensitive projects
    • Mobile-first editing needed
    • Quick load times critical
    • Minimal bundle size important
  5. Migrating from Decap/Netlify CMS

    • Existing config.yml can be reused
    • Drop-in replacement (change 1 line)
    • Better performance and UX
    • Active maintenance and bug fixes

❌ Don't Use Sveltia CMS When:

  1. Real-Time Collaboration Needed

    • Multiple users editing simultaneously (Google Docs-style)
    • Use Sanity, Contentful, or TinaCMS instead
  2. Visual Page Building Required

    • Drag-and-drop page builders needed
    • Use Webflow, Builder.io, or TinaCMS (React) instead
  3. Highly Dynamic Data

    • E-commerce with real-time inventory
    • Real-time dashboards or analytics
    • Use traditional databases (D1, PostgreSQL) instead
  4. React-Specific Visual Editing Needed

    • In-context component editing
    • Use TinaCMS instead (React-focused)

Sveltia CMS vs TinaCMS

Use Sveltia for:

  • Hugo, Jekyll, 11ty, Gatsby (non-React SSGs)
  • Traditional CMS admin panel UX
  • Lightweight bundle requirements
  • Framework-agnostic projects

Use TinaCMS for:

  • React, Next.js, Astro (React components)
  • Visual in-context editing
  • Schema-driven type-safe content
  • Modern developer experience with TypeScript

Both are valid - Sveltia complements TinaCMS for different use cases.


Setup Patterns by Framework

Use the appropriate setup pattern based on your framework choice.

1. Hugo Setup (Most Common)

Hugo is the most popular static site generator for Sveltia CMS.

Steps:

  1. Create admin directory:

    mkdir -p static/admin
    
  2. Create admin index page:

    <!-- static/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/dist/sveltia-cms.js" type="module"></script>
      </body>
    </html>
    
  3. Create config file:

    # static/admin/config.yml
    backend:
      name: github
      repo: owner/repo
      branch: main
    
    media_folder: static/images/uploads
    public_folder: /images/uploads
    
    collections:
      - name: posts
        label: Blog Posts
        folder: content/posts
        create: true
        slug: '{{year}}-{{month}}-{{day}}-{{slug}}'
        fields:
          - { label: 'Title', name: 'title', widget: 'string' }
          - { label: 'Date', name: 'date', widget: 'datetime' }
          - { label: 'Draft', name: 'draft', widget: 'boolean', default: true }
          - { label: 'Tags', name: 'tags', widget: 'list', required: false }
          - { label: 'Body', name: 'body', widget: 'markdown' }
    
  4. Start Hugo dev server:

    hugo server
    
  5. Access admin:

    http://localhost:1313/admin/
    

Template: See templates/hugo/


2. Jekyll Setup

Jekyll is commonly used with GitHub Pages and Sveltia CMS.

Steps:

  1. Create admin directory:

    mkdir -p admin
    
  2. Create admin index page:

    <!-- 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/dist/sveltia-cms.js" type="module"></script>
      </body>
    </html>
    
  3. Create config file:

    # admin/config.yml
    backend:
      name: github
      repo: owner/repo
      branch: main
    
    media_folder: assets/images/uploads
    public_folder: /assets/images/uploads
    
    collections:
      - name: posts
        label: Blog Posts
        folder: _posts
        create: true
        slug: '{{year}}-{{month}}-{{day}}-{{slug}}'
        fields:
          - { label: 'Layout', name: 'layout', widget: 'hidden', default: 'post' }
          - { label: 'Title', name: 'title', widget: 'string' }
          - { label: 'Date', name: 'date', widget: 'datetime' }
          - { label: 'Categories', name: 'categories', widget: 'list', required: false }
          - { label: 'Body', name: 'body', widget: 'markdown' }
    
  4. Start Jekyll dev server:

    bundle exec jekyll serve
    
  5. Access admin:

    http://localhost:4000/admin/
    

Template: See templates/jekyll/


3. 11ty (Eleventy) Setup

11ty works well with Sveltia CMS for flexible static sites.

Steps:

  1. Create admin directory:

    mkdir -p admin
    
  2. Create admin index page:

    <!-- 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/dist/sveltia-cms.js" type="module"></script>
      </body>
    </html>
    
  3. Create config file:

    # admin/config.yml
    backend:
      name: github
      repo: owner/repo
      branch: main
    
    media_folder: src/assets/images
    public_folder: /assets/images
    
    collections:
      - name: blog
        label: Blog Posts
        folder: src/posts
        create: true
        slug: '{{slug}}'
        fields:
          - { label: 'Title', name: 'title', widget: 'string' }
          - { label: 'Description', name: 'description', widget: 'text' }
          - { label: 'Date', name: 'date', widget: 'datetime' }
          - { label: 'Tags', name: 'tags', widget: 'list', required: false }
          - { label: 'Body', name: 'body', widget: 'markdown' }
    
  4. Add passthrough copy to .eleventy.js:

    module.exports = function(eleventyConfig) {
      eleventyConfig.addPassthroughCopy('admin');
      // ... rest of config
    };
    
  5. Start 11ty dev server:

    npx @11ty/eleventy --serve
    
  6. Access admin:

    http://localhost:8080/admin/
    

Template: See templates/11ty/


4. Astro Setup

Astro is a modern framework that works well with Sveltia CMS.

Steps:

  1. Create admin directory:

    mkdir -p public/admin
    
  2. Create admin index page:

    <!-- public/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/dist/sveltia-cms.js" type="module"></script>
      </body>
    </html>
    
  3. Create config file:

    # public/admin/config.yml
    backend:
      name: github
      repo: owner/repo
      branch: main
    
    media_folder: public/images
    public_folder: /images
    
    collections:
      - name: blog
        label: Blog Posts
        folder: src/content/blog
        create: true
        slug: '{{slug}}'
        format: mdx
        fields:
          - { label: 'Title', name: 'title', widget: 'string' }
          - { label: 'Description', name: 'description', widget: 'text' }
          - { label: 'Published Date', name: 'pubDate', widget: 'datetime' }
          - { label: 'Hero Image', name: 'heroImage', widget: 'image', required: false }
          - { label: 'Body', name: 'body', widget: 'markdown' }
    
  4. Start Astro dev server:

    npm run dev
    
  5. Access admin:

    http://localhost:4321/admin/
    

Template: See templates/astro/


5. Framework-Agnostic Setup

Applies to: Gatsby, Next.js (SSG mode), SvelteKit, Remix, or any framework

Steps:

  1. Determine public directory:

    • Gatsby: static/
    • Next.js: public/
    • SvelteKit: static/
    • Remix: public/
  2. Create admin directory in public folder:

    mkdir -p <public-folder>/admin
    
  3. Create admin index page:

    <!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/dist/sveltia-cms.js" type="module"></script>
      </body>
    </html>
    
  4. Create config file tailored to your content structure:

    backend:
      name: github
      repo: owner/repo
      branch: main
    
    media_folder: <your-media-path>
    public_folder: <your-public-path>
    
    collections:
      # Define based on your content structure
    
  5. Access admin:

    http://localhost:<port>/admin/
    

Authentication Setup

Choose the authentication method that fits your deployment platform.

Option 1: Cloudflare Workers OAuth (Recommended) 🔥

Best For: Cloudflare Pages, Cloudflare Workers, any deployment

This uses the official sveltia-cms-auth Cloudflare Worker for OAuth.

Steps:

  1. Deploy Worker:

    # Clone the auth worker
    git clone https://github.com/sveltia/sveltia-cms-auth
    cd sveltia-cms-auth
    
    # Install dependencies
    npm install
    
    # Deploy to Cloudflare Workers
    npx wrangler deploy
    

    Or use one-click deploy:

  2. Register OAuth App on GitHub:

  3. Configure Worker Environment Variables:

    # Set GitHub credentials
    npx wrangler secret put GITHUB_CLIENT_ID
    # Paste your Client ID
    
    npx wrangler secret put GITHUB_CLIENT_SECRET
    # Paste your Client Secret
    
    # Optional: Restrict to specific domains
    npx wrangler secret put ALLOWED_DOMAINS
    # Example: yourdomain.com,*.yourdomain.com
    
  4. Update CMS config:

    # admin/config.yml
    backend:
      name: github
      repo: owner/repo
      branch: main
      base_url: https://your-worker.workers.dev  # ← Add this line
    
  5. Test authentication:

    • Open your site's /admin/
    • Click "Login with GitHub"
    • Authorize the app
    • You should be redirected back to the CMS

Complete guide: See references/cloudflare-auth-setup.md

Template: See templates/cloudflare-workers/


Option 2: Vercel Serverless Functions

Best For: Vercel deployments

Steps:

  1. Create API route:

    // api/auth.ts
    export default async function handler(req, res) {
      // OAuth handling logic
      // See templates/vercel-serverless/api-auth.ts
    }
    
  2. Set environment variables in Vercel:

    GITHUB_CLIENT_ID=your_client_id
    GITHUB_CLIENT_SECRET=your_client_secret
    
  3. Update CMS config:

    backend:
      name: github
      repo: owner/repo
      branch: main
      base_url: https://yourdomain.com/api/auth
    

Template: See templates/vercel-serverless/


Option 3: Netlify Functions (Not Recommended)

Note: Sveltia CMS deliberately omits Git Gateway support for performance reasons.

If deploying to Netlify, use either:

  • Cloudflare Workers OAuth (recommended, faster)
  • Netlify Functions with custom OAuth (similar to Vercel pattern)

Option 4: Local Development (GitHub/GitLab Direct)

For local development only - no authentication proxy needed.

Requirements:

  • GitHub/GitLab personal access token
  • Browser with File System Access API (Chrome, Edge)

Setup:

  1. Generate personal access token:

  2. Configure local backend:

    # admin/config.yml
    backend:
      name: github
      repo: owner/repo
      branch: main
    
    local_backend: true  # Enable local mode
    
  3. Use Sveltia's local repository feature:

    • Click "Work with Local Repository" in login screen
    • Select your local Git repository folder
    • Changes save directly to local files
    • Commit and push manually via Git

Note: This is for development only - production requires OAuth proxy.


Configuration Best Practices

Basic Config Structure

# admin/config.yml

# Backend (Git provider)
backend:
  name: github  # or gitlab, gitea, forgejo
  repo: owner/repo
  branch: main
  base_url: https://your-auth-worker.workers.dev  # OAuth proxy

# Media storage
media_folder: static/images/uploads  # Where files are saved
public_folder: /images/uploads        # URL path in content

# Optional: Multiple media libraries
media_libraries:
  default:
    config:
      max_file_size: 5242880  # 5 MB in bytes
      slugify_filename: true
      transformations:
        raster_image:
          format: webp
          quality: 85
          width: 2048
          height: 2048
        svg:
          optimize: true

# Optional: Custom branding
logo_url: https://yourdomain.com/logo.svg

# Collections (content types)
collections:
  - name: posts
    label: Blog Posts
    folder: content/posts
    create: true
    fields:
      # Field definitions

Collection Patterns

Collections define content types and where they're stored.

Blog Post Collection

collections:
  - name: posts
    label: Blog Posts
    folder: content/posts
    create: true
    slug: '{{year}}-{{month}}-{{day}}-{{slug}}'
    format: yaml  # or md, toml, json
    fields:
      - label: Title
        name: title
        widget: string

      - label: Date
        name: date
        widget: datetime
        date_format: 'YYYY-MM-DD'
        time_format: false  # Date only

      - label: Draft
        name: draft
        widget: boolean
        default: true

      - label: Featured Image
        name: image
        widget: image
        required: false

      - label: Excerpt
        name: excerpt
        widget: text
        required: false

      - label: Tags
        name: tags
        widget: list
        required: false

      - label: Body
        name: body
        widget: markdown

Template: See templates/collections/blog-posts.yml


Documentation Page Collection

collections:
  - name: docs
    label: Documentation
    folder: content/docs
    create: true
    slug: '{{slug}}'
    format: mdx
    fields:
      - label: Title
        name: title
        widget: string

      - label: Description
        name: description
        widget: text

      - label: Order
        name: order
        widget: number
        value_type: int
        hint: Sort order in sidebar

      - label: Category
        name: category
        widget: select
        options:
          - Getting Started
          - API Reference
          - Tutorials
          - Advanced

      - label: Body
        name: body
        widget: markdown

Template: See templates/collections/docs-pages.yml


Landing Page Collection (Structured Content)

collections:
  - name: pages
    label: Landing Pages
    folder: content/pages
    create: true
    slug: '{{slug}}'
    format: json
    fields:
      - label: Title
        name: title
        widget: string

      - label: SEO
        name: seo
        widget: object
        fields:
          - { label: Meta Title, name: metaTitle, widget: string }
          - { label: Meta Description, name: metaDescription, widget: text }
          - { label: OG Image, name: ogImage, widget: image }

      - label: Hero Section
        name: hero
        widget: object
        fields:
          - { label: Headline, name: headline, widget: string }
          - { label: Subheadline, name: subheadline, widget: text }
          - { label: Hero Image, name: image, widget: image }
          - label: CTA Button
            name: cta
            widget: object
            fields:
              - { label: Text, name: text, widget: string }
              - { label: URL, name: url, widget: string }

      - label: Features
        name: features
        widget: list
        fields:
          - { label: Title, name: title, widget: string }
          - { label: Description, name: description, widget: text }
          - { label: Icon, name: icon, widget: image }

Template: See templates/collections/landing-pages.yml


Internationalization (i18n) Setup

Sveltia CMS has first-class i18n support with multiple structure options.

Multiple Files Structure (Recommended)

Best for: Hugo, Jekyll with separate locale files

i18n:
  structure: multiple_files
  locales: [en, fr, de, ja]
  default_locale: en

collections:
  - name: posts
    label: Blog Posts
    folder: content/posts
    create: true
    i18n: true  # Enable i18n for this collection
    fields:
      - label: Title
        name: title
        widget: string
        i18n: true  # Translatable field

      - label: Date
        name: date
        widget: datetime
        i18n: duplicate  # Same value across locales

      - label: Body
        name: body
        widget: markdown
        i18n: true

Result: Creates files like:

  • content/posts/hello-world.en.md
  • content/posts/hello-world.fr.md
  • content/posts/hello-world.de.md

Multiple Folders Structure

Best for: Next.js, Astro with locale directories

i18n:
  structure: multiple_folders
  locales: [en, fr, de]
  default_locale: en

collections:
  - name: blog
    label: Blog Posts
    folder: content/{{locale}}/blog  # {{locale}} placeholder
    create: true
    i18n: true
    fields:
      # Same as above

Result: Creates files like:

  • content/en/blog/hello-world.md
  • content/fr/blog/hello-world.md
  • content/de/blog/hello-world.md

Single File Structure

Best for: i18n libraries that manage translations in one file

i18n:
  structure: single_file
  locales: [en, fr, de]
  default_locale: en

collections:
  - name: translations
    label: Translations
    files:
      - name: ui
        label: UI Strings
        file: data/translations.json
        i18n: true
        fields:
          - label: Navigation
            name: nav
            widget: object
            i18n: true
            fields:
              - { label: Home, name: home, widget: string, i18n: true }
              - { label: About, name: about, widget: string, i18n: true }

Reference: See references/i18n-patterns.md for complete guide.


DeepL Translation Integration

Sveltia CMS includes one-click translation using DeepL.

Setup:

  1. Get DeepL API key:

  2. Add to config:

    # admin/config.yml
    backend:
      name: github
      repo: owner/repo
    
    i18n:
      structure: multiple_files
      locales: [en, fr, de, es, ja]
      default_locale: en
    
    # DeepL integration
    deepl:
      api_key: your-deepl-api-key
      # Or use environment variable: DEEPL_API_KEY
    
  3. Use in editor:

    • Switch to non-default locale
    • Click "Translate from [Default Locale]" button
    • DeepL translates all translatable fields instantly

Note: Translation quality depends on DeepL's AI - always review translations.


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/auth instead of GitHub login

Symptoms:

  • Login button does nothing
  • Redirects to wrong domain
  • Authentication popup closes immediately

Causes:

  • Missing base_url in backend config
  • Incorrect OAuth proxy URL
  • CORS policy blocking authentication
  • 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: Verify Worker environment variables:

npx wrangler secret list
# Should show: GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET

Step 4: Test Worker directly:

curl https://your-worker.workers.dev/health
# Should return: {"status": "ok"}

Prevention:

  • Always include base_url when not using GitHub direct auth
  • Test OAuth flow in incognito window
  • Check browser console for CORS errors

2. ❌ TOML Front Matter Errors

Error Message:

  • "Parse error: Invalid TOML"
  • Files missing +++ delimiters
  • Body content appearing in frontmatter

Symptoms:

  • New files created by CMS don't parse in Hugo
  • Existing TOML files break after editing
  • Content appears above body separator

Causes:

  • Sveltia's TOML generation is buggy in beta
  • Incomplete TOML delimiter handling
  • 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:

  1. Manually fix delimiters after CMS saves
  2. Use pre-commit hook to validate TOML
  3. Wait for beta fixes (track GitHub issues)

Migration from TOML to YAML:

# Convert all posts from TOML to YAML
for file in content/posts/*.md; do
  # Use Hugo's built-in converter
  hugo convert toYAML "$file"
done

Prevention:

  • Prefer YAML format for new projects
  • If Hugo requires TOML, test CMS thoroughly before production
  • Keep watch on Sveltia GitHub releases for TOML fixes

3. ❌ YAML Parse Errors

Error Message:

  • "YAML parse error: Invalid YAML"
  • "Error: Duplicate key 'field_name'"
  • "Unexpected character at position X"

Symptoms:

  • Existing posts won't load in CMS
  • Can't save changes to content
  • CMS shows empty fields

Causes:

  • Sveltia is stricter than Hugo/Jekyll about YAML formatting
  • Multiple YAML documents in one file (---\n---\n---)
  • Incorrect indentation or special characters
  • Smart quotes from copy-paste

Solution:

Step 1: Validate YAML:

# Install yamllint
pip install yamllint

# Check all content files
find content -name "*.md" -exec yamllint {} \;

Step 2: Common fixes:

Problem: Multiple documents in one file

---
title: Post 1
---
---  # ← Remove this extra separator
title: Post 2
---

Problem: Incorrect indentation

# ❌ Bad - inconsistent indentation
fields:
  - name: title
     label: Title  # Extra space
  - name: date
    label: Date

# ✅ Good - consistent 2-space indentation
fields:
  - name: title
    label: Title
  - name: date
    label: Date

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:

# Install
go install github.com/google/yamlfmt/cmd/yamlfmt@latest

# Fix all files
find content -name "*.md" -exec yamlfmt {} \;

Prevention:

  • Use YAML-aware editors (VS Code with YAML extension)
  • Enable YAML schema validation
  • Run yamllint in pre-commit hooks

4. ❌ Content Not Listing in CMS

Error Message:

  • "No entries found"
  • Empty content list
  • "Failed to load entries"

Symptoms:

  • Admin loads but shows no content
  • Collections appear empty
  • Files exist in repository but CMS doesn't see them

Causes:

  • Format mismatch (config expects TOML, files are YAML)
  • Incorrect folder path
  • File extension doesn't match format
  • Git backend not connected

Solution:

Step 1: Verify folder path matches actual files:

# 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)

# If files are: content/posts/hello.toml
collections:
  - name: posts
    folder: content/posts
    format: toml
    extension: toml

Step 3: Check file extensions:

# Config expects .md files
ls content/posts/*.md  # Should show files

# If files have different extension:
# Either rename files OR set extension in config

Step 4: Verify Git backend connection:

backend:
  name: github
  repo: owner/repo  # Must be correct owner/repo
  branch: main      # Must be correct branch

Prevention:

  • Keep folder paths relative to repository root
  • Match format to actual file format
  • Test with one file first before creating collection

5. ❌ "SVELTIA is not defined" Error

Error Message:

  • Console error: Uncaught ReferenceError: SVELTIA is not defined
  • Blank admin page
  • Admin page stuck loading

Symptoms:

  • Admin page loads but shows white screen
  • Browser console shows JavaScript error
  • CMS never initializes

Causes:

  • Incorrect script tag
  • CDN failure or blocked
  • Wrong script URL
  • Missing type="module" attribute

Solution:

Step 1: 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>

<!-- ❌ Wrong - incorrect path -->
<script src="https://unpkg.com/sveltia-cms/dist/sveltia-cms.js" type="module"></script>

Step 2: Verify CDN is accessible:

# Test CDN URL
curl -I https://unpkg.com/@sveltia/cms/dist/sveltia-cms.js
# Should return: 200 OK

Step 3: Use version pinning (optional but recommended):

<!-- Pin to specific version for stability -->
<script src="https://unpkg.com/@sveltia/cms@0.113.3/dist/sveltia-cms.js" type="module"></script>

Step 4: Check for CSP blocking:

<!-- If you have Content Security Policy, add: -->
<meta http-equiv="Content-Security-Policy" content="
  default-src 'self';
  script-src 'self' https://unpkg.com;
  style-src 'self' 'unsafe-inline' https://unpkg.com;
  connect-src 'self' https://api.github.com https://your-worker.workers.dev;
">

Prevention:

  • Copy-paste official script tag from Sveltia docs
  • Pin to specific version in production
  • Test admin page in different browsers

6. ❌ 404 on /admin

Error Message:

  • "404 Not Found" when visiting /admin/
  • Admin page doesn't exist

Symptoms:

  • Site loads but /admin/ returns 404
  • Works locally but not in production
  • Files exist but aren't served

Causes:

  • Admin directory not in public/static folder
  • Admin files not deployed
  • Incorrect build configuration
  • Framework not copying admin files

Solution:

Step 1: Verify admin directory location:

Hugo: static/admin/ Jekyll: admin/ 11ty: admin/ (with passthrough copy) Astro: public/admin/ Next.js: public/admin/ Gatsby: static/admin/

Step 2: Check files exist:

ls -la static/admin/  # Hugo example
# Should show: index.html, config.yml

Step 3: 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

Step 4: Verify deployment:

# After build, check output directory
ls -la public/admin/  # or _site/admin/ or dist/admin/

Prevention:

  • Test admin page access before deploying
  • Add admin directory to version control
  • Document admin path in project README

7. ❌ Images Not Uploading (HEIC Format)

Error Message:

  • "Unsupported file format"
  • "Failed to upload image"
  • Image appears but doesn't save

Symptoms:

  • iPhone photos won't upload
  • HEIC files rejected
  • Only JPEG/PNG work

Causes:

  • HEIC format not supported by browsers
  • Image too large (exceeds max_file_size)
  • Media folder path incorrect

Solution:

Step 1: Convert HEIC to JPEG:

On Mac:

# Convert single file
sips -s format jpeg image.heic --out image.jpg

# Batch convert
for f in *.heic; do sips -s format jpeg "$f" --out "${f%.heic}.jpg"; done

On iPhone:

  • Settings > Camera > Formats > Most Compatible
  • This saves photos as JPEG instead of HEIC

Or use online converter: https://heic.to/

Step 2: Enable image optimization to auto-convert:

# admin/config.yml
media_libraries:
  default:
    config:
      max_file_size: 10485760  # 10 MB
      transformations:
        raster_image:
          format: webp  # Auto-converts to WebP
          quality: 85
          width: 2048
          height: 2048

Step 3: Increase max file size if needed:

media_libraries:
  default:
    config:
      max_file_size: 10485760  # 10 MB in bytes
      # Default is often 5 MB

Prevention:

  • Document image requirements for content editors
  • Enable auto-optimization in config
  • Set reasonable max_file_size (5-10 MB)

8. ❌ CORS / COOP Policy Errors

Error Message:

  • "Authentication Aborted"
  • "Cross-Origin-Opener-Policy blocked"
  • Authentication popup closes immediately

Symptoms:

  • OAuth popup opens then closes
  • Can't complete GitHub login
  • Console shows COOP error

Causes:

  • Strict Cross-Origin-Opener-Policy header
  • CORS headers blocking authentication
  • CSP blocking script execution

Solution:

Step 1: Adjust COOP header:

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"
        }
      ]
    }
  ]
}

Step 2: Add OAuth proxy to CSP:

<meta http-equiv="Content-Security-Policy" content="
  connect-src 'self' https://api.github.com https://your-worker.workers.dev;
">

Step 3: For Cloudflare Pages, allow API access:

# admin/config.yml (if using Cloudflare Pages webhooks)
# Add to CSP: https://api.cloudflare.com

Prevention:

  • Set COOP header to same-origin-allow-popups by default
  • Test authentication in different browsers
  • Document required headers in project README

Migration from Decap CMS

Sveltia CMS is a drop-in replacement for Decap CMS (formerly Netlify CMS).

Migration Steps

Step 1: Update script tag:

<!-- 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/dist/sveltia-cms.js" type="module"></script>

Step 2: Keep existing config.yml:

# Your existing Decap config.yml works as-is!
backend:
  name: github
  repo: owner/repo

collections:
  # ... no changes needed

Step 3: Test locally:

# Start your site's dev server
hugo server  # or jekyll serve, or npm run dev

# Visit /admin/ and test:
# - Login
# - Content listing
# - Editing
# - Saving
# - Media uploads

Step 4: Deploy:

git add static/admin/index.html  # or your admin path
git commit -m "Migrate to Sveltia CMS"
git push

That's it! Your content, collections, and workflows remain unchanged.


What's Different?

Config Compatibility: 100% compatible

UI Changes:

  • Faster interface (no virtual DOM)
  • Better mobile experience
  • Dark mode support
  • Improved search

Performance Improvements:

  • 5x smaller bundle (300 KB vs 1.5 MB)
  • Instant content loading (GraphQL)
  • No API rate limit issues

New Features:

  • DeepL translation integration
  • Image optimization built-in
  • UUID slug generation
  • Better i18n support

Not Supported:

  • Git Gateway backend (for performance reasons)
  • Azure backend (may be added later)
  • Bitbucket backend (may be added later)

Workaround: Use Cloudflare Workers or Vercel OAuth proxy instead.


Testing Checklist

Before fully migrating, test these workflows:

  • Login with OAuth
  • View content list
  • Create new entry
  • Edit existing entry
  • Upload images
  • Publish/unpublish
  • Search content
  • Switch between collections
  • Mobile editing (if applicable)
  • i18n switching (if applicable)

Complete guide: See references/migration-from-decap.md


Deployment Patterns

Cloudflare Pages

Best For: Static sites with Cloudflare ecosystem

Steps:

  1. Connect Git repository to Cloudflare Pages:

    • Dashboard > Pages > Create Project
    • Connect GitHub/GitLab
    • Select repository
  2. Configure build settings:

    Build command: hugo  # or jekyll build, or npm run build
    Build output directory: public  # or _site, or dist
    Root directory: /
    
  3. Deploy OAuth Worker (see Cloudflare Workers OAuth section)

  4. Update config.yml with Worker URL:

    backend:
      base_url: https://your-worker.workers.dev
    
  5. Deploy:

    • Push to main branch
    • Cloudflare Pages builds automatically
    • Access admin at: https://yourdomain.pages.dev/admin/

Vercel

Best For: Next.js, Astro, or any framework with Vercel deployment

Steps:

  1. Connect Git repository:

    • Dashboard > Add New Project
    • Import repository
  2. Configure build:

    Framework Preset: <Auto-detected>
    Build Command: <Default>
    Output Directory: <Default>
    
  3. Deploy OAuth serverless function (see Vercel setup section)

  4. Set environment variables:

    GITHUB_CLIENT_ID=your_client_id
    GITHUB_CLIENT_SECRET=your_client_secret
    
  5. Deploy:

    • Push to main branch
    • Vercel builds automatically

Netlify

Best For: JAMstack sites, legacy Netlify CMS migrations

Steps:

  1. Connect Git repository:

    • Dashboard > Add New Site
    • Import repository
  2. Configure build:

    Build command: <your-build-command>
    Publish directory: public  # or _site, or dist
    
  3. Use Cloudflare Workers for OAuth (recommended over Netlify Functions)

  4. Deploy:

    • Push to main branch
    • Netlify builds automatically

GitHub Pages

Best For: Jekyll sites, simple static sites

Steps:

  1. Configure Jekyll (if using):

    # _config.yml
    include:
      - admin
    
  2. Create GitHub Actions workflow:

    # .github/workflows/deploy.yml
    name: Deploy
    on:
      push:
        branches: [main]
    jobs:
      deploy:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
          - name: Build
            run: jekyll build  # or your build command
          - name: Deploy
            uses: peaceiris/actions-gh-pages@v3
            with:
              github_token: ${{ secrets.GITHUB_TOKEN }}
              publish_dir: ./_site
    
  3. Deploy OAuth Worker for authentication

  4. Access admin:

    https://username.github.io/repo/admin/
    

Additional Resources

Templates

All templates available in 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
    • blog-posts.yml
    • docs-pages.yml
    • landing-pages.yml
  • admin/ - Base admin page templates

References

Comprehensive guides in 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
  • i18n-patterns.md - Internationalization strategies
  • framework-guides.md - Per-framework specifics

Scripts

Automation tools in scripts/:

  • init-sveltia.sh - Automated setup for new projects
  • deploy-cf-auth.sh - Deploy Cloudflare Workers OAuth
  • check-versions.sh - Verify compatibility

Official Documentation


Token Efficiency

Estimated Savings: 60-65% (~9,000 tokens saved)

Without Skill (~14,000 tokens):

  • Initial research and exploration: 2,500 tokens
  • Framework setup trial & error: 2,000 tokens
  • OAuth configuration attempts: 2,500 tokens
  • Error troubleshooting: 3,500 tokens
  • i18n setup: 1,500 tokens
  • Deployment configuration: 2,000 tokens

With Skill (~5,000 tokens):

  • Skill discovery: 100 tokens
  • Skill loading (SKILL.md): 3,500 tokens
  • Template selection: 400 tokens
  • Minor project-specific adjustments: 1,000 tokens

Errors Prevented

This skill prevents 8 common errors (100% prevention rate):

  1. ✅ OAuth authentication failures
  2. ✅ TOML front matter generation bugs
  3. ✅ YAML parse errors (strict validation)
  4. ✅ Content not listing in CMS
  5. ✅ "SVELTIA is not defined" errors
  6. ✅ 404 on /admin page
  7. ✅ Image upload failures (HEIC format)
  8. ✅ CORS / COOP policy errors

Quick Start Examples

Example 1: Hugo Blog with Cloudflare OAuth

# 1. Create Hugo site
hugo new site my-blog
cd my-blog

# 2. Create admin directory
mkdir -p static/admin

# 3. Copy templates
cp [path-to-skill]/templates/hugo/index.html static/admin/
cp [path-to-skill]/templates/hugo/config.yml static/admin/

# 4. Deploy OAuth Worker
git clone https://github.com/sveltia/sveltia-cms-auth
cd sveltia-cms-auth
npx wrangler deploy

# 5. Configure and test
hugo server
open http://localhost:1313/admin/

Example 2: Jekyll on GitHub Pages

# 1. Create Jekyll site
jekyll new my-site
cd my-site

# 2. Create admin
mkdir admin
cp [path-to-skill]/templates/jekyll/index.html admin/
cp [path-to-skill]/templates/jekyll/config.yml admin/

# 3. Add to _config.yml
echo "include:\n  - admin" >> _config.yml

# 4. Deploy
git add .
git commit -m "Add Sveltia CMS"
git push

Example 3: Migrate from Decap CMS

# 1. Update script tag in admin/index.html
sed -i 's|decap-cms|@sveltia/cms|g' static/admin/index.html
sed -i 's|decap-cms.js|sveltia-cms.js" type="module|g' static/admin/index.html

# 2. Test locally
hugo server
open http://localhost:1313/admin/

# 3. Deploy
git add static/admin/index.html
git commit -m "Migrate to Sveltia CMS"
git push

Production Examples

  • Hugo Documentation: 0deepresearch.com (Hugo + GitHub Pages + Sveltia)
  • Jekyll Blog: keefeere.me (Jekyll + Sveltia + DeepL i18n)
  • 11ty Portfolio: Various community projects

Support

Issues? Check references/common-errors.md first

Still Stuck?


Last Updated: 2025-10-24 Skill Version: 1.0.0 Sveltia CMS Version: 0.113.3 (Beta) Status: Production-ready, v1.0 GA expected early 2026