Creating Custom Previews

The NetlifyCMS exposes a window.CMS global object that you can use to register custom widgets, previews and editor plugins. The available customization methods are:

registerPreviewStyle: Register a custom stylesheet to use on the preview pane.
registerPreviewTemplate: Registers a template for a collection.

React Components inline interaction

NetlifyCMS is a collection of React components and exposes two constructs globally to allow you to create components inline: ‘createClass’ and ‘h’ (alias for React.createElement).
registerPreviewStyle

Register a custom stylesheet to use on the preview pane.

CMS.registerPreviewStyle(file);

Params:

file: css file path

Example:

// index.html
<script src=”https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js”></script>
<script>
CMS.registerPreviewStyle(“/example.css”);
</script>

/* example.css */

html,
body {
color: #444;
font-size: 14px;
font-family: ‘Helvetica Neue’, Helvetica, Arial, sans-serif;
}

body {
padding: 20px;
}

registerPreviewTemplate

Registers a template for a folder collection or an individual file in a file collection.

CMS.registerPreviewTemplate(name, react_component);

Params:

name: The name of the collection (or file for file collections) which this preview component will be used for.
Folder collections: Use the name of the collection
File collections: Use the name of the file

react_component: A React component that renders the collection data. Six props will be passed to your component during render:

entry: Immutable collection containing the entry data.

widgetFor: Returns the appropriate widget preview component for a given field.

widgetsFor: Returns an array of objects with widgets and associated field data. For use with list and object type entries.

getAsset: Returns the correct filePath or in-memory preview for uploaded images. Example:

<script src=”https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js”></script>
<script>
var PostPreview = createClass({
render: function() {
var entry = this.props.entry;
var image = entry.getIn([‘data’, ‘image’]);
var bg = this.props.getAsset(image);
return h(‘div’, {},
h(‘h1’, {}, entry.getIn([‘data’, ‘title’])),
h(‘img’, {src: bg.toString()}),
h(‘div’, {“className”: “text”}, this.props.widgetFor(‘body’))
);
}
});

CMS.registerPreviewTemplate(“posts”, PostPreview);
</script>

document: The preview pane iframe’s document instance.

window: The preview pane iframe’s window instance.
Lists and Objects

The API for accessing the individual fields of list- and object-type entries is similar to the API for accessing fields in standard entries, but there are a few key differences. Access to these nested fields is facilitated through the widgetsFor function, which is passed to the preview template component during render. Note: as is often the case with the NetlifyCMS API, arrays and objects are created with Immutable.js. If some of the methods that we use are unfamiliar, such as getIn, check out their docs to get a better understanding. List Example:

<script>
var AuthorsPreview = createClass({
// For list fields, the widgetFor function returns an array of objects
// that you can map over in your template. If our field is a list of
// authors containing two entries, with fields `name` and `description`,
// the return value of `widgetsFor` would look like this:
//
// [{
//   data: { name: ‘Mathias’, description: ‘Co-Founder’},
//   widgets: { name: (<WidgetComponent>), description: (WidgetComponent>)}
// },
// {
//   data: { name: ‘Chris’, description: ‘Co-Founder’},
//   widgets: { name: (<WidgetComponent>), description: (WidgetComponent>)}
// }]
//
// Templating would look something like this:

render: function() {
return h(‘div’, {},

// This is a static header that would only be rendered once for the entire list
h(‘h1’, {}, ‘Authors’),

// Here we provide a simple mapping function that will be applied to each
// object in the array of authors
this.props.widgetsFor(‘authors’).map(function(author, index) {
return h(‘div’, {key: index},
h(‘hr’, {}),
h(‘strong’, {}, author.getIn([‘data’, ‘name’])),
author.getIn([‘widgets’, ‘description’])
);
})
);
}
});
CMS.registerPreviewTemplate(“authors”, AuthorsPreview);
</script>

Object Example:

<script>
var GeneralPreview = createClass({
// Object fields are simpler than lists – instead of `widgetsFor` returning
// an array of objects, it returns a single object. Accessing the shape of
// that object is the same as the shape of objects returned for list fields:
//
// {
//   data: { front_limit: 0, author: ‘Chris’ },
//   widgets: { front_limit: (<WidgetComponent>), author: (WidgetComponent>)}
// }
render: function() {
var entry = this.props.entry;
var title = entry.getIn([‘data’, ‘site_title’]);
var posts = entry.getIn([‘data’, ‘posts’]);

return h(‘div’, {},
h(‘h1’, {}, title),
h(‘dl’, {},
h(‘dt’, {}, ‘Posts on Frontpage’),
h(‘dd’, {}, this.props.widgetsFor(‘posts’).getIn([‘widgets’, ‘front_limit’]) || 0),

h(‘dt’, {}, ‘Default Author’),
h(‘dd’, {}, this.props.widgetsFor(‘posts’).getIn([‘data’, ‘author’]) || ‘None’),
)
);
}
});

CMS.registerPreviewTemplate(“general”, GeneralPreview);
</script>

Accessing Metadata

Preview Components also receive an additional prop: fieldsMetaData. It contains aditional information (besides the plain textual value of each field) that can be useful for preview purposes. For example, the Relation widget passes the whole selected relation data in fieldsMetaData.

export default class ArticlePreview extends React.Component {
render() {
const {entry, fieldsMetaData} = this.props;
const author = fieldsMetaData.getIn([‘authors’, data.author]);

return <article><h2>{ entry.getIn([‘data’, ‘title’]) }</h2>
{author &&<AuthorBio author={author.toJS()}/>}
</article>
}
}

Examples

Do you have a great, open source example? Submit a pull request to this page!

Example  Tools  Type  Source  More info Gatsby & Netlify CMS Meetup Group Template  Gatsby  demo  robertcoopercode/gatsby-netlify-cms  blog post This Developing Journey  middleman  blog  bdougie/blog  blog post Jamstack Recipes  Hugo, Azure  demo  hlaueriksson/jamstack-cms  blog post Bael  Vue, Nuxt  blog  jake-101/bael-template  blog post Forest Garden Wales  Hugo  blog  forestgardenwales/forestgarden.wales  blog post Jekyll Demo  Jekyll, Gulp  demo  NickStees/jekyll-cms  read me Jekyll feat Alembic Theme Demo  Jekyll  demo  DavidDarnes/alembic-netlifycms-kit  read me Eleventy Starter Project  Eleventy  demo  danurbanowicz/eleventy-netlify-boilerplate  read me YellowCake – Complete website with blog  Gatsby, Netlify-CMS, Uploadcare  demo  thriveweb/yellowcake  blog post Vue.js – Nuxt.js Starter Project  Vue, Nuxt  demo  renestalder/nuxt-netlify-cms-starter-template  read me Hexo Demo  Hexo  demo  DemoMacro/Hexo-NetlifyCMS  read me Gitbook Demo  Gitbook  demo  DemoMacro/Gitbook-NetlifyCMS  read me VuePress Demo  VuePress  demo  DemoMacro/VuePress-NetlifyCMS  read me Jigsaw Blog Starter Template Demo  Jigsaw  demo  erickpatrick/jigsaw-blog-netlify-netlifycms-template  blog post Nuxt & NetlifyCMS Boilerplate  Vue, Nuxt  demo  tylermercer/nuxt-netlifycms-boilerplate  read me Next.js demo  Next.js  blog  masives/netlifycms-nextjs  read me Delog – Jamstack Blog with Netlify CMS  Gatsby, Netlify-CMS  demo  W3Layouts/gatsby-starter-delog  blog post Netlify CMS template for Gridsome  Gridsome, Vue  demo  suits-at/netlifycms-gridsome  read me Next.js blogging template for Netlify  Next.js, Netlify  blog  wutali/nextjs-netlify-blog-template  read me Netlify CMS and OAuth server on AWS  Netlify, Pulumi, AWS  blog  pulumi/examples/aws-ts-netlify-cms-and-oauth  blog post Eleventy Starter Boilerplate  Eleventy, Netlify  demo  ixartz/Eleventy-Starter-Boilerplate  read me Nuxt, Tailwind & NetlifyCMS Boilerplate  Vue, Nuxt  demo  Knogobert/ntn-boilerplate  read me Gatsby & Netlify CMS Personal Portfolio  Gatsby  portfolio  EarlGeorge/React-Gatsby  read me Gatsby, Tailwind CSS & NetlifyCMS Starter  Gatsby v3, Netlify-CMS, Tailwind CSS  demo  jimmybutton/gatsby-netlifycms-tailwind-starter  read me Metalsmith NetlifyCMS Starter  Metalsmith and Netlify-CMS  demo  metalsmith-netlify-starter  read me

Update the CMS Version

The update procedure for your CMS depends upon the method you used to install Netlify CMS.
Package Manager

If you are using a package manager like Yarn or NPM, use their standard procedure to update. This is how both the Hugo and Gatsby starters are set up.

CDN

If you are using the CMS through a CDN like Unpkg, then that depends on the version tag you are using. You can find the version tag in the /admin/index.html file of your site.

(Recommended) If you use ^2.0.0, the CMS does all updates except major versions automatically.
It upgrades to 2.0.1, 2.1.0, 2.1.2.
It does not upgrade to 3.0.0 or higher.
It does not upgrade to beta versions.

If you use ~2.0.0, the CMS will do only patch updates automatically.
It upgrades 2.0.1, 2.0.2.
It does not upgrade to 2.1.0 or higher.
It does not upgrade beta versions.