Create a Markdoc plugin in less than 15 lines of code
Tags: markdoc, markdown, parcel
Published: 2022-05-27 17:18:23

---
title: Create a Markdoc plugin in less than 15 lines of code
published: true
description: Markdoc is an extension of Markdown so learn how to build your own plugin so you can use Markdoc with any framework.
tags: markdoc, markdown, parcel
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nv5saos16agbxxpe0zqe.png
---

A couple of weeks ago, we open-sourced [Markdoc](https://markdoc.io/), the authoring tool powering the [Stripe docs](https://stripe.com/docs). To accompany the launch, we published a [blog post](https://dev.to/stripe/getting-started-with-markdoc-in-nextjs-ioj) showing how to get started using Markdoc with Next.js, using the [@markdoc/next.js plugin](https://github.com/markdoc/next.js).
In this blog post, I’ll show you how to create your own plugin, using the one I wrote for [Parcel](https://parceljs.org/), 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](https://github.com/charliegerard/parcel-transformer-markdoc).

## 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:

```js
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];
 },
});
```

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:

```js
{
 "extends": "@parcel/config-default",
 "transformers": {
   "*.md": [
     "parcel-transformer-markdoc"
   ]
 }
}
```


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:

```js
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>
 );
}
```

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:

* [Svelte-markdoc](https://github.com/joshnuss/svelte-markdoc)
* [Esbuild-markdoc-plugin](https://github.com/toddw/esbuild-markdoc-plugin)
* [Solidjs-markdoc](https://github.com/dillonchanis/solidjs-markdoc)
* [Vue-markdoc](https://github.com/wobsoriano/vue-markdoc)

If you end up creating your own plugin, let us know!
 
📣 Follow [@StripeDev](https://twitter.com/stripedev)[ and our team](https://twitter.com/i/lists/1459720002567868418) on Twitter
📺 Subscribe to our [Youtube channel](https://www.youtube.com/StripeDevelopers)
💬 Join the official [Discord server](https://discord.com/invite/RuJnSBXrQn)
📧 Sign up for the [Dev Digest](https://go.stripe.global/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.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3sq81ik9f53e5qr3iuvh.png)

[Charlie Gerard](https://twitter.com/@devdevcharlie) is a Developer Advocate at Stripe, a [creative technologist](https://charliegerard.dev/) and [Google Developer Expert](https://developers.google.com/community/experts). She loves researching and experimenting with technologies. When she’s not coding, she enjoys spending time outdoors, trying new beers and reading.