Skip to content

Successor to Netlify CMS

Sveltia CMS was built from scratch as a modern successor to Netlify CMS, which was abandoned in early 2022 (and later rebranded as Decap CMS). We have picked up where they left off and have already solved hundreds of issues reported in the predecessor’s repository, ranging from critical bugs to top feature requests.

Here’s our backstory and what makes Sveltia CMS different.

Netlify vs. Netlify CMS

Netlify CMS was one of the open source projects maintained by Netlify, the popular web hosting and automation platform. While the CMS is no longer part of their portfolio, Netlify itself remains a thriving company offering various services for modern web development.

Independent Project

We are not affiliated with Netlify or any of its partners. Sveltia CMS is an independent, open source project created and maintained by Kohei Yoshino. It’s platform-independent and not tied to any specific hosting provider.

TL;DR

  • A complete, modern rewrite of Netlify CMS (now Decap CMS)
  • Actively maintained and outperforming stagnant Decap CMS in all aspects
  • De facto successor to Netlify CMS that works better by design
  • Drop-in replacement for common Netlify/Decap CMS use cases
  • Solved 290+ Netlify/Decap CMS issues (625+ including duplicates)
  • Significant UX/DX improvements with more enhancements planned
  • Many sites already migrated from Netlify/Decap CMS to Sveltia CMS

290 Netlify/Decap CMS issues solved in Sveltia CMS

Motivation

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 ultimately decided to build an alternative from the ground up, while ensuring an easy migration path from the other. After proving the idea with a rapid Svelte prototype, development was accelerated to address their primary use cases. The new product has since been named Sveltia CMS and released as open source software to encourage wider adoption.

We loved the simple, unique setup of Netlify CMS that turned a Git repository into a database with a single-page app served from a CDN plus a plain YAML config file. In support of the Jamstack concept, we wanted to revive it, modernize it, and take it to the next level.

Objectives

Our goal is not just to create another CMS that is compatible with Netlify CMS, but to succeed Netlify CMS as a whole by addressing its numerous issues reported to its repository over the years. Here’s how we’re doing:

Ensuring High Compatibility with Netlify/Decap CMS

  • Inherits the CDN-served SPA architecture of Netlify CMS, with various improvements
  • Aims to work as a drop-in replacement for common use cases, as long as deprecated features are not in use
  • The vast majority of existing configurations work out of the box
  • Some missing features will be implemented before or shortly after GA

Tackling as Many Netlify/Decap CMS Issues as Possible

  • So far, 290+ issues, or 625+ if including duplicates, have been effectively solved in Sveltia CMS (Yes, you read it right)
  • Target:
    • 300 issues, or 600 if including duplicates, by v1.0 — Almost there! 🚀
    • 450 issues, or 950 if including duplicates, in the future 💪
    • or every single issue that’s relevant, fixable, and worth dealing with 🔥
  • Issues include everything:
  • Many of the bugs, including the annoying crashes, have already been solved
  • Many of their top-voted features are on our table or already implemented in Sveltia CMS

What About Decap CMS?

Due to its unfortunate abandonment in early 2022, Netlify CMS spawned three successors. Sveltia CMS is one of them, along with Static CMS and Decap CMS. Here’s a brief comparison of the three projects:

  • Static CMS: a community fork
    • Initial commit made in September 2022
    • ❌ Discontinued in September 2024 after making meaningful improvements
  • Sveltia CMS: not a fork but a complete rewrite
    • Started in November 2022, first appeared on GitHub in March 2023
    • Personal project of an experienced UX engineer
    • ✅ Actively developed with frequent releases and numerous improvements
    • ✅ Relevant issues are being resolved regardless of their age or status
    • ✅ Most of new bug reports are addressed promptly, usually within a day
    • ✅ Pull requests are reviewed quickly, though we only accept trivial ones for now
    • ✅ Provides comprehensive documentation, including Netlify CMS migration guide
    • ✅ The Showcase page features various real-world sites using Sveltia CMS
    • ✅ An extensive roadmap is available to keep users informed
    • ✅ No known unpatched security vulnerabilities, with dependencies kept up-to-date
  • Decap CMS: a rebranded version
    • Announced in February 2023 as an official continuation with a Netlify agency partner taking ownership
    • Maintained by a company with three developers
    • ⚠️ Seemingly random issues were closed as stale following the takeover
    • ⚠️ It took six months to ship the first release (v3.0) under the new name
    • ⚠️ Mostly low activity with only occasional releases and a few minor improvements
    • ⚠️ Bug reports continue to pile up, often without any response
    • ⚠️ Pull requests, including those from maintainers, sit idle for months or years
    • ⚠️ Keeps poor documentation without any migration guide or compatibility notes
    • ⚠️ The Examples page only has demos, not real-world users
    • ⚠️ No public roadmap is available, leaving users in the dark
    • ❌ A moderate severity XSS vulnerability, a local server vulnerability, high severity dependency vulnerabilities and fatal crashes remain unaddressed

While Decap CMS emerged as the official successor, it has largely stagnated and failed to revive the original Netlify CMS project as hoped. Unfortunately, it’s not even in maintenance mode, as critical bugs and security vulnerabilities have gone unaddressed for a long time. This leaves users with no choice but to switch to Sveltia CMS or other alternatives.

Created months before the announcement of Decap CMS, Sveltia CMS has firmly established itself as the de facto successor. We have a clear focus on delivering a superior experience for users seeking a modern alternative to Netlify CMS. Regardless of other projects in this field, we are committed to continuously enhancing the platform for the benefit of our users.

True Successor, Better by Design

Among the three successors, Sveltia CMS is the only project that doesn’t inherit the complexity, technical debt, and numerous bugs of Netlify CMS.

  • We rebuilt the app from scratch using a modern framework
  • We don’t reuse any part of the predecessor’s codebase
  • We incorporate i18n support into the core instead of adding it as an afterthought
  • We closely monitor and analyze the predecessor’s issue tracker
  • We rearchitect the entire user experience (UX) and developer experience (DX)

This “total reboot” has enabled us to implement hundreds of improvements without getting stuck in a legacy system. Furthermore:

  • We carry forward the original vision of Netlify CMS as a simple, Git-based content management solution for Jamstack sites
  • We dedicate significant time and effort to modernizing the platform, including documentation and developer tools
  • We continue to address issues reported in the predecessor’s repository
  • We materialize the enhancements that Netlify CMS users have long desired

For that reason, Sveltia CMS is the true successor to Netlify CMS, not just a spiritual successor or mere alternative, albeit unofficial. Whether you’re migrating from the original Netlify CMS or another successor, Sveltia CMS offers the best overall experience.

Adoption

GitHub search shows that Netlify/Decap CMS users are migrating to Sveltia CMS every day to take advantage of its numerous improvements. Many sites have already made the switch. Visit our Showcase page to see some of them!

Improvements over Netlify/Decap CMS

Netlify/Decap CMS users will definitely be pleased and surprised by the numerous improvements we have made, from the small to the large. We make everything better.

Note

This lengthy section compares Sveltia CMS with both Netlify CMS and Decap CMS. Some of the listed issues may have been resolved in the current version of Decap CMS.

Better UX

  • Created and actively maintained by an experienced UX engineer who loves code, design, marketing, localization, documentation and everything in between. You can expect constant improvements to the user experience (UX) and developer experience (DX) across the platform.
  • The maintainer tries to respond to bug reports as quickly as possible. While there are no guarantees, the typical turnaround time for a bug fix is less than 24 hours.
  • Frequent releases deliver new features and enhancements to users more quickly. Meanwhile, Decap CMS’s release interval has been irregular and often long, sometimes exceeding two months, even between patch releases, which can be frustrating for both users and contributors.
  • Many of our minor releases address one or more Netlify/Decap CMS issues, giving you even more reasons to switch from the legacy predecessor.
  • Offers a modern, intuitive user interface that utilizes the full viewport,[1] inspired in part by the Netlify CMS v3 prototype.[2][3][4][5][6]
  • Provides immersive dark mode.[7] The UI theme follows the user’s system preference by default and can be changed in the application settings.
  • Users can easily manage content on-the-go with mobile and tablet support.[8][9]
    • For a smoother experience, we even go beyond responsive design with optimized navigation, floating action buttons, view transitions, larger buttons, and other tweaks. We’ll continue to fully optimize the app for small screens and touch devices.
    • If you’re already signed in on your desktop, open the Account menu in the top right corner of the CMS, click Sign In with Mobile, and scan the QR code for passwordless sign-in. Your settings will be automatically copied.
  • Made with Svelte, not React, means we can spend more time on UX rather than tedious state management. It also allows us to avoid common fatal React application crashes.[10][11] Best of all, Svelte offers great performance.
  • Other crashes in Netlify/Decap CMS are also irrelevant to us, making Sveltia CMS much more stable.[12][13][14][15] Netlify/Decap CMS continues to receive crash reports on a daily basis, with no effective solution in sight.
  • We build our own UI component library, including custom dialogs, to ensure optimal usability without compromising accessibility.[16][17][18][19][20][21][22][23]
  • Users can personalize the application with various settings, including appearance and language. Developer Mode can also be enabled, which enables certain features and displays the CMS version number.[24]
  • Never miss out on the latest features and bug fixes by being notified when an update to the CMS is available.[25] Then update to the latest version with a single click.[26]

Better Performance

  • Built completely from scratch with Svelte instead of forking React-based Netlify/Decap CMS. The app starts fast and stays fast with no virtual DOM overhead. Note that Svelte is a compiler and Sveltia CMS is framework-agnostic; it’s served as a vanilla JavaScript bundle.
  • Small footprint: The bundle size is less than 500 KB when minified and brotlied, which is much lighter than Netlify CMS (1.5 MB), Decap CMS (1.5 MB) and Static CMS (2.6 MB).[27] This significant reduction in size is thanks to the combination of Svelte 5 and Vite. Sveltia CMS also dynamically loads certain dependencies only when needed, further reducing the initial load time.
  • Uses the GraphQL API for GitHub and GitLab to quickly fetch content at once, so that entries and assets can be listed and searched instantly[28][29] (the useless search configuration option is therefore ignored). It also avoids the slowness and potential API rate limit violations caused by hundreds of requests with Relation fields.[30]
  • Saving entries and assets to GitHub is also much faster thanks to the GraphQL mutation.
  • The Gitea/Forgejo backend is also faster because it utilizes an efficient API method introduced in Gitea 1.24 and Forgejo 12.0.
  • Our local repository workflow utilizes the modern File System Access API to read and write files natively through the web browser, rather than using a slow, ad hoc REST API through a proxy server.
  • Sorting, filtering and grouping of entries is done instantly without reloading the entire content.
  • Uses caching, lazy loading and infinite scrolling techniques. A list of repository files is stored locally for faster startup and bandwidth savings.
  • Thumbnails of assets, including videos and PDF files, are generated and cached for faster rendering of the Asset Library and other parts of the CMS.[31][32]
  • No typing lag on input fields, especially within nested lists and objects.[33]
  • The entry preview doesn’t use an <iframe> by default because it’s a performance overhead.[34]

Better Productivity

We’ve made various improvements to help you get your work done faster and more efficiently:

  • Developers can work with a local Git repository without any additional configuration or proxy server, resulting in a streamlined workflow and improved performance.[35]
    • It also avoids a number of issues, including potential security risks,[36][37][38] a 30 MB file size limit,[39] an unknown error with publish_mode,[40] and an unused logo_url.[41]
    • When you delete an entry or an asset file, the empty folder that contains it is also deleted, so you don’t have to delete it manually.
  • Provides a smoother user experience in the Content Editor with various enhancements:
    • Users can upload multiple files at once to File/Image fields when the multiple option is enabled.[42]
    • Uploading files can be done with drag and drop.[43]
    • Users can translate entry fields with one click using an integrated translation service without having to leave the CMS.
    • A local backup of an entry draft is automatically created without interruption by a confirmation dialog, which annoys users and can cause a page navigation problem if dismissed.[44] The backup can then be reliably restored without unexpected overwriting.[45]
    • Click once (the Save button) instead of twice (Publish > Publish now) to save an entry. Or just hit the Ctrl+S (Windows/Linux) or Command+S (macOS) key to save your time.
    • The editor closes automatically when an entry is saved. This behavior can be changed in the application settings.
  • Thanks to the built-in image optimizer, there’s no need for an external application to convert or resize images before uploading them.[46][47]
  • Users can delete multiple entries and assets at once.
  • Users can manage content on-the-go with mobile and tablet support.[8:1][9:1] This is especially useful for content editors who need to make quick updates while away from their desks.
  • Instant full-text search with results sorted by relevance helps you find entries faster. In Netlify/Decap CMS, you often won’t get the results you expect.
  • Some keyboard shortcuts are available for faster editing.

Better Security

  • Avoids vulnerabilities in dependencies through constant updates, Dependabot alerts, pnpm audit, and frequent releases, unlike Netlify/Decap CMS where a number of high severity vulnerabilities remain unaddressed for a long time.[48][49]
    • We also use the cooldown option for ncu and the minimumReleaseAge option for pnpm to avoid upgrading to a version that was just released. These options help protect against npm supply chain attacks.
  • The unpatched XSS vulnerability in Decap CMS does not affect Sveltia CMS, as our entry preview implementation is completely different.
    • However, the Markdown widget was potentially vulnerable to XSS attacks because the sanitize_preview option was set to false by default for compatibility with Netlify/Decap CMS. This behavior is documented and is not a bug, but it’s definitely not secure. In Sveltia CMS 0.105.0, we changed the default value to true, assuming that most users would prefer security over compatibility.
  • Our local repository workflow does not require a proxy server. This reduces attack surfaces by eliminating the possibility of compromised dependencies[36:1], unauthorized API access[37:1] or incomplete path validations[38:1] in the proxy server.
  • Thanks to pnpm, Vite, GitHub Actions and npm package provenance, our release process is fast, reliable and transparent. This setup makes it easy to verify the integrity of published code and assets. It also helps us avoid errors that can occur with manual build steps.[50]
  • We have enabled trusted publishing and 2FA for package publishing.
  • We have created a security policy.
  • We have documented how to set up a Content Security Policy for the CMS to prevent any unexpected errors or otherwise insecure configuration.[51]
  • The unsafe-eval and unsafe-inline keywords are not needed in the script-src CSP directive.[52]
  • The same-origin referrer policy is automatically set with a <meta> tag.
  • Sveltia CMS has a secure context requirement that forces the site content, including the CMS configuration file, to be served over HTTPS.
  • GitHub commits are automatically GPG-signed and marked as verified.[53]

Better Accessibility

  • Improved keyboard handling lets you efficiently navigate through UI elements using the Tab, Space, Enter and arrow keys.[54][55]
  • Comprehensive WAI-ARIA support enables users who rely on screen readers such as NVDA and VoiceOver.[56] An announcement is read out when you navigate to another page.
  • The rich text editor is built with Lexical, which is said to follow accessibility best practices. The Dragon NaturallySpeaking support is enabled.
  • Ensures sufficient contrast between the foreground text and background colors.
  • Enabled and disabled buttons can be clearly distinguished.[57]
  • Links are underlined by default to make them easier to recognize. This behavior can be changed in the Accessibility Settings if you prefer.
  • Honours your operating system’s reduced motion and reduced transparency settings. Support for high contrast mode will be added later.
  • Browser console logs for developers are readable in either light or dark mode.[58]
  • We’ll continue to test and improve the application to meet WCAG 2.2.

Better Installation

  • Sveltia CMS is built with Svelte, and we only publish precompiled, minified vanilla JavaScript bundles. No dependencies will be installed when you install the app with npm, meaning:
    • No React compatibility issues that might prevent developers from upgrading a project for many months.[59]
    • No peer dependency conflicts mainly due to legacy third-party React UI libraries.[60] We build the app using our own Svelte UI component library to reduce reliance on third parties.
    • No build errors due to browser-unfriendly packages and other dependency issues.[61][62][63]
  • Some servers and frameworks are known to remove the trailing slash from the CMS URL (/admin) depending on the configuration. In such cases, the config file is loaded from the proper URL (/admin/config.yml) instead of a regular relative URL (./config.yml = /config.yml), which results in a 404 Not Found error.[64]
  • The robots meta tag is automatically added to HTML to prevent the admin page from being indexed by search engines.[65] Developers are still encouraged to manually add <meta name="robots" content="noindex"> to index.html, as not all crawlers support dynamically added tags. However, our solution should at least work with Google in case you forget to do so.
  • Initializing the CMS twice (due to the incorrect or missing placement of window.CMS_MANUAL_INIT) will not result in a NotFoundError.[66]
  • Sveltia CMS automatically enables manual initialization when you import the JavaScript module, so you don’t need to have window.CMS_MANUAL_INIT = true in your code.
  • We provide only one package, @sveltia/cms, instead of many (decap-cms, decap-cms-app, decap-cms-core and so on), which is simpler and less confusing.

Better Configuration

  • Sveltia CMS supports a JSON configuration file that can be generated for bulk or complex collections.[67] A TOML configuration file is also supported.
  • Also supports multiple configuration files to allow developers to modularize the configuration.[68]
  • We provide an up-to-date JSON schema for YAML/JSON configuration files, which enables autocomplete and validation in VS Code and other editors.[69] If you use deprecated options in a supported code editor, you should receive a warning.
  • Improved TypeScript support:
    • We keep our type definitions for CMS.init() and other methods complete, accurate, up-to-date and annotated.[70][71][72][73][74] This makes it easier to provide a config object when manually initializing the CMS.
  • Config validation enhancements:
    • Sveltia CMS has additional validation rules designed to prevent common misconfigurations that could lead to runtime errors:
      • Common backend misconfigurations, such as an incorrect repository name or a missing OAuth client ID[75]
      • A mismatch between the format and extension options for a collection
      • Invalid collection, collection file, field, variable type names (e.g. names containing . or *)
      • slug templates containing slashes
      • Mutually exclusive config options (e.g. field, fields and types on List fields)
      • collection and file references on Relation fields
      • Duplicate variable type names
      • Unsupported widgets and options
      • (more to come)
    • The error messages include the specific collection, field, variable type and fields names, rather than indexes such as collections[7].fields[9].types[1]. This helps you to quickly identify the problematic configuration.
    • There are no false error messages saying should match case "color" schema.
    • There are no error messages that advise to use deprecated camel case options like valueField.

Better Backend Support

