releases.shpreview
Sanity/Sanity Changelog

Sanity Changelog

Mon
Wed
Fri
JunJulAugSepOctNovDecJanFebMarAprMayJun
Less
More
Releases71Avg22/moVersionsv0.4.0 to v13.0.0
v6.0.0

Sanity Studio v6

v6 is a focused major release. Your schemas, plugins, configuration shape, and content APIs are unchanged, so for most studios this is a one-line upgrade:

npm install sanity@latest

The bump is clean if your studio runs on Node.js 22.12 or newer, runs cleanly under React strict mode, and has no custom auth.providers. Otherwise, test against the pre-release first (npm install sanity@next-major) and work through the changes below.

Requirements
  • Node.js 20 dropped. With Node.js 20 at end of life, the minimum is now Node.js 22.12, matching the Sanity CLI. Upgrade Node and set engines.node to >=22.12. Only affects builds still on Node 20.
Behavior changes (new defaults)
  • React strict mode on by default in development. Strict mode surfaces existing effect-cleanup and concurrent-rendering bugs earlier in development. It doesn't create new ones. Opt out with reactStrictMode: false in sanity.cli.
  • Custom auth providers now replace by default. auth.providers now replaces the built-in providers instead of appending them, and mode: 'append' is no longer supported. To keep the old behavior, use the callback config instead. (This one breaks existing mode: 'append' setups.)
  • Default search strategy is now groq2024. It replaces groqLegacy as the default: better performance on large datasets, deeper nested-content and full Portable Text coverage, and Google-style queries (wildcards, phrases, negation). Search results, ordering, and counts may shift slightly, since each strategy uses different query logic. For most studios this is an improvement you won't need to act on. To keep the old behavior, set search.strategy back to groqLegacy.
Under the hood

Vite 8. The Studio build moves to Vite 8, with build times between 2–9× faster in our internal testing, and smaller bundles from better tree shaking. The React plugin updates automatically. If you customize the Vite config in sanity.cli, run the pre-release before bumping to catch any breakage.

v5.31.1

Fixes "Reference search failed: score() function received unexpected expression" when searching with the groq2024 search strategy. Searches involving document types whose preview select traverses a reference (e.g., subtitle: 'author.name') no longer fail.

Note that these reference-traversed preview fields do not contribute to search matching or ranking under groq2024 (matching pre-5.31.0 behavior); they remain searchable under the default groqLegacy strategy.

v2.13.0

The App SDK adds a new React hook for managing content releases and ships several fixes to document editing, permission handling, and data freshness. Together these improvements make release workflows easier to build and make document subscriptions more reliable.

Apply release actions with useApplyReleaseActions

The new useApplyReleaseActions hook lets you create, edit, schedule, unschedule, publish, archive, and delete content releases from your React app. It follows the same pattern as useApplyDocumentActions: call the hook to get an apply function, then pass it the release action you want to run.

import {useApplyReleaseActions} from '@sanity/sdk-react'

function PublishReleaseButton({releaseId}: { releaseId: string}) { 
  const applyReleaseActions = useApplyReleaseActions()
  const publishRelease = () =>  applyReleaseActions({type: 'release.publish', releaseId})
  return <button onClick={publishRelease}>Publish release</button>
}

🐛 Notable bugfixes and improvements

  • Projections now re-notify subscribers when an element re-enters the viewport, so you receive fresh data on re-entry.
  • Permission lookups no longer fail when they encounter unknown grants.
  • Documents that don't belong to a dataset can now be edited correctly.
  • Local access control list (ACL) evaluations now use the correct identity.
  • The document store now returns a warm listener when a subscription retries, avoiding an unnecessary cold reload.
v5.31.0

This release improves the responsive design for smaller screens by collapsing the side-by-side editor view into tabs, fixes annotation popovers and modals to display at proper widths, and corrects issues with scheduled drafts and authentication component layouts.

Sanity Studio v6

v5.31.0 marks the final v5 of studio. We will be bumping to a new major, v6, and this will include deprecating support for Node.js 20 (which has reached EOL) and a few additional changes. Read more on v6 here.

Switch between Presentation and Structure on mobile

Presentation now adapts to narrow viewports. When the window is too small to show the preview and the document editor side-by-side, they collapse into a tab bar at the top so you can switch between “Presentation” and “Structure” (and “Navigator”, when configured) one pane at a time, instead of a cramped split view. Wider viewports are unchanged.

