JavaScript API
Sveltia CMS provides a flexible, client-side JavaScript/TypeScript API that allows developers to customize and extend its functionality. This document provides an overview of the main API components and how to use them.
Accessing the CMS Object
The main entry point for the Sveltia CMS JavaScript API is the global CMS object. This object exposes various methods for initializing the CMS, registering custom components, and interacting with the CMS programmatically.
There are two primary ways to access the CMS object: via a CDN build or by installing the NPM package.
Using the CDN
CMS is exposed as a global variable when using the UNPKG CDN build. You can access it directly in your scripts:
<script src="https://unpkg.com/@sveltia/cms/dist/sveltia-cms.js"></script>
<script>
CMS.init({ config });
CMS.registerPreviewStyle(filePath);
CMS.registerEditorComponent(definition);
</script>Alternatively, you can use the ES module version, which can be imported using the mjs file extension. This script is the same as the NPM package version:
<script type="module">
import CMS from 'https://unpkg.com/@sveltia/cms/dist/sveltia-cms.mjs';
CMS.init({ config });
CMS.registerPreviewStyle(filePath);
CMS.registerEditorComponent(definition);
</script>Using the NPM Package
Install the @sveltia/cms package via your preferred package manager:
npm install @sveltia/cmsyarn add @sveltia/cmspnpm add @sveltia/cmsbun add @sveltia/cmsThen, import the CMS object in your script to access the initialization and other API methods:
import CMS from '@sveltia/cms';
CMS.init({ config });
CMS.registerPreviewStyle(filePath);
CMS.registerEditorComponent(definition);or import only the methods you need:
import { init } from '@sveltia/cms';
init({ config });TypeScript types are included in the package, so if you edit your project with a TypeScript-aware editor like VS Code, you should get type checking and autocompletion without any additional setup.
Available Methods
Currently, the following methods are available on the CMS object:
- Manual Initialization:
init - Custom Preview Styles:
registerPreviewStyle - Custom Preview Templates:
registerPreviewTemplate - Custom Editor Components:
registerEditorComponent - Custom Field Types:
registerFieldType(alias:registerWidget),getFieldType(alias:getWidget) - Custom File Formats:
registerCustomFormat - Event Hooks:
registerEventListener
Breaking changes from Netlify/Decap CMS
The methods other than those listed above are not supported in Sveltia CMS. This includes:
registerLocale: Sveltia CMS automatically detects and uses the browser’s language settings for localization. No manual registration of locales is necessary.registerRemarkPlugin: Sveltia CMS uses the Lexical framework for Markdown processing instead of Remark. Therefore, Remark plugins are not compatible.- All other undocumented methods, including custom backends and custom media storage providers. We may support these features in the future, but our implementation would likely be incompatible with Netlify/Decap CMS.
Writing React Components
For Custom Preview Templates, Custom Editor Components and Custom Field Types, you can use React components to create rich, interactive previews and editor interfaces. Sveltia CMS supports both JSX and non-JSX syntax for defining these components.
Without JSX
Sveltia CMS exposes two constructs globally to allow you to create React components inline without requiring a build step:
h— An alias forReact.createElement(), used to create React elements in the non-JSX examplesrf- An alias forReact.Fragment, used to create React fragments in the non-JSX examplescreateClass— Used to define React class components when not using JSX syntax
These are available on the window object when Sveltia CMS is loaded. No additional imports are necessary to use them.
Define the methods you pass to createClass, such as render, as function expressions rather than arrow functions. createClass binds each method to the component instance, which an arrow function doesn’t allow, so this.props would be undefined within it. Any other function, including a callback within a method, can be an arrow function.
See React Without JSX for more information on how to use React without JSX.
Future Plans
We plan to add support for Preact+HTM components in the future, which will allow you to write preview templates using a more lightweight syntax without JSX.
With JSX
Sveltia CMS does not provide a built-in JSX transpiler. To use JSX syntax, you need a build step to transpile it to JavaScript, such as Vite.
Rendering Markdown
The value of a RichText or Markdown field is a Markdown string. When you render such a value yourself — in a Custom Preview Template, the preview output of a Custom Editor Component, or a Custom Field Type — the string is used as is, so text like **bold** appears verbatim unless you convert it to HTML.
To make that possible without adding a dependency of your own, Sveltia CMS exposes the two libraries it uses internally:
marked— The Marked parser, which converts a Markdown string to an HTML stringDOMPurify— The DOMPurify sanitizer, which strips scripts and other dangerous markup from an HTML string
These are available on the window object when Sveltia CMS is loaded, whether you use the CDN build or the npm package. No additional imports are necessary to use them.
const html = DOMPurify.sanitize(marked.parse(markdown));The CMS renders the preview pane with the breaks option enabled, meaning a single line break becomes a <br>. Pass the same option if you want your output to match:
const html = DOMPurify.sanitize(marked.parse(markdown, { breaks: true }));Security Risk
Always sanitize the HTML before inserting it into the DOM, as the examples above do. Markdown allows raw HTML, so skipping the sanitizer can expose your CMS to cross-site scripting (XSS) attacks if untrusted users have access to the CMS, especially when using Open Authoring, because entries can be written by anybody.
Shared parser instance
marked is the very parser the CMS uses to render the preview pane, so any extension you add with marked.use() also changes how the CMS itself renders Markdown. Prefer passing options to marked.parse() for one-off customization.