I host my blog on my own site and while this will always remain my main platform, I decided to write a node.js script to cross-post my articles to medium. I’ll show you how to cross-post Markdown posts to Medium using the node medium-sdk. There are several good reasons to do so. In fact, there’s not a single disadvantage if you’re doing it correctly.

Why cross-post to Medium?

  1. Medium already has a huge audience, which means new people will discover your content that wouldn’t have found you otherwise. You also don’t need to be afraid about Google reducing the search engine ranking of your self-hosted blog due to duplicated content because we can set the post’s canonical link, the single source of truth, in Medium to point back to the original post on our own website. This way, there is no SEO disadvantage of having your posts on both platforms.
  2. The on-site Medium Editor sucks. The editor doesn’t even allow you to write in Markdown directly. Even though Medium supports Markdown (as we’ll see later), there’s no toggle to switch between WYSIWYG / Markdown / HTML views. Most developers I know prefer to write in Markdown instead of inserting links/images through a toolbar. Using the cross-posting approach, we can write Markdown in our familiar environment — for me, it’s VS Code + gatsbyjs for live reloading.
  3. Posting to Medium programmatically is easier from a workflow perspective. Previously, I tried Medium’s Import Story feature directly on the post on my site, which often broke the formatting when reading the HTML, or to import the Markdown through tools like markdowntomedium, which work well, but they pollute your GitHub account with (private) gists and set an incorrect canonical URL to the GitHub gist. Now, with gatsbyjs or any other static site generator, my workflow looks like this:
  • Write post in Markdown
  • Push to GitHub => Netlify git-hook runs and deploys my site
  • I run my cross-post script: npm run crosspost which publishes the new post to Medium

If this convinced you, here’s how to setup cross-posting to Medium.


All you need is nodejs version 8 or higher, and a post written in Markdown. The Markdown post should have a frontmatter containing the title, slug, and medium tags, . For instance, this post looks like this:

Creating credentials for the scripts

You need to set up an app in your Medium account settings and create an integration token to grant your script the rights to publish posts on your behalf.

1. Create the app

In your Medium settings, click on Manage Applications, New application and fill in the App details as you please:

Click on save and write down the Client ID and Client Secret of the app you just created.

2. Create an integration token

In your Medium settings, go to Integration Tokens, fill out the description, click on Get Integration Token and write down the token.

Medium Integration Token
Medium Integration Token

Cross-post Script

Here comes the fun part — we’re ready to create the node.js script. Let’s take a look at the outline of what our script needs to do:

  1. Read the Markdown file, parse it into a markdown abstract syntax tree (MAST)
  2. Get the title, slug, and medium tags from the frontmatter.
  3. Rewrite all relative image and link URLs to absolute URLs prefixing our website
  4. Inject custom footer backlinking to our original post
  5. Use Medium API to create the post with the modified markdown post’s content, correct canonical-link, and tags.

I’ll go through the main ideas here, the fully functional code can be seen on GitHub.

Parsing the markdown file

We will use remark with its many plugins to parse the Markdown file. remark works by creating a chain of plugins. This way, we start with the file's contents, and the output of each plugin is then given as the input for the next plugin in the chain. We'll use the parse plugin to parse the markdown file, then process the returned MAST to parse the yaml frontmatter node, and finally use stringify again to recreate markdown content out of the MAST.

We follow this pattern of putting new custom remark plugins into the chain for the rest of the steps we need to do.

Getting the frontmatter

To read the frontmatter and convert it to a javascript object, we will write our first remark plugin. It traverses the MAST checking for yaml nodes and creates a javascript object out of it.

Remark plugins are just functions that return a transformer function themselves.

Then our transformPostFromPath function can use the frontmatter to extract the slug:

Resolving relative URLs to absolute URLs

Next, we need to write a plugin that transforms all relative image and link URLs to absolute URLs. The reason is that an image hosted on our own blog, which is embedded like

will not work in Medium. Therefore, we will use the slug to rewrite the MAST for images and links to have a structure like this:

The plugin’s code is quite simple, we use the visitor pattern again to traverse the MAST and rewrite the url property of these nodes.

Injecting the custom footer

Let’s add a footer to the medium markdown post linking back to the originally published post. We will just write a plugin which appends a divider and a paragraph to the children of the MAST.

Using medium-sdk to publish the transformed post

Now we just need to call the transformPostFromPath function which sequentially executes all of our remark plugins, and returns the new post as markdown along with the frontmatter.

The medium client implementation looks like this:

You need to set the correct credentials mentioned in the setup section in a .env file.

Again, the complete working code can be seen on GitHub. After calling this function you should have a new story in your Medium account as a draft. 🎉


Writing these auto-post-generator scripts is addicting. Here are some more things you could do:

  • Write a remark-plugin that replaces code nodes with a Codepen / GitHub gist to enable syntax highlighting in Medium.
  • Add a signature / an image to the footer promoting your products.
  • Cross-post to other platforms. The next post will be on cross-posting to steemit.

Originally published at cmichel.io

Medium Clap
Medium Clap

Written by

Full Stack Software Engineer #javascript #EOS. Into Recreational Math / CS 🤯 Just message me about anything, my mind is open.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store