🐛 Notable bugfixes and improvements

  • Fixes Portable Text annotation/object edit popovers, such as link annotations containing a reference field, rendering too narrow when the type set options.modal without a width. They now use the default width, so embedded reference fields and their autocomplete results are usable.
  • Fixes a bug in scheduled drafts where viewing a document from an archived draft showed an “Add to release” option that errored when clicked. The archived draft now shows the correct “Archived release” banner.
  • Increases the width of some authentication components, including the workspace selection screen.
  • Studio will now show a warning if auth config resolves to no providers.

What it is

An ISO 8601 timestamp recording when Shopify triggered the sync event that last wrote the document. This is the time of the sync event itself, not the time the content was last edited.

Why it's there

Shopify can deliver sync events out of order, and Sanity Connect processes many of them at once. Before writing to your dataset, Sanity Connect compares the incoming event's trigger time against store.shopifyTriggeredAt on the existing document and only applies the update if it's newer. This prevents an older, delayed event from overwriting fresher data, whether the update comes from an individual change in Shopify or a full sync.

What you need to do

The field is managed entirely by Sanity Connect and is safe to ignore in your queries and applications. Avoid editing or removing it, as it's used to keep your dataset consistent with Shopify.

v2.21.0

Improvements

  • give_feedback tool: The server instructions include a Feedback section, and unexpected tool errors point agents to the tool for reporting problems.

Removals

  • Document tools: Removed Markdown-specific document creation and patching tools, and renamed the JSON document tools to create_documents and edit_document.
  • migration_guide tool: Removed the tool now that migration guidance is provided as a separate sanity-migration agent skill (npx skills add sanity-io/agent-toolkit --skill sanity-migration).
v5.30.0

This release fixes an authentication loop that could trap users on the login screen and missing getWorkspace in @sanity/cli.

If you experience a login loop and are unable to upgrade to this version, clear your browser's site data for the Studio (or run localStorage.removeItem('__studio_auth_token_<projectId>') in the devtools console) and reload.

🐛 Notable bugfixes and improvements

  • Fixes an authentication loop that could in certain cases trap users on the login screen.
  • Adds missing changeset for @sanity/cli-core.
  • Fixes an issue causing “getWorkspace is not a function” when running sanity schema extract.
v5.29.0

This release improves the Sanity init setup process, adds a page-builder template, enhances dataset export and authentication features, and fixes several bugs including array field initialization, document scrolling, reference input loading, and media preview permissions.

Add best practice skills during init

sanity init will now prompt to configure Sanity MCP and install the sanity-best-practices agent skill for detected AI editors in a single step during sanity init. Add --no-skills to opt out.

🐛 Notable bugfixes and improvements

  • CLI: adds page-builder template using @​sanity/presets.
  • CLI: adds the no-strict-asset-verification flag to datasets export.
  • CLI: MCP can now use oauth for claude code config.
  • CLI: Allow ctrl-c to cancel browser login.
  • Fixed a bug where an array field with an initialValue set on both the parent field and a child field within defineArrayMember would incorrectly use the child field’s value. The parent’s initialValue now takes precedence, consistent with object fields and the documented behavior; the child’s initialValue still fills any keys the parent omits.
  • Fixes incoming references input flashing loading state.
  • Fixes an issue causing the document editor to unexpectedly scroll to the top in certain circumstances after entering Studio using a deep-link.
  • Fixed a regression in v5.26.0 where editors with a custom role lacking the Project datasets read permission saw a permissions error toast and broken media previews. Previews now load normally for these roles.
  • Fixes intermittent issue preventing navigating by URL to Portable Text Editor deep-links.
  • Fixes a bug where an array field with an initialValue set on both the parent field and a child field within defineArrayMember would incorrectly use the child field’s value. The parent’s initialValue now takes precedence, consistent with object fields and the documented behavior; the child’s initialValue still fills any keys the parent omits.
  • Fixes a bug where the incoming references input loading state would flash.
  • Fixes an issue causing the document editor to unexpectedly scroll to the top in certain circumstances after entering Studio using a deep-link.
  • Fixes a regression in v5.26.0 where editors with a custom role lacking the Project datasets read permission saw a permissions error toast and broken media previews. Previews now load normally for these roles.
  • Fixes an intermittent issue preventing navigating by URL to Portable Text Editor deep-links.

In addition to all the product updates from across Sanity, the documentation surface continues to grow with updated Next.js articles, a new guide for search, and additional guidance on organizing your blueprints. The platform also received a variety of fixes, along with some exciting personalizing and search improvements.

New and updated docs

Next.js updates

next-sanity 13 was released, and with it comes updates to many of the Sanity + Next.js articles. There’s a new guide on how to use Sanity Live with cache components.

