159 Commits

Author SHA1 Message Date
Daniel Shapiro 0b33767998 docs(groq): guide agents away from expensive query filters (#90) 2026-09-10 11:35:48 -04:00
Daniel Shapiro 8675ed36b5 docs(groq): teach query construction before execution (#89) 2026-09-09 13:27:28 -07:00
Eric Streske e5c04f42b0 Add sanity-studio-upgrade skill (#85)
* added skill for creating upgrade plans for Sanity Studio

* PR comments
2026-09-09 08:16:12 -07:00
claude[bot] e447ef10e0 fix(skills): correct initial value template examples in localization rule (#84)
* fix(skills): nest initial value templates under schema in localization rule

* fix(skills): correct newDocumentOptions filter in localization rule

The "New document" filter in section 5 of the localization reference
empties the menu instead of narrowing it to the base language.

Two things combine. Templates that declare `parameters` are excluded
from the auto-generated new-document list, so `post-en` never reaches
the filter. The remaining items are built as `{templateId, description,
icon, title}` with no `parameters` key, so `item.parameters?.language
=== 'en'` is always false and `post`/`page` are dropped as well. The
result is an empty menu, verified by resolving a real workspace and
calling `document.resolveNewDocumentOptions({type: 'global'})`.

Add the parameterized templates to `newDocumentOptions` explicitly,
with the parameter values on the item, and filter out only the
auto-generated entries they replace. Generalize both blocks over a
`LOCALIZED_TYPES` list so `page` gets a template too, rather than being
filtered out with nothing to replace it.

Verified against sanity@6.11.0: the menu now offers `post-en` and
`page-en`, and each resolves an initial value of `{language: 'en'}`.
Both blocks type-check under `tsc --strict`, including in the annotated
`const config: Config` form where excess-property checking fires.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Chk3fV36ApvJWqN7gs4Fzy

* fix(skills): use type-only import for Template in localization rule

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XowPCwHVq9KVxW48fQisT

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-08-25 21:53:57 +02:00
Josh 65960de3e7 docs: document app visibility in the App SDK skill (#83) 2026-08-19 10:42:46 +01:00
Jonah Snider 6b48aeddf9 feat: support Agent Plugins (#81)
Signed-off-by: Jonah Snider <jonah@jonahsnider.com>
2026-08-18 07:28:10 -07:00
Daniel Shapiro 77a54f7850 docs(get-started): document the sanity.new flow (#80) 2026-08-11 16:29:19 +01:00
shapirodaniel 0bf992248c fix: integrate remaining getting-started updates (#79) 2026-08-05 12:53:24 -07:00
shapirodaniel aa66a8d90b fix: publish usable sample content (#68) 2026-08-04 15:41:06 -07:00
shapirodaniel a398215aea fix: register the example post schema (#72) 2026-08-04 13:43:28 -07:00
shapirodaniel b714675160 fix: choose MCP-managed setup early (#73) 2026-08-04 13:43:08 -07:00
shapirodaniel b8a7f81d46 fix: document unattended Studio setup (#77) 2026-08-04 13:41:53 -07:00
shapirodaniel f25bd02a44 fix: align the minimal Next.js fetch path (#71) 2026-08-04 16:07:24 -04:00
shapirodaniel d023496a44 fix: import defineLive from live entrypoint (#76) 2026-08-04 16:04:57 -04:00
shapirodaniel c45d9a3fa7 fix: make API version placeholder explicit (#75) 2026-08-04 16:00:51 -04:00
shapirodaniel 1d35ef80e2 fix: exercise client-side navigation (#69) 2026-08-04 16:00:43 -04:00
shapirodaniel 35b0daecd2 fix: detect empty Studio schemas (#74) 2026-08-04 16:00:33 -04:00
shapirodaniel 8ad49a35d3 fix: run schema deploy from Studio (#70) 2026-08-04 16:00:24 -04:00
claude[bot] dfcdd2844a docs: fix schema.md icon examples for @sanity/icons v5 subpath imports (#66)
* docs: fix schema.md icon examples for @sanity/icons v5 subpath imports

@sanity/icons v5 (pulled in transitively by sanity ^6.7.0) removed named
icon exports from the package root; only the icons map and Icon component
remain there, with named icons moved to per-icon subpaths. The root's
type declarations still declare the old names (as `never`, with a
deprecation note), so the old import style type-checks but crashes
Sanity Studio at runtime.

Update schema.md's icon import example and content-type table to use
the v5 subpath style (e.g. `@sanity/icons/DocumentText`) so agents
following this skill don't ship a working build that crashes in the
browser.

* docs: fix @sanity/icons v5 subpath imports in localization, page-builder, seo refs

Same broken root-import pattern fixed in schema.md: @sanity/icons v5
removed named icon exports from the package root, so the old
`import { XIcon } from '@sanity/icons'` style type-checks but crashes
Sanity Studio at runtime. Update the icon import examples in
localization.md, page-builder.md, and seo.md to the v5 per-icon
subpath style (e.g. `@sanity/icons/Home`).

* docs: trim icon-import explanation to the code examples

The mechanism paragraph explained internals an agent never acts on, and
claimed the bad import "crashes Studio at runtime". It doesn't — Vite
and esbuild both fail the bundle with `"DocumentTextIcon" is not
exported by @sanity/icons`, so `sanity build` errors immediately.

Keep the / pair and the table's Import column (the parts that change
behavior), and correct the failure mode in the  comment.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Rune Botten <rbotten@gmail.com>
2026-07-29 13:40:39 -07:00
Matthew Martindale fc0e709f61 fix: correct buggy example code in skills, standardize CLI command form (#55)
* fix: correct buggy example code in skill references

Several reference examples contain code an agent would copy verbatim but
that doesn't behave as intended:

content-experimentation-best-practices/references/cms-integration.md
- assignVariant drew Math.random() * 100 without normalizing against the
  sum of variant weights, so weights that don't total 100 skew the split
- it reused a cached cookie value without checking it's still a valid
  variant, leaving users bucketed to removed/renamed IDs
- it assumed a non-empty variants array (variants[length - 1] throws on [])
- the GROQ example filtered experimentVariants only by experiment status,
  so the first running experiment won regardless of the user's assignment;
  now scoped by experimentId plus the assigned variantId

sanity-best-practices/references/migration-html-import.md
- the custom <a> deserializer returned a top-level _type: 'link' block;
  htmlToBlocks expects an __annotation with a markDef and children from
  next(), matching portable-text-conversion/rules/html-to-pt.md

sanity-best-practices/references/functions.md
- the auto-tag function listened on create/update and wrote to tags with
  no guard, re-triggering itself in a loop; added !defined(tags) to the
  filter, mirroring the recursion guard in the translation example

* fix: more buggy example code in skill references

Second batch of fixes from automated review (Cursor Bugbot):

- cms-integration.md: the assignVariant fallback returned the last variant
  without calling setCookie, so visitors who hit that path (stale/invalid
  cookie, zero total weight) were re-bucketed on every request; persist it
- functions.md: the step-by-step 'Creating a Function' tutorial filtered on
  _type == "post" while its handler patches the same document — add the
  !defined(firstPublished) recursion guard the file itself prescribes
- angular.md: the Transfer State snippet had literal '+' diff markers pasted
  in, making it invalid TypeScript; strip them and hoist the imports

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* fix: address Copilot review findings in skill examples

- migration-html-import: guard `el.tagName` with optional chaining so the
  custom rules fall through for non-element nodes (text nodes) instead of
  throwing, matching portable-text-conversion/rules/html-to-pt.md.
- angular: widen the TransferState key to `ClientReturn<Query> | null` so
  `get(key, null)` type-checks against Angular's
  `get<T>(key: StateKey<T>, defaultValue: T): T`.

* fix: guard null href/src in htmlToBlocks deserializer examples

`getAttribute` returns null for a missing attribute, so the examples could
emit `href: null` markDefs and the literal string `image@null` — the latter
only fails later at asset-upload time, with no pointer back to the bad node.
Both rules now read the attribute once and fall through when it is absent,
so the surrounding text is still deserialized by the default handling.

Applies the same fix to portable-text-conversion/rules/html-to-pt.md, which
carried the identical `image@null` bug.

* docs: scope _sanityAsset examples to the NDJSON import path

`_sanityAsset` is resolved by the CLI importer, which fetches each `image@<url>`
and swaps in a real asset reference. The mutation API does not interpret it, so
the same blocks written via @sanity/client, `sanity exec`, or `defineMigration`
are stored verbatim, leaving an image field with no `asset` reference.

Neither example said so, and migration-html-import.md labelled the directive
"Upload image separately, store reference" — a description of the client-upload
path it is not. It then went on to demonstrate `defineMigration`, the very path
where the directive is inert. Name the supported path at both call sites, add a
note pointing at the upload-first alternative, and flag the constraint in the
`defineMigration` section.

Refs: https://www.sanity.io/docs/content-lake/importing-data

* docs: use canonical plural CLI topics throughout

The skills used both forms: `sanity dataset import` / `schema deploy` /
`migration run` alongside `blueprints *` / `functions *`. Standardize on the
plural form.

Plural is the canonical topic in @sanity/cli 7.x — registered in oclif.config.js
and backed by dist/commands/<topic>/, so oclif dispatches it directly. Singular
resolves only by missing oclif lookup and landing in the command_not_found hook,
which rewrites it via topicAliases. That shim works today and is silent, but it
is a compatibility path, and it is not what the docs show.

Covers dataset -> datasets, schema -> schemas, migration -> migrations.
`blueprints` and `functions` were already plural.

---------

Co-authored-by: Rune Botten <rbotten@gmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-07-28 12:51:15 -07:00
claude[bot] fc8116b2ef Add video hosting guidance to sanity-best-practices (#59)
* Add video hosting guidance to sanity-best-practices

Users keep serving video from Sanity file assets in production, which
delivers raw downloads with no adaptive streaming and leads to very high
bandwidth usage. Add a Video section to the skill's global guidance:
use sanity-plugin-mux-input or an external video platform and store only
the playback ID or embed URL in Sanity.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Siwz2hh1ZJdWfqnZZhQ9T1

* docs(skill): recommend Media Library video on Enterprise plans

Address PR feedback: Media Library supports transcoded, adaptively
streamed video (via Mux), but only as a paid add-on on certain
Enterprise plans. Recommend it first for those plans, and clarify that
sanity-plugin-mux-input uploads/manages videos in your own Mux account
rather than streaming from the Studio.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Knut Melvær <knut@sanity.io>
2026-07-28 12:30:56 -07:00
Chewie 9433a0edf0 fix: correct Hydrogen docs examples (#64) 2026-07-28 12:25:27 -07:00
claude[bot] c8f774ecfb fix(rules): correct GROQ pagination example — slice bounds can't be params (#65)
* fix(rules): correct GROQ pagination example, slice bounds can't be params

`[$start...$end]` is shown in groq.md and nextjs.md as valid pagination
syntax, but GROQ slice bounds must be constant numbers — parameters
aren't allowed there. Running it produces:

  Invalid GROQ query: slicing must use constant numbers

Update both examples to validate the page bounds and interpolate them
into the query string instead of passing $start/$end as params.

* fix(sanity-best-practices): trim GROQ slice bounds guidance to a plain statement

Per maintainer feedback, drop the negative example and shorten the
explanation instead of dwelling on the failure mode. State plainly that
slice bounds must be constant numbers and keep only the corrected example.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ej91qtX9Y4EkNXTW9djBwU

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-28 11:57:50 -07:00
Chewie af54474c21 fix(sanity-best-practices): use configured dataset in functions example (#63) 2026-07-22 09:56:01 -07:00
renovate[bot] 3b8f56d5d8 chore(deps): update actions/setup-node action to v7 (#58) 2026-07-22 09:47:54 -07:00
renovate[bot] b5e51fa043 chore(deps): update actions/checkout action to v7 (#56) 2026-07-22 09:46:38 -07:00
Jonah Snider 62f5ae2a6b feat: mention webhooks in sanity-best-practices (#62)
Signed-off-by: Jonah Snider <jonah@jonahsnider.com>
2026-07-22 09:46:16 -07:00
Taylor Beseda 6c81e246ed docs(skill): update blueprints best practices (#57) 2026-07-08 11:11:36 -07:00
Jonah Snider 2ec17ddc60 feat: replace references to edit_document with patch_documents (#54)
Signed-off-by: Jonah Snider <jonah@jonahsnider.com>
2026-06-17 14:29:06 -07:00
Jon Eide Johnsen 2d7b7c08a3 Merge pull request #52 from sanity-io/docs/recommend-standalone-studio-nextjs
docs(skill): recommend standalone Studio over embedded for Next.js
2026-06-10 13:33:52 -07:00
Jonah Snider be762f2fc6 feat: update references to MCP server (#53)
Signed-off-by: Jonah Snider <jonah@jonahsnider.com>
2026-06-10 10:38:56 -07:00
Jon Eide Johnsen 838d025baf Merge pull request #51 from sanity-io/feat/sanity-migration-skill
Add Sanity migration skill
2026-06-09 18:25:44 -07:00
Jon Eide Johnsen b294a7f83a docs(skill): handle side-by-side Studio/app layout in get-started
Onboarding flows start the agent from a parent folder containing the
Studio (studio/ or studio-*) next to the app folder. Teach the
get-started reference to find the Studio config across the workspace,
locate the app folder before detecting the framework (asking the user
when ambiguous), and run the smoke test from the app folder.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 18:25:22 -07:00
Jon Eide Johnsen a0567f5a90 docs(skill): recommend standalone Studio over embedded for Next.js
Embedding the Studio in the Next.js app slows dev/builds (Studio compiles
through next build instead of Vite), rules out Studio auto-updates (Next.js
lacks ESM import map support) and TypeGen watch mode, and nudges content
models toward being website-centric. Flip the recommendation to a standalone
Studio in a simple monorepo layout (studio/ + web/) and add migration steps
for existing embedded Studios.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 18:20:39 -07:00
Jon Eide Johnsen c997678f6a docs(skill): address migration PR review notes
Use the shorthand skill install command and replace unclear WordPress examples with runnable auth and XML parsing guidance.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-09 18:03:10 -07:00
Jon Eide Johnsen 6d19e5623d docs(skill): use agent-facing migration wording
Rewrite migration instructions to address the agent directly instead of referring to AI as a separate actor.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 13:55:54 -07:00
Jon Eide Johnsen 22801f6bb6 docs(skill): refine migration workflow guidance
Add agent-facing migration checkpoints, Sanity-safe multi-pass imports, and Contentful-specific taxonomy and asset validation notes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-05 13:54:05 -07:00
Jon Eide Johnsen 66f0ec5d91 Merge pull request #50 from sanity-io/docs/sanity-generated-id-guidance
docs: discourage deterministic Sanity document IDs
2026-06-04 10:59:39 -07:00
Jon Eide Johnsen f78fae7024 feat(skill): add Sanity migration guidance
Add a standalone migration skill with platform-specific references and route migration topics through the workspace knowledge router.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 17:13:49 -07:00
Jon Eide Johnsen c85045f42b docs: discourage deterministic Sanity document IDs 2026-06-02 16:07:33 -07:00
Jon Eide Johnsen 7e04973754 Merge pull request #47 from sanity-io/fix/get-started-frontend-integrations
fix(skill): get-started frontend integrations — verified, modernized, and fixed
2026-06-02 14:24:04 -07:00
KenJonesPizza 7ee98d4147 docs(skill): fix RR env trap that breaks client-side navigation
Reading process.env from a shared module bundled into the client throws
on lazy route transitions; split publishable VITE_* vars from secrets,
add image URL builder + smoke test step, and surface a cross-Vite warning.
2026-05-28 14:54:17 -05:00
Jon Eide Johnsen d7545f5cc6 Merge pull request #49 from sanity-io/fix/rename-review-slash-command
fix: rename /review slash command to /sanity-review
2026-05-28 17:36:33 +02:00
Jon Eide Johnsen 07e8751d78 Merge pull request #48 from sanity-io/docs/marketplace-install-instructions
docs: update plugin install instructions for official marketplaces
2026-05-28 17:36:06 +02:00
Jon Eide Johnsen ab46253b1a fix: rename /review slash command to /sanity-review
Avoids collision with other Claude Code plugins (e.g. CodeRabbit) that also register /review in the shared flat slash-command namespace.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 08:10:31 -07:00
Jon Eide Johnsen 27891aae07 merge: resolve main conflicts for marketplace install docs
Combine updated Claude Code, Cursor, and Lovable install instructions with Codex plugin support from main.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 07:58:30 -07:00
Jon Eide Johnsen 7b413db533 docs: update plugin install instructions for official marketplaces
Point users to the official Claude Code and Cursor marketplace install flows, update Lovable to use the prebuilt chat connector, and align the Claude plugin name to sanity across manifests.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-28 07:57:06 -07:00
KenJonesPizza 5168aa82c5 docs(skill): drop redundant groq install + surface @nuxtjs/sanity auto-imports
@nuxtjs/sanity bundles groq, @sanity/client, @sanity/visual-editing, and
@portabletext/vue as direct dependencies. It also auto-imports the groq and
defineQuery template tags plus a full set of composables (useSanity,
useSanityQuery, useSanityConfig, useSanityPerspective, the visual-editing
state helpers) and auto-registers <SanityContent>, <SanityImage>, and
<SanityFile> components. None of those needed to be in a separate install
step or import statement.

Updates:
- Drop `groq` from the install line (it's a transitive of @nuxtjs/sanity,
  auto-imported by the module so Node-level resolution is irrelevant)
- Make @sanity/image-url an optional second install (only needed for the
  manual urlFor() approach; <SanityImage> covers the common case)
- New "What the module auto-imports" subsection listing the composables,
  GROQ helpers, and components agents can use without imports
- §4 Components now correctly documents <SanityContent> (the module's
  Portable Text renderer) instead of <PortableText>
- §4 Images shows both <SanityImage> (asset-id based, falls back to NuxtImg
  if @nuxt/image is installed) and the manual @sanity/image-url builder
- Bumped apiVersion default to 2026-05-15 for consistency
2026-05-21 15:45:27 -05:00
KenJonesPizza 01b6638d69 docs(skill): switch Next.js inline guide to next-sanity
next-sanity is the official toolkit for Next.js + Sanity. It bundles
@sanity/client, groq (with defineQuery), and @portabletext/react, and adds
Next.js-specific subpath exports for live content (defineLive), draft mode,
visual editing, the Sanity Image component, embedded Studio, and webhooks.

Updates to the Next.js inline guide:
- Install line shrinks from four packages to two: next-sanity + @sanity/image-url
- createClient, defineQuery, PortableText, and SanityDocument all import from
  next-sanity (no more direct deps on @sanity/client, groq, @portabletext/react)
- Add { next: { revalidate: 30 } } fetch options to demonstrate Next.js ISR
  integration
- Use SanityDocument type from next-sanity for fetch return shape
- Bump apiVersion default to 2026-05-15 to match other framework references
- Updated "see nextjs.md" pointer to enumerate the next-sanity subpath exports
  (live, draft-mode, visual-editing, image, studio, webhook)
2026-05-21 15:30:57 -05:00
KenJonesPizza f5ee39c6f1 docs(skill): switch SvelteKit reference to @sanity/sveltekit for Svelte 5
The previous SvelteKit guide used @sanity/svelte-loader, whose useQuery store
returns empty on the client under Svelte 5 (no error, just no data). Replace
the entire flow with the official @sanity/sveltekit package, which is built
for Svelte 5 and bundles @sanity/client, @sanity/visual-editing, and groq as
re-exports.

Updates throughout:
- Svelte 5 idioms: const {data} = $props(), {@render children()}, $derived
- useQuery wrapped in $derived and read via $query.data (the working pattern)
- Scaffold command added (npx sv@latest create … --no-add-ons --install npm)
- Full file set: api.ts, client.ts, client.server.ts, queries.ts, image.ts,
  hooks.server.ts, app.d.ts, +layout.{server.ts,svelte}, +page.{server.ts,svelte},
  post/[slug]/+page.{server.ts,svelte}
- Named createImageUrlBuilder import (the default export warns at runtime)
- Yarn-classic + Visual Editing caveat called out
2026-05-21 14:36:47 -05:00