Arrow keys: ← previous · → next 24 of 35
@nodedk/sanity
0.24.5 stable

sanity#

Query Sanity, hydrate locally stored documents, and render CMS content.

Requirements#

A Sanity project for API calls. Local reference hydration requires a native MongoDB database with document and draft collections.

Install#

npm i @nodedk/sanity

Usage#

Create a configured CMS instance. Pass your connected MongoDB database as db when using local hydration:

var sanity = require('@nodedk/sanity')

var cms = sanity({
  db,
  locale: 'no-NB',
  blockOptions: {
    components: {}
  },
  clientOptions: {
    projectId: 'project-id',
    dataset: 'production',
    apiVersion: '2025-02-06',
    token: process.env.SANITY_TOKEN,
    useCdn: false
  }
})

Configuration#

sanity(options = {}) returns the configured CMS object.

  • db: native MongoDB database used by published and draft.
  • clientOptions: projectId (default 'test'), dataset (default 'production'), apiVersion (default '2025-02-06', optional leading v), token, and useCdn (queries only, default false).
  • markdownOptions: forwarded to markdown.
  • blockOptions: Portable Text options, including components.
  • locale: default date locale, 'no-NB'.
  • localeOptions: Intl.DateTimeFormat options for dates; default { day: '2-digit', month: '2-digit', year: 'numeric' }.

Local hydration#

published(data) and draft(data) return Promises. They walk objects and arrays in place and resolve Sanity _ref objects by _id. An unresolved reference becomes {}. They read MongoDB, without fetching from Sanity.

Published hydration resolves document references from the document collection and leaves all other values unchanged:

var data = await cms.published(document)

Draft hydration checks root documents and references in the draft collection using their drafts.<id> IDs, then falls back to published documents:

var data = await cms.draft(document)

Content rendering#

block(state, content, options) converts Portable Text to an HTML string. options replaces the configured blockOptions for that call. Custom component functions receive (state, props) rather than only Portable Text props. Missing content and arrays of blank text blocks return ''.

var { esc, html } = require('@nodedk/page')

var content = cms.block(state, document.content, {
  components: {
    types: {
      notice: function (state, props) {
        return html`<aside>${esc(props.value.text)}</aside>`
      }
    }
  }
})

markdown(source = '') renders a Markdown block; inline(source = '') renders inline Markdown without a paragraph wrapper. Both use the configured markdownOptions; nullish input becomes ''. Results are strings by default, or Promises when Marked’s async option is enabled. Raw HTML is preserved.

cms.markdown('## About\n\nA **short** introduction.')
cms.inline('A **short** title')

date(value, options = {}) formats a Date or date string. A YYYY-MM-DD string is interpreted as a local calendar date. Unsupported or invalid values return ''. options.locale and options.localeOptions override the configured date settings for that call.

cms.date('2026-09-11')
cms.date('2026-09-11', {
  locale: 'en-GB',
  localeOptions: { day: 'numeric', month: 'long', year: 'numeric' }
})

image(node = {}) accepts a hydrated Sanity image node with asset.url and optional crop/hotspot data. Returns a copy of the asset with its generated image URL, or {} when the asset URL is missing.

var asset = cms.image(document.image)
console.log(asset.url)

link(node = {}) returns a URL string according to node.type, or '' when the required data is missing:

  • 'page': node.page.route.
  • 'file': node.file.asset.url.
  • 'image': node.image.asset.url.
  • 'url': node.url.
  • 'exhibit': node.exhibit.route, replacing :slug with node.document.slug.current when present in the route.

route(node) reads node.route and expands /:slug with node.slug.current. Missing routes or required slugs return ''.

cms.link({ type: 'url', url: 'https://example.com' })
cms.route({ route: '/articles/:slug', slug: { current: 'hello' } })
// '/articles/hello'

sanity.revive(value)#

Recursively replaces ISO timestamp strings with Dates and encoded regular expressions such as '%r/hello/ig' with RegExps. Mutates objects and arrays and returns the supplied or converted value. Existing Dates and RegExps are preserved. Use it when restoring typed values from JSON.

var data = sanity.revive({
  publishedAt: '2026-09-11T10:00:00Z',
  pattern: '%r/hello/ig'
})

Client#

All four client methods return Promises. The configured token is sent as a Bearer token with every request. useCdn affects queries; writes always use the API endpoint.

client.fetch(query, params = {}, queryOptions = {})#

Runs a GROQ query and returns its result. params contains GROQ parameter values; queryOptions is forwarded as API URL parameters, omitting nullish values.

var pages = await cms.client.fetch(
  '*[_type == $type]',
  { type: 'page' },
  { perspective: 'published' }
)

client.mutate(mutations, mutationOptions = {})#

Create, replace, update, and delete documents with mutation objects:

await cms.client.mutate({ create: { _type: 'page', title: 'New page' } })

await cms.client.mutate({
  createOrReplace: { _id: 'page-1', _type: 'page', title: 'Page' }
})

await cms.client.mutate({
  patch: { id: 'page-1', set: { title: 'Updated page' } }
})

await cms.client.mutate({ delete: { id: 'page-1' } })

Pass an array to run mutations in one transaction. Options are forwarded as Sanity API query parameters.

var result = await cms.client.mutate(
  [
    { create: { _id: 'page-1', _type: 'page', title: 'Page' } },
    { patch: { id: 'settings', set: { home: 'page-1' } } }
  ],
  { returnDocuments: true, visibility: 'sync' }
)

Queries return the Sanity result. Mutations return the full response with the transaction ID and mutation results.

client.action(actions)#

Create or edit drafts and publish documents with actions:

await cms.client.action({
  actionType: 'sanity.action.document.edit',
  publishedId: 'page-1',
  draftId: 'drafts.page-1',
  patch: { set: { title: 'Updated page' } }
})

await cms.client.action({
  actionType: 'sanity.action.document.publish',
  publishedId: 'page-1',
  draftId: 'drafts.page-1'
})

Pass one action object or an array. Returns the full API response.

client.upload(type, body, uploadOptions = {})#

Upload image and file assets from a buffer, blob, or stream. type must be 'image' or 'file'; other values throw:

var image = await cms.client.upload('image', imageBuffer, {
  filename: 'photo.png',
  contentType: 'image/png'
})

var file = await cms.client.upload('file', fileStream, {
  filename: 'document.pdf',
  contentType: 'application/pdf'
})

Uploads return the created Sanity asset document. Upload options include filename (defaults to body.name) and contentType (defaults to body.type).

Errors#

HTTP errors return a JARPC result. Network and invalid JSON errors reject.

var error = {
  ok: false,
  message: 'Forbidden',
  code: 403,
  details: { error: { description: 'Mutation denied' } }
}

Created by Vidar Eldøy