惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
C
Check Point Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
月光博客
月光博客
博客园 - 【当耐特】
Jina AI
Jina AI
雷峰网
雷峰网
J
Java Code Geeks
腾讯CDC
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 叶小钗
aimingoo的专栏
aimingoo的专栏
Martin Fowler
Martin Fowler
The Register - Security
The Register - Security
罗磊的独立博客
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Security Latest
Security Latest
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
有赞技术团队
有赞技术团队
The Hacker News
The Hacker News
Scott Helme
Scott Helme
T
The Blog of Author Tim Ferriss
Spread Privacy
Spread Privacy
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
The Exploit Database - CXSecurity.com
Vercel News
Vercel News
Cisco Talos Blog
Cisco Talos Blog
美团技术团队
B
Blog RSS Feed
L
LangChain Blog
大猫的无限游戏
大猫的无限游戏
SecWiki News
SecWiki News
Webroot Blog
Webroot Blog
N
News | PayPal Newsroom
D
Docker
云风的 BLOG
云风的 BLOG
Recorded Future
Recorded Future
W
WeLiveSecurity
C
CERT Recently Published Vulnerability Notes
L
Lohrmann on Cybersecurity
T
Tenable Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
阮一峰的网络日志
阮一峰的网络日志
I
Intezer
Hugging Face - Blog
Hugging Face - Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org

Sanity.io

A Board Game agent built using Sanity Context and Vercel's AI SDK | Sanity Build a prototype with Claude Code that your whole team can edit | Sanity What’s New - May 2026 | Sanity I built a London pub guide with v0 and the Sanity MCP in six hours. Here's what I learned. | Sanity Build a conference concierge with Agent Context and Anthropic | Sanity Build a content-aware Telegram agent with Vercel AI SDK and Chat SDK | Sanity How I used Agent API to generate photos for my family’s recipes | Sanity What’s New April - 2026 | Sanity Better context, better matches: An AI love story (for dogs) | Sanity How to write for an agent | Sanity Content Agent, meet Slack: AI content operations in your workflow | Sanity Structure powers intelligence | Sanity Your agent needs better content. Here's how to give it. | Sanity How to serve content to agents (a field guide) | Sanity Sanity TypeGen GA: Automatic TypeScript types for content and GROQ | Sanity Sanity is now available on the Vercel Marketplace | Sanity The logo soup problem (and how to solve it) | Sanity Content Releases: From scattered updates to coordinated publishing | Sanity What's New - February 2026 | Sanity How we solved the agent memory problem | Sanity v0 Builder Challenge: The winners | Sanity Introducing: Sanity Agent Skills | Sanity Content Agent: Days of work in one conversation | Sanity Our Sanity Values | Sanity Open Source Pledge 2025: Stepping up when it matters | Sanity v0 builder challenge: $3000 in prizes | Sanity Why AI Breaks Without Structured Content Operations | Sanity What’s New January - 2026 | Sanity BFCM 2025: What teams built when infrastructure stopped being the problem | Sanity How AI shaped holiday shopping and what it means for content in 2026 | Sanity Sanity Studio v5: Embracing React 19 | Sanity You’ll need a CMS eventually. Let your agent set it up. | Sanity “You should never build a CMS” | Sanity AI Content Operations: A 30-Day Implementation Guide | Sanity What’s New December - 2025 | Sanity Scheduled Drafts: Stop manually publishing content at midnight | Sanity What’s New November - 2025 | Sanity Everything *[NYC] 2025 recap: A day of AI, Content Operations, and Culture | Sanity Clankers and content operations | Sanity Content Agent: AI that understands your structured content is here | Sanity Why design-driven content modeling creates technical debt, not velocity | Sanity What's New October - 2025 | Sanity From studio to inbox: How Kevin Green eliminated email campaign friction | Sanity The content editor's guide to content operations [E-commerce edition] | Sanity styled-components maintenance mode: A 40% faster fork | Sanity From zero code to a live website in 7 hours (thanks, Cursor!) | Sanity First attempt will be 95% garbage: A staff engineer's 6-week journey with Claude Code | Sanity Internationalization is more than translating words | Sanity What's New - September 2025 | Sanity We just deleted our 35k-member community Slack | Sanity What's New - August 2025 | Sanity The engineer's guide to content operations [E-commerce edition] | Sanity SEO for AI: Evolving from Web Pages to the Content Lake | Sanity What's New - July 2025 | Sanity Sanity Studio v4: A major version bump for a minor reason | Sanity What's New - June 2025 | Sanity Dashboard and Insights: Your New Content HQ | Sanity Canvas: AI-accelerated, context-aware, freeform authoring | Sanity Agent Actions: AI building blocks for structured content | Sanity Functions: Life beyond pressing publish | Sanity A new era for content applications with Sanity App SDK | Sanity The end of CMS era and our $85M Series C. | Sanity What's New – May 2025 | Sanity Introducing the Sanity Model Context Protocol (MCP) server | Sanity What's New – April 2025 | Sanity Pushing all the envelopes with ambitious content | Sanity Self-hosting is only free if your time is worth nothing | Sanity Content that lasts: Scaling beyond your frontend | Sanity The Live Content API is now Generally Available | Sanity The future beyond AI chat bots | Sanity Learning the new skill of working with AI | Sanity What's New - March 2025 | Sanity Give it in plain text: Making your content AI-Ready | Sanity No More 'DO NOT PUBLISH': Introducing Content Releases | Sanity React in 2025, what's next? | Sanity The final boss of front-end: block editors | Sanity Introducing Sanity for Startups | Sanity A block content editor that loves you back | Sanity A Black Friday Snooze Fest: Massive Traffic, No Drama | Sanity How to make a recipe site that scales well | Sanity The Sanity Winter Release 2024 | Sanity AVIF Arrives, Sanity’s Promise Fulfilled | Sanity Sanity joins the Open Source Pledge | Sanity Your content is now Live by default | Sanity Begin Team to Join Sanity | Sanity Sanity Digest - September '24 Edition | Sanity Sanity partners with Google. Now live on the Google Cloud Marketplace. | Sanity Sanity Digest - August ‘24 Edition | Sanity Now playing: the latest Mux Video Input plugin for Sanity | Sanity Community Digest - June ‘24 Edition | Sanity Community Digest - May ‘24 Edition | Sanity Guide to Sanity's newest product announcements | Sanity AI and Content Creation: A Leader's Guide | Sanity Of course, you should be able to type your content quickly! | Sanity New to AI Assist: translation, reference suggestions, image generation | Sanity Speak the language of your editors: Sanity Studio UI localization | Sanity Introducing the new Sanity Growth plan to serve collaborative teams | Sanity Presentation: Work faster than ever with structured content | Sanity Goodbye Feedback Frenzy, Hello Sanity Studio Comments! | Sanity Easing into the App Router with the Sanity Toolkit for Next.js | Sanity
Obvious features aren't obviously made | Sanity
Mikolaj Dobrucki · 2021-12-17 · via Sanity.io

