Build IT Better: Architecture ft. Guillermo Rauch & Kapehe

In this round‑table episode of Build It Better, host Jesse Tomczak brings together Guillermo Rauch (Vercel/Next.js) and Kapehe (Sanity) to design a marketing site built on a headless CMS. The conversation walks through the full content‑to‑deployment pipeline: requirements for collaborative authoring, Sanity’s structured content model and Studio UI, choosing between GROQ and GraphQL, preview mode and staging datasets, role‑based permissions and custom publish workflows, Vercel preview deployments and incremental static regeneration with revalidation, image handling via Sanity’s CDN and Next.js Image component, collaboration tools like the Presence API, and broader topics such as performance monitoring, data export/migration, and experimental canary releases. Throughout, the panel emphasizes empowering non‑technical contributors while keeping the site fast and reliable, and they share practical tips, tooling details, and best‑practice patterns for teams building modern marketing sites.
Chapters
Hey everyone, welcome to Build It Better. I'm your host, Jesse Tomczak, a senior engineer with This Dot. Today we're going to be building out a new marketing site and we've got a lot of moving pieces. We've got headless CMS through Kapehe with Sanity. Hello. And we've got Guillermo from Vercel and Next.js. How are you doing today?
Doing great, thank you.
Fantastic. So, the Build It Better, the idea of the show is we want to get experts together on the show and talk about some of the real gritty details. You know, oftentimes when we have shows or blogs, they stay in a single lane and a single topic, which is great to consume, but most of us spend our day in multiple lanes, crossing traffic, even oncoming traffic, right? There's, there's a lot coming at us at one point, so there's a lot of moving parts. So for this Build It Better, we're going to take the, the idea of sort of a team meeting, a sort of roundtable discussion. We have a new marketing site that has static content and maybe some forms, and it has some basic requirements that we can go into at the top, and then we'll sort of break it down piece by piece And then I'll let you guys have the floor and you can sort of tell me where you want to go or how we should build it or what we should start with and how these sort of things fit together. So some of the requirements from our collective bosses, things that have come across our desk is we need to— everyone needs to contribute to this marketing site. Everyone needs to be able to add content, moderate content., but only the boss can publish. They need to be able to see the content in its beautiful production pristine environment first before we hit publish. So we, you know, is that a staging environment, a preview? Preferably it's not my dev laptop, you know, at, at, at their whim. We've all done those presentations and I think they're really difficult to do when you can't, like, can we just email them a link or is there a permanent way that they can just sort of review it at their, you know, the, the head honcho, they work early, they work late, the rest of us, you know,, are sleeping sometimes. So, let's start with the content. So we've chosen Sanity as our backend CMS. Um, Kap, can you give us like a rundown of Sanity for those of us who haven't used it before, some of its features and highlights and sort of how we're going to structure sort of marketing content for the group?
Yeah. So aloha everyone. Uh, yeah. So coming from Sanity, there is So it's a platform for structured content. And the really fun thing about Sanity is the Sanity Studio. And it's an, it's a UI for your backend. So a UI for all of your content. And so if somebody that's not developing wants to check out the content and they want to make sure everything looks good, like the boss wants to make sure to review it before it goes live, that's where, um, they would be directed to the studio. And in the studio it would have. All the content, title for a blog post, or if it's an e-commerce, pricing, images, um, and then the way images are handled in Sanity, um, I can get more into that later, but everything kind of would live there. And so the team can work there, it can be reviewed there, and then there's like a, a backlog of information. We call it review changes, where if you wanted to roll back to something else, you can revert back and get rid of some changes that were made and go back to an earlier version. But yeah, that's Sanity in a nutshell.
So we've got this, uh, studio, uh, it's got rich content. I've been in the studio before. It's really great. Um, our photo and media video guys like to pump up 4K images and all sorts of stuff into the content. What is the interface for the, for the backend? How do we get stuff out of Sanity?
Yeah. So let's say we're using Next and we want to show our data on our frontend. Uh, there is, well, we, there's two ways to query for your data. Um, you can use GraphQL or there's an in-house made query language called Groq. And that's how you would query, query for your data from the frontend. So, from Next, you would just write the command of what you needed and then pull it out.
So, if we do, like, Next new template, should we go with GROQ or should we go with GraphQL? Like, we haven't started the project yet. So, my first worry is if we go with GraphQL, are we going to miss out on something? And if we go with GROQ, is there too much overhead to understand the Groqy language? Right? Like this fork in the road. Here's our first fork in the road. So, Guillermo, like hop in here with Next. If you've got experience in GROQ, like here's our first fork. Yeah. Walk us through it.
I can introduce my side of things. So, we have our content platform. We have our content studio where non-technical folks can contribute. And we want to create a frontend that is a part of my brand experience, right? Like there's a structured content, but I wanna express it as whether it's beautiful marketing pages, like we're gonna study now, or whether it's a dashboard or whether it's any kind of experience on the web that's rich, interactive, beautiful, that is part of my brand, I'll use Next.js deployed over Vercel to distribute all my websites globally. But Vercel on its own doesn't necessarily know and neither does Next.js about where my data is coming from, you can plug into any data source. So say you're building an e-commerce experience, you may use Shopify in combination with Next.js and Vercel to create a really scalable e-commerce website. Or if I'm creating a marketing website, I actually tend to go for Sanity plus Next.js. So Next.js has this concept of sort of a data fetching hook. Next.js itself builds on top of React. But for anyone that's been familiar with React, they might know that data fetching in React has never been sort of a first-class primitive of the library. So we built Next.js to act as a framework to build actual websites and web applications on top of React. And one of the key ingredients that we added is this data fetching hook. So what's nice about Next.js is that Next.js has never been prescriptive about And like I said, where the data comes from and how you get it, you can get it over a REST API. You can get it over a GraphQL API. You can get it over gRPC. So this is where it gets interesting, I think, because we could pull data out of Sanity in either query model. Uh, and I think that's actually really cool because for a provider like Sanity, it means that they have no limit whatsoever. They don't have to fit into a specific GraphQL mold. But if the developer knows GraphQL and they have basic needs and they're familiar, I would go with the GraphQL data adapter. I don't know what you all think, but luckily there's a lot of flexibility in this world.
Yeah, and that's, that's like perfect because if you are really familiar with GraphQL, by all means, definitely use GraphQL and you don't want to learn a new query language. But if you do want to take the Groq route, there are like playgrounds that have been created. So groq.dev is one where you can just go and like learn all about Groq. Um, and then there is the Vision plugin that you can bring in, or it's in your studio. In, in there you can like run a query and see what would happen and see, um, what would be brought out, what data you'd get back. So, uh, both options are there.
Yeah, and so Vision's great. It's a lot like GraphQL playground but in Groq language, right? Yeah. One of the examples people— I've come across this fork in the road before. And the one— we went with GraphQL initially. But we turned back to Groq for one specific query. And it was a one-to-many relationship where we had tags, a group of tags to a post. And those tags belong to a parent category. But if you just want to go to the category and know all the tags that live down here, there's no for— like we had to go fetch two fetches from GraphQL and zip them up. But Groq has this really neat thing where you can embed a nested query inside of a field. So, we were able to say like categories and then list the tag titles as a string array. Inside of a nested query. And I was like, ooh, that's pretty slick.
Yeah. We, so we listen a lot to like those, those concerns, like things that another query language isn't fulfilling. 'Cause you would wanna do that. You would wanna have that nested query. You would wanna like be able to grab the data that you want exactly without having to like write multiple things.
So, um, and we see that as a pain point a lot, by the way, in the Next.js world when developers have to do like lots of asynchronous fetch, fetch, promise, async await, like having a query language that's terse, that gets me the data in one hop. I'll always go for that if I can. And again, going back to like, this plays into a strength of Next, which to your point, you could build 9 pages that are using GraphQL and then use GROQ in one of them. Like Next.js is not really opinionated about that. And obviously I think every time we talk about this architecture broadly, the headless architecture where you have a content platform, there's an API, and then you have your frontend. When you decouple these things, there's obviously some complexity that comes with it. When you work on a WordPress site, WordPress already has data in the theme in a way. In this world, you're saying, well, the data is coming from somewhere else, an external system. And I think you always have to try to capitalize on those advantages because there's a little bit of more complexity cost that you're splitting things up, but then you can capitalize on all the benefits. So with Sanity, for example, you can serve a mobile experience natively, or you can serve a frontend hosted on Vercel, and they're both using the same API. So you can reuse. The other thing that I'm seeing a lot is developers mixing and matching query languages, models, including APIs as well. We see a lot of in the e-commerce world, Sanity and Shopify or Sanity and BigCommerce. So I love the idea that we can capitalize on the flexibility of Next.js. And I think having this ability to go with Groq, go with GraphQL, go with REST plays right into the advantages of this separated world.
Yeah, and I think it's important. The Groq is not like, we're not writing C#, right? It's template strings, right? We're, it's very GraphQL query, GraphQL SQL type stuff. It's not a foreign space, like whitespace literate. I'm not writing Python as a string, right? It's very—
It also looks a little bit like CSS for your data, which I really like.
Yeah, yeah. I was, I have to say, I was really sort of like, I made this kind of face When someone's like, oh, we have a query language and then we have GraphQL and then we have another endpoint. And I was like, how am I gonna know what to do? But inside of Next, using these hooks, it didn't— it was very contextualized, right? It didn't cost me a lot to— I didn't have to trip over 4 or 5 different queries for that to happen per page, right? It was broken down very well. So, so we've got our backends, we've got our queries. Sanity has this idea of a dataset and we've got staging data where we can put like a bunch of filler information and sort of keep that and a production set for, for the public. How can we hook up those different data models? So now they're coming from different data. And so, uh, Guillermo, you talked about, you know, Next doesn't really care where the data is coming from. When we couple that with Vercel, how do we have a staging URL? Like how do we host staging data and host the production data?
Yeah, so when it comes down to content websites, like building a marketing page like in our, uh, case scenario here, what we typically recommend is use Next.js. You just pull the data assuming it's production, like you write all your queries against the production dataset, and then we have this adapter that Sanity can plug into called Preview Mode. Preview mode is able to basically render your website in the old school way. What I mean by this is typically when you build a modern website with Next.js, if you're building a marketing page, you probably, not always, but probably want to statically generate that page. Meaning there is a phase where the page pulls the data, we build it and we create HTML. Then that HTML is distributed all over the world in the Vercel CDN, and then when visitors all over the world go to it, they can get it really, really fast. Now the question becomes, what if I want to preview what a set of content changes coming from Sanity would look like? Until Next.js and Vercel— and maybe there were other options before, but not that I know of— you had to rebuild the entire website in a staging environment. You had to go through a very expensive and slow static generation process to get all the benefits of this decoupled architecture, to get, to get great speed, great availability, etc. So one of the innovations that Next.js put forward is preview mode. So when you access your website with a special cookie that in this case would be set by the Sanity preview functionality, we're basically rendering your website synchronously. And what I mean by this is you're going to Sanity for every page navigation that you make. And this is interesting because it's almost like the old school WordPress way. So WordPress was based on PHP and MySQL, and for every page load, it goes to the database. So what happens with WordPress is any spike of traffic and boom, it gets destroyed. So, because your database can't always deal with all that traffic. In our modern web development world, we've become better at that because what we say is, well, we get data from Sanity, we produce a static file, we distribute it all over the place, but then we got into that sort of catch-22. And this is where Next.js preview mode can help a lot because you can almost go into WordPress mode where all the data comes from, whether it's Sanity, whether it's Shopify while you're in the preview cookie mode. And then when you exit it, you're back to the static mode, meaning the visitor mode and all that plumbing is kind of boring in a way because this is just a, My expectation of how every website should work is that I go to Sanity, I have a preview button, it works, and all this plumbing is sort of hidden away from me, which is sort of what we've been working very closely with the Sanity team to sort of hide all this plumbing. But I think it's important for developers to understand that that plumbing is really providing you with a very robust production experience. And it's giving you this best of both worlds of having a live preview,, and also having your production that is super solid, can deal with massive traffic spikes and so on.
Nice. Cap, maybe you can take me through the, the portal, the Studio experience of doing preview. So if I've got, uh, Sanity Studio up and running and I create a cookie in Sanity and I've got an API endpoint on Next.js and I say, okay, here's my preview endpoint, the cookies match. To help me get across the finish line from there?
Yeah, so right within the Studio, um, let's say it's a, yeah, e-commerce and we want to have a product and we want to update it, um, before. So you maybe you're changing the image and you want to change the hotspot on the image because it was kind of wonky before. And so you want to preview it before it goes live. Um, you can have different things in your schema. You could have a publish date, so if you don't set that, it wouldn't be published. Or you could do like a hidden toggle, so once you do hit publish, it's still hidden, but you can have, there's a little like, uh, 3 dots in the upper right hand corner, you click on that and you click on preview, and that will show you exactly what it would look like without having it go live. Like without having that content go live and everyone sees it, you get to preview it and make sure.
I also love, yeah, I love what you mentioned about the unlisted mechanism too, because we use that a lot where It's almost like YouTube when you publish a video and you can only access it with the URL. That's a really cool way of doing live previews as well, because unless you happen to know the URL, no one knows it exists, but you can also take it a step further with preview mode and be like, only you have to have the URL and you also have to be in preview mode securely. You're going to have both options with Sanity and Vercel.
Oh, I think I missed the magic part about the the flag. So in the schema you've got is hidden as just a, a Boolean value.
Yeah, and you can toggle it on. So currently, like, there's a Community Studio, and in there people can write content and they can keep it hidden while they're working on their blog post or their project. And so, um, they can go back and they can see it, and they can publish their work to their studio, but there's a toggle there that says hidden and it just stays hidden from the public and they can continue working on it. They can continue like editing it until they feel ready. And then once you untoggle that and then hit publish again, then it's live.
Okay. So then in the, I'm in my head, I'm thinking in Next.js, when we're doing a query for our data, we're ensuring that the hidden is false. In that sort of build step when we're doing like getStaticProps for— Yeah, for example.
Okay. Another thing that's really cool is in the data fetching hook, Next.js gives you basically like an isPreviewMode helper of sorts. So you can say, I make this query when I'm in preview, it's valid. And when I'm not in preview, it's this other query. So you can have that flexibility there in the data fetching logic, which is only known by the server. This is really important because, uh, you can make it so secure that nobody can ever see your hidden posts, for example, or you can even make it so no one can see your unlisted URLs, or you can make it so no one can access a specific dataset within Sanity that is only available within preview mode. The developer has a lot of flexibility there. You can keep You can even keep two studios. You can have your staging one and your prod one. You can have a staging dataset and a production dataset. You can have documents with flags. I think that's where the developer has a ton of flexibility and it's actually not hard. You have to obviously set up, you have to get Sanity and Next wired together, but past that is just joy. And you mentioned getStaticProps. What's really cool about getStaticProps is it runs at build time. So when you push code, fetch data from Sanity, and this is kind of the innovation of Next.js and Vercel, you can also run that same logic at runtime. So you can push content from Sanity to a live site without regenerating it, as I said there. So getStaticProps is almost turned dynamic as well. By Next.js such that you don't have to wait hours and hours and hours for your content to go live.
Or for rebuild. I want to explore that a little more. We've got— is that something where— so I run get static props and I've run my static build and it's published. So I've got my assets, they're deployed across. Inside of Sanity Studio, we make some changes and hit publish. Sanity's got some great webhooks. And yes, what, what, where do I, how do I get back to dynamic data in that sense? Is that just a hook in the component that's checking on page load for a new additional data after static render?
Yeah, yeah. So there's, there's two primary ways that you can make that static page dynamic. One, like I said, is preview mode, where if you are in preview mode, you're synchronously basically like an old SSR monolithic app at that point. You're always going to Sanity, you're always going to Shopify, you're always going to like whatever data provider you have. Once you're outside of preview mode, you're always going to the latest generated page. So I guess what your question is going towards is how do I update that one? The one that's actually live. So the easiest way that Next.js offers today is that it has a flag called revalidate. That allows you to revalidate the page in the background. So you give it a number, like revalidate 1. And then when a visitor comes, we can check in the background very efficiently and cheaply. We can go to Sanity and every other data store and be like, give me the latest data. And we do so only at once concurrently. So we never put a lot of load on your backend or anything like that. In practice, this works extremely well because when Sanity gives us a hook, we can also run that, right? But if your data provider doesn't have support for hooks, which is a lot of them, we can still revalidate data in the background. And the in the background part here is really important because we always want to give the visitor the solid generated page, right? You don't want to have your marketing page be offline or slow because some data provider had a glitch or it was partially slow. So this is why a lot of our listeners are like, why should I go with this? Why don't I just go to the data source for every page view? You could, and Next.js is so flexible, it certainly lets you do that. But if you go through the slightly more overhead of saying, I'm going to define this as a static data fetching function, you get all these benefits of static generation, both at build time and at runtime.
Nice. Okay. That's fantastic. Cap, when we're talking about this data fetching and, and, and from Sanity pulling, so we're in preview mode, we are content in our Next.js. They've done their cookie handshake. We're in preview mode. Are there elevated permissions or roles? Because I know that the Sanity dataset is public when it's published, but if it's in draft mode, do we need API endpoints and like elevated permissions or roles or extra access tokens or something? Like, can you sort of walk me through this? Like if it's not public public, like if it's in drafts or something else, how, how does, how does this work back and forth?
So I think I understand.
So if you— I think I just asked like 10 questions. So you just pick one of them and run with it.
Yeah. So in your dashboard, say you're working on your dashboard and you want to make sure there are specific roles for a project or a dataset, you can set all of that there. And you just add someone via their email and they have access to it. So that's like a way that you could set a role so that people aren't just able to go in and like update and change things. I think that's what you're asking. Is that it? Yeah.
Okay. From like what, when I, is there anything additional besides that cookie handshake? Like, so I'm in the Studio and I click like show me the live preview. It kicks, am I right in thinking that it kicks me out into another, it kicks me back to my Next.js site and renders that page, right? Yeah. So does that— okay, does that site— now that I'm over here, does— do I need extra talk? Like extra— I made the handshake, do I need extra APIs or a proxy or a pathway? Or I feel like that's too easy. Like I feel like I— oh, as a developer I owe some more, like a pound of flesh to get there.
So what, what's really nice that you can do with Nuxt is that I mentioned that you, you're using, for example, this function for data fetching called getStatic props, that function always runs in a protected privileged environment, right? So whether it's in build time, it can access all your private keys, like your, your, you can access your entire service account on the Sanity side. You could even access your entire AWS account and it would be a token that is running in a protected server-side environment. Now, when we execute previews, when we render previews, and when we push new pages to the edge, we're always also generating your page in a protected server-side environment, which also has access to all your private keys. So the client side doesn't ever even need JS. We even have an experimental flag in Next.js called don't even include React, don't include anything on the client side. And this would still work because we would be pulling the data from Sanity in our server-side environment. We'd be generating the HTML, whether it's build time, whether it's preview, whether it's runtime, and then we, we push it, right? We return it to the user or to our edge network. So at that point you can access the entire Sanity account, you know, like you populate your Sanity environment which our Sanity integration does automatically. And then you just make your queries. So it's a very simple model from a security standpoint. The thing that we just talked about is also how you can use Sanity's roles to make sure that access in the Content Studio, you can have roles, you can have permissions to make sure that no one has the ability to just override any content. But the key that you use on Next.js does have access to all your content. And it can also be read-only mode. So you can be very, very thorough with security. You can say, well, what if my Next.js component— sorry, let's say there is a terrible scenario where your Next.js application embedded a malicious third-party module from npm and your Sanity keys leak. They could only be read-only keys. So from a security standpoint, super solid. You can honor any permission system that you want in the backend with any roles and capabilities and so on. And Next.js just reads and generates HTML.
Nice. Cap, from, from a studio perspective, let's say we jump— our, our head of marketing, Don, give him a name, uh, he, he insists that he is the only one to push publish, right? Everything has to go through him, right? It's, it's It's how he feels good about himself and, you know, it's— he wants to make sure, you know, maybe he's a really good speller. Let's say Don's positive. So he's a really good speller and he's gonna catch all these mistakes for us. How do we give Don the ability to publish, but you and me and Guillermo, like, we still wanna add content and get it ready and stuff. Can you walk me through, like, is it a scheme in the structure? Is it in the Sanity editor? Dashboard? Is it— where am I going for this one?
So there are multiple ways you could do it. One example would be, so anybody, if you want anyone to have access to that content and be able to edit it and update it, then they have access to the Studio. And so they can go in and do all that. A way you could do it is adding like that toggle where only that person is allowed to change that to true or Only that person is allowed to have the access to put it on, like, a date on it of when it goes public. Um, anybody can hit that publish button, but that person would have that final, like, that last final step to make it actually go live. Um, but then within there you have, like, the review changes so they can see, like, if a change is made that they don't like, and it's easily, like, revertible if it's not okay, and you can do, like, a section at a time, or an entire edit at a time. Um, but yeah, creating those like parts of the schema to make it more specific for your team and like how you want it published, that's definitely there.
Okay. So like, I, I think what I'm, what I usually think of in my head is in, in Git terms, and maybe this doesn't fit right on top, is like there's, there's publish and then there's deploy, right? So maybe we just want to sort of gate off, like everyone can publish. That means the document's sort of pressed and, and done or ready. And then there's deployment, which is that final sort of like public trigger. Are there, are there webhooks? How do we generate a webhook to get into Vercel? Do we do that in the Sanity Studio and then take it over to Vercel or vice versa?
Yeah, I think one option there is that the— in this case, anybody would be able to preview changes, but not everyone would be able to submit them in the final state. One option is we can do it with flags. We can even do it with separate datasets like your staging dataset and your production dataset. In this case, Next.js is not opinionated at all. I've seen customers, what they do is they use the git full rebuild as a final step depending on the size of the site. I've seen them use incremental static generation where, again, in preview mode, Anybody can put a change that goes into preview mode and then you can use branching on the data fetching function. Say if preview mode, oh, it comes from this dataset where I'm putting my drafts, for example. If production is coming from the production dataset and basically you have complete flexibility there. You can say, well, production can only come from this type of query. For which you should have had a certain role to publish to meet the results of that query. Does it make sense?
Yeah, and you can completely customize that publish button to be like specific to a role.
Yeah, so the one thing, something that we've done is, is we've got, uh, approval and request for change buttons, custom. Yeah, you call them document actions. Did I get that right? Yeah. Okay. We've added those in there because to try and help with a collaborative workflow of like, okay, I, I've built this document and in there we've said, hey, if your role is a moderator, you get the approve or request changes button for creators, right? So we have a creator role and a moderator role and they, they go back and forth. And those, that changelog down the side that, that you were talking about where you can roll changes back. We were initially coming up with like, how do we talk? How do we communicate the need for change? Like, how do we talk about your document and like your blog post or your marketing text or like, look, this, we want better shoes or we want better copy or we want something shinier here. And like, how do we communicate that back and forth? And we found just writing it in there and then opening that sidebar in the studio and being like, oh, Cap says that, you know, Cap did this change and she thinks it looks great. And Guillermo came back and he got the picture with the green shoes and I don't know about the green shoes, so I'm gonna Maybe I'll request for changes green, maybe not Guillermo Rauch. Let's go with something a little more like subdued. But like we had those conversations, we were like, where do we put this stuff? And we ended up just embedding it in the document and rolling those back and forth. I think this is really good. We've got our site, we've got it running. My question for you, do we have a specific, we have a domain, Do we have a permanent preview domain, or do we just send marketing and executives and everyone through the Studio portal to get there? Like, what's the lowest friction to share preview information with the different groups, right? Marketing, executives, whoever, the guys making the shoes, they're green still.
I would say it's always you invite them to where where the collaboration happens. So in this case would be a Sanity Studio. And then the only thing really that they need to know is that there's little dots where you press and you have access to preview functionality. It's as easy as that. Now, something that I think is what is worth discussing a little bit is that a Sanity schema can evolve over time as well, right? So it's not just, collaborating on content in itself with a fixed schema, but things can also evolve over time where you're introducing new schemas, new datasets, new data types. Um, and that's where Vercel helps a lot with the preview deployment functionality, right? Because now let's go back a little bit to like the development side of things, right? We've talked a lot about the content, so Let's say that I'm going to add some sort of new editable content capability to my website. Maybe it's a set of logos on my marketing page that I want to let my team contribute to. Right now there are no logos on the marketing site. A PM or a marketing manager told me, let's add logos. I'm a developer. I sit down, I create a Git branch. We all start that way. Git checkout -b, you know, new logos. And then I'm like, oh, so where do I get the logos from? The marketing team told me they have to be, you know, contributed by anyone in the company. So the easiest thing for me as a developer is, uh, image source, image source, image source, and copy and paste some stuff. But I'm gonna do it the right way, right? So I'm gonna make it editable on, on Sanity. And I decided to use GraphQL because this is really simple. Give me 10 logos, right? So what I realized is that the production dataset for Sanity doesn't have a schema for me to store these logos, right? So in my branch, what I'm going to do is I'm going to make a query to my, you know, staging schema that I just created I'm gonna get my logos, I'm gonna render them, and then press git push.
This—
what's really cool is that Vercel will create a new deployment just for that branch, and that deploy will receive the environment variables for the preview environment. So instead of going to my production Sanity, it can go to my new Sanity, right, like where this schema in particular lives. Now we can share that URL that typically has a form of mycompany-git-newlogos.vercel.app. Now I can also collaborate on that other new dimension, which is I can collaborate on the stuff that's coming soon. I can collaborate on almost like a beta version of the website that is still grabbing information from Sanity in the cloud. This is really cool because that you're staging doesn't mean that you're not using the real Sanity. So as you push and as you evolve this branch that adds the new logos, you're basically that far away from what the actual production experience will be. And every feature of Next.js and Vercel still work on that preview environment. So preview mode works, uh, it's all at the edge, all globally replicated, so you can actually test the performance of these logos in a realistic environment. It's SSL enabled. So what I find really cool is that with Sanity and Vercel, you can sort of— it's all collaboration. Collaboration and content, collaboration and features and code, and both can sort of coexist and, and be a great experience.
I want to take your example and I want to push it a little further because First of all, your git branch sounds suspiciously like things that I do and the ACs that I get. I may just be like static assets are fine, we're just going to throw these in here because it's always temporary, it's never permanent. I feel very seen at that moment. If we take those logos and now you do that and you publish into production and everyone thinks it's amazing, But they, they want more. They want meta details. They want the company name and a little blurb about them under that logo. Can we go into schema? Do we have to create a new document for these things? We already have a sort of logo document. How, how can we add a sort of block of information without a whole new document, a whole new thing and a whole new thing? Like how can we go into the scheme and, and create that without rebuilding logo from scratch.
Yeah, so when you, let's say you update a logo and it's, uh, like the main image on a schema, um, there's a lot of data that comes back with that, a lot of metadata that comes back with it. So you don't have to kind of be specific in your schema of what is there. Like you'll just have asset ratios, you'll have, um, of course sizing and stuff. But you can also add to that particular image to get more data out. And then when you query for it or when you start using it in your Next app, then you have— you just kind of dive into that, that logo and dive into it.
That sort of extra meta. Mm-hmm. Guillermo, now that we're talking logos and images, how can I use these images in a, in a really sort of appropriate way. I know, um, Next.js 9 just had, uh, images, a lot of help rendering images. Um, I know I don't do them correct at all because as soon as I add them, my page load just goes right in the garbage. Um, so, uh, yeah. Right. And, and I, nobody ever has enough time to be like, I want you to spend 3 days just optimizing this image. Right. That's never a ticket. I've never gotten that ticket.
Uh, so Sanity supports rich media, right? So it's not just text, which is really cool. So it's not that you're creating a schema that says image URL. You can actually have an entire collaboration and content experience around uploading images. Now, the issue that you're alluding to is, I think you mentioned earlier, 4K images. I could upload a logo that's 100 megabytes. Someone just sent me some illustration, is Adobe Illustrator file. And I upload it, right? And then I've seen it all at this point, right? Someone uploads SVG, someone uploads another one as an animated GIF. And I think what's really cool about Sanity and Next.js in this case is that we can actually have the best of both worlds where like we let the content people upload anything as long as it looks good to them, right? Like they upload, they preview, they see it, they push. On the Next.js side, instead of going directly for the image tag that has been the same HTML element since 1995, pretty much, uh, which has a lot of performance issues. So we'll take those images, and if you only use the image tag, we'll, we'll get them from the Sanity CDN, which is really cool, but they'll still be different formats, different sizes. There might be a logo that's gigantic and and we're giving it to a tiny screen. So if instead of using the image element, you use the Image component that we introduced in Next.js 10, it basically has almost the exact same syntax as the image tag. So it's only uppercase and it's the entire word image. So it's I-M-A-G-E. And then you say on the source, you point it to the URL that Sanity automatically creates for you in their image CDN. And then also, as, as we just alluded to, you get a lot of rich meta information about the image. So the, the two critical components here are the width and the height. That's the only requirement that the Next.js Image component introduces above a standard image element. And the cool thing is that Those are required because then we can render this beautiful marketing page. You can think of it as in one pass. We already know where to lay out everything perfectly because we have that important meta information. This might sound like something small, but modern websites are mostly made out of rich media. That's what is compelling about doing all that we do. So when you know that width and height that Sanity gives you, you just make your page flow better, perform better, have better web vitals. Basically you make the world better, really. Like the, the, you'll save battery life even on the, on the device. And then like you can go, you can kind of go nuts with that. You can get the average color of the image and do a really cool placeholder. You can, you know, create a gradient from the meta information of the image. So that's how you can create a really rich content experience. And, you know, like traditional CMS and traditional solutions for frontend, it's not that it's been impossible, but what we're talking about here is that Sanity and Next.js are giving you this as like primitives that in some cases are even easier to use than the alternative. So that's kind of how I think we've collectively raised the bar by each of us doing— specializing Sanity in content and Next in frontend. We can both kind of create this better defaults for the web that I think just make everything better.
Yeah. And to add to that, so, uh, the metadata that does come back with an image, uh, you kind of touched on it a little bit. The palette is given back to you. So, you know, exactly what are like the main colors that are coming from that logo or that image. And you can be given, like, foreground colors. So maybe you want to put text over it, and you can— you don't have to be searching around to see what's, like, the best for accessibility.
You can pick out the color. Because the content folks might upload a logo with a certain color. Well, now we're taking the logo metaphor too far, but, like, you can even generate a shadow. If the logo is white and the page is white, you can say, "Oh, the dominant color Sanity is telling me is white." CSS box shadow to this one logo. Like, you can go really nuts. And this is why, you know, developers love these tools. If there are people that are not so experienced in like React and web, they're probably listening to us saying like, what, like query languages and Groq and components? Like, why? I had it so easy with WordPress, right? I had it so easy with Drupal. But really, like, it's about just being super ambitious with what you can do in this unique combination of content and front-end experience.
Yeah. And I think—
Oh, go ahead.
Well, and if, so, if you have your team, your content editors, and they do not know code, they can go into the Studio and upload, and then that one image can be used across many different devices because we use that one image. You can set that hotspot, you can crop it in that one spot that it's uploaded, and it can be used across any device, any aspect ratio, and it will adjust to make sure that hotspot that the content editor picked, so maybe like the upper right always wants to be in view, it will adjust and it will make sure that on every device it shows that.
Yeah, and I think Guillermo, you said that it was a little thing, but I would, I would push back on that and say that because you've given content creators this like anything goes up here, the work underneath that developers do to accommodate is— I think that we fall back to the lowest common denominator. Because if you let them put anything in that, they're going to put 4K. Someone will find an 8K image of the moon and stick it in there because they can. Right.
NASA does distribute these images that are like 300 gigabytes. I'm sure someone will try to upload it.
Right? Like the ones from NASA. They're like, I found this thing on NASA on the weekend and I put it in there and they'll do it because they can. And as a developer, you have to sort of like funnel that down into like reality. But you also don't want to hamstring the content creators, right? Because they're your customers and, you know, we're all on the same team and they want to put up the new green shoes and pictures and stuff. So it's like, how do you give them the tools without making our lives harder.
Yeah, when you zoom out, what we've been noticing as we work together with the community and, and companies in their new ways of creating content online, what we notice is the new role of the developer is to service and amplify and give new skills to non-technical people, which is really cool on one hand, On the other hand, end users. Google is coming out and saying, we're going to start ranking your marketing page that we're just building. We're going to rank it based on performance on google.com, not just on keyword matching. That in itself makes you as a developer want to focus a lot more on the end user and on performance, which is great. On the other hand, when you implement content APIs, You're working in the service of your peers at your company, at your teams, even yourself. In a lot of cases, it's just so much easier to like upload an image to Sanity than creating a pull request. Right. So this is really cool because the developer is no longer self-serving in a way.
Right.
Like, and I know that almost, I'm not saying that developers were self-serving before, but sometimes it is easy to just, oh, I'm going to write some markdown. That only I know and I'm going to write some handwritten WebAssembly to render this page because I want it.
It's an artisan blog. It has to be handwritten WebAssembly. Artisan blog.
It's cool that it can still be super fun. It can be technically super awesome as well. Yet now you are serving these two personas. That I think just everyone becomes happier as a result, you know, like your boss will be happy to pay for this and you'll empower a lot of people and you'll make your visitors happy. So it's really great.
Yeah, it gives the developer the power to still like customize the studio and like make it like you can even customize it down to the color of your company, but like it can look like it was built by your team and Um, the developer has that ability to like change a schema and, but then once it gets to the content editor's hands, it's all set up for them. And then they have the power that in the past only developers had, like adding an image or markdown.
Yeah, I think you really hit on a, on a key point is empowering the other people in the company, not empowering other developers, but other people in the community. And I think. One of the reasons why I gravitated to Sanity, um, so early on was the studio had such a, such a nice, easy interface. Like it was, it made sense. It was something that I sent across the wall and they're like, oh yeah. Like I never got any feedback or friction or like, how do I do this? Or where is this? I never had to like explain in 5 or 6 steps. How to copy and paste the markdown into the thing to do the thing. And then if you have to do it in this order, like I never had to do that. And I don't think I ever really understood how much friction I was introducing because of this like goat's milk artisan way of adding content to the site. Uh, so I think, uh, applaud to Sanity Studio for doing that. I will, Cap, I wanna ask you about the Sanity dashboard. And since we're talking about, um, the, the people that are consuming this, can you explain to me a little bit about the dashboard and like your sort of vision for it and helping sort of push this idea of everyone in the company contributing and, and being a, uh, sort of a spot to add content?
Yeah. So in the dashboard, um, depending on how the company's set up or if it's personal, Uh, all your Sanity projects will live there. You can view like your analytics, your usage, how many people are coming, um, to your site. Um, you can do roles there. Um, but yeah, that is all like under the manage dashboard and, um, you can add like tokens there. You can add, uh, I could just pull it up. Um, but there's a lot going on on the dashboard that really like gives you, you continue to own your content. It's like you can go in there and you can make sure that specific roles have been given or a role is taken away, or you have different data sets. You have your staging, you have your production, and you have the ability to set all that up there.
Now I brought up the dashboard 'cause I wanna throw you guys a curveball. Staging data, we want to make a huge breaking schema change. We want to rewrite a ton of the data that's gone in there. We basically need to, you know, the company has split or there's been some changes and we need to go in and rebrand a bunch of posts and topics and content. Am I going to be— do I have to pick a short straw to go into the studio and manually type all this out? Or is there a way for me to like export all— you said I own the data. So is there a way for me to pull all the data out and sort of massage it around and then shove it all back in?
Yes, there is. Um, so it's been heavily worked on recently by the team, but yeah, like taking your dataset and moving it to Another one is definitely there, but it's an enterprise thing currently.
But yes. At the end of the day, what we need to realize too is that these are also databases at the end of the day. It's a content database, but it's a database. I think a lot of the rules of the database world still apply.
Right?
Like you might need to export your data and reimport in a different form. You might have to sometimes merge datasets. You might have to go through some migrations. I think that's a good thing because at the end of the day, um, you have to treat this not as some magical thing, but as a system that has its own query language and its own rules and its own access controls. So yeah, I think, uh, it's great to hear that the Sanity team's working on making this a pleasant experience. Because in my experience, the bigger you get, the more frequently these things happen. Whether it's that you buy a company, you merge a company, you reorganize teams, and, and the data shapes tend to follow the shape of your company, and, and they tend to grow with the organizational structure of your company and the business units of your company. So It's, it's as I, that's why I mentioned that Vercel is giving you preview environments where you can start sort of rethinking your content strategy. Um, you might even want to migrate after listening to us talk all this awesome stuff. You may even move away from another CMS and then you'll use Vercel preview environments to start getting the data from Sanity. And then you can share that URL with your entire team and say, hey, what do you think? This is a new page that I created with Sanity, uh, and then you merge it to master or main, and then it's live. So it's, it's good to be able to operate on the two levels, right?
Yeah. And there's, uh, you know, the, the data within the organization is organic, it's growing and changing, and I would be worried if it wasn't, right, that it was stagnant and very brittle. Um, Sanity has, uh, I went through this recently where I had to pull the data and run it because I had personally fat-fingered several auth or several IDs and sort of relationship keys, and I had to manually go back and do them. But there's several pages that say like, look, here's how you export the data and here's how you can script through it. It's just a big JSON blob and you can sort of iterate through it. And I like followed the doc and I went through it, you know, and paid my dues. Then I turned around and just imported it over the top. It was great. It ran through, it gave me great permission, great upload percentage, and I jumped back to the studio and it's like, hey, everything had just shifted just ever so slightly in the massaging that I needed it to be. Fields needed to be arrays and not a string, multiple authors and not a single author. There's these little things that are constantly happening Because we did it in staging, I just threw it on preview and was like, is this what we were after? I just shared that URL. I was like, is this better? They were like, oh, that's much better. Then we were able to, we had the script, we had done it once. Doing it in production, I felt really confident in doing the same thing again because I had seen the input and the output and I felt really fine. I was like, okay, I'll do it. I'll do it late at night and I'll just run the thing and no one will know the difference. It'll just be better. So, um, again, kudos to Sanity for taking the time out to make those sort of, it was like a page and a half, but it was enough for me to be like, oh, is this how I get my data back out? Like, okay, cool. And it's like, here's, you can iterate over it. Then there's like, here's a couple packages for you. Um, so I thought that was, that was really great. Is there, have we missed any feature set? To our new branding that, that you think would, would really elevate this project? You know, we've talked about live preview and adding content and images and making them mobile friendly. And, you know, we're going to be the new hot green shoe company, uh, any day now. I really feel it. Um, is there anything— uh, I want to give you guys the floor— is there anything that, that you're just bursting to talk about that you just want to shout from the roof?
I think it's really important that we keep performance and end user experience always as a sort of focus of the conversation, because what happens when we discuss backends is that even, even if you're helping lots of people inside your company and they'll be greatly empowered and thankful, the reality is that if your site is not performing well with your visitors your inner workings of your content strategy and your team's collaboration, at the end of the day, you might fall short of your ultimate goal as a business. And this is especially true in e-commerce, right? And also ad-backed media when you're printing ads and native ad content. So the big thing to add here is Not only do you wanna make sure that your web vitals, your performance scores are good as you develop and as you preview, you can turn on, on the Vercel side of things, you can one-click enable analytics that grab data in the real world from your real traffic. We grab performance data from your visitors. So we're actually— so you give a great example of like, I'm going to implement a new way of doing content with Sanity. You can put it on the main branch, it immediately goes live and it gets served to your traffic. You can now start seeing how your— how the devices that visit your website are responding from a performance standpoint to your new pages. So, uh, we, we talked about the example of images, right? If you don't use an Next.js image component and you don't know the width and height of an image, that's going to cause a lot of junkiness, a lot of layout shift. So Vercel, the Vercel dashboard will literally tell you, hey, this page is not performing well because we recorded from your visitors that their layouts are shifting around. You So as a developer, you can, you have this full circle of feedback of I create, I stage, I put it live, I measure, and sometimes I go back to the drawing board and I create again and I improve, I preview, I ship and go back and measure. So that really for us, I mean, there's a lot to it, of course, but that kind of seals the story for us, right? Like You develop, you preview, you ship, and then you iterate. And I think what we're going to be doing a lot in 2021 is everything around experimentation. Because what we're noticing is, okay, so preview URLs are awesome, preview mode, awesome. But inside a company, we might all be like high-fiving, this code looks great. The marketing campaign does— no one likes it. So we're gonna be working a lot and we're doing work already with the Sanity team on tooling for being more experimental around your content, like delivering it in canaries or saying 10% of my traffic or targeting it to certain audiences. So the new logos that we talked about adding, we'll first try it in San Francisco and see how people react there. Uh, and if we don't like it, we de-risk. We literally delete all the Sanity schemas, we delete all the documents, we set them on fire, and we're all happy because it's not a black and white thing. We're just, oh, it's live. I think we need to empower teams and developers, by the way, to be more hypothetical about their next move. I think we've created tools that almost give them too much certainty, but the world is not that certain. Does it make sense?
Yeah, yeah. I mean, you know, when you talk about merge and deploy, like, it's, it's such a linear process, you know, and, and we've gone to such painful lengths to do rollbacks because it's such a concrete path, right? And For a long time it was like, well, just don't roll back, we roll forward, which basically just means we run until we fall down. I really like the idea of branching off and doing this sort of experimental A/B preview branch in targeted areas. I think it gives everyone in the company a chance to— maybe it gives them the freedom or the permission to sort of try that weird idea that they're never gonna get to go into production usually, but you could certainly branch it off and try it, right? There's no harm in that.
Totally, I think that's really the, it's about giving everybody in the team kind of this fearlessness around content and around code too, right? Because in a lot of cases, this is a partnership. It's I create the code to fetch the logos render them and there is a part of me that's thinking, well, did I get it right? Did I use the right incantation of what Next.js or Google or Safari or whatever think? But then also the content team is maybe thinking, did we feature the right logos? Does anyone know what McDonald's is these days? Maybe. You can be hypothetical about things.
Nice. Cap, what are you excited about to see rolling out this year?
This year? Well, I can speak on something that happened last year that I'm really still so excited about.
Anything that anyone is still excited about in 2020, you have my full attention.
So it's so true though, what you say is like the user's experience If it's too slow, if things are taking too long to load, if there's nothing on their screen, that's, that's where things fail. And so like the Next Insanity combo is like the perfect, it's the perfect like solution to make sure like your apps are running quickly and your content's being loaded quickly and an image isn't gonna slow it down or your battery life isn't gonna go down because of all these things having to load. But it's so important to have that team collaboration so apparent in the studio. Um, last year, Presence API was actually announced and it's in full force and it's awesome. So what it is, is in the studio, your team, whoever has access to it, there's a little avatar of them that will pop up in the upper right-hand corner. And there you can click on those avatars and click on a little link. It'll drop down and it'll show everyone that's working in the studio and you can go directly to where they are in the studio. So it's kind of like a, like a Google Docs, Notion type thing where, where is everyone working? I like, I want to go find where they're at and where they're editing because I have some things I need to add. Or you're in a meeting and they said, oh yeah, um, I'm in this, I'm in this, uh, document and they can't find you. But Presence makes it so that team collaboration is so, it's so apparent and so strong that you don't have to be running around and wasting time trying to find each other. It's just right there for you.
I have a real-world example of this. I got a Slack message, this was months ago, near the end of the year, and someone was like, I'm looking for this document post and I cannot find it. And I was like, oh, here's the URL. And they're like, that doesn't, doesn't work for me. And I was like, that's really strange. I was like, why don't you just— like, let me go there and follow my avatar. And they're like— first I had to explain to them that my avatar, the little circle up in the top. But then they, they— it dropped them right— they were like one post off. They were just offset from something. And they were like, well, that's— are you always there? And I was like, no, no, no, no, no. Who's ever in the document, you know. So we explained the presence to them, but that earlier when we were talking real collaboration and like where do we keep these notes about, you know, who made what content where, people started to have like conversations in the text like as a sidebar, which was really interesting. It's very like Google Noti sort of notion I think is a really great way to describe it. But it definitely made that sort of asynchronous approval request for changes thing it removed a lot of friction and a lot of really weird, like, why do I need, why does this need more changes? Like, it removed a lot of that sort of like unsettling bits from it and gave us back just the interaction, right? The sort of like collaborative, like working on the document together, not gatekeeper and producer sort of roles. So it really helped out a lot in that situation. iPresence is pretty slick. I've even seen it used outside the Studio to, like, create a subscription in preview mode back to using ArcGIS— using the Sanity client back to the content using, like, CodeMirror instead of, like, the embedded Studio side. People are doing all sorts of crazy stuff with it. It's— I was like, this is really, really neat. Well, I think we have— I think we have gotten into the gritty parts of it today. I want to thank you guys so much for coming on the show and sort of building this great marketing and going through— like, it's not often we get a chance to talk from content to laptop to deployment to CDN to preview URLs, this whole sort of arc. I think I'm gonna listen back to this and it's just gonna melt my face off how much ground we've covered in so little time. I think there's threads here that can be pulled on and really exposed. I want to thank Thank you both so much for taking the time out today, uh, to speak with me. If you can tell everyone where they can find you, um, on the internet, Kaap, and where your content is, and then Guillermo after that.
Yeah, so you can find me on Twitter @kaapehe_ok. That's K-A-P-E-H-E underscore OK. I know it's kind of hard. Um, but yeah, I'm there and I'm also in the Sanity community. So sanity.io/community.
So you can find that. Is that the Discord?
No. So that's a new, um, a new thing that we started up where people can like create a profile. They can have like their projects, plugins that they create, blog posts that they write. It's kind of like a portfolio of types for, um, each individual person, person.
So yeah. And that's sanity.io/community.
Yeah. And then you can sign up and then you can see other people's contributions there as well.
I'm gonna head right over there. That sounds awesome. Yeah. Guillermo, what about you? Where can people find you on the internet today?
Uh, Twitter as well. Uh, R-A-U-C-H-G, uh, on Twitter, RauchG. And yeah, looking forward to hearing all your comments and questions as well. So feel free to either tweet at me or DM me. My DMs are open. I'd love to hear about how you're using Sanity, Next.js, and Vercel.
Thank you. And the, The Vercel team, the Sanity team, you guys are just crushing it. The developer experience, I think, echoes out to the user experience and the customer experience. I think the, you know, this wave of tooling and attention has lifted all boats and has really brought forth, I think, just the start of what is going to be a very awesome decade in technology. I just, I can taste it. It's like, Things are really getting cooking here. So I'm super excited to see what happens these next couple years.
Same. It's early days and I'm really excited about what's coming.
Right. I feel like we're just getting out of like medieval into like enlightenment. It sort of feels like, you know, we're sort of just evolving into like, you know, printing press type knowledge here on this thing. If you have questions, you can reach me. @jtomshock. You know, all these Twitter handles are just a monster, so they'll all be in the show notes. So reach out to us. I'd love to hear your questions, your concerns, your anything you want to expand upon, or your input or critiques. I'd love to hear those as well. So thank you so much, and this has been Build It Better with this.labs.
More from Guillermo

Guillermo Rauch at Founders in Arms Live: Simplicity, Focus, and the Bet That Built Vercel

The Man Who Built a $9B Dev Platform Thinks You're Overcomplicating AI | Guillermo Rauch

Inside v0: How Guillermo Rauch Is Building 100 Million Engineers | Lenny's Podcast - EP.89

Architecting for model step-changes: A fireside with Vercel's Guillermo Rauch

Keynote Interview: Vercel's Guillermo Rauch on the Agent Era | Azure Cosmos DB Conf 2026

Vercel CEO: 70% of Our Traffic Is Now AI Agents "Nobody Was Prepared" | Anthropic, OpenClaw, OpenAI

Why being "terminally online" is more important than ever, with Vercel CEO Guillermo Rauch

Argentina Week 2026 | Argentine Talent Powering Global AI | Guillermo Rauch & Hernán Kazah


