Enhancing Our Writing Workflow: Adding Markdown Support to Sanity CMS
How we added a Markdown editor to our Sanity setup and other improvements
Author:
Yomi Eluwande
In 2023, we transitioned from our GitHub-based blog posting system to Sanity, a powerful content operating system. This move significantly accelerated our content creation process and improved our media asset management. However, our engineering team quickly discovered they missed the familiarity of writing in Markdown, as Sanity Studio ships with a Rich Text editor by default.
During our recent Milan hackathon/offsite, I tackled this challenge by implementing Markdown support in our Sanity dashboard. This post walks through how we enhanced our content creation workflow to accommodate both rich text and Markdown enthusiasts.
Why we chose Sanity?
Sanity describes itself as a "Content Operating System", which is essentially a fully customizable, code-first backend for content-driven websites and applications. We made the switch primarily for:
Faster writing process - streamlined content creation workflows
Better media asset management - no more checking image files into our GitHub repository.
Flexible content modeling - adapting to our specific publishing needs.
Despite these advantages, our engineering team wasn't entirely comfortable with Sanity's default Rich Text editor. It turns out engineers really do love their Markdown!
Implementing Markdown Support
Modifying the Post Schema
The first step was updating our Post schema to accommodate Markdown content alongside the existing Rich Text option:
// schemas/post.tsimport {defineField, defineType} from 'sanity';export default defineType({ name: 'post', title: 'Post', type: 'document', fields: [ // ... other fields ... defineField({ name: 'markdownBody', title: 'Markdown Body', description: 'Use this field for Markdown content', type: 'markdown', options: { imageUrl: (imageAsset: any) => `${imageAsset.url}?w=800`, }, validation: rule => rule.custom((currentValue: any, context: any) => { const richTextBody = context.document?.body; if (!currentValue && !richTextBody) { return 'Either Rich Text Body or Markdown Body must be provided'; } return true; }), }), // ... other fields ... ],});
This modification above does the following:
Adds a dedicated markdownBody field.
Implements validation ensuring at least one content format is used.
Gives writers the freedom to use their preferred writing method.
Creating a Custom Markdown Editor
Next, we built a custom Markdown input component that delivers the familiar editing experience our team was looking for:
With all the changes above, we were now able to write blog posts in Markdown and have them render nicely on the Polar Signals blog.
This article was in fact written with the newly added Markdown editor!
One more thing
As a bonus enhancement to our workflow, we've integrated Vercel's Comments Toolbar, enabling real-time feedback on blog post drafts. Team members who are signed into our Vercel organization can easily add comments to drafts, streamlining our review process.
This was quite easy to do. We used the @vercel/toolbar package to enable the toolbar on the blog post pages.
// next.config.jsconst withVercelToolbar = require('@vercel/toolbar/plugins/next')();module.exports = withBundleAnalyzer( withMDX( withVercelToolbar({ // ... other next config here }) ))// src/components/BlogPostPreview/index.tsximport {VercelToolbar} from '@vercel/toolbar/next';export default function BlogPostPreview() { return ( <> <BlogPost meta={meta} post={post} /> <VercelToolbar /> </> );}
You can read more about how to implement this here.
Conclusion
By adding Markdown support to our Sanity CMS, we've created a more flexible content creation environment that caters to our team's preferences. Engineers can now work in the familiar Markdown syntax they love, while others can continue using the rich text editor.
The implementation was straightforward and has significantly improved our content creation experience. I hope this guide helps you in implementing a Markdown editor in your writing workflow.