The GitHub, GitLab, Gitea/Forgejo and Test backends are available in Sveltia CMS. For performance reasons, we don’t plan to support other backends.

  • Uses the GraphQL API where possible for better performance, as mentioned above. You don’t need to set the use_graphql option to enable it for GitHub and GitLab.[29:1]
  • The Git branch name is automatically set to the repository’s default branch (main, master or whatever) if not specified in the configuration file, preventing data loading errors due to a hardcoded fallback to master.[76][77] If a branch name is specified, it works as expected.[78]
  • It’s possible to disable automatic deployments by default or on demand to save costs and resources associated with CI/CD and to publish multiple changes at once.[79]
  • Users can quickly open the source file of an entry or asset in your repository via the 3-dot menu when Developer Mode is enabled.
  • Service status checks are performed frequently and an incident notification is displayed prominently.
  • Authentication improvements:
    • We provide our own OAuth client for GitHub and GitLab.
    • The external OAuth window will not get stuck on a blank page after signing in.[80]
    • Users can sign in directly with a Git-based backend using a personal access token (PAT) instead of going through the regular OAuth flow.[81]
    • The OAuth access token is automatically renewed when using PKCE authorization.[82]
  • GitLab-specific improvements:
    • Implements the GraphQL API with proper authorization.[83]
    • Comes with background service status checking, just like GitHub.
    • Supports Git LFS (documentation).[84]
    • Users won’t get a 404 Not Found error when you sign in to the GitLab backend.[85]
    • We implemented a workaround for a GraphQL complexity limit issue in GitLab 18.4.2, while Netlify/Decap CMS continued to suffer from the same problem.[86] Our workaround was removed after GitHub 18.4.5 solved the underlying issue.
  • Our Gitea/Forgejo backend is high-performing because it retrieves multiple entries at once. It also supports Git LFS (documentation). Additionally, the backend won’t cause 400 Bad Request errors due to the presence of DRAFT_MEDIA_FILES in file paths.[87]
  • Unlike Netlify/Decap CMS, Sveltia CMS does not have a hardcoded API request timeout of 60 seconds, which can lead to unexpected errors when working with large files or slow networks.[88] Though users may still experience timeouts due to server-side limitations, at least the client-side won’t impose an arbitrary limit.
  • Features the all-new local repository workflow for a better DX. See the productivity section above.
  • An indicator is displayed in the account menu when using the local repository workflow.[89]
  • Developers can select the local and remote backends while working on a local server.
  • The Test backend saves entries and assets in the browser’s origin private file system (OPFS) so that changes are not discarded when the browser tab is closed or reloaded.[90] The persistent storage support works with all modern browsers except Safari.
  • Commit message template supports the {{author-email}} template tag to include the author’s email address.
  • API error messages are displayed in a user-friendly manner instead of generic messages like Failed to fetch.[91]

Better I18n Support

Sveltia CMS has been built with a multilingual architecture from the very beginning. You can expect first-class internationalization (i18n) support, as it was required by clients of the maintainer, @kyoshino, who himself was a long-time Japanese localizer for Mozilla and currently lives in the most diverse city in the world where 150+ languages are spoken.

  • Configuration
    • The i18n limitations in Netlify/Decap CMS do not apply to Sveltia CMS:
      • File collections support multiple files/folders i18n structures.[92] To enable it, simply use the {{locale}} template tag in the file path option, e.g. content/pages/about.{{locale}}.json or content/pages/{{locale}}/about.json. For backward compatibility, the global structure option only applies to folder collections, and the default i18n structure for file collections remains single file.
      • The List and Object widgets support the i18n: duplicate field configuration so that changes made with these widgets are duplicated between locales.[93][94] The i18n configuration can normally be used for the subfields.
    • Gives more control over entry file paths:
      • The new multiple_root_folders i18n structure allows to have locale folders below the project root: /<locale>/<folder>/<path>.<extension>.[95]
      • The new omit_default_locale_from_file_path i18n option allows to exclude the default locale from file paths. This option applies to all multiple files/folders structures, aiming to support Zola’s multilingual sites. (Discussion)
      • Entry-relative media folders can be used in conjunction with the multiple_folders i18n structure.[96]
    • Entry slug enhancements:
    • The required field option accepts an array of locale codes in addition to a boolean, making the field required for a subset of locales when i18n support is enabled. For example, if only English is required, you could write required: [en]. An empty array is equivalent to required: false.
    • The {{locale}} template tag can be used in the preview_path collection option to provide site preview links for each language.[100]
    • It’s possible to embed the locale code in an entry by using widget: hidden along with default: '{{locale}}'.[101]
    • The value_field Relation field option can contain a locale prefix like {{locale}}/{{slug}}, which will be replaced with the current locale. It’s intended to support i18n in Astro. (Discussion)
    • The collection filters are applied correctly regardless of the i18n structure.[102]
    • The summary collection option supports the {{locales}} template tag to show enabled entry locales in the entry list.
  • User interface
    • Eliminates UI confusion: The Preview Pane can be displayed without toggling i18n in the Content Editor. Both panes are scrollable. There is no condition where both panes are edited in the same language at the same time.
    • Users can easily switch between locales while editing by clicking a button instead of a dropdown list when there are less than 5 locales.
    • Language labels appear in human-readable display names instead of ISO 639 language codes because it’s not easy for everyone to recognize DE as German, NL as Dutch, ZH as Chinese, and so on.
    • It’s possible to set the editor pane locale via a URL query parameter, e.g. ?_locale=fr.
  • Content editing
    • Integrates translation services to allow translation of text fields from another locale with one click.
    • The Content Editor supports RTL scripts such as Arabic, Hebrew and Persian.[103]
    • It’s possible to disable non-default locale content.[104]
    • Boolean, DateTime, List and Number fields in the entry preview are displayed in a localized format.
    • Boolean fields are updated in real time between locales like other widgets to avoid confusion.[105]
    • Relation fields with i18n enabled won’t trigger a change in the content draft status when you start editing an existing entry.[106]
    • Solves problems with Chinese, Japanese and Korean (CJK) IME text input in the rich text editor for the Markdown widget.[107]
    • Raises a validation error instead of failing silently if the single_file structure is used and a required field is not filled in any of the locales.[108]
    • Fields in non-default locales are validated as expected.[109]
    • No internal error is thrown when changing the locale.[110]
    • Duplicating an entry duplicates all locale content, not just the default locale.[111]
    • Copying Markdown from another locale using the menu works as expected.[112]

Better Collections

  • Configuration
    • Provides some new options, including:
      • icon: Choose a custom icon for each collection.[113]
        • The option can also be used for individual files within a file collection. The specified icon will then appear in the file list.
      • thumbnail: Specify the field name for a thumbnail displayed on the entry list, like thumbnail: featuredImage.
        • A nested field can be specified using dot notation, e.g. heroImage.src.
        • A wildcard in the field name is also supported, e.g. images.*.src.
        • Multiple field names can be specified as an array for fallback purpose, e.g. [thumbnail, cover].
        • Occasionally, you may not have suitable images for thumbnails. For example, your images may have subtle differences or varied aspect ratios. In that case, you can disable the thumbnail with thumbnail: false.
        • If this option is omitted, any non-nested, non-empty Image or File field will be used.[114] Sveltia CMS doesn’t have hardcoded inference fields.[115]
      • limit: Specify the maximum number of entries that can be created in a folder collection.[116]
      • divider: Add dividers to the collection list.
    • Enhancements to the entry filter option for folder collections:
      • Boolean value works as expected.[117]
      • value accepts null to match an undefined field value.
      • value accepts an array to provide multiple possible values.[118]
      • pattern can be used instead of value to provide a regular expression, just like the view_filters collection option.[119]
    • Enhancements to string transformations:
      • Transformations can be used in more places than just the collection summary:
        • The slug, path and preview_path collection options[120]
        • The summary field option for the List and Object widgets
      • The default transformation accepts a template tag like {{fields.slug | default('{{fields.title}}')}}, making it possible to fall back to a different field value. (Discussion)
      • The date transformation supports the time zone argument. The only available value is utc, which converts a date to UTC. This is useful if the specified DateTime field is local, but you want to force UTC in the entry slug, e.g. {{date | date('YYYYMMDD-HHmm', 'utc')}}. (Discussion)
      • The date transformation returns an empty string if an invalid date is given.[121]
      • Multiple transformations can be chained like {{title | upper | truncate(20)}}.
    • Enhancements to file collections:
      • Sveltia CMS supports singletons, a simple form of a file collection.[122]
      • File collections support files without extensions.[123] This is useful for editing site deployment configuration files, such as _headers and _redirects.
      • Each file in a file collection has the format and frontmatter_delimiter options, which can be used to specify the file format, making it possible to have yaml-frontmatter, toml-frontmatter and json-frontmatter side by side.[124]
      • The new raw format allows you to edit raw files without front matter, such as plain text files, CSV files, JSON files and YAML files.[125] When using this format, make sure to have only one field named body with the widget type set to code, markdown, richtext or text.
    • The create option for folder collections defaults to true, providing a better out-of-the-box experience.
    • The collection label defaults to the name value according to the Decap CMS document, while Netlify/Decap CMS actually throws a configuration error if the label option is omitted.
    • Nested fields (dot notation) can be used in the path option for a folder collection, e.g. {{fields.state.name}}/{{slug}}.[126]
    • Markdown is supported in the description collection option.[127] Bold, italic, strikethrough, code and links are allowed.
    • The collection folder can be an empty string (or . or /) if you want to store entries in the root folder. This supports a typical VitePress setup.
  • Entry slugs
    • The global slug options have the following new options:
      • trim: Remove leading and trailing replacement characters, such as hyphens, from an entry slug. The default value is true. Set to false to keep them.
      • lowercase: Convert an entry slug to lowercase. The default value is true. Set to false to preserve the original casing.[128]
      • maxlength: The maximum number of characters for an entry slug; avoid deployment errors with Netlify or other platforms.[129] Default to undefined, meaning no limit.
    • It’s possible to use a random UUID for an entry slug.
    • Entry slugs are editable.[130]
      • To allow users to explicitly edit the entry slug in an initial entry draft, add {{fields._slug}} to the slug collection option. This will display a special slug editor UI that looks like a standard string field, but the value will be used as the entry slug.
      • Once an entry is saved, users can edit the slug via the 3-dot menu in the Content Editor.
    • Entry slugs are localizable.[97:1]
      • Use {{fields._slug | localize}} to make the slug field editable and localizable.
    • Slug generation is fail-safe: If a slug cannot be determined from entry content, part of a random UUID is used instead of throwing an error or filling in with arbitrary string field values.[131]
    • If a collection only has the Markdown body field, an entry slug will be generated from a header in the body, if exists. This supports a typical VitePress setup.
    • Entry slug template tags support transformations just like summary string template tags.[120:1] For example, you can use {{fields.date | date('YYYY-MM-DD')}} to generate a slug like 2025-01-23 from a DateTime field.
    • Single quotes (apostrophes) in a slug will be replaced with sanitize_replacement (default: hyphen) rather than being removed.[132]
    • Setting the collection path doesn’t affect the entry slugs stored with the Relation widget.[133]
  • Entry listing
    • The default sort field and direction can be specified.[134]
    • The default filter and group can also be specified in the same way as with Static CMS.[135]
    • Sorting entries by a DateTime field works as expected.[136]
    • Entry grouping and sorting can work together. For example, it’s possible to group by year and then sort by year if configured properly.[137]
    • The sortable_fields option accepts a special slug value to allow sorting by entry slugs.
    • Index file inclusion allows users to edit Hugo’s special _index.md file, including localized ones like _index.en.md, within a folder collection.[138] If the index_file option is not defined, these files will be hidden in a folder collection unless the path option is configured to end with _index and the extension is md.[139]
    • A console error won’t be thrown when a collection doesn’t have the title field.[140] In that case, an entry summary will be generated from a header in the Markdown body field, if exists, or from the entry slug, so the summary will never be an empty.[141] This supports a typical VitePress and Docusaurus setup.[142]
    • If there was an error while parsing an entry file, such as duplicate front matter keys, it won’t show up as a blank entry, and a clear error message will be displayed in the browser console.[143]
    • A single file can be used for more than one item in a file collection.[144]
  • User interface
    • The collection list displays the number of items in each collection.
    • Users can select multiple entries and delete them at once.
    • In an entry summary, basic Markdown syntax used in the title, including bold, italic and code, are parsed as Markdown. HTML character references (entities) are also parsed properly.[145]
    • If you update an entry field that appears in the collection’s summary, such as title, the entry list displays an updated summary after you save the entry.[146]
    • Thumbnails of entries are displayed not only in the grid view but also in the list view, making it easier to navigate.
    • If entries don’t have an Image field for thumbnails, the entry list will only be displayed in the list view, because it doesn’t make sense to show the grid view.[147]
    • Assets stored in a collection media folder can be displayed next to the entries.
    • The New Entry button won’t appear when a developer accidentally sets the create: true option on a file collection because it’s useless.[148]
    • The Delete Entry button won’t appear when a developer accidentally sets the delete: true option on a file collection because the preconfigured files should not be deleted.

