Post to Mastodon

Official(made by Sanity team)

By Simon MacDonald & Ken Jones Pizza

Spread the word on Mastodon when publishing a blog post

schemaTypes/post.ts

defineField({
  name: 'mastodonPost',
  title: 'Mastodon Post Content',
  type: 'text',
  description: 'Content to post on Mastodon when this post is published',
})

index.ts

import {env} from 'node:process'

import {Client, MastodonStrategy} from '@humanwhocodes/crosspost'
import {documentEventHandler} from '@sanity/functions'

const {MASTODON_TOKEN = '', MASTODON_HOST = ''} = env

interface NotificationData {
  slug: {
    current: string
  }
  mastodonPost: string
  title: string
}

export const handler = documentEventHandler<NotificationData>(async ({event}) => {
  const {data} = event
  const {title, mastodonPost, slug} = data

  try {
    const mastodon = new MastodonStrategy({
      accessToken: MASTODON_TOKEN,
      host: MASTODON_HOST,
    })
    const client = new Client({
      strategies: [mastodon],
    })

    const postContent = `${title}

${mastodonPost}

${slug.current}`

    await client.post(postContent)
    console.log('Successfully sent post to Mastodon')
  } catch (error) {
    console.error('Error posting to Mastodon:', error)
    throw error
  }
})

sanity.blueprint.ts

// sanity.blueprint.ts
import 'dotenv/config'
import process from 'node:process'
import {defineBlueprint, defineDocumentFunction} from '@sanity/blueprints'

const {MASTODON_TOKEN, MASTODON_HOST} = process.env
if (typeof MASTODON_TOKEN !== 'string' || typeof MASTODON_HOST !== 'string') {
  throw new Error('MASTODON_TOKEN and MASTODON_HOST must be set')
}

export default defineBlueprint({
  resources: [
    defineDocumentFunction({
      type: 'sanity.function.document',
      name: 'mastodon-post',
      src: './functions/mastodon-post',
      memory: 1,
      timeout: 10,
      event: {
        on: ['create'],
        filter: "_type == 'post' && defined(mastodonPost)",
        projection: '{title, mastodonPost, slug}',
      },
      env: {
        MASTODON_TOKEN: MASTODON_TOKEN,
        MASTODON_HOST: MASTODON_HOST,
      },
    }),
  ],
})

The Problem

Content teams want to automatically share their published articles on Mastodon to reach decentralized social media audiences. Manually cross-posting to multiple social platforms is time-consuming and often forgotten, leading to missed opportunities for content promotion across the fediverse.

The Solution

This Sanity Function automatically posts to Mastodon when content is published using the @humanwhocodes/crosspost library. When a post is published, the function creates a Mastodon post containing the title, mastodonPost, and slug, helping maintain consistent presence across decentralized social networks.

Quick Start

View full instructions and source code.

Initialize blueprints if you haven't already: npx sanity blueprints init

Then: npx sanity blueprints add function --example mastodon-post

Then deploy: npx sanity blueprints deploy

Mastodon Setup

More detailed instructions in the GitHub README

  1. Log into your Mastodon instance: Go to your Mastodon instance (e.g., mastodon.social, mastodon.online, etc.) and sign in with your account.
  2. Access Development Settings: Click Preferences, then in the sidebar, click "Development" and "New Application".
  3. Create Application: Give it a descriptive name (e.g., "Sanity Auto-Post"), leave Redirect URI as default, and select write:statuses.
  4. Get Access Token: After creating the application, copy the "Your access token" and note your instance URL.
  5. Environment Variables: Add MASTODON_TOKEN and MASTODON_HOST to your .env file.

How It Works

When a post is published, the function automatically:

• Posts the title, mastodonPost, and slug to Mastodon

• Uses the @humanwhocodes/crosspost library to handle posting

• Ensures consistent presence across decentralized social networks

Key Benefits

Automates fediverse sharing by posting to Mastodon on content publish

Saves time by eliminating manual cross-posting tasks

Reaches decentralized audiences by sharing on Mastodon instances

Ensures consistency with automatic posting of title, mastodonPost, and link

Reduces missed opportunities by never forgetting to share published content

Technical Implementation

The function uses the @humanwhocodes/crosspost library to automate posting to Mastodon. It's built with:

• Event-driven architecture (triggers on publish)

• Integration with Mastodon API using access tokens

• Error handling and logging for reliable operation

Perfect For

• Content teams looking to expand their reach to decentralized social media

• Workflows that benefit from automated social media posting

• Teams managing multiple social media platforms

• Projects that require consistent content promotion across the fedivers

Contributors

Official Recipes by Sanity

First Published Timestamp Function

Featured contribution
Official(made by Sanity team)

Automatically track when content was first published with a timestamp that sets once and never overwrites, providing reliable publication history for analytics and editorial workflows.

Knut Melvær
Go to First Published Timestamp Function

Automatically tag blog posts

Featured contribution
Official(made by Sanity team)

AI-powered automatic tagging for Sanity blog posts that analyzes content to generate 3 relevant tags, maintaining consistency by reusing existing tags from your content library.

Go to Automatically tag blog posts