DEV Community

Cover image for Create a Markdoc plugin in less than 15 lines of code
Charlie Gerard for Stripe

Posted on

Create a Markdoc plugin in less than 15 lines of code

A couple of weeks ago, we open-sourced Markdoc, the authoring tool powering the Stripe docs. To accompany the launch, we published a blog post showing how to get started using Markdoc with Next.js, using the @markdoc/next.js plugin.
In this blog post, I’ll show you how to create your own plugin, using the one I wrote for Parcel, as an example, so that you can use Markdoc with it.

Before we get started, Parcel is a zero-configuration build tool that includes a development server, hot reloading, automatic production optimization and more, out of the box. However, it does not parse Markdown files by default so, to be able to use Markdoc with Parcel, you need a specific plugin. As Markdoc is an extension of Markdown, a standard Markdown plugin won’t be enough to parse files properly.

If you want to skip directly to the complete plugin, feel free to check out the repo.

Creating a plugin

Depending on the framework or tool you’d like to build a plugin for, they might handle their plugin system a little differently but the code contained in the plugin should be relatively similar. At its core, what needs to be done is call the Markdoc.parse() and Markdoc.transform() methods.

In Parcel, a plugin that transforms assets is called a Transformer.

Here’s what this Transformer looks like:

import { Transformer } from "@parcel/plugin";
import Markdoc from "@markdoc/markdoc";

export default new Transformer({
 async transform({ asset }) {
   const code = await asset.getCode();

   const ast = Markdoc.parse(code);
   const content = Markdoc.transform(ast);

   asset.type = "js";
   asset.setCode(`export default ${JSON.stringify(content)}`);

   return [asset];
 },
});
Enter fullscreen mode Exit fullscreen mode

To start, you need to import Transformer from Parcel, and Markdoc from @markdoc/markdoc.

Then, the way to access the content of files in a Parcel transformer is to call asset.getCode(). From there, you have to call the .parse() and .transform() methods from Markdoc to handle the raw Markdown content.

Finally, you need to return the transformed content. Markdoc.transform() returns a JSON object, so we need to specify that the type of the content is now JavaScript, by changing the .type property to ‘js’. Then, you need to call the setCode method to replace the content with the newly generated one and append it after export default. This last part is specific to Parcel, however, calling parse and transform is required to create a plugin for any other tool.

Using a plugin

To use this plugin, you need to start by pasting the following lines in the .parcelrc file in your application:

{
 "extends": "@parcel/config-default",
 "transformers": {
   "*.md": [
     "parcel-transformer-markdoc"
   ]
 }
}
Enter fullscreen mode Exit fullscreen mode

What this code does is extend Parcel’s default configuration to handle files ending in *.md and applying the custom transformer to the content of these files.

Then, if you imagine a React app with a Markdown file called getting-started.md, the code needed to display this content would look something like this:

import content from "./getting-started.md";
import Markdoc from "@markdoc/markdoc";
import React from "react";

export function App() {
 const html = Markdoc.renderers.react(content, React);
 return (
   <main>
     {html}
   </main>
 );
}
Enter fullscreen mode Exit fullscreen mode

That’s it! Now, Markdown files will be parsed properly and you can use all the features Markdoc provides.

Other plugins

Other members of the developer community have also started making their own plugins. Feel free to check them out:

If you end up creating your own plugin, let us know!

📣 Follow @StripeDev and our team on Twitter
📺 Subscribe to our Youtube channel
💬 Join the official Discord server
📧 Sign up for the Dev Digest

About the author

Charlie's profile picture. She's a caucasian woman with long brown hair and is wearing silver glasses. Behind her is purple lights.

Charlie Gerard is a Developer Advocate at Stripe, a creative technologist and Google Developer Expert. She loves researching and experimenting with technologies. When she’s not coding, she enjoys spending time outdoors, trying new beers and reading.

Top comments (3)

Collapse
 
ben profile image
Ben Halpern

Marcdoc is really interesting

Collapse
 
ephraimduncan profile image
Ephraim Duncan

I checked Markdoc out. I have a question though.

Was it built to replace Markdown or to improve it?

Collapse
 
devdevcharlie profile image
Charlie Gerard

Oh we're not trying to replace Markdown :) it's an extension, so we built it to be able to add more functionality like using variables and functions, custom components, doing syntax validation, etc.