Better Content Editing

  • Required fields, not optional fields, are marked for efficient data entry.
  • Users can revert changes to all fields or a specific field.
  • If you revert changes and there are no unsaved changes, the Save button is disabled as expected.[149]
  • The new readonly field option makes the field read-only. This is useful when a default value is provided and the field should not be editable by users.[150] The option defaults to false except for the UUID widget, where it defaults to true.
  • Fields with validation errors are automatically expanded if they are part of nested, collapsed objects.[151]
  • A full regular expression, including flags, can be used for the widget pattern option.[152] For example, if you want to allow 280 characters or less in a multiline text field, you could write /^.{0,280}$/s (but you can now use the maxlength option instead.)
  • A long validation error message is displayed in full, without being hidden behind the field label.[153]
  • Any links to other entries will work as expected, with the Content Editor being updated for the other.[154]
  • In the Boolean and Select widgets, you don’t have to update a value twice to re-enable the Save button after saving an entry.[155]
  • data can be used as a field name without causing an error when saving the entry.[156]

Better Content Preview

  • The Preview Pane comes with a minimal default style.[157] It looks nice without a custom preview style or template.
  • For better performance, the Preview Pane doesn’t use an <iframe> unless a custom preview stylesheet is registered.[34:1]
  • The Preview Pane displays all fields, including each label, making it easier to see which fields are populated.
  • Entering a long value into a field will not cause the field label to disappear.[158]
  • Clicking a field in the Preview Pane focuses the corresponding field in the Edit Pane.[159] It automatically expands when collapsed.
    • This is equivalent to the (misleading) visual editing feature introduced in Decap CMS 3.6.0, but our click-to-highlight feature is enabled by default; you don’t need to opt in with the editor.visualEditing collection option. We don’t plan to support this option because it’s confusing, unnecessary and undocumented. (Plus, why camel case?)
  • The Preview Pane doesn’t cause a scrolling issue.[160]
  • The Preview Pane doesn’t crash with a Minified React error.[161]
  • Provides better scroll synchronization between the panes when editing or previewing an entry.[162]
  • Developers can hide the preview of a specific field using a new field option: preview: false.[163]
  • See below for widget-specific enhancements, including support for variable types[164] and YouTube videos.

Better Data Output

  • Keys in generated JSON/TOML/YAML content are always sorted by the order of configured fields, making Git commits clean and consistent.[165]
  • Netlify/Decap CMS often, but not always, omits optional and empty fields from the output.[166] Sveltia CMS aims at complete and consistent data output — it always saves proper values, such as an empty string, an empty array or null, instead of nothing (undefined), regardless of the required field option.[167][168][169][170]
    • In other words, in Sveltia CMS, required: false makes data input optional, but doesn’t make data output optional.
    • To omit empty optional fields from data output, use omit_empty_optional_fields: true in the data output options. This is useful if you have data type validations that expect undefined.[171]
  • JSON/TOML/YAML data is saved with a new line at the end of the file to prevent unnecessary changes being made to the file.[172]
  • Leading/trailing whitespaces in text-type field values are automatically removed when you save an entry.[173] No option is required to trim the values.[174]
  • YAML string folding (maximum line width) is disabled, mainly for framework compatibility.[175]
  • A standard time is formatted as HH:mm:ss instead of HH:mm for framework compatibility.
  • DateTime field values in ISO 8601 format are stored in native date/time format instead of quoted strings when the data output is TOML.[176]
  • Provides JSON/YAML format options as part of the data output options, including indentation and quotes.[177][178]
  • It’s impossible to inject front matter through the body field.[179]

Better Widgets

Sveltia CMS supports all the built-in widgets available in Netlify/Decap CMS. We have improved these widgets significantly while adding some new ones.

  • Boolean
    • A required Boolean field with no default value is saved as false by default, without raising a confusing validation error.[167:1]
    • An optional Boolean field with no default value is also saved as false by default, rather than nothing.[168:1]
  • Code
    • More than 300 languages are available, thanks to Prism’s extensive language support.
    • The language switcher always appears in the user interface, so it’s easy to spot and change the selected language.
    • Dynamic loading of language modes work as expected.[180]
    • A Code field under a List field work as expected, saving both code and language.[181]
    • A wrong initial value will not cause a crash with a TypeError.[182]
  • Color
    • The widget doesn’t cause scrolling issues.[183]
    • The preview shows both the RGB(A) hex value and the rgb() function notation.
  • DateTime
    • A DateTime field doesn’t trigger a change in the content draft status when you’ve just started editing a new entry.[184]
    • User’s local time is not saved in UTC unless the picker_utc option is true.[185]
    • The widget doesn’t throw a RangeError for formatting days of the month.[186][187]
  • Hidden
    • The default value supports the following template tags:
      • {{locale}}: The current locale code.[101:1]
      • {{datetime}}: The current date/time in ISO 8601 format.[188]
      • {{uuid}}, {{uuid_short}} and {{uuid_shorter}}: A random UUID or its shorter version, just like the slug template tags.[189]
      • {{author-email}}, {{author-login}} and {{author-name}}: The signed-in user’s email, login name and display name, respectively.[190]
    • The default value is saved when you create a file collection item, not just a folder collection item.[191]
  • List
    • It’s possible to edit data files with a top-level list using the new root option.[192]
    • The min and max options can be used separately. You don’t need to specify both to use either option.[193]
    • The Add Item button appears at the bottom of the list when the add_to_top option is not true, so you don’t have to scroll up each time to add new items.
    • A list item comes with a menu that allows users to duplicate the item, insert a new item above/below it, or remove it.[194]
    • Users can expand or collapse the entire list, while the Expand All and Collapse All buttons allow you to expand or collapse all items in the list at once.[195]
    • A required List field with no subfield or value is marked as invalid.[196] No need to set the min and max options for the required option to work.
    • An optional List field with no subfield or value is saved as an empty array, rather than nothing.[169:1]
    • An optional List field won’t populate an item by default when the subfield has the default value.[197]
    • A simple List field with no subfields is displayed as a multiline text field,[198] where users can use spaces[199] and commas[200] for list items. A comma is no longer treated as a list delimiter.
    • Users can preview variable types without having to register a preview template.[164:1]
    • It’s possible to omit fields in a variable type object.[201] In that case, only the typeKey (default: type) is saved in the output.
    • The new thumbnail option allows developers to specify an Image field name for the list item thumbnail. Thumbnails are displayed alongside the summary in the collapsed item view. (Discussion)
    • A collapsed List field will not display a programmatic summary like List [ Map { "key": "value" } ] if the summary option is not set.[202]
    • The allow_remove and allow_reorder options can be used to prevent users from removing items and reordering them, respectively.[203]
  • Map
    • A search bar enables users to quickly locate a specific place on the map.[204]
    • With the Geolocation API, users can get their current location with one click.
    • The value can be cleared by clicking the Clear button.
    • The map’s zoom level is adjusted more intuitively using pinch gestures.
    • The map looks good in dark mode.
  • Markdown
    • The rich text editor is built with the well-maintained Lexical framework, which solves various issues with a Slate-based editor in Netlify/Decap CMS,[205] including fatal application crashes,[206][207][208][209] lost formatting when pasting,[210][211] an extra line break when pasting,[212] extra HTML comments when pasting,[213] backslash injections,[214] dropdown visibility,[215] and text input difficulties with IME.[107:1]
    • For better security, the sanitize_preview option defaults to true since Sveltia CMS 0.105.0.
    • The default editor mode can be set by changing the order of the modes option.[216] If you want to use the plain text editor by default, add modes: [raw, rich_text] to the field configuration.
    • A Markdown field plays well with a variable type List field.[217]
    • The bullet list marker is a hyphen (-) rather than an asterisk (*), which is the comment form’s default behavior on GitHub and GitLab.[218]
    • A combination of bold and italic doesn’t create a confusing 3-asterisk markup.[219] In our editor, bold is 2 asterisks and italic is an underscore.
    • When deleting a linked text, the link is removed cleanly without leaving behind any unwanted characters.[220]
    • Bare URLs are rendered as clickable links in the preview.[221]
    • An editor component can be removed with a single click on the Remove button.[222]
    • The built-in image component can be inserted with a single click.
    • The built-in image component allows users to add, edit or remove a link on an image.[223] To disable this feature, add linked_images: false to the Markdown field options.
    • It’s possible to paste/drop local/remote images into the rich text editor to insert them as expected. Note: Pasting multiple images is not supported in Firefox. In Netlify/Decap CMS, pasting an image may cause the application to crash.[224]
    • Inline images are supported.[225]
    • The built-in code-block component is implemented just like a blockquote. You can simply convert a normal paragraph into a code block instead of adding a component.
    • Code in a code block in the editor can be copied as expected.[226]
    • Language-annotated code block doesn’t trigger unsaved changes.[227]
    • Soft line breaks are rendered as hard line breaks in the Preview Pane.
    • Uploaded images will not disappear while editing an entry.[228][229]
  • Number
    • If the value_type option is int (default) or float, the required option is false, and the value is not entered, the field will be saved as null instead of an empty string.[170:1]
    • The value_type option accepts int/string and float/string to save the number as a string instead of a number.
  • Object
    • Sveltia CMS offers two ways to have conditional fields in a collection:[230]
      • The Object widget supports variable types (the types and typeKey options) just like the List widget.[231]
      • An optional Object field (required: false) can be manually added or removed with a checkbox.[232] If unadded or removed, the required subfields won’t trigger validation errors,[233] and the field will be saved as null.
  • Relation
    • Field options are displayed with no additional API requests.[30:1] The confusing options_length option, which defaults to 20, is therefore ignored.[234]
    • The widget reliably displays the selected option in the summary and all available options in the dropdown list.[235]
    • slug can be used for value_field to show all available options instead of just one in some situations.[236]
    • Template strings with a wildcard like {{cities.*.name}} can also be used for value_field.[237]
    • display_fields is displayed in the Preview Pane instead of value_field.
    • The redundant search_fields option is optional in Sveltia CMS, as it defaults to display_fields, value_field or the collection’s identifier_field, which is title by default.
    • The value_field option is also optional in Sveltia CMS, as it defaults to {{slug}} (entry slugs).
    • A new item created in a referenced collection is immediately available in the options.[238]
    • A referenced DateTime field value is displayed in the specified format.[239]
    • It’s possible to refer to a List field with the field option, which produces a single subfield but does not output the subfield name in the data, using the value_field: cities.*.name syntax. (Discussion)
    • Supports the filters option to filter available options based on field values in the referenced collection.[240] The implementation is compatible with Decap CMS.
  • Select
    • It’s possible to select an option with value 0.[241]
    • label is displayed in the Preview Pane instead of value.
  • String
    • When a YouTube video URL is entered in a String field, it appears as an embedded video in the Preview Pane. Check your site’s CSP if the preview doesn’t work.
    • When a regular URL is entered in a String field, it appears as a link that can be opened in a new browser tab.
    • Supports the type option that accepts url or email as a value, which will validate the value as a URL or email.
    • Supports the prefix and suffix string options, which automatically prepend and/or append the developer-defined value to the user-input value, if it’s not empty.
  • Boolean, Number and String
    • Supports the before_input and after_input string options, which allow developers to display custom labels before and/or after the input UI.[242] Markdown is supported in the value.
      • Compatibility note: In Static CMS, these options are implemented as prefix and suffix, respectively, which have different meaning in Sveltia CMS.
  • File and Image
    • Provides a reimagined all-in-one asset selection dialog for File and Image fields.[243]
      • Field, entry, file, collection and global assets are listed on separate tabs for easy selection.[244]
      • A new asset can be uploaded by dragging & dropping it into the dialog.[43:1]
      • A URL can also be entered in the dialog.
      • Integration with Pexels, Pixabay and Unsplash makes it easy to select and insert a free stock photo.[245] More stock photo providers will be added in the future.
    • Users can also simply drag and drop a file onto a File/Image field to attach it without having to open the Select File dialog.
    • Supports the boolean multiple option, which can be set to true to allow multiple file uploads.[42:1]
      • When enabled, users can select and upload multiple files at once in the Select File dialog, as well as drag and drop multiple files onto the field. The field value will be an array of strings instead of a single string.
      • The min and max options are also available to limit the number of files that can be uploaded. Both accept positive integers. If min is not specified, it defaults to 0. If max is not specified, it defaults to Infinity.
    • The new accept option allows files to be filtered by a comma-separated list of unique file type specifiers, in the same way as the HTML accept attribute for <input type="file">.[246]
      • By default, the Image widget only accepts an AVIF, GIF, JPEG, PNG, WebP or SVG image. BMP, HEIC, JPEG XL, PSD, TIFF and other less common or non-standard files are excluded.[247]
      • The File widget has no default restriction.
    • If the collection’s public_folder contains {{slug}} and you’ve edited a slug field (e.g. title) of a new entry after uploading an asset, the updated slug will be used in the saved asset path.[248] Other dynamic template tags such as {{filename}} will also be populated as expected.[249]
    • The CMS prevents the same file from being uploaded twice. It compares the hashes and selects an existing asset instead.
    • Large images automatically fit in the Preview Pane instead of being displayed at their original size, which can easily exceed the width of the pane.
  • List and Object
    • The summary is displayed correctly when it refers to a Relation field[250] or a simple List field.
    • The summary template tags support transformations, e.g. {{fields.date | date('YYYY-MM-DD')}}.
    • The collapsed option accepts the value auto to automatically collapse the widget if any of its subfields are filled out. The same applies to the minimize_collapsed option for the List widget.
  • Markdown, String and Text
    • A required field containing only spaces or line breaks will result in a validation error, as if no characters were entered.
  • Relation and Select
    • If a dropdown list has options with long wrapping labels, they won’t overlap with the next option.[251]
    • When there are 5 or fewer options, the UI automatically switches from a dropdown list to radio buttons (single-select) or checkboxes (multi-select) for faster data entry.[252] This number can be changed with the dropdown_threshold option for the relation and select widgets.
  • String and Text
    • Supports the minlength and maxlength options, which allow developers to specify the minimum and maximum number of characters required for input without having to write a custom regular expression with the pattern option. A character counter is available when one of the options is given, and a user-friendly validation error is displayed if the condition is not met.

The following new widgets are available in Sveltia CMS:

  • Compute
    • The experimental 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.[253] Use the value property to define the value template, e.g. posts-{{fields.slug}}. (Example)
    • The value property also supports a value of {{index}}, which can hold the index of a list item. (Example)
  • KeyValue (Dictionary)
    • The new keyvalue widget allows users to add arbitrary key-value string pairs to a field.[254]
    • While the implementation is compatible with Static CMS, we provide a more intuitive UI. You can press Enter to move focus or add a new row while editing, and the preview is displayed in a clean table.
    • The root option is also available for a top-level key-value field, just like the List widget.
  • RichText
    • Currently, the richtext widget is a simple alias of markdown. We plan to add HTML output support in the future.
  • UUID
    • In addition to generating UUIDs for entry slugs, Sveltia CMS supports the proposed uuid widget with the following properties:[189:1]
      • 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.

