1902 lines
43 KiB
Markdown
1902 lines
43 KiB
Markdown
---
|
|
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 260+ 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.
|
|
license: MIT
|
|
allowed-tools: ['Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep']
|
|
metadata:
|
|
token_savings: "60-65%"
|
|
errors_prevented: 8
|
|
package_version: "0.113.5"
|
|
last_verified: "2025-10-29"
|
|
frameworks: ["Hugo", "Jekyll", "11ty", "Gatsby", "Astro", "Next.js", "SvelteKit", "Framework-agnostic"]
|
|
deployment: ["Cloudflare Workers", "Vercel", "Netlify", "GitHub Pages", "Cloudflare Pages"]
|
|
---
|
|
|
|
# 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:**
|
|
```bash
|
|
mkdir -p static/admin
|
|
```
|
|
|
|
2. **Create admin index page:**
|
|
```html
|
|
<!-- 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:**
|
|
```yaml
|
|
# 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:**
|
|
```bash
|
|
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:**
|
|
```bash
|
|
mkdir -p admin
|
|
```
|
|
|
|
2. **Create admin index page:**
|
|
```html
|
|
<!-- 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:**
|
|
```yaml
|
|
# 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:**
|
|
```bash
|
|
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:**
|
|
```bash
|
|
mkdir -p admin
|
|
```
|
|
|
|
2. **Create admin index page:**
|
|
```html
|
|
<!-- 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:**
|
|
```yaml
|
|
# 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`:**
|
|
```javascript
|
|
module.exports = function(eleventyConfig) {
|
|
eleventyConfig.addPassthroughCopy('admin');
|
|
// ... rest of config
|
|
};
|
|
```
|
|
|
|
5. **Start 11ty dev server:**
|
|
```bash
|
|
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:**
|
|
```bash
|
|
mkdir -p public/admin
|
|
```
|
|
|
|
2. **Create admin index page:**
|
|
```html
|
|
<!-- 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:**
|
|
```yaml
|
|
# 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:**
|
|
```bash
|
|
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:**
|
|
```bash
|
|
mkdir -p <public-folder>/admin
|
|
```
|
|
|
|
3. **Create admin index page:**
|
|
```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>
|
|
```
|
|
|
|
4. **Create config file tailored to your content structure:**
|
|
```yaml
|
|
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:**
|
|
```bash
|
|
# 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**:
|
|
- Visit https://github.com/sveltia/sveltia-cms-auth
|
|
- Click "Deploy to Cloudflare Workers" button
|
|
|
|
2. **Register OAuth App on GitHub:**
|
|
- Go to https://github.com/settings/developers
|
|
- Click "New OAuth App"
|
|
- **Application name**: Your Site Name CMS
|
|
- **Homepage URL**: https://yourdomain.com
|
|
- **Authorization callback URL**: https://your-worker.workers.dev/callback
|
|
- Save Client ID and Client Secret
|
|
|
|
3. **Configure Worker Environment Variables:**
|
|
```bash
|
|
# 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:**
|
|
```yaml
|
|
# 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:**
|
|
```typescript
|
|
// 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:**
|
|
```yaml
|
|
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:**
|
|
- GitHub: https://github.com/settings/tokens
|
|
- Scopes: `repo` (full control of private repositories)
|
|
|
|
2. **Configure local backend:**
|
|
```yaml
|
|
# 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
|
|
|
|
```yaml
|
|
# 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
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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)
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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:**
|
|
- Sign up at https://www.deepl.com/pro-api
|
|
- Free tier: 500,000 characters/month
|
|
|
|
2. **Add to config:**
|
|
```yaml
|
|
# 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`:**
|
|
```yaml
|
|
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:**
|
|
```bash
|
|
npx wrangler secret list
|
|
# Should show: GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET
|
|
```
|
|
|
|
**Step 4: Test Worker directly:**
|
|
```bash
|
|
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):
|
|
```yaml
|
|
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:**
|
|
```bash
|
|
# 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:**
|
|
```bash
|
|
# 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
|
|
```yaml
|
|
---
|
|
title: Post 1
|
|
---
|
|
--- # ← Remove this extra separator
|
|
title: Post 2
|
|
---
|
|
```
|
|
|
|
**Problem**: Incorrect indentation
|
|
```yaml
|
|
# ❌ 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
|
|
```yaml
|
|
# ❌ 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:**
|
|
```bash
|
|
# 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:**
|
|
```yaml
|
|
# 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:**
|
|
```yaml
|
|
# 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:**
|
|
```bash
|
|
# 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:**
|
|
```yaml
|
|
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:**
|
|
```html
|
|
<!-- ✅ 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:**
|
|
```bash
|
|
# 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):**
|
|
```html
|
|
<!-- 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:**
|
|
```html
|
|
<!-- 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:**
|
|
```bash
|
|
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`:
|
|
```yaml
|
|
include:
|
|
- admin
|
|
```
|
|
|
|
**11ty**: Add to `.eleventy.js`:
|
|
```javascript
|
|
module.exports = function(eleventyConfig) {
|
|
eleventyConfig.addPassthroughCopy('admin');
|
|
};
|
|
```
|
|
|
|
**Astro**: Files in `public/` are automatically copied
|
|
|
|
**Step 4: Verify deployment:**
|
|
```bash
|
|
# 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:**
|
|
```bash
|
|
# 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:**
|
|
```yaml
|
|
# 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:**
|
|
```yaml
|
|
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):
|
|
```json
|
|
{
|
|
"headers": [
|
|
{
|
|
"source": "/(.*)",
|
|
"headers": [
|
|
{
|
|
"key": "Cross-Origin-Opener-Policy",
|
|
"value": "same-origin-allow-popups"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Step 2: Add OAuth proxy to CSP:**
|
|
```html
|
|
<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:**
|
|
```yaml
|
|
# 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:**
|
|
|
|
```html
|
|
<!-- 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:**
|
|
|
|
```yaml
|
|
# Your existing Decap config.yml works as-is!
|
|
backend:
|
|
name: github
|
|
repo: owner/repo
|
|
|
|
collections:
|
|
# ... no changes needed
|
|
```
|
|
|
|
**Step 3: Test locally:**
|
|
|
|
```bash
|
|
# 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:**
|
|
|
|
```bash
|
|
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:**
|
|
```yaml
|
|
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:**
|
|
```yaml
|
|
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):**
|
|
```yaml
|
|
# _config.yml
|
|
include:
|
|
- admin
|
|
```
|
|
|
|
2. **Create GitHub Actions workflow:**
|
|
```yaml
|
|
# .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
|
|
|
|
- **Website**: https://sveltia.com (coming soon)
|
|
- **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**: 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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?**
|
|
- GitHub Issues: https://github.com/sveltia/sveltia-cms/issues
|
|
- Discussions: https://github.com/sveltia/sveltia-cms/discussions
|
|
- Stack Overflow: Tag `sveltia-cms`
|
|
|
|
---
|
|
|
|
**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
|