The demo plugin we're about to build is called Record Metrics. It will enhance your editorial experience when creating for instance a blog post by providing useful metrics such as word count and a reading time indicator. The metrics will be shown in a sidebar panel for a given record.
In order to successfully complete this tutorial:
You'll need the latest LTS version of Node.js installed on your machine. If you don't have Node.js
installed, you can download it here.
You should be comfortable using your computer’s command line and text editor.
You’ll need to be able to read and write HTML, CSS, and JavaScript.
You should be familiar with installing software using NPM.
You'll need a free DatoCMS account and a project. You can sign up here.
You'll need either Firefox or Chrome. Safari currently does not work due to a limitation in how it handles insecure iframes pointing to localhost
.
We will use several tools and libraries throughout the tutorial. We chose these technologies because we think they provide the best possible developer experience.
We use React to render our views for the app and handle our logic. React is a JavaScript library for building user interfaces. However, using React is not mandatory to create apps.
The Plugin SDK provides the methods that are necessary to interact with the DatoCMS web app. We will only use a subset of the methods, but if you want to know the full scope of what is possible, take a look at the other sections of this guide.
To achieve the same look and feel of the DatoCMS web app we use datocms-react-ui
which exposes a number of React components ready to be used.
The plugin is written in TypeScript. This allows us to have documentation, autocompletion in our editor, as well as the assurance that we are passing the right parameters to our libraries. However, you do not need any TypeScript knowledge in order to complete this tutorial. Plugins can also be written in JavaScript without losing any of the functionality.
As a first step, you need to create a project directory. We will use a tool called create-react-app
. This tool makes it easy to create apps with React using a template, and offers a modern build setup with no configuration.
npx create-react-app@latest my-first-plugin --template datocms-plugin --use-npm
After some time, our script is ready and initializes our first app. Navigate to the newly created folder and start the app.
cd my-first-pluginnpm run start
This hosts your plugin on http://localhost:3000
. We'll later connect to this through the DatoCMS web app.
In order for you to see your app running in the DatoCMS web app, you need to create a private plugin in DatoCMS.
Enter your project, and go to "Settings > Plugins". Click on the plus icon, then choose "Create new Plugin". In the modal, provide details about your plugin:
Provide a name and (optionally) a description for your plugin. This can be whatever you want; we chose Record Metrics for this tutorial.
Enter the Entry point URL. This is the URL where our app is running. Since we are running our app locally the URL is http://localhost:3000
.
Specify any special permission you want to grant to the plugin. For this tutorial, we don't need any of them.
Then submit the form to create the plugin. Congrats, your plugin is now installed to your current project and environment! 🎉
The config screen of the plugin is rendered by the ConfigScreen
React component.
Let's fire up our code editor of choice and open the src/entrypoints/ConfigScreen.tsx
file in the project directory that was previously generated. Any changes you make here will be reflected in the DatoCMS web app. Let's change our welcome text from Welcome to your plugin!
to Welcome to Record Metrics!
Save the file and watch the config screen update in real time:
Inside the src/entrypoints/ConfigScreen.tsx
file you'll notice the use of <ContextInspector />
, which is a component made available by datocms-react-ui
to get an instant overview of all the information/methods available within any SDK hook.
Remember to use it during development, it's very convenient to avoid going back and forth in the documentation!
To add sidebar panels to the DatoCMS interface, we need to implement the itemFormSidebarPanels
and renderItemFormSidebarPanel
hooks.
Open the src/index.tsx
file and add the following code:
import SidebarMetrics from './entrypoints/SidebarMetrics';connect({// ...itemFormSidebarPanels() {return [{id: 'metrics',label: 'Metrics',},];},renderItemFormSidebarPanel(sidebarPaneId, ctx) {render(<SidebarMetrics ctx={ctx} />);},});
We also need to add the new SidebarMetrics
component in src/entrypoints/SidebarMetrics.tsx
:
import { RenderItemFormSidebarPanelCtx } from 'datocms-plugin-sdk';import { Canvas } from 'datocms-react-ui';type PropTypes = {ctx: RenderItemFormSidebarPanelCtx;};export default function SidebarMetrics({ ctx }: PropTypes) {return <Canvas ctx={ctx}>Hello from the sidebar!</Canvas>;}
Make sure to have a model with some text fields, and a record we can test the plugin on (if you are not familiar with the concept of models, you can read more about them here).
Then go to your Content tab, and create a blog post record. You should see a "Metrics" sidebar panel now in the page:
All the changes you make here to the component will also be reflected directly in the web app.
It's time to calculate some metrics for the record. For calculating the word count and the reading time we will use a library called reading-time
. Navigate to your project folder and install the libraries and its dependencies with:
npm install reading-timenpm install stream util --save-dev
We can use the ctx
object, which gets passed into every hook, to interact with DatoCMS:
The ctx.fields
object holds all the currently loaded fields for the current project;
The ctx.itemType
object holds the model for the current record;
The ctx.formValues
object holds the current values present in the record form;
We can use this information to get the values of all the text fields present in the record, concatenate them in a single string and then call the readingTime
function, which will calculate our desired metrics. It will do all the heavy lifting for us and return an object which holds the word count and the time to read.
The last thing we want to do is display the calculated metrics in our sidebar. For this we import the Canvas
component from datocms-react-ui
to give our app the look and feel of the DatoCMS web app.
The final code should look like this:
import { RenderItemFormSidebarPanelCtx } from 'datocms-plugin-sdk';import { Canvas } from 'datocms-react-ui';import readingTime from 'reading-time';import { Field } from 'datocms-plugin-sdk';type PropTypes = {ctx: RenderItemFormSidebarPanelCtx;};export default function SidebarMetrics({ ctx }: PropTypes) {const modelFields = ctx.itemType.relationships.fields.data.map((link) => ctx.fields[link.id]).filter<Field>((x): x is Field => !!x);const textFields = modelFields.filter((field) =>['text', 'string'].includes(field.attributes.field_type),);const allText = textFields.map((field) => ctx.formValues[field.attributes.api_key]).join(' ');const stats = readingTime(allText || '');return (<Canvas ctx={ctx}><ul><li>Word count: {stats.words}</li><li>Reading time: {stats.text}</li></ul></Canvas>);}
Type some content in your field and see how the app updates!
To deploy your plugin and make it available to everyone in your organization, you need to create a production build of your app and then host it somewhere on the internet. We strongly suggest using Netlify or Vercel, as they make the overall experience incredibly easy.
When configuring your hosting service, make sure to specify the following build command:
npm run build
Once deployed, go to "Settings > Plugins", and inside your plugin click the "Edit private plugin" button. In the modal, change the "Entry point URL" to the new Netlify/Vercel URL.
Congratulations, you just deployed your first plugin! 🥳
Learn to build a DatoCMS plugin from scratch with this video tutorial: