How to customize content preview on Netlify CMS with Gridsome
In my previous post, we took a look at how to create and manage content for a Gridsome powered blog using Netlify CMS.
Netlify CMS is an easy-to-set-up content management system that uses file storage and direct updates on Git repositories to keep track of changes. While Gridsome is a static site generator built on VueJS.
Now that we have our blog’s CMS setup, we would like to be able to see how our blog posts would look once they are published from the CMS. In this tutorial, we will implement a custom preview to our post editing dashboard.
Registering Script Module
The first step to achieving flexibility with Netlify CMS on Gridsome is to register the JavaScript module that will house the custom functionality. We do this by adding modulePath: ‘src/admin/index.js’
as a plugin config option to the gridsome.config.js
file where we registered the gridsome-plugin-netlify-cms
plugin. Our plugin entry will then look like this:
... { use: `gridsome-plugin-netlify-cms`, options: { publicPath: `/admin`, modulePath: `src/admin/index.js`, htmlPath: `src/admin/index.html` } },
💡Remember you can name your admin dashboard anything by changing the folder name in
publicPath
and updating the folder name inmodulePath
andhtmlPath
In our index.js
file we will import and initialize the Netlify CMS module in preparation for our customizations:
import CMS from "netlify-cms"
// Initialize the CMS objectCMS.init()
Creating and applying our customizations
With Netlify CMS there is a lot of flexibility to create widgets, apply custom previews to content and apply custom styles to the CMS. In this tutorial, we will focus on custom previews and custom styles.
As discussed previously, we manage content as collections that are file stored. And we define these collections in the config.yml
file placed in our admin folder.
💡 A collection is how we define a category of content and in its definition, we set the attributes that are needed to make up the content.
To apply a custom preview to a collection we use:
CMS.registerPreviewTemplate('posts', PostPreview)
where posts is the name of our collection and PostPreview is the React component that defines our custom template.
For our react component we will use two main tools provided by Netlify CMS, which are createClass
and ‘h’
. We will also use the property entry
which is passed to our react component at render as an immutable container for our collection data. To learn about immutable structures and how to access data from them checkout immutable.js
💡
createClass
and‘h’
are global constructs injected by Netlify CMS as aliases for theReact.Component
class andReact.createElement
function respectively.
Let us create our react component by adding the following to our index.js
file:
var PostPreview = createClass({ render: function() { const { entry, getAsset, widgetsFor } = this.props const imagePath = entry.getIn(['data', 'image']) const image = getAsset(imagePath) return h('div', { className: 'container' }, h('div', { className: 'row' }, h('div', { className: 'card col-md-12' }, h('img', { src: image.toString(), className: 'img-fluid rounded' }), h('div', { className: 'card-body' }, h('h5', { className: 'card-title' }, entry.getIn(['data', 'title']) ), h('p', { classname: 'card-text' }, entry.getIn(['data', 'body']), h('p', { className: 'small font-weight-light mt-3' }, `Created On: ${entry.getIn(['data', 'date'])}` )), widgetsFor('categories').map( function(category) { return h('span', { className: 'badge badge-primary mr-3 p-2' }, `${category.getIn(['data'])}`) }) ) ) ) ) }})
In the above snippet, we used getAsset
and widgetsFor
which are properties Netlify CMS makes available in our react component to return an in-memory render of an uploaded image and move through lists of content respectively. To see all the properties made available to our react components, take a look at the documentation here.
💡As an alternative to reading
entry
content usinggetIn
or looping through lists of entry content withwidgetsFor
, we can parse the immutable collectionentry
into a JSON object by runningvar entryData = entry.getIn([‘data’]).toJS()
and then reference attributes for our component using dot notation.
Creating custom styles for our admin dashboard
We have now created our React component to custom preview our Posts collection. If you are familiar with the library Bootstrap, you would notice that we’re using some Bootstrap classes on our component. The problem with this is our Netlify CMS admin does not have access to bootstrap styles so in this section we will provide that access.
First, we will install the Bootstrap library (if you don’t already have it installed) with yarn by running yarn add boostrap
Next, we will install a css-loader and sass-loader using yarn add sass-loader css-loader
Now that we have all our needed libraries installed, we will import our Bootstrap styles and apply them to the CMS using CMS.registerPreviewStyle
:
import styles from '!css-loader!sass-loader!../../node_modules/bootstrap/scss/bootstrap.scss';...CMS.registerPreviewStyle(styles.toString(), { raw: true })
💡In the above snippet, we converted our style to string and applied the config option
{ raw: true }
because ourstyles
variable contained the css file’s content. We can exclude theraw
config option if we instead import a publicly accessible css file e.g. usingCMS.registerPreviewStyle(‘assets/main.css’)
When we run our app and view the post on the admin editor we will see custom preview:
Conclusion
The entire code from this tutorial is available on Github. If you would like to explore more customizations and functionality with Netlify CMS, please share with us in the comments section!