GROQ search patterns

We’ve added a new guide on the different ways to implement search with GROQ. This includes patterns for both traditional search using BM25 (the industry standard ranking algorithm) as well as embeddings-based semantic similarity searching.

Everyday Content Agent prompts and workflows

Our content operations team put together an operator-focused guide filled with practical tips and prompts for making the most of Content Agent.

Managing Blueprints and Functions in a monorepo

The new Project layout and monorepos guide takes you through different ways to add Blueprints and Functions to your project, along with our recommended organization patterns. If you haven’t tried Blueprints yet, this is a great time to start.

Platform improvements

Better search

Sanity Learn now shows up in docs search. The Cmd-K palette gained a dedicated Learn group that surfaces public Learn courses and lessons alongside your regular docs results. It’s powered by a live GROQ full-text search (BM25 ranking plus semantic similarity), so conceptual or slightly-misspelled queries still find the right course.

Personalized content

Logged-in Sanity users now have the ability to see dynamic code snippets with their own customizable project and dataset details. Any time you see a PROJECT_ID or DATASET_NAME placeholder, click to populate with your own values.

Better for AI agents

Changelog history is now part of the Markdown and LLM output. When an agent or LLM fetches a doc’s .md twin (for example /docs/ai/mcp-server.md), it now gets a Related changelog entries section listing the versioned changes that reference that document, matching the live changelog tab one-to-one. This works for articles and HTTP/OpenAPI reference pages, while the raw JSON and YAML spec output stays clean.

The API reference site is now discoverable by agents. sanity.io/llms.txt now links out to reference.sanity.io/llms.txt. Compliant agents (Cursor, Claude Code, Aider, Continue, and others) follow that link to reach the per-package descriptions and Markdown twins on the reference site. This closes a gap where agents searching for SDK hooks bounced off /docs and never found the canonical reference.

Platform and dependencies

The docs app moved to Next.js 16.2.6, React 19.2.6, and the latest next-sanity (cache-components line), alongside routine Sanity client and dependency bumps.

Fixes
  • Search results for headings whose IDs start with a number now land on the correct anchor instead of jumping to the top of the page.
  • Deep links to a heading inside a non-default tab now activate that tab and scroll to the heading, instead of silently doing nothing.
  • The Astro, Nuxt, and React Router quickstart cards on the docs homepage navigate reliably again after hydration, now guarded by a regression test.
v2.20.0

New Features

  • give_feedback tool: Report tool errors, missing capabilities, confusing output, or documentation issues directly from your MCP client.

Improvements

  • Authentication: Adds a note about restarting your MCP client after reauthenticating with mcp configure.
v5.28.0

This release fixes critical bugs in Visual Editing including null reference errors when resolving paths, unnecessary page reloads when switching perspectives in the Presentation tool, and incorrect preview content when using agent bundles.

🐛 Notable bugfixes and improvements

  • Fixes a regression in the Visual Editing schema union-type resolver that could throw TypeError: Cannot read properties of null when resolving paths on documents that don’t exist on the active perspective.
  • Fixes a regression where switching the perspective in the Presentation tool caused the preview iframe to do a full page reload. Mainly visible to next-sanity@13 users with visual editing enabled. Users on next-sanity@12 or earlier, integrations built on @sanity/react-loader or @sanity/core-loader, and next-sanity@13 setups using the usePresentationQuery hook were not affected. Affected users on next-sanity@13 should also bump to next-sanity@^13.0.5 or later to pick up the matching client-side fix.
  • Fixes Presentation previews when an agent bundle (e.g., Content Agent’s “Proposed changes”) is selected. Previously the preview iframe always received the drafts perspective regardless of the active agent bundle, so iframes rendered draft content instead of the bundle’s content. Iframes now receive the agent bundle’s full perspective stack, and combining an agent bundle with a scheduled draft chip continues to work as before. No API or behavior change for non-agent perspectives.
v5.27.0

This release improves image preview display in the Portable Text editor and fixes toolbar menu rendering issues.

🐛 Notable bugfixes and improvements

  • Improves Portable Text editor block image previews: images are now displayed in the correct aspect ratio, preventing cropping and zooming.
  • Fixes an issue preventing Portable Text toolbar menus from rendering correctly.
  • Fixed an issue where the comments field wrapper displayed an empty element when the field component was hidden.
v2.12.0

Releases support

The document store now includes release actions, and a new useAllReleases hook makes it easier to fetch releases from your application.

