Sveltia CMS is a Git-based lightweight headless CMS under active development as a modern, quick replacement for Netlify CMS and Decap CMS. In some simple cases, migration is as easy as a single line of code change, although we’re still working on improving compatibility. The free, open source, UX-focused alternative to Netlify/Decap CMS is now in public beta — with more features to come.
Sveltia CMS was born in November 2022, when the progress of Netlify CMS was stalled for more than six months. @kyoshino’s clients wanted to replace their Netlify CMS instances without much effort, mainly to get better internationalization (i18n) support.
To achieve radical improvements in UX, performance, i18n and other areas, it was decided to build an alternative from the ground up, while ensuring an easy migration path from the other. After proving the concept with a rapid Svelte prototype, development was accelerated to address their primary use cases. The new offering has since been named Sveltia CMS and released as open source software to encourage wider adoption.
Our goal is to make it a viable successor to Netlify CMS, expand the Git-based headless CMS market, empower small businesses and individuals who need a simple yet powerful CMS solution, and showcase the huge potential of the Svelte framework.
We are working hard to create a much better alternative to Netlify CMS and Decap CMS by improving everything. Here’s what makes Sveltia CMS different. Look how serious we are!
logo_url
defined in the configuration will be used[^49].Alt+1
Alt+2
Ctrl+F
(Windows/Linux) or Command+F
(macOS)Ctrl+E
(Windows/Linux) or Command+E
(macOS)Ctrl+S
(Windows/Linux) or Command+S
(macOS)unsafe-eval
or unsafe-inline
keywords are not needed in the script-src
CSP directive[^33].same-origin
referrer policy is automatically set with a <meta>
tag.use_graphql
option to enable it for GitHub and GitLab.main
, master
or whatever) if not specified in the configuration file, preventing data loading errors due to a hardcoded fallback to master
[^27].i18n: duplicate
field configuration[^7].multiple_folders
i18n structure[^21].slug_length
collection option[^25].sanitize_replacement
(default: hyphen) rather than being removed[^52].preview: false
.yaml_quote: true
option for a collection, mainly for framework compatibility[^9].false
by default, without raising a confusing validation error[^45].false
by default, rather than nothing[^46].options_length
property is therefore ignored.type
property that accepts url
or email
as a value, which will validate the value as a URL or email.prefix
and suffix
string properties, which automatically prepend and/or append the developer-defined value to the user-input value.before_input
and after_input
string properties, which allow developers to display custom labels before and/or after the input UI[^28]. Markdown is supported in the value.summary
is displayed correctly when it refers to a Relation field[^36].uuid
widget with the following properties[^12]:prefix
: A string to be prepended to the value. Default: an empty string.use_b32_encoding
: Whether to encode the value with Base32. Default: false
.read_only
: Whether to make the field read-only. Default: true
.compute
widget allows to reference the value of other fields in the same collection, similar to the summary
property for the List and Object widgets. Use the value
property to define the value template, e.g. posts-{{fields.slug}}
(example)./
as expected[^48].While it’s not our goal to recreate all the features found in Netlify/Decap CMS, we plan to maximize compatibility before the 1.0 release so that more users can migrate to our modern alternative. The table below is a summary of the current limitations of Sveltia CMS:
Feature | Status in Sveltia CMS |
---|---|
Installation | Installing with npm is not supported yet. |
Backends | Only the GitHub and GitLab backends are available. We’ll add the Test backend for our demo site, but Azure, Bitbucket and Gitea are unlikely to be supported due to performance limitations. Git Gateway will not be supported for the same reason; we may implement a performant alternative sometime later. |
UI Locales | Only English and Japanese are available at this time. |
Media Libraries | External media storage services are not supported yet. We will add support for Cloudinary and Uploadcare soon. We will not support deprecated Netlify Large Media. |
Workflow | Editorial Workflow and Open Authoring are not supported yet. |
Collections | Nested collections are not supported yet. |
Widgets | Custom widgets are not supported yet. See below for other limitations. |
Customizations | Custom previews, custom formatters, manual initialization and event subscriptions are not supported yet. |
Widget | Status in Sveltia CMS |
---|---|
Code | Not supported yet. |
Date | Sveltia CMS has dropped the support for the deprecated widget following Decap CMS 3.0. Use the DateTime widget instead. |
DateTime | The date_format and time_format options with Moment.js tokens are not supported yet. Note: Decap CMS 3.1 has replaced Moment.js with Day.js; we’ll follow the change soon. |
File/Image | Field-specific media folders and media library options are not supported yet other than media_library.config.max_file_size for the default media library. |
Map | Not supported yet. |
Markdown | Editor components are not supported yet. Remark plugins will not be supported. |
Currently, Sveltia CMS is primarily intended for existing Netlify/Decap CMS users. If you don’t have it yet, follow their documentation to add it to your site and create a configuration file first. Then migrate to Sveltia CMS as described below.
As the product evolves, we’ll implement a built-in configuration editor and provide comprehensive documentation to make it easier for everyone to get started with Sveltia CMS.
Here are some starter kits for popular frameworks created by community members. More to follow!
Alternatively, you can probably use one of the Netlify/Decap CMS templates and make a quick migration to Sveltia CMS.
Have a look at the compatibility chart above first. If you’re already using Netlify/Decap CMS with the GitHub or GitLab backend and don’t have any custom widget, custom preview or plugin, migrating to Sveltia CMS is super easy. Edit /admin/index.html
to replace the CMS script
tag, and push the change to your repository.
From Netlify CMS:
-<script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script>
+<script src="https://unpkg.com/@sveltia/cms/dist/sveltia-cms.js" type="module"></script>
From Decap CMS:
-<script src="https://unpkg.com/decap-cms@^3.0.0/dist/decap-cms.js"></script>
+<script src="https://unpkg.com/@sveltia/cms/dist/sveltia-cms.js" type="module"></script>
That’s it! You can open https://[hostname]/admin/
as before to start editing. There is even no authentication process if you’ve already been signed in with GitHub or GitLab on Netlify/Decap CMS because Sveltia CMS uses your auth token stored in the browser. Simple enough!
That said, we strongly recommend testing your new Sveltia CMS instance first on your local machine. See below for how.
Updating Sveltia CMS is transparent, unless you include a specific version in the <script>
source URL. Whenever you (re)load the CMS, the latest version will be served via UNPKG. The CMS also periodically checks for updates and notifies you when a new version is available. After the product reaches GA, you could use a semantic version range (^1.0.0
) like Netlify/Decap CMS.
You can host your Sveltia CMS-managed site anywhere, such as Cloudflare Pages or GitHub Pages. But moving away from Netlify means you can no longer sign in with GitHub or GitLab via Netlify. Instead, you can use our own OAuth client, which can be easily deployed to Cloudflare Workers, or any other 3rd party client made for Netlify/Decap CMS.
You can use Sveltia CMS with a local Git repository like Netlify/Decap CMS, but Sveltia CMS has simplified the workflow by removing the need for additional configuration (the local_backend
property) and proxy server, thanks to the File System Access API available in some modern browsers.
npm run dev
or pnpm dev
.http://localhost:[port]/admin/index.html
with Chrome or Edge. The port number varies by framework.git init
) or GUI, and the hidden .git
folder exists.git diff
or a GUI like GitHub Desktop.http://localhost:[port]/
to check the rendered pages.Remember that the local repository support doesn’t do any Git operation. You have to fetch, pull, commit and push all changes manually with a Git client. Also, at this point, you have to reload the CMS to see the latest content after retrieving remote updates (this will be unnecessary once browsers support the proposed FileSystemObserver
API).
You can have an icon for each collection for easy identification in the collection list.
config.yml
as the new icon
property, like the example below. - name: tags
label: Tags
+ icon: sell
create: true
folder: data/tags/
This is actually not new in Sveltia CMS but rather an undocumented feature in Netlify/Decap CMS[^4]. You can specify media and public folders for each collection that override the global media folder. Well, it’s documented, but that’s probably not what you want.
Rather, if you’d like to add all the media files for a collection in one single folder, specify both media_folder
and public_folder
instead of leaving them empty. The trick is to use an absolute path for media_folder
like the example below. You can try this with Netlify/Decap CMS first if you prefer.
media_folder: static/media
public_folder: /media
collections:
- name: products
label: Products
create: true
folder: data/products/
+ media_folder: /static/media/products
+ public_folder: /media/products
In Sveltia CMS, those per-collection media folders are displayed prominently for easier asset management.
Sveltia CMS comes with a handy DeepL integration so that you can translate any text field from another locale without leaving the content editor. To enable the high-quality, quick translation feature:
You can now disable output of content in selected non-default locales by adding the save_all_locales
property to the top-level or per-collection i18n
configuration. Then you’ll find “Disable (locale name)” in the three-dot menu in the top right corner of the content editor. This is useful if the translation isn’t ready yet, but you want to publish the default locale content first.
With the following configuration, you can disable the French and/or German translation while writing in English.
i18n:
structure: multiple_files
locales: [en, fr, de]
default_locale: en
+ save_all_locales: false
By default, the slug for a new entry file will be generated based on the entry’s title
field. Or, you can specify the collection’s slug
option to use the file creation date or other fields. While the behaviour is generally acceptable and SEO-friendly, it’s not useful if the title might change later or if it contains non-Latin characters like Chinese. In Sveltia CMS, you can easily generate a random UUID for a slug without a custom widget!
It’s simple — just specify {{uuid}}
(full UUID v4), {{uuid_short}}
(last 12 characters only) or {{uuid_shorter}}
(first 8 characters only) in the slug
option. The results would look like 4fc0917c-8aea-4ad5-a476-392bdcf3b642
, 392bdcf3b642
and 4fc0917c
, respectively.
- name: members
label: Members
create: true
folder: data/members/
+ slug: '{{uuid_short}}'
You may already have a CI/CD tool set up on your Git repository to automatically deploy changes to production. Occasionally, you make a lot of changes to your content to quickly reach the CI/CD provider’s (free) build limits, or you just don’t want to see builds triggered for every single small change.
With Sveltia CMS, you can disable automatic deployments by default and manually trigger deployments at your convenience. This is done by adding the [skip ci]
prefix to commit messages, the convention supported by GitHub, GitLab, CircleCI, Travis CI, Netlify, Cloudflare Pages and others. Here are the steps to use it:
automatic_deployments
property to your backend
configuration with a value of false
: backend:
name: github
repo: owner/repo
branch: main
+ automatic_deployments: false
[skip ci]
is automatically added to each commit message. However, deletions are always committed without the prefix to avoid unexpected data retention on your site.[skip ci]
.If you set automatic_deployments
to true
, the behaviour is reversed. CI/CD will be triggered by default, while you have an option to Save without Publishing that adds [skip ci]
only to the associated commit.
Gotcha: Unpublished entries and assets are not drafts. Once committed to your repository, those changes can be deployed any time another commit is pushed without [skip ci]
, or when a manual deployment is triggered.
If the automatic_deployments
property is defined, you can manually trigger a deployment by selecting Publish Changes under the Account button in the top right corner of the CMS. To use this feature:
repository_dispatch
event with the sveltia-cms-publish
event type. Update your build workflow to receive this event: on:
push:
branches: [$default-branch]
+ repository_dispatch:
+ types: [sveltia-cms-publish]
If your site adopts Content Security Policy (CSP), use the following policy for Sveltia CMS, or some features may not work.
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;
img-src 'self' blob: data:;
media-src blob:;
frame-src blob:;
script-src 'self' https://unpkg.com;
connect-src 'self' blob: data: https://unpkg.com;
And combine the following policies depending on your Git backend and enabled integrations.
img-src https://*.githubusercontent.com;
connect-src https://api.github.com https://www.githubstatus.com;
img-src https://gitlab.com https://secure.gravatar.com;
connect-src https://gitlab.com;
img-src https://images.pexels.com;
connect-src https://images.pexels.com https://api.pexels.com;
img-src https://pixabay.com;
connect-src https://pixabay.com;
img-src https://images.unsplash.com;
connect-src https://images.unsplash.com https://api.unsplash.com;
connect-src https://api-free.deepl.com;
connect-src https://api.deepl.com;
If you choose to disable automatic deployments and have configured a webhook URL, you may need to add the origin to the connect-src
directive. For example,
connect-src https://api.netlify.com;
connect-src https://api.cloudflare.com;
If you have image field(s) and expect that images will be inserted as URLs, you may want to allow any source using a wildcard instead of specifying individual origins:
img-src 'self' blob: data: https://*;
Sveltia CMS is open source for sure! You can host it on your server rather than loading it from UNPKG, though it’s not recommended due to missing bug fixes. Simply copy the latest sveltia-cms.js
file from the CDN, or build it yourself:
pnpm install && pnpm build
at the project root.sveltia-cms.js
will be generated under the dist
directory.Importing the CMS as an npm package is not supported yet.
Visit the Discussions page on this GitHub repository and start a new discussion. Tell us about your use cases!
Want to build a website with Sveltia CMS? Maintainer @kyoshino is available for hire depending on your requirements.
Since Sveltia CMS is still in beta, we expect various problems. Please report any bugs to us so we can make it better for everyone. Feel free to submit feature requests as well. Meanwhile, pull requests may not be accepted for the time being due to limited review resources and the upcoming Svelte 5 migration. As we get closer to the 1.0 release, we’ll be welcoming localizers.
This software is provided “as is” without any express or implied warranty. We are not obligated to provide any support for the application. This product is not affiliated with or endorsed by Netlify, Decap CMS or any other integrated services. All product names, logos, and brands are the property of their respective owners.
[^1]: Netlify/Decap CMS #2557 [^2]: Netlify/Decap CMS #3267 [^3]: Netlify/Decap CMS #1040 [^4]: Netlify/Decap CMS #3671 [^5]: Netlify/Decap CMS #1032 [^6]: Netlify/Decap CMS #3240 [^7]: Netlify/Decap CMS #4386, #6978 [^8]: Netlify/Decap CMS #2579 [^9]: Netlify/Decap CMS #3505 [^10]: Netlify/Decap CMS #341, #1167 [^11]: Netlify/Decap CMS #1382, #6994 [^12]: Netlify/Decap CMS #1975 [^13]: Netlify/Decap CMS #5112, #5653 [^14]: Netlify/Decap CMS #4635, #4738, #5920, #6410 [^15]: Netlify/Decap CMS #6932 [^16]: Netlify/Decap CMS #2103 [^17]: Netlify/Decap CMS #1333, #7077 [^18]: Netlify/Decap CMS #441 [^19]: Netlify/Decap CMS #5910 [^20]: Netlify/Decap CMS #4563 [^21]: Netlify/Decap CMS #4781 [^22]: Netlify/Decap CMS #6642 [^23]: Netlify/Decap CMS #2 [^24]: Netlify/Decap CMS #6831 [^25]: Netlify/Decap CMS #526, #6987 [^26]: Netlify/Decap CMS #3285 [^27]: Netlify/Decap CMS #3285 [^28]: Netlify/Decap CMS #6836 [^29]: Netlify/Decap CMS #4783 [^30]: Netlify/Decap CMS #565 [^31]: Netlify/Decap CMS #1045, #3353 [^32]: Netlify/Decap CMS #302, #5549 [^33]: Netlify/Decap CMS #6513 [^34]: Netlify/Decap CMS #2138 [^35]: Netlify/Decap CMS #7086 [^36]: Netlify/Decap CMS #6325 [^37]: Netlify/Decap CMS #1481 [^38]: Netlify/Decap CMS #1984 [^39]: Netlify/Decap CMS #946 [^40]: Netlify/Decap CMS #5630 [^41]: Netlify/Decap CMS #7011 [^42]: Netlify/Decap CMS #2307 [^43]: Netlify/Decap CMS #5381 [^44]: Netlify/Decap CMS #2613 [^45]: Netlify/Decap CMS #1424 [^46]: Netlify/Decap CMS #4726 [^47]: Netlify/Decap CMS #2370, #5596 [^48]: Netlify/Decap CMS #5569 [^49]: Netlify/Decap CMS #5752 [^50]: Netlify/Decap CMS #4646 [^51]: Netlify/Decap CMS #6731 [^52]: Netlify/Decap CMS #7147 [^53]: Netlify/Decap CMS #5673, #6482, #6707, #6999, #7047, #7123, #7152 [^54]: Netlify/Decap CMS #1347, #4629, #6287 — Decap 3.0 updated the Slate library in an attempt to fix the problem, but the IME bug on mobile/tablet browsers remains unresolved.