Discovery Days at Medusa: How I created Cross Post tool from Notion

Feb 16, 2023 by

Shahed Nasser

Shahed Nasser

How I built a tool that heavily reduced the time spent on cross posting articles.
I’m a technical writer at Medusa. Part of my work includes managing the content on our blog and across platforms. Typically, we publish an article on our blog (which is built with Stackbit), then cross-post that article across platforms such as Dev.to, Hashnode, and Medium.
This process has become tedious and time-consuming. We publish at least 2 articles per week, and each article can take more than 30 minutes to be published across our blog and the 3 mentioned platforms. This includes adding the content in the format that each platform supports, uploading images if there are any, setting meta attributes such as description and meta tags, and more.
So, I decided to build a cross posting tool that would automate this task. cross-post-notion now allows us to publish an article from Notion to a GitHub repository (which holds the content of our main blog), Dev.to, Hashnode, and Medium in less than a minute. I decided to build this tool as part of our Discovery Days at Medusa.

What are Discovery Days?

Every Friday, the Medusa team members can dedicate half or their full day towards doing something different from their typical daily work. You can use this day to learn something new, read a book specific to your field, try out an interesting tool, or build a new tool.
As I realized this tool would heavily reduce the time I spend on publishing content to our blog, I dedicated the past 4 Discovery Days (Fridays) to building this tool.

How it Works

You can use
Copy to clipboard
cross-post-notion
either as an NPX command, as a global CLI tool, or just by cloning the GitHub repository.
Then, after adding the configurations necessary (more on this later), you can publish to all the different platforms using one command. You can also choose specific platforms to publish to.

Publishing to GitHub

Publishing to GitHub can be useful for any blogging platform that uses Markdown files hosted in a GitHub repository. This includes Stackbit, GitHub Pages, 11ty, Hugo, Docusaurus, etc…
Articles are pushed to GitHub as Markdown files with front matter metadata. The front matter includes by default the
Copy to clipboard
title
and
Copy to clipboard
date
of the article. The values of these fields are extracted from your Notion document, and you can specify the properties to extract these fields from.
In addition, you can specify custom front matter fields to add and from which properties to extract them from Notion. You can also specify front matter fields with fixed values. This is helpful if you have front matter fields that you need to always add to your articles.
If an article has images, the images are pushed to the GitHub repository as well. You can specify the path to upload the images to and the prefix to use within the article.

Publishing to Dev.to

You can publish articles to dev.to with this tool, either on your personal account, or in an organization. Similar to posting to GitHub, the values of dev.to fields such as the title, tags, or series can all be extracted from Notion properties.
One limitation to publishing to dev.to is that you can’t upload the images in the article using their APIs. So, you’ll still have to manually go in and upload any images in your article.

Publishing to Hashnode

You can publish articles to Hashnode with this tool, either on your personal blog or in a specific publication. Similar to the other platforms, the values of Hashnode fields are extracted from Notion properties.
One limitation to publishing to Hashnode is that it’s not possible to publish an article as a draft with their APIs. It’s only possible to choose to hide it from Hashnode’s feed. So, the article will automatically be available to your followers.

Publishing to Medium

You can publish articles to Medium with this tool, either on your personal account or in a specific publication. Similar to the other platforms, the values of Medium fields are extracted from Notion properties.

Using this Tool

Requirements

This tool requires an Internal Notion Integration created and installed in your Notion workspace. The integration must have access to the pages you want to publish as well. You can learn more about this in Notion’s documentation.

Install the Tool

There are three ways you can use this tool:
1. With NPX, which does not directly install the tool on your machine:
npx cross-post-notion
2. Install as a global CLI tool with NPM or Yarn:
# using NPM
npm install -g cross-post-notion
# using Yarn
yarn add cross-post-notion global
3. Clone the GitHub repository:
git clone https://github.com/shahednasser/cross-post-notion.git
cd cross-post-notion
npm install
npm start

Set Environment Variables

