4 min read

How to automatically publish a new post to dev.to with Next.js and Sanity CMS

Writing and publishing a new post on our blog and sharing our knowledge is great. To get a better outreach, we would also like to publish our post on dev.to, Hashnode, Medium or maybe sharing on Twitter for the visibility. Having to manually copy and paste our content on the respective platforms can be troublesome, even more so if we need to update our content across the different platforms.

In this article, I would walkthrough how I ran an automated way to publish new post to dev.to (to Hashnode and Twitter later) using Next.js API routes and Sanity webhook.

Creating our API in Next.js

  1. Create a file named post-to-dev-community.ts (You can name this whatever you prefer) in /api/ of your project.
  2. Prepare a dev.to API key from https://dev.to/settings/extensions. Set the API key in a .env file.



Below is the following code to create the API that reads from the webhook and calling the dev.to creating new article API.

import { NextApiRequest, NextApiResponse } from "next";
import { HOST_URL } from "lib/config";
import { sanityClient } from "lib/sanity-server";
import { postUpdatedQuery } from "lib/queries";

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
  const body = await readBody(req);

  const publishedPost = JSON.parse(body);
  const { _id: id, content } = publishedPost;

  const slug = await sanityClient.fetch(postUpdatedQuery, { id });

  try {
    const post = await fetch("https://dev.to/api/articles", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "api-key": process.env.DEV_TO_API_KEY
      body: JSON.stringify({
        article: {
          body_markdown: content,
          published: true,
          canonical_url: `${HOST_URL}/blog/${slug}`
    }).then((res) => res.json());

    return res
      .json({ message: `Successfully published on: ${post.url}` });
  } catch (err) {
    return res.status(400).json({ message: err.message });

export default handler;

// Next.js will by default parse the body, which can lead to invalid signatures
export const config = {
  api: {
    bodyParser: false

const readBody = async (readable: NextApiRequest) => {
  const chunks = [];
  for await (const chunk of readable) {
    chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
  return Buffer.concat(chunks).toString("utf-8");

This will now expose your API as: https://example.com/api/post-to-dev-community. Deploy your code to your respective hosting platform. In this case, I am just using Vercel to do so.

Note: Do remember to update your environment variables for DEV_TO_API_KEY on the deployment platform you use in order for the API to work.

Creating the webhook on Sanity

  1. Navigate to https://sanity.io/manage
  2. Open your studio project and select the API tab
  3. You should now see a section GROQ-powered Webhooks
  4. Create a webhook as per the screenshot

Create a webhook on Sanity CMS


Once you are done, deploy everything and we can start writing a new post and have it automatically published to the respective platform.

To check if this is actually working, navigate to dev.to and check your dashboard. If it worked, the new post will appear and set to published.

Alternatively, you may also check for the attempt log from the webhook.

Upon a successful publish on dev.to, you should be able to see the following response in the attempt log.

	"id": "redacted",
	"projectId": "redacted",
	"inProgress": false,
	"duration": 4997,
	"createdAt": "2023-01-26T17:58:44.369Z",
	"updatedAt": "2023-01-26T17:58:44.369Z",
	"messageId": "redacted",
	"hookId": "redacted",
	"isFailure": false,
	"failureReason": null,
	"resultCode": 200,
	"resultBody": "{\"message\":\"Successfully published on: https://dev.to/ruchernchong/test-auto-posting-to-devto-from-a-cms-420k\"}"

And there you have it. How to automatically publish a newly created post on our blog and have it automatically published onto dev.to using the Next.js API Routes and Sanity CMS webhook.

I will also be updating this code in the future to handle automatic updating of the post. There is no deleting for post to dev.to due to the lack of the API. Subsequently, I will also expand this to Hashnode and sharing a short tweet on Twitter for a new post.

You may also find this code on my GitHub repository at: https://github.com/ruchernchong/portfolio