You can now work with Content Releases from your application. The document store exposes release actions for creating, scheduling, and publishing releases, and the new useAllReleases hook returns all releases in your project. Use it to build release pickers, dashboards, or scheduling UI.

import {useAllReleases} from '@sanity/sdk-react'

function ReleaseList() {
  const releases = useAllReleases()
  // ...
}
v13.0.0

next-sanity v13 ships first-class support for Next.js Cache Components (cacheComponents: true), cleans up long-deprecated APIs, and adds new escape hatches for error handling and connection lifecycle events.

Cache Components support

You can now pass cacheComponents: true to defineLive to opt in to Next.js Cache Components. This unlocks full 'use cache' support for sanityFetch, giving you fine-grained, tag-based cache invalidation that integrates directly with Sanity Live.

We've been running this in production for the past couple of months. sanity.io runs with cacheComponents: true, and sanity.io/docs runs with cacheComponents: false. Both have been solid.

The fastest way to adopt Cache Components is with the sanity-live-cache-components skill, which drives the migration with an AI agent. For best results, set up AGENTS.md first, then run:

npx skills add https://github.com/sanity-io/next-sanity --skill sanity-live-cache-components

Suggested prompt for your agent:

Use the /sanity-live-cache-components skill to migrate this app to use Cache Components. When verifying with `next dev`, test both draft mode enabled and draft mode disabled because each mode has different rendering rules. `next build --debug-prerender` is not sufficient to verify that draft mode works correctly.

Breaking changes

See the v12 to v13 migration guide for full details and code snippets. The key changes are:

  • The default cache-invalidation behavior changed. revalidateSyncTags on <SanityLive> is replaced by action; sanityFetch no longer caches the internal sync-tag lookup when cacheComponents: false.
  • Removed the <SanityLive> props that were on by default: refreshOnFocus, refreshOnReconnect.
  • Removed the opt-in <SanityLive> / defineLive props: refreshOnMount, intervalOnGoAway, fetchOptions, stega; onGoAway signature changed (no longer receives interval).
  • Removed deprecated hooks: useDraftModePerspective, useIsLivePreview, useDraftModeEnvironment.
  • Removed deprecated tag option on sanityFetch and tag prop on <SanityLive>. Use requestTag instead.
  • Renamed next-sanity/live type exports: DefinedSanityFetchTypeDefinedFetchType, DefinedSanityLivePropsDefinedLiveProps, DefineSanityLiveOptionsDefineLiveOptions.

What else is new

Customize or silence the welcome message with onWelcome

By default, <SanityLive> logs a welcome message to the console when the live event stream connects. Pass a custom onWelcome handler to replace it with your own logic, or pass onWelcome={false} to disable it entirely.

"use client";

import type { SanityLiveOnWelcome } from "next-sanity/live";

export const onWelcome: SanityLiveOnWelcome = (
  event,
  { includeDrafts, waitFor }
) => {
  console.info(
    `<SanityLive${
      includeDrafts ? " includeDrafts" : ""
    }> is connected and listening for live events to ${
      includeDrafts
        ? "all content including drafts and version documents in content releases"
        : "published content"
    }.${
      waitFor === "function"
        ? " Events will be delayed until after a Sanity Function has processed them."
        : ""
    }`
  );
};
import { onWelcome } from "./client-functions";
import { SanityLive } from "@/sanity/lib/live";

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      {children}
      <SanityLive onWelcome={onWelcome} />
    </>
  );
}
Error boundaries with retry via onError="throw"

The default behavior still logs errors with console.error (CORS errors use console.warn). Pass onError="throw" to throw errors during render so they can be caught by the Next.js unstable_catchError API, which supports unstable_retry for retrying the render. This lets you build rich error UIs. For example, a toast that offers a retry button when Sanity Live can't connect.

"use client";

import { isCorsOriginError } from "next-sanity/live";
import { unstable_catchError, type ErrorInfo } from "next/error";
import { useEffect } from "react";
import { toast } from "sonner";