Better Asset Management

  • A completely new, full-fledged Asset Library, built separately from the image selection dialog, makes it easy to manage all of your files, including images, videos and documents.[255]
    • Navigate between the global media folder and collection media folders.[256]
    • Preview image, audio, video, text and PDF files. Check your site’s CSP if the preview doesn’t work.
    • Copy the public URL,[257] file path, text data or image data of a selected asset to clipboard. The file path starts with / as expected.[258]
    • Edit plain text assets, including SVG images.
    • Rename existing assets. If the asset is used in any entries, the File/Image fields will be automatically updated with a new file path.
    • Replace existing assets.
    • Download one or more selected assets at once.
    • Delete one or more selected assets at once.
    • Upload multiple assets at once, including files in nested folders, by browsing or dragging and dropping them into the library.
    • Sort or filter assets by name or file type.
    • View asset details, including size, dimensions, commit author/date and a list of entries that use the selected asset.
    • View some Exif metadata if available, including the creation date and GPS coordinates displayed on a map.
  • Enhancements to media storage:
    • Supports multiple media storage providers with the new media_libraries option.[259]
    • Default media storage provider
      • It supports multiple file selection.[42:2] This can be enabled by setting the new multiple File/Image widget option to true. For compatibility with other media storage providers, the media_library.config.multiple option is also supported.
      • It comes with a built-in image optimizer. With a few lines of configuration, images selected by users for upload are automatically converted to WebP format for reduced size,[46:1] and it’s also possible to specify a maximum width and/or height.[47:1] SVG images can also be optimized.
      • The max_file_size option for the File/Image widget can be defined within the global media_library option, using default as the provider name. It applies to all File/Image entry fields, as well as direct uploads to the Asset Library. The option can also be part of the new media_libraries option.
      • Unlike Netlify/Decap CMS, files are uploaded with their original names. Sanitization is still applied to avoid issues with special characters, but uppercase letters and spaces are not converted to lowercase letters and hyphens.[260] If you want to slugify filenames according to the slug option, use the slugify_filename internal media storage option.
    • Cloudinary
      • Field-specific media storage configuration works as expected.[261]
      • When the multiple option is enabled, the output is always an array of strings, regardless of whether a single file is selected.[262]
      • The script-src CSP directive is not required for the widget to work, as we implemented the Cloudinary media storage without using their hosted widget script.
      • Image previews work as expected when the output_filename_only option is true.[263]
    • Uploadcare
      • An API-based integration allows users to select existing files from their Uploadcare account.[264]
      • Supports signed uploads to prevent unauthorized uploads. Files are uploaded with a signature computed using your secret key.
      • No error is raised for file collections if the media_folder option is not defined.[265]
    • Other integrations
      • Integrates stock photo providers, including Pexels, Pixabay and Unsplash.[245:1] Developers can disable them if needed.
      • More integration options, including Amazon S3 and Cloudflare R2/Images/Stream, would be added in the future.
  • Assets stored in the subfolders of media_folder are scanned recursively and displayed in the Asset Library.[266]
  • The global media_folder can be an empty string (or . or /) if you want to store assets in the root folder.
  • PDF documents are displayed with a thumbnail image in both the Asset Library and the Select File dialog, making it easier to find the file you’re looking for.[32:1]
  • Assets stored in an entry-relative media folder are displayed in the Asset Library.[267]
  • These entry-relative assets are automatically deleted when the associated entry is deleted because these are not available for other entries.[268] When you’re working with a local repository, the empty enclosing folder is also deleted.
  • Hidden files (dot files) don’t appear in the Asset Library.[269]
  • Users can add assets using the Quick Add button in the upper right corner of the application.

Better Customization

  • It’s possible to display a custom application title on the login page and in the browser tab by setting the app_title property.
  • A custom logo defined with the logo_url property is displayed on the global application header and the browser tab (favicon).[270] A smaller logo is also correctly positioned on the authentication page.[271]
  • Developers can specify the URL to redirect users after logging out with the logout_redirect_url global option.[272]
  • Enhancements to custom editor components:
    • CMS.registerEditorComponent() accepts a component definition with the icon property. Developers can specify a Material Symbols icon name just like custom collection icons.
    • The fromBlock function can be omitted if the pattern regex contains named capturing groups for the values.
    • Inline components are supported.[273]
    • Field validation works as expected.[274]
    • No error is raised in the browser console saying Sent invalid data to remark[275] or onValidate is not a function.[276]
    • A link with kramdown inline attributes (e.g. {:.class}) is parsed correctly.[277]
  • Enhancements to event hooks:
    • Missing identifier_field won’t cause an error when the preSave hook is triggered.[278]
  • Enhancements to custom field types (widgets):
    • The API method has been renamed from CMS.registerWidget() to CMS.registerFieldType() for better clarity, while keeping the old name for backward compatibility.[279]
  • Async functions can be used for custom parsers/formatters.[280]
  • The application renders within the dimensions of a custom mount element, if exists.[281]

Better Localization

  • The application UI locale is automatically selected based on the preferred language set with the browser.[282] Users can also change the locale in the application settings. Therefore, the locale configuration option is ignored and CMS.registerLocale() is not required.
  • The application UI is ready to be localized into RTL languages like Arabic, Hebrew and Persian.[283]
  • The List widget’s label and label_singular are not converted to lowercase, which is especially problematic in German, where all nouns are capitalized.[284]
  • Long menu item labels, especially in non-English locales, don’t overflow the dropdown container.[285][286]

Better Documentation

  • We provide well-structured and comprehensive documentation with detailed guides and examples to help you configure and use Sveltia CMS effectively.
  • Site navigation has been improved by categorizing topics more clearly, including creating separate pages for each field type and distinguishing the JavaScript API.[287]
  • Our documentation supports dark mode for better readability in low-light environments.
  • We provide clear migration instructions from Netlify CMS, including step-by-step guides and best practices to ensure a smooth transition.
  • Our compatibility information to help you avoid unsupported options and configurations that might cause errors. By contrast, the Netlify/Decap CMS documentation does not mention anything about the deprecation of camel case options, the removal of the Date widget and the replacement of Moment.js. Furthermore, the Decap blog claims that Decap CMS 3.0 is ”fully backward compatible” even though it removed the Date widget.
  • We have listed some common use cases of the CMS in the introduction.[288] In addition, we have a dedicated Showcase page featuring real-world examples of websites using Sveltia CMS.
  • We document how the collection-level media_folder option works with a relative or absolute path.[289]
  • We document the CmsConfig type available on the global CMS object, which provides type definitions for the configuration object in TypeScript. It’s undocumented in Netlify/Decap CMS.
  • The Collapsible Note custom editor component example works as expected.[290]
  • We provide llms.txt to help you use AI tools like GitHub Copilot, Claude and ChatGPT more effectively when writing Sveltia CMS configuration files.

Ready to Migrate?

