Publish Straight to Sanity from SyncPen (No Copy-Paste, No CMS Wrestling)

Write it once, in the calm of your editor. Click once. It's live in Sanity — drafts, slugs, images, code blocks and all. No copy-paste, no format-mangling, no second guessing.
The annoying part of publishing (that we deleted)
You wrote something good. Now comes the tax: open the CMS, recreate the structure, re-paste the text, watch your formatting quietly fall apart, re-upload the images, set the slug, fix the bits that broke. By the time it's live you've done the work twice.
SyncPen's Sanity integration skips all of that. You write in SyncPen — markdown, focused, collaborative — and hit Publish to Sanity. We do the translation, the image uploads, the slug, and the draft/publish dance for you. Your words land in your own Sanity dataset, ready to ship.
It's the same idea as our WordPress and Ghost publishing, pointed at Sanity. Connect once, publish forever.
How it works, in plain terms
When you publish, SyncPen takes the current version of your document and:
- Converts your markdown to Portable Text — Sanity's native rich-text format. Headings, lists, quotes, links, bold/italic, code blocks — they come across as real structured content, not a wall of text.
- Uploads your images — every image is copied into your Sanity asset store (not just linked to wherever it lived before), so the references point at Sanity's own CDN. Your published post stays intact even if the original file is moved, renamed, or deleted. You don't re-upload anything by hand.
- Generates a slug from your title — automatically, so the document is valid the moment it lands (more on why this matters below).
- Writes it into your dataset as the document type you chose — and if you publish the same doc again, it updates the same entry instead of spawning duplicates.
That's it. Draft in SyncPen, polish with penFriend, publish to Sanity. The whole pipeline, no tab-switching.
Your images, truly yours in Sanity
Worth underlining, because it's a real difference: SyncPen doesn't hand Sanity a link back to your image and hope it stays alive. It fetches the actual file and uploads the bytes into your Sanity project, then references that Sanity asset. The result:
- The published post is self-contained — it depends on Sanity, not on where the image originally lived.
- Images survive housekeeping on the source side. Move or delete the original, and your live article doesn't break.
- It works whether you dropped the image on its own line or inline in a sentence — both publish.
Slugs, handled for you
Most Sanity blog schemas make the slug a required field — and for good reason, it's your post's URL. The catch: Sanity's "generate from title" feature only fires when you click the button inside Sanity Studio. Tools publishing over the API have to set the slug themselves, or the document shows up incomplete and can't be published automatically.
SyncPen does it for you. On every publish we turn your title into a clean, URL-safe slug — lowercased, spaces to hyphens, accents flattened (Café déjà vu → cafe-deja-vu). So your document arrives valid and publishable, no manual step in Studio.
A couple of details worth knowing:
- The slug is derived from your title each time you publish, exactly like Sanity's own "generate from title." Rename the post and re-publish, and the slug (and its URL) updates to match.
- If your schema uses a field name other than
slug, just tell SyncPen — see the schema mapping below.
Drafts vs. Published — you're in control
When you hit Publish, you pick:
- Save as Draft → the document lands in Sanity as a draft. It shows up in your Sanity Studio for review, but stays invisible to your live site. Perfect for "let me look at it in context first."
- Publish Immediately → it goes live, and any leftover draft of the same doc is cleared out automatically.
Change your mind later? Re-publish from SyncPen and it promotes cleanly. Same document, no mess.
It works with your schema
Here's the part coders appreciate: Sanity projects don't all look alike. So the connection lets you tell SyncPen exactly where your content goes:
- Document type — the
_typeto write to (defaults topost) - Title field — where the title lands (defaults to
title) - Slug field — where the auto-generated slug lands (defaults to
slug) - Body field — where the rich text lands (defaults to
body)
Point those at your schema and publishing just fits. No assumptions, no forking your content model to match ours.
Set it up once (~2 minutes)
- In SyncPen, go to Settings → Sanity.
- Add a connection: your Project ID, dataset (usually
production), and a write-enabled API token from your Sanity project. - Set the document type / title field / slug field / body field to match your schema (or leave the sensible defaults).
- Hit Test Connection — a green check means SyncPen can reach your dataset.
Your token is encrypted at rest and never shown back to you or anyone else. Revoke it from Sanity anytime and the connection simply stops working — no lingering access.
Now open any document, click Publish to Sanity, pick draft or publish, and you're done.
One tip for the coders: code blocks
If you write fenced code blocks (and let's be honest, you do), SyncPen sends them to Sanity as proper code blocks. To make your Sanity Studio display and edit them happily, add Sanity's official code plugin to your studio:
npm install @sanity/code-input// sanity.config.ts
import { codeInput } from "@sanity/code-input";
export default defineConfig({
// ...
plugins: [structureTool(), codeInput()],
});…and allow the code type in your block content:
defineField({
name: "body",
type: "array",
of: [
{ type: "block" },
{ type: "image" },
{ type: "code" }, // 👈 lets code blocks render in Studio
],
});Good to know: Sanity happily stores whatever you publish — but its Studio only renders block types your schema defines. So if you ever see "Block of type code is not allowed by the schema," it's not a publishing failure; your content is safe in the dataset. Your Studio schema just needs to know about that block type. Add the plugin above and the warning disappears.
Quick troubleshooting
- Published a blank post? Make sure you've actually edited and saved the document first — SyncPen publishes your latest saved version. A brand-new, never-saved doc has nothing to send yet.
- Document won't publish in Studio — slug looks empty? That's the classic API-publishing gotcha, and SyncPen handles it: we generate the slug from your title automatically. If your schema's slug field isn't named
slug, set the correct name in the connection's schema mapping. - An image didn't show up? SyncPen only pulls images from public web addresses (a safety measure). If an image lives somewhere private or unreachable, it's skipped rather than published broken.
- Made a duplicate in Sanity? You shouldn't — re-publishing updates in place. If you see two, you probably published through a different connection. One SyncPen doc maps to one Sanity entry per connection.
Write here. Ship anywhere.
SyncPen is where your words live: focused writing, real-time collaboration, markdown end to end. With Sanity publishing, "where they live" and "where they go" finally connect with a single click.
Write with focus. Publish without the busywork.
— The SyncPen team ✍️