Skip to content

bartekpierscinski/arena-sanity-sync

Repository files navigation

Arena-Sanity Sync

Sync Are.na channels into Sanity.

This monorepo provides:

  • arena-sanity-core - framework-agnostic sync engine (Are.na to Sanity)
  • arena-sanity-adapter-nuxt - Nuxt 3 API route for triggering syncs
  • sanity-plugin-arena-sync - Sanity Studio dashboard plugin

Packages

The low-level sync engine.

  • Syncs Are.na blocks into Sanity documents
  • Handles retries, image uploads, drift-fix, idempotency
  • Use directly in Node, serverless functions, or custom cron jobs

Read docs


Nuxt 3 adapter.

  • Exposes a POST /api/sync endpoint
  • Reads config from .env and runtimeConfig
  • Useful for cron jobs or manual triggers

Read docs


Sanity Studio plugin.

  • Adds an "Are.na Sync" tool with channel picker and block browser
  • Bundles and auto-registers all schemas (areNaBlock, arenaSyncConfig, arenaChannelSettings)
  • Structure builder for organized desk hierarchy (by type, by channel, orphans)
  • Schemas are extensible — add your own custom fields
  • Real-time config updates, manual sync trigger

Read docs


Quickstart

1. Install dependencies

npm install arena-sanity-core @sanity/client are.na

2. Create a sync endpoint

Example Nuxt API route (server/api/sync.post.ts):

import {
  syncArenaChannels,
  createSanityClient,
  createArenaClient,
} from "arena-sanity-core";

export default defineEventHandler(async (event) => {
  const cfg = useRuntimeConfig();

  const sanity = createSanityClient({
    projectId: cfg.sanityProjectId,
    dataset: cfg.sanityDataset,
    token: cfg.sanityApiToken,
  });

  const arena = createArenaClient({
    accessToken: cfg.arenaAccessToken,
  });

  const result = await syncArenaChannels({
    arena,
    sanity,
    options: {
      channels: process.env.ARENA_CHANNELS?.split(",") ?? [],
    },
  });

  return result;
});

3. Configure environment variables

SANITY_PROJECT_ID=xxx
SANITY_DATASET=production
SANITY_API_TOKEN=...
ARENA_ACCESS_TOKEN=...
ARENA_CHANNELS=my-channel-1,my-channel-2
SYNC_CRON_SECRET=optional-secret

4. Trigger a sync

curl -X POST "https://your-app.com/api/sync" \
  -H "Authorization: Bearer $SYNC_CRON_SECRET"

CLI Usage

You can also run syncs directly from the command line using npx:

npx arena-sanity-core --channels my-channel

Options

Option Description
-c, --channels <slugs> Comma-separated channel slugs (required)
-i, --image-upload <mode> Image upload mode: off, auto, on (default: auto)
-d, --dry-run Print what would happen without making changes
-v, --verbose Show detailed progress logs
-h, --help Show help message
--version Show version

Examples

# Sync a single channel
npx arena-sanity-core --channels my-channel

# Sync multiple channels without uploading images
npx arena-sanity-core -c channel-1,channel-2 -i off

# Verbose output to see detailed progress
npx arena-sanity-core -c my-channel -v

# Dry run to preview what would be synced
npx arena-sanity-core -c my-channel --dry-run

Required Environment Variables

ARENA_ACCESS_TOKEN    # Are.na API access token
SANITY_PROJECT_ID     # Sanity project ID
SANITY_DATASET        # Sanity dataset name
SANITY_TOKEN          # Sanity API token with write access

Sanity schemas

If you use the Studio plugin (recommended), schemas are bundled and auto-registered:

import { arenaSyncPlugin } from "sanity-plugin-arena-sync";
plugins: [arenaSyncPlugin()]; // registers all three schemas

To extend schemas with custom fields, set schemas: false and spread the exports. See the plugin README.

Standalone schemas are also available in schemas/arena/ for projects not using the plugin:

  • arenaBlock.jsx — document schema for Are.na blocks
  • arenaChannelSettings.js — per-channel settings (visibility)
  • arenaSyncConfig.js — sync configuration singleton

The sync engine only updates fields prefixed with arena* and respects lockAll/lockImage flags.


Image upload modes

Mode Behavior
off Never uploads images (stores Are.na URLs only)
auto Uploads if missing in Sanity (default)
on Always uploads if changed

Uploading to Sanity counts toward asset storage costs.


Rate limits

  • Are.na API: ~60 requests/minute (retries and backoff are built in)
  • Use timeBudgetMs option to set a soft timeout for long syncs

Monorepo structure

arena-sanity-sync/
├── packages/
│   ├── core/                     # arena-sanity-core
│   ├── adapter-nuxt/             # arena-sanity-adapter-nuxt
│   └── sanity-plugin-arena-sync/ # Sanity Studio plugin
├── schemas/arena/                # Example Sanity schemas
├── examples/                     # Example configurations
└── README.md

License

MIT - Bartek Pierscinski

About

Sync Are.na channels into Sanity

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors