This tool allows posting from Notion to different platforms.
- Cross Post Tool for Notion
- GitHub (Markdown)
- frontmatter customization
- Dev.to
- Hashnode
- Medium
NOTION_TOKEN
: Token on a Notion internal integration
GH_TOKEN
: (required) GitHub personal tokenGH_OWNER
: (required) GitHub usernameGH_REPO
: (required) Repository nameGH_BRANCH
: Branch name. default ismaster
.
DEVTO_API_KEY
: (required) Your personal dev.to API key. Learn how to retrieve it here.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 (https://dev.to/dashboard/organization/ORG_ID
). Alternatively, you can use Dev.to's List Organizations endpoint to find the ID.
HASHNODE_TOKEN
: (required) Hashnode personal tokenHASHNODE_PUB_ID
: (required) 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 (https://hashnode.com/PUB_ID/dashboard
).
MEDIUM_TOKEN
: (required) Medium Integration Token. Can be retrieved from here.MEDIUM_PUB_NAME
: The name of the Medium publication. Must be the exact name as it is on Medium.
You can use this command as an NPX command:
npx cross-post-notion
You can install this as a global CLI tool:
# using npm
npm install -g cross-post-notion
# using yarn
yarn add cross-post-notion global
You can clone this repository, then run the following command after installing the dependencies:
# using npm
npm start
# using yarn
yarn start
To cross-post an article from Notion to other platforms, use the post
command:
# using npx
npx cross-post-notion <url>
# using CLI tool
cross-post-notion <url>
# using cloned repository
npm start post <url>
Where <url>
is the URL of the Notion document.
By default, the article will be published to github, devto, hashnode, and medium.
You can specify which platforms to publish the article on using the -p, --platforms
option. For example:
yarn start example.com -p devto hashnode
This will publish the article only on dev.to and hashnode.
Allowed values are:
github
devto
hashnode
medium
If you want to test out the entire flow without actually posting the article, you can pass the -d, --dryRun
option:
yarn start example.com --dryRun
By default, this tool will look for configurations under config/default.json
or config/local.json
. You can also pass the -c, --config
option to load configurations from a different JSON file.
For example:
yarn start <url> -c path/to/file.json
The JSON configuration file can have the following fields:
{
"config": {
"notion": {
"options": {
"skip_block_types": [
]
}
},
"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",
"nested": {
"field1": "value1"
}
},
"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"
}
}
}
}
}
Where:
config
: wraps all configurations.notion
: A JSON object with all configurations related to Notion. These are:options
: Include all options related to cross posting:skip_block_types
: An array of block types that should be skipped from the Notion document. For example,toggle
would skip all toggle list blocks in the Notion document.
github
: A JSON object with all configurations related to GitHub. These are:options
: Include all options related to cross posting:image_path
: The path in the repository to upload images to.image_prefix
: The prefix to add to images in the markdown output.article_path
: The path in the repository to upload the markdown article to.add_default_frontmatter
: Whether to add default frontmatter to the markdown file. The default frontmatter are:title
date
slug
properties
: A JSON object that allows you to override the name of the properties in Notion to pull the values of frontmatter fields.frontmatter_labels
: A JSON object that allows you to override the labels of the frontmatter fields.extra_frontmatter
: Allows you to add extra frontmatter to the output markdown.extra_frontmatter_mapper
: If you want the values of the frontmatter keys inextra_frontmatter
to be pulled out of Notion, you can map each key to a property name in the Notion document.
devto
: A JSON object with all configurations related to Dev.to. These are:should_publish
: A boolean value indicating whether the article should be created in dev.to as a draft or it should be published.properties
: A JSON object that allows you to override the name of the properties in Notion to pull the values of frontmatter fields. You can set the following properties:title
date
description
tags
(the property's value in Notion should be a comma separated list.)series
(the property's value in Notion should be the name of the series)canonical_url
description
hashnode
: A JSON object with all the configurations related to Hashnode. These are:should_hide
: A boolean value indicating whether the post should be shown on Hashnode's public feed or not. Learn more in the limitations section.properties
: A JSON object that allows you to override the name of the properties in Notion to pull the values of frontmatter fields. You can set the following properties:title
original_article_url
(refers to the property holding the canonical url of the article)tags
(the property's value in Notion should be a list of tag names separated by a comma. The tag name can either be tag slug or display name)subtitle
medium
: A JSON object with all the configurations related to Medium. These are:should_publish
: A boolean value indicating whether the article should be created in dev.to as a draft or it should be published.should_notify_followers
: A boolean value indicating whether your followers should be notified about the article.properties
: A JSON object that allows you to override the name of the properties in Notion to pull the values of frontmatter fields. You can set the following properties:title
subtitle
tags
(the property's value in Notion should be a list of tag names separated by a comma.)canonical_url
When you're loading configurations from a custom file using the -c, --config
option, you can't use the environment variables anymore. You'll have to pass them in the same config file as follows:
{
"config": {
"notion": {
"connection_settings": {
"token": "..."
}
},
"github": {
//...
"connection_settings": {
"token": "...",
"owner": "...",
"repo": "...",
"branch": "..."
}
},
"devto": {
//...
"connection_settings": {
"api_key": "...",
"organization_id": "..."
}
},
"hashnode": {
"connection_settings": {
"token": "...",
"publication_id": "..."
}
},
"medium": {
"connection_settings": {
"token": "...",
"publication_name": "..."
}
}
}
}
- If a file with the same name and path exists in the repository, an error is thrown. There's no support for updating files.
- As Dev.to does not expose an endpoint to upload images, it's not possible to upload images in the article. Images are added as they are in Notion, which may or may not work as expected. You'll have to upload them manually from Dev.to's interface.
- Hashnode's API does not provide the option to post an article as a draft. As an alternative, the
should_hide
will allow you to hide the article from Hashnode's public feed. It will still, however, show up on your blog. - Due to a limitation in Hashnode's APIs, it's not possible to map all available categories. So, some categories you use in Notion will not show up when you cross-post to Hashnode.
To retrieve the URL of a Notion document:
- In the document, click on Share at the top right.
- Click on Copy Link at the bottom right of the pop up.
The URL should be of the format https://www.notion.so/{workspace}/{path}
.
When you copy the URL from Notion, sometimes it has a query parameter at the end of it such as ?psv=4
. Some terminals can't read that.
Make sure to remove any query parameters and try again.
After the first time you use the command with NPX, it might not use updated versions moving forward.
So, it's recommended to use @latest
with your commands:
npx cross-post-notion@latest <url>