{
"$type": "site.standard.document",
"canonicalUrl": "https://johnnyreilly.com/posts/publishing-docusaurus-to-devto-with-devto-api",
"description": "The dev.to API provides a way to cross post your Docusaurus blogs to dev.to. This post describes how to do that with TypeScript, Node.js and the dev.to API.",
"path": "/posts/publishing-docusaurus-to-devto-with-devto-api",
"publishedAt": "2022-12-11T00:00:00.000Z",
"site": "at://did:plc:yy3apqjlms24kso7ahn7lbmb/site.standard.publication/3mova7c4nho2b",
"tags": [
"docusaurus",
"github actions"
],
"textContent": "The dev.to API provides a way to cross post your Docusaurus blogs to dev.to. This post describes how to do that with TypeScript, Node.js and the dev.to API.\n\n\n\nWhy not use \"Publishing to DEV Community 👩💻👨💻 from RSS\"?\n\nIf you take a look at the dev.to settings (under extensions) you'll see that you can post to dev.to using an RSS feed:\n\nThis is great, but it has a number of downsides:\n\n- every post published to your blog will be published to dev.to - there's no fine grained control\n- every post published arrives as \"draft\" - you have to manually push it \"live\".\n- _most significantly_ - it handles code snippets poorly. Everything ends up as a single line of text. This is a real shame because code snippets are a key part of a blog post.\n\nSo after initially setting this up, I decided to look for a better way.\n\nThe dev.to API\n\nIt turns out that dev.to have an API.. The API is pretty well documented and it's pretty easy to use. The docs mention version 0 and version 1 of the API. Version 0 is officially deprecated, but version 1 appears to be incomplete - certainly the docs are. I ended up using version 0 for this post despite attempting to use version 1; I'll update this post when v1 gets there.\n\nThe only thing you need to do to use the API is generate an API key:\n\nTypeScript console app\n\nI'm going to use a TypeScript console app to do the work. Let's scaffold up an example project alongside our Docusaurus site:\n\nAnd in the package.json file add a start script:\n\nFinally, create an empty index.ts file. We'll fill this in shortly.\n\nTypeScript dev.to API client\n\nBefore we do that, we're going to need a dev.to API client. Let's create a devtoApiClient.ts file and add the following:\n\nThis is a simple API client that uses the Fetch API to make requests to the dev.to API. It's not a complete implementation of the API, but we only need a few article related endpoints to do the following:\n\n- Get all the articles that have been published to dev.to\n- Create a new article\n- Update an existing article\n\nFrom blog post markdown to published blog posts\n\nNow we can use the API client in our index.ts file:\n\nThere's a lot happening here, let me summarise it:\n\n- Grab the last 5 blog posts from the Docusaurus blog directory; this is the number of posts I want to publish to dev.to on each run\n- For each blog post, parse the front matter and the content\n- Build up the article object to send to dev.to. We do a few tricks here to make the article look nice:\n - To make the URL we'll use the slug front matter if it exists, otherwise use the date and title\n - Enrich the images in the content with the GitHub URLs so we can use images from the blog post\n - Use the first 4 tags from the front matter - dev.to only allows 4 tags. Also we'll strip those tags of any non-word characters\n - Default to published immediately\n- If the article already exists on dev.to, update it, otherwise create it\n\nBecause dev.to practise rate limiting on their API, I've added a 5 second sleep between each article to ensure we don't get blocked. It's a little arbitrary, but it works well enough.\n\nDoes it work? Let's find out!\n\nIt works! I've published 5 posts to dev.to from my blog. I can now go to dev.to and see them.\n\nRunning the script from GitHub Actions\n\nNow that we have the script, we need to run it. I'm going to use GitHub Actions to do this, but you could use any CI/CD tool you like.\n\nI add a new deploy_to_devto_job to my existing workflow and I set it to run on every push to the main branch. I don't want to publish to dev.to on every pull request; I want to publish once a blog post is published. So I add an if condition to the job to check that the event is not a pull request.\n\nIf you'd like to use this you'll need to add a DEVTO_APIKEY secret to your repository secrets. You can get this from your dev.to account settings. Remember to keep it secret!\n\nConclusion\n\nThis is all a bit of an experiment to see what happens if I start to cross publish my blog posts to dev.to. I'm not sure if I'll keep doing it, but I'm going to trial it and see how it goes.\n\nYou can use this approach with your own blog site - you'll need to do a little path and URL fiddling, but everything else should be just as you need.",
"title": "Publishing Docusaurus to dev.to with the dev.to API"
}