You need to set the following environment variables before you can use the tool. The requirements of the environment variables depends on which platforms you want to publish to:
  • Notion:
    • Copy to clipboard
      NOTION_TOKEN
      : (required for all platforms) Token on a Notion internal integration
  • GitHub:
    • Copy to clipboard
      GH_TOKEN
      : (required) GitHub personal token
    • Copy to clipboard
      GH_OWNER
      : (required) GitHub username
    • Copy to clipboard
      GH_REPO
      : (required) GitHub Repository name
    • Copy to clipboard
      GH_BRANCH
      : Branch name. Default is 
      Copy to clipboard
      master
      .
  • Dev.to:
    • Copy to clipboard
      DEVTO_API_KEY
      : (required) Your personal dev.to API key. Learn how to retrieve it here.
    • Copy to clipboard
      DEVTO_ORG_ID
      : The ID of the organization to publish the article under. You can retrieve it either from the organization dashboard page, where the ID is the last part of the URL (
      Copy to clipboard
      https://dev.to/dashboard/organization/ORG_ID
      ). Alternatively, you can use Dev.to's List Organizations endpoint to find the ID.
  • Hashnode:
    • Copy to clipboard
      HASHNODE_TOKEN
      : (required) Hashnode personal token
    • Copy to clipboard
      HASHNODE_PUB_ID
      : The ID of the publication to publish the article under. You can retrieve it either from the publication's dashboard page, where the ID is the second part of the URL (
      Copy to clipboard
      https://hashnode.com/PUB_ID/dashboard
      ).
  • Medium:
    • Copy to clipboard
      MEDIUM_TOKEN
      : (required) Medium Integration Token. Can be retrieved from here.
    • Copy to clipboard
      MEDIUM_PUB_NAME
      : The name of the Medium publication. Must be the exact name as it is on Medium.

Add Configurations

Configurations are used to customize how the article is published on the different platforms. They can be used to define what properties to extract data from in Notion, whether the article should be published or added as a draft, and more. You only need to set these configurations the first time you use the tool.
By default, configurations are loaded from the file
Copy to clipboard
config/default.json
relative to the current directory you’re running the command from. Alternatively, you can pass the path to the config file as an option.
The file can have the following configurations:
{
"config": {
"notion": {
"options": {
"skip_block_types": [
"toggle"
]
}
},
"github": {
"options": {
"image_path": "public",
"image_prefix": "/",
"article_path": "content",
"properties": {
"title": "Title for Blog",
"date": "Publishing Date",
"slug": "Slug"
},
"add_default_frontmatter": true,
"frontmatter_labels": {
"title": "title",
"date": "date"
},
"extra_frontmatter": {
"excerpt": "this is description"
},
"extra_frontmatter_mapper": {
"excerpt": "Description"
}
}
},
"devto": {
"options": {
"should_publish": false,
"properties": {
"title": "Title for Dev.to"
}
}
},
"hashnode": {
"options": {
"should_publish": true,
"should_notify_followers": false,
"properties": {
"title": "Title for Hashnode"
}
}
},
"medium": {
"options": {
"should_publish": false,
"should_notify_followers": false,
"properties": {
"title": "Title for Medium"
}
}
}
}
}
You can learn what each of these fields are and what more fields can be accepted in the GitHub repository.

Run Post Command

Grab the URL of a Notion document that includes an article you want to publish. It should be an internal URL which you can obtain from the Notion document by:
  • Click on Share at the top right.
  • Click on “Copy link” at the bottom of the pop-up.
Then, run the following command:
# using NPX
npx cross-post-notion post <url>
# using CLI tool
cross-post-notion post <url>
# using cloned repository
npm start post <url>
Where
Copy to clipboard
<url>
is the URL to the Notion document.
If all environment variables are set correctly, you should see logged in your terminal that the article was published on each of the platforms.
You can also specify which platforms you want to publish the article on using the
Copy to clipboard
-p
option:
npx cross-post-notion post <url> -p devto hashnode
This would publish the article only on Dev.to and Hashnode.

Learn More about this Tool

You can learn more about this tool and its limitations by checking out the GitHub repository. If you use it, let me know if it helps out! Although I’m mainly focused on using it for publishing articles at Medusa, feel free to open issues and contribute to further improve the tool.

Share this post

Try Medusa

Spin up your environment in a few minutes.