Skip to content
Writing Room

Document types

View as Markdown

The room writes Posts by default. To write other kinds too, list their document types:

writingRoom({
  types: ['post', 'caseStudy'],
})

Fields

The room reads each type’s schema to find what it writes:

It looks for If there’s none
Title title, else the field the type’s preview shows as its title, else the first string field The type is left out
Body body, else content, else the first portable text field The type is left out
Slug slug, else the first slug field No slug is settled on publish
Published date publishedAt, else the first date field whose name contains “publish” No date is stamped on publish
Cover image coverImage, else mainImage, else the first image field No “Add a cover image” nudge after a publish

If it guesses wrong, name the field: {type: 'article', fields: {body: 'content', title: 'headline'}}. Every other field (excerpt, tags, a client name…) shows up under Details, with nothing to configure.

Details

Details in the room’s controls swaps the body for the document’s other fields, on one page in the order your schema gives them. The title stays where it is, and the arrow or Esc goes back to the writing.

  • Simple fields get the room’s own inputs: strings, text, numbers, booleans, dates, slugs and tag lists.
  • Everything else is Sanity’s own input, looking as it does in the rest of your Studio: references, images, files, arrays of objects, and lists of choices. With the matching theme they sit closer to the room’s look.
  • Your custom inputs are used as they are. A field with its own components.input or components.field is never replaced.
  • List the Writing Room last in plugins if another plugin wraps every input. For simple fields the room’s inputs take the place of Sanity’s, which ends Sanity’s chain of input components there. A plugin listed before the Writing Room still wraps the room’s inputs in Details; one listed after it, and a form.components.input in your own Studio config, does not. Everything still appears in the Structure form.
  • Your schema’s rules apply: hidden, readOnly and validation behave as they do in the standard form. Field groups are not shown as tabs; fieldsets are kept.
  • A type with only a title and a body has no Details button.

Details are saved as you type, like the writing. If a required field blocks a publish, the room opens Details at that field.

If the Details view can’t be shown in your Studio, the room says so and offers Open in Structure instead.

The body

The editor is built from the body field’s own type, so the room only offers what that type can store. A blockContent with headings, quotes, bullets, links and images gets exactly those: no code blocks, embeds or numbered lists in the Insert Menu, selection bubble or markdown shortcuts. Image description and caption inputs appear only when your image type has alt and caption fields.

To offer the room’s own blocks (YouTube/Vimeo/Spotify embeds, code blocks, section breaks), add them to your body type. The plugin registers them for you, under prefixed names that can’t clash with yours:

import {writingRoomBlocks} from 'sanity-plugin-writing-room'

defineType({
  name: 'blockContent',
  type: 'array',
  of: [{type: 'block'}, {type: 'image'}, ...writingRoomBlocks],
})

Your site then renders them as writingRoomEmbed, writingRoomCodeBlock and writingRoomSectionBreak. (The starter writingRoomSchemaTypes uses the original names, embed, codeBlock and sectionBreak; the room handles both.)

Blocks of your own that the room doesn’t know (a callout, a product card…) keep their place in the text as a quiet placeholder: the Writer can move or delete them, and Edit in Structure opens that block in the standard form.

Labels and URLs

The Lobby’s New button starts a document of your type (“New Post”); with several types it asks which. Recent writing lists them together. The room names each type with its schema title (“Case Study”). If a name comes out wrong, set it yourself:

writingRoom({
  types: ['post', {type: 'news', title: 'News', pluralTitle: 'News'}],
})
Option Default What it does
types ['post'] The document types the room writes, as names or {type, title?, pluralTitle?, fields?}.
types[].title the schema type’s title What one is called: “New Case Study”.
types[].pluralTitle title made plural What several are called: “Case Studies”.
types[].fields detected {title?, body?, slug?, publishedAt?, image?}: field names, when the room guesses wrong.

The first type is the default: its documents open at /writing-room/<id>, the others at /writing-room/<type>/<id>. A Studio with one type keeps short URLs, and links to it keep working if you add more types later, as long as it stays first.

If a type in types isn’t in your schema, or has no title or body the room can find, the room leaves it out and says why in the browser console. Slugs are unique within a type, so a Post and a Case Study can both be hello-world.