function SanityLiveErrorBoundary(
  _props: {},
  { error, unstable_retry }: ErrorInfo
) {
  useEffect(() => {
    let toastId: string | number | undefined;
    if (isCorsOriginError(error)) {
      const { addOriginUrl } = error;
      toastId = toast.warning(`Sanity Live couldn't connect`, {
        description: `${new URL(window.origin).host} is blocked by CORS policy`,
        richColors: true,
        duration: Infinity,
        action: addOriginUrl
          ? { label: "Manage", onClick: (e) => { e.preventDefault(); window.open(addOriginUrl.toString(), "_blank"); } }
          : { label: "Retry", onClick: () => unstable_retry() },
        cancel: addOriginUrl
          ? { label: "Retry", onClick: () => unstable_retry() }
          : undefined,
      });
    } else if (error instanceof Error) {
      console.error(error);
      toastId = toast.error(error.message, {
        richColors: true,
        duration: Infinity,
        action: { label: "Retry", onClick: () => unstable_retry() },
      });
    } else {
      console.error(error);
      toastId = toast.error("Unknown error", {
        description: "Check the console for more details",
        richColors: true,
        duration: Infinity,
        action: { label: "Retry", onClick: () => unstable_retry() },
      });
    }
    return () => { toast.dismiss(toastId); };
  }, [error, unstable_retry]);

  return null;
}

export default unstable_catchError(SanityLiveErrorBoundary);
import SanityLiveErrorBoundary from "./SanityLiveErrorBoundary";
import { SanityLive } from "@/sanity/lib/live";

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <>
      {children}
      <SanityLiveErrorBoundary>
        <SanityLive onError="throw" />
      </SanityLiveErrorBoundary>
    </>
  );
}
Strict mode for staged Cache Components migrations

Enable strict: true in defineLive to split your Cache Components migration across two PRs: first update all sanityFetch and <SanityLive> call sites to satisfy the new requirements, then flip cacheComponents: true in next.config.ts and add 'use cache' to functions that call sanityFetch.

Other additions
  • usePresentationQuery, useIsPresentationTool, and useVisualEditingEnvironment no longer require both <SanityLive> and <VisualEditing> to be rendered in layout.tsx. Rendering <VisualEditing> alone is now enough
  • onRestart prop on <SanityLive>: calls router.refresh() by default; pass onRestart={false} to disable
  • onReconnect prop on <SanityLive>: logs to console by default; pass onReconnect={false} to disable
  • includeDrafts prop on <SanityLive>: override the automatic draft-mode detection when a browserToken is set
  • resolvePerspectiveFromCookies utility: exposes the same perspective resolution sanityFetch uses internally, useful for custom toolbars and cacheComponents: true boundaries
  • stega: true now works on the published perspective, enabling Visual Editing overlays on published content (useful for Vercel Content Link)

Improved search

Search now handles partial matches more accurately, making it easier to find what you’re looking for.

Improved private video support

Private videos now support proper thumbnails, timeline scrubbing, and full-screen previews.

v5.26.0

This release improves studio navigation and user experience by automatically routing to the first visible workspace, enabling proper upload field restrictions, resolving validation error visibility for date fields, correcting preview data handling for arrays, and fixing authentication issues with image cropping in private datasets.

🐛 Notable bugfixes and improvements

  • Studio now routes to the first workspace the user can see, fixing the case where the configured default is hidden from them.
  • Fixes an issue where you could still upload to fields where the schema type has had upload disabled with options.disableNew.
  • Fixes “useDocumentDivergences must be used within a DocumentDivergencesContext” error in third-party code that renders the FormBuilder component.
  • Custom validation rules on date/datetime fields no longer hide behind “Required” when the user’s input doesn’t match dateFormat. The field-level tooltip and the global validation panel now surface the parser error directly (e.g., Invalid date. Must be on the format "YYYY-MM-DD"), making the format requirement actionable without any schema changes.
  • Document / list previews that use preview.select with arrays of primitives and dotted paths (e.g., names.0, names.length) now receive the correct values instead of dropping the first element or misshaping the array.
  • The crop dialog now authenticates private-dataset image requests directly, fixing a 403 that surfaced in Firefox and on deployed studios.
  • CLI: The CLI now supports login with the --with-token flag. Use it to pass standard input to the command to bypass the interactive login. For example: npx sanity login --with-token < token.txt.
v5.25.1

This release fixes CSS file handling errors and improves the Studio pane layout by truncating long document titles instead of allowing them to overflow.

🐛 Notable bugfixes and improvements

  • Fixes an issue that caused the Error: Unknown file extension &quot;.css&quot; error.
  • Long document titles in the Studio pane header now truncate with an ellipsis instead of overflowing into adjacent panes (e.g. when the Comments pane is open).
  • fix: show login screen instead of error when session expires
v2.11.1

Fixed an issue where the authentication subscription would stop after a failed user fetch. This could cause apps to hang indefinitely when the Sanity Dashboard issued a new token after expiry, since the SDK wouldn't pick up the refreshed session. The subscription now stays active through fetch errors, ensuring token refreshes work as expected.

Last Checked
6h ago
Latest
6.0.0
Tracking since Jan 22, 2026