References in Place lets you create references to new documents inline, without having to navigate away from the document you’re currently authoring—a must-have feature if you want connected content.

And starting with v2.23.0, you’ll see the feature as a “Create new” button, as well as a clickable preview that opens the referred document in a new pane alongside your current one. Sounds pretty straightforward to make, right?

It was not.

Believe it or not, this feature was planned to launch with the initial release of Sanity but was later deprioritized due to the challenges we’ll talk about in this post. Since then, References in Place has never really left our minds. It just took a few breakthroughs to make the feature possible.

Watch the demo from the Open House:

What’s a document?

Let’s start by defining a document. It’s not as straightforward as it may appear.

There are two possible definitions of a document:

  1. In the context of Content Lake, a document is a JSON object with an _id and a _type.
  2. But in the context of the Sanity Studio, a document can be comprised of two Content Lake documents. We call this a document pair. One document represents the “published” variant of the document while the other document contains the “draft” variant.

When you edit a document, you’re not editing the published variant. You’re actually editing a copy of that document that only initially differs by its ID. If you start editing a published document without a draft variant, we’ll copy the contents of the published document, create a new draft document, and attach a special prefix (drafts.) to its _id.

What does “publish” mean?

In the context of the Sanity Studio, publishing is the opposite of the process we outlined above. We copy the contents of the draft document into a “published” version, removing the drafts. prefix.

But that’s not all there is to publishing. In order for this publish operation to be allowed the document must pass your validation criteria. This is an important concept to understand for the next section.

So why was making References in Place so hard?

Prior to References in Place, the Studio didn’t let you reference a document unless it had a published version.

This is an important aspect of Sanity’s data integrity model because it ensured that the document being referenced was in a valid state and had gone through your organization’s approval process.

Implementing References in Place was challenging because it required us to let you reference draft documents anyway.

So we tried to do exactly that and the more we thought about it the more issues we found.

If we naively allowed referencing draft documents, then we would break the assumption that all referenced documents are in a valid state. Breaking this assumption causes two issues:

  1. Applications that assumed all references were validated could break. For example, if you have a document with validation that ensures an array always has one item, it’d be safe to assume the first item of the array will always be present.
  2. Authenticated clients could potentially leak draft content. For example, if you use a static site generator that fetches data with an authenticated client, it could potentially output draft content if you forgot to filter it out.

Then there were user experience implications as well. We knew we wanted References in Place to be quick and easy to use. And we found that if we allowed referencing draft documents, then you’d quickly run into an issue – draft documents couldn’t be deleted unless you removed all references to it.

Typically, you’d want this deletion protection because it ensures your apps don’t break due to missing references but when iterating on multiple drafts by multiple editors in real-time, it can add a lot of friction.

Though seemingly minor, this problem led to an important breakthrough that made everything come together.