If you have scrolled this far, you must be interested in trying out Sveltia CMS! Check out the migration guide to get started. Enjoy better content management experience! 🚀


  1. Netlify/Decap CMS #2536 ↩︎

  2. Netlify/Decap CMS #2557 ↩︎

  3. Netlify/Decap CMS #3263 ↩︎

  4. Netlify/Decap CMS #3264 ↩︎

  5. Netlify/Decap CMS #3265 ↩︎

  6. Netlify/Decap CMS #3266 ↩︎

  7. Netlify/Decap CMS #2039, #3267, #7084 ↩︎

  8. Netlify/Decap CMS #441, #1277, #1339, #2500, #2833, #2984, #3852, #7083 ↩︎ ↩︎

  9. Netlify/Decap CMS #7241 ↩︎ ↩︎

  10. Netlify/Decap CMS #5656, #5837, #5972, #6476, #6516, #6930, #7080, #7105, #7106, #7119, #7176, #7194, #7244, #7278, #7301, #7342, #7348, #7354, #7376, #7408, #7412, #7413, #7422, #7427, #7434, #7438, #7454, #7464, #7471, #7485, #7499, #7515, #7564, #7571, #7574, #7580, #7583, #7589, #7593, #7595, #7601, #7610, #7614, #7620, #7621, #7622, #7631, #7643, #7644, #7648, #7669, #7688, #7689, #7690, #7700, #7707, #7711, #7713, #7714 — These removeChild crashes are common in React apps, likely caused by a browser extension or Google Translate. ↩︎

  11. Netlify/Decap CMS #4961, #4979, #5545, #5778, #6279, #6464, #6810, #6922, #7118, #7293, #7630, #7712, #7727 — A comment on one of the issues says the crash was due to Google Translate. Sveltia CMS has turned off Google Translate on the admin page. ↩︎

  12. Netlify/Decap CMS #5815, #6522, #6532, #6588, #6617, #6640, #6663, #6695, #6697, #6764, #6765, #6835, #6983, #7205, #7450, #7453, #7572, #7602, #7655, #7704, #7710 ↩︎

  13. Netlify/Decap CMS #7360, #7462 ↩︎

  14. Netlify/Decap CMS #7240, #7428 ↩︎

  15. Netlify/Decap CMS #5867, #6159, #7016, #7306, #7554 ↩︎

  16. Netlify/Decap CMS #86 ↩︎

  17. Netlify/Decap CMS #3057, #3260 — We use Svelte though. ↩︎

  18. Netlify/Decap CMS #3257 ↩︎

  19. Netlify/Decap CMS #3258 ↩︎

  20. Netlify/Decap CMS #3259 ↩︎

  21. Netlify/Decap CMS #3261 ↩︎

  22. Netlify/Decap CMS #3262 ↩︎

  23. Netlify/Decap CMS #3296 ↩︎

  24. Netlify/Decap CMS #292 — It cannot be found in the current version of Decap CMS. ↩︎

  25. Netlify/Decap CMS #1045 ↩︎

  26. Netlify/Decap CMS #3353 ↩︎

  27. Netlify/Decap CMS #328, #1290 ↩︎

  28. Netlify/Decap CMS #302, #5549 ↩︎

  29. Netlify/Decap CMS #6034 ↩︎ ↩︎

  30. Netlify/Decap CMS #4635, #5920, #6410, #6827, #6924 ↩︎ ↩︎

  31. Netlify/Decap CMS #946, #1970 ↩︎

  32. Netlify/Decap CMS #1984 ↩︎ ↩︎

  33. Netlify/Decap CMS #2009, #2293, #3415, #3952, #6563 ↩︎

  34. Netlify/Decap CMS #1891 ↩︎ ↩︎

  35. Netlify/Decap CMS #3285, #7030, #7067, #7217 ↩︎

  36. Netlify/Decap CMS #6107 ↩︎ ↩︎

  37. Netlify/Decap CMS #7579 ↩︎ ↩︎

  38. Netlify/Decap CMS #7692, #7696 ↩︎ ↩︎

  39. Netlify/Decap CMS #6731 ↩︎

  40. Netlify/Decap CMS #5472 ↩︎

  41. Netlify/Decap CMS #5752 ↩︎

  42. Netlify/Decap CMS #213, #1032, #3244, #6730, #7459 ↩︎ ↩︎ ↩︎

  43. Netlify/Decap CMS #4563 ↩︎ ↩︎

  44. Netlify/Decap CMS #2822 ↩︎

  45. Netlify/Decap CMS #5055, #5470, #6956, #6989 ↩︎

  46. Netlify/Decap CMS #5419, #7107 ↩︎ ↩︎

  47. Netlify/Decap CMS #1322, #6442 ↩︎ ↩︎

  48. Netlify/Decap CMS #4532, #6513, #7295, #7567 ↩︎

  49. Netlify/Decap CMS #542 ↩︎

  50. Netlify/Decap CMS #7557 ↩︎

  51. Netlify/Decap CMS #6879 ↩︎

  52. Netlify/Decap CMS #2138, #2343, #4367, #5932 ↩︎

  53. Netlify/Decap CMS #3284 ↩︎

  54. Netlify/Decap CMS #1333, #4216 ↩︎

  55. Netlify/Decap CMS #7077 ↩︎

  56. Netlify/Decap CMS #6762 ↩︎

  57. Netlify/Decap CMS #5701 ↩︎

  58. Netlify/Decap CMS #3431 ↩︎

  59. Netlify/Decap CMS #2673, #5315, #6499, #6544, #6551, #6679, #6773, #6883, #7363, #7365 — This problem occurs every time a new major version of React is released. ↩︎

  60. Netlify/Decap CMS #5376, #7203, #7380 ↩︎

  61. Netlify/Decap CMS #7375 ↩︎

  62. Netlify/Decap CMS #7518 ↩︎

  63. Netlify/Decap CMS #7616 ↩︎

  64. Netlify/Decap CMS #332, #683, #999, #1456, #4175, #4818, #5688, #6828, #6829, #6862, #7023, #7680 ↩︎

  65. Netlify/Decap CMS #6616 ↩︎

  66. Netlify/Decap CMS #6965, #7445 ↩︎

  67. Netlify/Decap CMS #283, #386 ↩︎

  68. Netlify/Decap CMS #3457, #3624, #6713 ↩︎

  69. Netlify/Decap CMS #6635, #7006, #7311 ↩︎

  70. Netlify/Decap CMS #4987 ↩︎

  71. Netlify/Decap CMS #5970 ↩︎

  72. Netlify/Decap CMS #6527 ↩︎

  73. Netlify/Decap CMS #6800 ↩︎

  74. Netlify/Decap CMS #6794 ↩︎

  75. Netlify/Decap CMS #3803 ↩︎

  76. Netlify/Decap CMS #4417 ↩︎

  77. Netlify/Decap CMS #4564, #5617, #5815 ↩︎

  78. Netlify/Decap CMS #7457 ↩︎

  79. Netlify/Decap CMS #6831 ↩︎

  80. Netlify/Decap CMS #7257 ↩︎

  81. Netlify/Decap CMS #663, #6729, #7466, #7545 ↩︎

  82. Netlify/Decap CMS #7352, #7581 ↩︎

  83. Netlify/Decap CMS #7611 ↩︎

  84. Netlify/Decap CMS #3704 ↩︎

  85. Netlify/Decap CMS #7172 ↩︎

  86. Netlify/Decap CMS #7627 ↩︎

  87. Netlify/Decap CMS #7281 — The issue was closed, but the attached PR is not yet merged. ↩︎

  88. Netlify/Decap CMS #4538, #6371 ↩︎

  89. Netlify/Decap CMS #3286 ↩︎

  90. Netlify/Decap CMS #7157 ↩︎

  91. Netlify/Decap CMS #2827 ↩︎

  92. Netlify/Decap CMS #5280 ↩︎

  93. Netlify/Decap CMS #4386, #4888, #7332, #7514 ↩︎

  94. Netlify/Decap CMS #6978 ↩︎

  95. Netlify/Decap CMS #4416, #7400 ↩︎

  96. Netlify/Decap CMS #4781 ↩︎

  97. Netlify/Decap CMS #5493, #6600 ↩︎ ↩︎

  98. Netlify/Decap CMS #4645 ↩︎

  99. Netlify/Decap CMS #1685 ↩︎

  100. Netlify/Decap CMS #4877 ↩︎

  101. Netlify/Decap CMS #5969 ↩︎ ↩︎

  102. Netlify/Decap CMS #7612 ↩︎

  103. Netlify/Decap CMS #2524 ↩︎

  104. Netlify/Decap CMS #6932 ↩︎

  105. Netlify/Decap CMS #7086 ↩︎

  106. Netlify/Decap CMS #7142, #7276 ↩︎

  107. Netlify/Decap CMS #1347, #1559, #4629, #4837, #6287, #6826 — Decap CMS 3.0 updated the Slate editor in an attempt to fix the problems, but the IME issues remain unresolved when using a mobile/tablet browser. ↩︎ ↩︎

  108. Netlify/Decap CMS #4480, #5122, #6353 ↩︎

  109. Netlify/Decap CMS #5112, #5653 ↩︎

  110. Netlify/Decap CMS #6307 ↩︎

  111. Netlify/Decap CMS #7371 ↩︎

  112. Netlify/Decap CMS #7507 ↩︎

  113. Netlify/Decap CMS #1040 ↩︎

  114. Netlify/Decap CMS #5317 ↩︎

  115. Netlify/Decap CMS #6571, #7539 ↩︎

  116. Netlify/Decap CMS #6203, #7417, #7451 ↩︎

  117. Netlify/Decap CMS #1000 ↩︎

  118. Netlify/Decap CMS #7328 ↩︎

  119. Netlify/Decap CMS #7347 ↩︎

  120. Netlify/Decap CMS #3750, #4735, #4783, #6801, #6806 ↩︎ ↩︎

  121. Netlify/Decap CMS #6427 ↩︎

  122. Netlify/Decap CMS #427, #535, #1284, #3846 ↩︎

  123. Netlify/Decap CMS #7355 ↩︎

  124. Netlify/Decap CMS #978 ↩︎

  125. Netlify/Decap CMS #1152 ↩︎

  126. Netlify/Decap CMS #7192 ↩︎

  127. Netlify/Decap CMS #5726 ↩︎

  128. Netlify/Decap CMS #7461 ↩︎

  129. Netlify/Decap CMS #526, #6987 ↩︎

  130. Netlify/Decap CMS #377 ↩︎

  131. Netlify/Decap CMS #445 ↩︎

  132. Netlify/Decap CMS #6970, #7147 ↩︎

  133. Netlify/Decap CMS #4092 ↩︎

  134. Netlify/Decap CMS #3715 ↩︎

  135. Netlify/Decap CMS #7568 ↩︎

  136. Netlify/Decap CMS #4637, #5198 ↩︎

  137. Netlify/Decap CMS #5276, #7430 ↩︎

  138. Netlify/Decap CMS #7381 ↩︎

  139. Netlify/Decap CMS #1245, #2727, #4884, #6908 ↩︎

  140. Netlify/Decap CMS #2491 ↩︎

  141. Netlify/Decap CMS #1274 ↩︎

  142. Netlify/Decap CMS #7486 ↩︎

  143. Netlify/Decap CMS #7262 ↩︎

  144. Netlify/Decap CMS #2289, #4518 ↩︎

  145. Netlify/Decap CMS #4350 ↩︎

  146. Netlify/Decap CMS #3796 ↩︎

  147. Netlify/Decap CMS #1341 ↩︎

  148. Netlify/Decap CMS #4255 ↩︎

  149. Netlify/Decap CMS #7267 ↩︎

  150. Netlify/Decap CMS #7483 ↩︎

  151. Netlify/Decap CMS #5630 ↩︎

  152. Netlify/Decap CMS #5593, #6500 ↩︎

  153. Netlify/Decap CMS #1654 ↩︎

  154. Netlify/Decap CMS #4147 ↩︎

  155. Netlify/Decap CMS #6202 ↩︎

  156. Netlify/Decap CMS #7399 ↩︎

  157. Netlify/Decap CMS #1948 ↩︎

  158. Netlify/Decap CMS #7532 ↩︎

  159. Netlify/Decap CMS #7011 ↩︎

  160. Netlify/Decap CMS #7085 ↩︎

  161. Netlify/Decap CMS #2368, #3454, #3585, #3651, #3885, #3962, #4037, #4143, #6585, #6664, #6665, #6739, #7243, #7379, #7469, #7694 ↩︎

  162. Netlify/Decap CMS #1466 ↩︎

  163. Netlify/Decap CMS #7279 ↩︎

  164. Netlify/Decap CMS #2307 ↩︎ ↩︎

  165. Netlify/Decap CMS #1609, #3557, #5253, #6760, #6901 — Looks like the fix for #215 was incomplete or regressed at some point. ↩︎

  166. Netlify/Decap CMS #1449, #1988, #5552 ↩︎

  167. Netlify/Decap CMS #1424 ↩︎ ↩︎

  168. Netlify/Decap CMS #4726 ↩︎ ↩︎

  169. Netlify/Decap CMS #2613 ↩︎ ↩︎

  170. Netlify/Decap CMS #2007, #2848 ↩︎ ↩︎

  171. Netlify/Decap CMS #995, #2017, #7120, #7186 ↩︎

  172. Netlify/Decap CMS #1382, #6994 ↩︎

  173. Netlify/Decap CMS #1481, #7398 ↩︎

  174. Netlify/Decap CMS #4762 ↩︎

  175. Netlify/Decap CMS #5640, #6444 ↩︎

  176. Netlify/Decap CMS #3583 ↩︎

  177. Netlify/Decap CMS #5870 ↩︎

  178. Netlify/Decap CMS #3505, #4211, #5439 ↩︎

  179. Netlify/Decap CMS #4945 ↩︎

  180. Netlify/Decap CMS #7442 ↩︎

  181. Netlify/Decap CMS #6254 ↩︎

  182. Netlify/Decap CMS #4353, #7513, #7544, #7654 ↩︎

  183. Netlify/Decap CMS #7092 ↩︎

  184. Netlify/Decap CMS #725 ↩︎

  185. Netlify/Decap CMS #7319 ↩︎

  186. Netlify/Decap CMS #6609, #6802, #6824, #6832, #6848, #6851, #7287, #7522 ↩︎

  187. Netlify/Decap CMS #7206, #7577, #7619, #7691 ↩︎

  188. Netlify/Decap CMS #1270, #7425 ↩︎

  189. Netlify/Decap CMS #1975, #3712 ↩︎ ↩︎

  190. Netlify/Decap CMS #1235, #1483 ↩︎

  191. Netlify/Decap CMS #2294, #3046, #4363, #4520, #5806 ↩︎

  192. Netlify/Decap CMS #531, #621, #1282, #1877, #2514, #2737 ↩︎

  193. Netlify/Decap CMS #4733 ↩︎

  194. Netlify/Decap CMS #1244 ↩︎

  195. Netlify/Decap CMS #756 — The Expand All and Collapse All buttons cannot be found in the current version of Decap CMS. ↩︎

  196. Netlify/Decap CMS #4387, #5381 ↩︎

  197. Netlify/Decap CMS #2380 ↩︎

  198. Netlify/Decap CMS #3018 ↩︎

  199. Netlify/Decap CMS #4646, #7167 ↩︎

  200. Netlify/Decap CMS #2153 ↩︎

  201. Netlify/Decap CMS #7322 ↩︎

  202. Netlify/Decap CMS #1275 ↩︎

  203. Netlify/Decap CMS #4702 ↩︎

  204. Netlify/Decap CMS #6629 ↩︎

  205. Netlify/Decap CMS #6905 — We use Lexical created by Facebook (Meta). ↩︎

  206. Netlify/Decap CMS #6999, #7000, #7001, #7152, #7220, #7283, #7316, #7429, #7465, #7500, #7552 ↩︎

  207. Netlify/Decap CMS #7047 ↩︎

  208. Netlify/Decap CMS #6993, #7123, #7127, #7128, #7237, #7251, #7361, #7391, #7393, #7470, #7475, #7480, #7503, #7504, #7524, #7531, #7535, #7553, #7561, #7584, #7591, #7609, #7628, #7677, #7699 ↩︎

  209. Netlify/Decap CMS #7190, #7218, #7392 ↩︎

  210. Netlify/Decap CMS #991, #4488, #7233 ↩︎

  211. Netlify/Decap CMS #3437 ↩︎

  212. Netlify/Decap CMS #7364 ↩︎

  213. Netlify/Decap CMS #6180 ↩︎

  214. Netlify/Decap CMS #512, #5673, #6707, #7501 ↩︎

  215. Netlify/Decap CMS #6482 ↩︎

  216. Netlify/Decap CMS #5125 ↩︎

  217. Netlify/Decap CMS #7458 ↩︎

  218. Netlify/Decap CMS #7638 ↩︎

  219. Netlify/Decap CMS #3291 ↩︎

  220. Netlify/Decap CMS #7640 ↩︎

  221. Netlify/Decap CMS #1004 ↩︎

  222. Netlify/Decap CMS #3531 ↩︎

  223. Netlify/Decap CMS #4754 ↩︎

  224. Netlify/Decap CMS #7585 ↩︎

  225. Netlify/Decap CMS #7705 ↩︎

  226. Netlify/Decap CMS #7143 ↩︎

  227. Netlify/Decap CMS #7431 ↩︎

  228. Netlify/Decap CMS #7575 ↩︎

  229. Netlify/Decap CMS #7576, #7587 ↩︎

  230. Netlify/Decap CMS #565, #6733 ↩︎

  231. Netlify/Decap CMS #7031, #7540, #7597 ↩︎

  232. Netlify/Decap CMS #1267 ↩︎

  233. Netlify/Decap CMS #2103, #2790, #7302 ↩︎

  234. Netlify/Decap CMS #4738 ↩︎

  235. Netlify/Decap CMS #7546 ↩︎

  236. Netlify/Decap CMS #4954 ↩︎

  237. Netlify/Decap CMS #5487 ↩︎

  238. Netlify/Decap CMS #4841 ↩︎

  239. Netlify/Decap CMS #3421 ↩︎

  240. Netlify/Decap CMS #2405, #3816 ↩︎

  241. Netlify/Decap CMS #6515 ↩︎

  242. Netlify/Decap CMS #2677, #6836 ↩︎

  243. Netlify/Decap CMS #2243, #4965 — Rather than relying on a third-party library, we built our own asset browser that integrates more seamlessly with the rest of the CMS. ↩︎

  244. Netlify/Decap CMS #5910 ↩︎

  245. Netlify/Decap CMS #2579 ↩︎ ↩︎

  246. Netlify/Decap CMS #1345 ↩︎

  247. Netlify/Decap CMS #5467, #6505 ↩︎

  248. Netlify/Decap CMS #5444 ↩︎

  249. Netlify/Decap CMS #3723, #6990 ↩︎

  250. Netlify/Decap CMS #6325 ↩︎

  251. Netlify/Decap CMS #6508 ↩︎

  252. Netlify/Decap CMS #1489, #5838 ↩︎

  253. Netlify/Decap CMS #450, #2122, #6819 ↩︎

  254. Netlify/Decap CMS #961, #5489 ↩︎

  255. Netlify/Decap CMS #962 ↩︎

  256. Netlify/Decap CMS #3240 ↩︎

  257. Netlify/Decap CMS #4209 ↩︎

  258. Netlify/Decap CMS #5569, #6754 ↩︎

  259. Netlify/Decap CMS #5901 ↩︎

  260. Netlify/Decap CMS #4288 ↩︎

  261. Netlify/Decap CMS #2001 ↩︎

  262. Netlify/Decap CMS #5812 ↩︎

  263. Netlify/Decap CMS #1934 ↩︎

  264. Netlify/Decap CMS #1794, #2966 ↩︎

  265. Netlify/Decap CMS #6243 ↩︎

  266. Netlify/Decap CMS #4208 ↩︎

  267. Netlify/Decap CMS #7124 ↩︎

  268. Netlify/Decap CMS #3615, #4069, #5097, #6642 ↩︎

  269. Netlify/Decap CMS #2370, #5596 ↩︎

  270. Netlify/Decap CMS #5548 ↩︎

  271. Netlify/Decap CMS #2133 ↩︎

  272. Netlify/Decap CMS #713 ↩︎

  273. Netlify/Decap CMS #5065 — The issue was closed, but it’s still not working as expected in Decap CMS. ↩︎

  274. Netlify/Decap CMS #1390, #4912, #6986 ↩︎

  275. Netlify/Decap CMS #3490, #3682, #4669, #4895, #4976, #5766, #6501, #6785, #7315 ↩︎

  276. Netlify/Decap CMS #4892 — We cannot reproduce the crash, but we do see the error message in the console. ↩︎

  277. Netlify/Decap CMS #1464 ↩︎

  278. Netlify/Decap CMS #6775 ↩︎

  279. Netlify/Decap CMS #3719 ↩︎

  280. Netlify/Decap CMS #13 — The issue appears to have been closed without a fix being available. ↩︎

  281. Netlify/Decap CMS #7197 ↩︎

  282. Netlify/Decap CMS #6816 ↩︎

  283. Netlify/Decap CMS #1769 ↩︎

  284. Netlify/Decap CMS #3856 ↩︎

  285. Netlify/Decap CMS #3562, #6215, #6605, #6355, #7479 ↩︎

  286. Netlify/Decap CMS #6215 ↩︎

  287. Netlify/Decap CMS #3764 ↩︎

  288. Netlify/Decap CMS #365 ↩︎

  289. Netlify/Decap CMS #3671 ↩︎

  290. Netlify/Decap CMS #6062 ↩︎

Released under the MIT License.