What if we used weak references?

By default, Content Lake ensures that all references resolve to documents that exist within your dataset. We call these strong references because they are enforced at every level. For example, if you try to delete a document that’s actively being used in a reference (even via the API), you’ll get an error message saying the mutation failed.


Weak references on the other hand are references that don’t need the referenced document to exist. If you try to delete a document that is weakly referenced, Content Lake will no longer stop you from doing so. This would allow draft documents to be deleted even if there was another draft that still referenced it. You may end up with some dangling references but those can be cleaned up by requiring them to resolve to existing documents using validation errors.

Weak references were a key breakthrough for multiple reasons. They solved the deletion overprotection problem and it turns out they gave us a path to solve the rest.

What if we referenced a document that didn’t exist?

The main issue with referencing draft documents is that we break the assumption that all referenced documents are in a valid state. So, with weak references in mind, the question became: What if we didn’t actually reference the draft document?

That is, what if we utilized weak references to reference the _id of the published document (that does not include the drafts. prefix) that didn’t exist yet?

This was our breakthrough. By utilizing weak references to reference the _id of the published document, we can keep the assumption that all referenced documents are in a valid state, preventing applications from breaking and preventing draft content from accidentally leaking.

How we pulled it off and how it works

Using weak references helped us solve a lot of the problems with referencing a draft document, but that strong reference protection was nice, right?

Of course, referential integrity is an important aspect of Sanity’s data integrity model and we wouldn’t ship this feature if we couldn’t keep that.

In order to keep referential integrity, we “strengthen” the reference at publish time.

We added a new key to the references, _strengthenOnPublish that tells the studio to convert the weak reference to a strong reference when you click the publish button. This re-introduces all the data integrity safeguards we mentioned earlier.

And with all that, we had our path forward to implement References in Place.

We’re quite happy with how it turned out. This allowed us to finally ship a feature that seemed to go against everything we uphold while still maintaining the status quo.

Other challenges we encountered

All the issues we’ve talked about so far have just been about making the feature possible.

Even after our breakthrough, References in Place still posed challenges across interaction and user interface design, as well as engineering with a lot of edge cases in consideration. That’s why it took us over 3 years to ship it. We knew we wanted to ship this feature in the right way and it wasn’t easy getting here.

Interaction design and panes

Opening one reference without losing context is one thing, but opening multiple references (from a reference, from a reference, from a reference) is another.

We had to ask ourselves what it meant to open a reference, what it should feel like, and what it would be similar to in the current studio. We knew shipping this feature in the right way meant we had to find a way to open those references in a recursive way that felt natural in the Studio.

So we built a new way of opening documents in a new pane.

This meant taking a deep dive into the existing pane system, refactoring it to support the new requirements, and preparing for potential pane-related additions too!.

Updating the reference input for drafts

Prior to Reference in Place, we only allowed references to published documents. This meant the previous reference input could filter out all draft documents to simplify search results.

With the addition of References in Place, this is no longer the case. We had to update the reference input to consider both the draft documents and published documents which meant we had to update the reference input to de-duplicate the results.

We now show two different icons so you can know if a published and/or draft variant of the document exists.

Updating validation for draft references

Similar to the reference input updates, validation also needed to be updated to support a new use case only relevant to Reference in Place.

Prior to Reference in Place, validation only depended on the current document but this is no longer the case. In order to ensure we can always “strengthen on publish”, we mark the current document as invalid if it references a document that has not been published.

This meant that we had to update the validation library to re-run when another document updated. Along the way, we fixed some bugs and converted it to TypeScript.

Arrays of references

We wanted the experience of editing an array of references to look and feel like a document list, meaning inline instead of a dialog.

This wasn’t as straightforward as it seemed because of how the Form Builder composes input components together. When we tried to render the reference inputs inline, we got not-so-great results.

So, we built a workaround that is aware of arrays and renders a special case. Now, we detect if an array item is a reference and we render it inline instead of inside a dialog. It’s not an ideal solution in our eyes but it’s a tradeoff we’re willing to make in the name of delightful editor experiences.

Arrays of references

Initial Value Templates and Roles

As you may know, the Studio is a highly customizable application with lots of surface area. That means when we create new features, we have to make sure it works with the rest of them.

Like Initial Value Templates and Roles.

Initial Value Templates allow you to specify multiple templates with different pre-populated values. Roles allow you to specify custom filters for granular control over documents (including creation).

Put those two together and you now have requirements to disable an initial value template depending on your role.

Templates and roles

Now layer that on the ‘Create new’ button.

Templates & roles with References in Place

In order to get this one done, we lifted some code to shared places, made some new (internal) APIs, and refactored existing implementations.

Conclusion

Implementing References in Place was an interesting and unique engineering challenge that involved many parts of the team and touched many surfaces of Sanity Studio. If solving these kinds of challenges sounds interesting to you, we’d encourage you to apply to our open positions so you can help us solve the next round of fun challenges!