Content is a crucial part of what you build on the web. Modern web technologies brings a lot to the developer experience in terms of building content-driven sites, but how can we improve things for editors and content creators? In this workshop you’ll learn how use Sanity.io to approach structured content modeling, and how to build, iterate, and configure your own CMS to unify data models with efficient and delightful editor experiences. It’s intended for web developers who want to deliver better content experiences for their content teams and clients.
How to create editor experiences your team will love
AI Generated Video Summary
The Workshop covers a range of topics related to content modeling, customization, and authoring experiences in Sanity. It emphasizes the importance of tailored content authoring experiences and structured content for apps and websites. The tooling and studio overview highlights the flexibility and functionality of the Sanity studio. The sessions also discuss validation, conditional fields, and customization options for images, rich text, and previews. The workshop concludes by emphasizing the community support and scalability of projects in Sanity.
1. Introduction and Agenda
We have an agenda today, starting with an introduction and opening lecture by Simon Skogsrud. Then we will cover content modeling and customization of forums. If time permits, we will also look at previews within the studio. Feel free to ask questions throughout the workshop.
Right, I think we have slides. So, yeah, we have an agenda today. Let's see how how far into it we actually get. But obviously we are in the introduction and we will have an opening lecture. With the city of Sanity. Simon Skogsrud, he will come and set the stage for what we are going to actually do today.
And then we are going to go into content modelling. Which is pretty important for editor experience as well as look at how you can customize these forums to to be more helpful and delightful, I guess. And if we have time, we can look into our previews and so on within the studio. But but let's see. And of course, if you have questions or whatever it is, feel free to to ask them and we can we can try our best to answer and show.
So, yeah. And obviously, this workshop is for you all to to can like learn and get from it what you came here for, I guess.
2. Authoring Experiences and Content Creation
To follow along in this workshop, start by installing the Sanity CLI. Authoring experiences matter in creating unique and diverse games. Content creators need tools to enable their creativity. The connection between front-end and content is crucial. Shift your mindset to prioritize the end user and the content creators.
Any questions so far, should you actually test out the discord, does it work? Where are you all coming from? Like, where are you calling in from? That's that's a good easy question. I see people typing. Duluth, Minnesota. I guess I can do the same. Let's see. Zambia, Tunisia, Norway, London. North Carolina? Cool. As I wrote in the top of the channel, you're all in, hopefully, now. To follow along in this workshop, and you can tag along and code with us, you should start by installing the Sanity CLI. By the way, Lauren, do we want them to rather clone the repo? it definitely has the full code in it already, but I think that's fine. We can give people the option. like they can tag along with our coding or they can cheat and just download the finished code, I guess. Yeah. Okay. We, the repo and discord otherwise, if you sanity a net, you want to choose the, um, e-commerce will be. Or kind of like options for, for like a starter studio template and e-commerce is the one. We can, we can drop these details in the discord chat. And if you hit any problems, um, please also let us know in discord and we will try our best to resolve them before the opening lecture is done. So any questions so far? Seems so sorry. So you said the final version will just be available at the end. Like Lauren just dropped the link to a GitHub repo where it kind of like the finished code is. So if you have it once, I have to come. I have a peek locally that's possible. Right. Uh, I think I will start with the video. I think it's like 12 minutes or something. I'm Simon. I am the CTO of a Sanity IO and thank you for your interest in today's topic. So I want to talk a little bit about authoring experiences and what really matters about them. And to do that, I want to go back to my beginning to this, this old machine, the Commodore 64. This is what I got in like 83 years of playing, I was 10 years old and I wanted to make games and to do that you had to kind of deal with all of this. This book is filled with this kind of inscrutable diagrams and maps and it explains all the different chips in the machine, the SID chip for sound, the VIC chip for video. Then you have to kind of use this kind of IO chip to figure out how the joystick is moving. And like actually at the back of this book, they put in the whole connection diagram for the whole machine. It's kind of beautiful, of course, you don't do that anymore. But also kind of scary because this is not irrelevant if you wanted to make a game. So even if what you're trying to do is to make a simple game, what you're trying to do is to make a exciting game about kind of mystical monsters and heroes. This is what you're going to do. So if your weekend is about like, Oh, this, this time I want to try to make sure like the characters move in front and behind each other in the right way. So now your weekend will be about creating a sorting algorithm in 6502 machine code. This is a language where like sort, like multiplying two numbers together looks it's like 15 lines of code, just to multiply two small numbers. So of course what you are going to do is going to be a lot about the medium and very little about what you're trying to do. So it's a little bit like building kind of a ship in a bottle, like you're going to spend all your time getting it in there and very little time on the actual ship itself. So that was kind of exciting at the time it was all we knew, of course, and kind of figuring this out was kind of interesting, like a puzzle. And of course, people overcame all of this in a sense like some incredible games came out of that. And the whole industry was basically invented in this mode of kind of machine code and assembly, and everything being very, very technical. But of course, also this meant that there's a certain kind of people who do this, who are kind of enabled to do this. Because at that time, the teams were really small. Typically, you wouldn't have like an artist or like a specialist in anything, but like, machine code. So all these other talents would be secondary. Like you would have someone who knew machine code, who also could draw like a cool egg in like, two bits, pixel style. And that was how it would be for like a decade, I guess. And fun. Great. But also, maybe we're missing out a little bit, because we can see that when in the nineties, the teams were growing a little bit, it became customary to kind of, as part of your development, you would also create tools, like authoring tools would be part of the, of the work of creating a game. And of course, this was to enable your teammates who now are specializing in kind of creating, let's say the, the art of creating a shooter, landscape or level. You have someone who are experts in thinking about the tactical opportunities, the flow, the visual style, the excitement of like a first-person shooter area. Maybe they don't know how to make a shooter, but maybe they are expert in maybe they don't know how to make like a sorting algorithm, but they really know how to create that kind of exciting flow and that kind of experience of always being vulnerable while you also have the upper hand somehow, maybe those people. But now keep looking over there cause you will be shot from there. And that's a specific skillset. And this created the whole new kind of subculture in the gaming and kind of culture because now you have modders, who are modifying games, who are creating these modules. I don't know if modding is about modifying or modules, but I think both, they create these content packages for these existing engines. And some of these kind of ended up being completely new commercial games, even though they are just kind of new content packages for existing systems. And that's clearly kind of enabled a new kind of creativity and a new kind of kind of person to be a part of this. And now, of course we have, we have systems like unity and, and, and, and real engine, which is kind of a game engines and offering tools kind of integrated into one. And we have, we are getting completely new kinds of games, like in the games now are such a wide variety of experiences. And, and like this game, the, the, the, the untitled goose game is a kind of game we definitely would never have seen in the eighties. Right. So kind of authoring really matters. It really matters in terms of what kind of experiences you will end up getting. It's not just something to be overcome. So when I started working with websites and digital experiences as a grownup, I did not make this connection at all. My kind of ethos was I want to make sure every dollar gets onscreen that, uh, the end user gets to enjoy every bit of resource that I spent on visible value. That's my thinking. And my content creators would get scraps. I would not waste any money on content management. I would say, we'll pick something off the shelf. If that is kind of really, if they insist, but usually they will get like a spreadsheet, some marked on files, some Yammer files, and they will just have to make do right? Because we want all, everyone wants to spend all of their energy towards the end user. So I was being frugal, effective, I was thinking. But then you see this kind of backsliding effect. So you made all of these awesome kind of experiences on this expressive kind of solution that you want your end users to know. Sorry that you want your content creators to use to kind of delight the end user. And you've given them all this secret codes, all of this kind of weird stuff to put in their Yammer files to kind of trigger these kind of beautiful things you made spent all this money on. And in the beginning they do that but then of course something breaks suddenly maybe even so they did kind of backslide. They try they use like a subset of that experience because they are just trying to get their job done and they like what you did, the delightful stuff, but they can't afford it in terms of their time to use it. So that's when we made the connection. It's not really about kind of that front and back. It's really about that front and isolation. People are coming of course for the content and they are coming for the experience that is kind of crafted by the content creators. So I need to shift my mind a bit.
3. Tailored Content Authoring Experiences
We prioritize creating tailored content authoring experiences that make a difference to content creators. Our goal is to automate irrelevant work and focus on what matters. Different scenarios require different approaches, whether visual or literal. We ensure the authoring experience aligns with the content creators' goals and needs. For example, in real estate, we focus on developments, buildings, flats, and quality of life experiences. We aim to create a strong connection between content creators and end users.
I'm making this connection. I'm making this kind of experience, the front and the thing that people see and engage with. Then if that is not connected to the content creators in an effective way that goes to waste. Any weak link in that connection from the content creator to the end user lessens the entire experience. Doesn't matter, like my awesome 3D effects or what not. We started being mindful of that. Mindful of the content authoring experience.
And our thinking was. Like. After trying a few more kind of traditional CMSs, we felt they contain so many assumptions about what's important to the content creators. They can contain all of this kind of these kind of preconceptions about pages, templates, I don't know. It didn't. It felt like I'd spent more time taking things out, making sure what's in the content authoring experience is relevant. I want it to be about what is making a difference to the people who create the content. I don't want it to be about anything else. Like freedom is kind of expensive if it's not about what we're trying to do. So that's why we made sanity essentially. We wanted to make sure creating content authoring experiences that are specifically tailored to what makes sense to the content creator is reasonably simple to do. That is something that gets done because it's not expensive. It's not super hard. It's a lot to do with figuring out what makes a difference to your content creators. And it might be very different.
There is no kind of single approach. It might be very visual or very literal. If someone are creating content, maybe let's say kind of a landing page. Yes, it's going to be like literally pages and modules maybe. And these modules will be calls to action and pricing and testimonials and case studies. So it's a very one-to-one experience. But still I will like if I then think okay, I'll give my content creators like a visual tool, like they can do whatever they like. I'm not helping them because not everything makes a difference to them. And not everything is relevant to the goal at hand. So now I kind of given them a lot of work that's irrelevant. Now they are moving a module. Now they broke the page because they forgot to put in a divider. And it needs to be the right divider. Oh, now the background is the wrong color, because this is supposed to be an enterprise product and now we should use the blue color. So what we need to think about now is like how do we make sure everything in the authoring experience is what makes different to these people? In a different scenario, let's say we are a real estate developer, and maybe we don't know which pages will kind of end up organizing this content and maybe there will be several pages because we have a ROM web page for our real estate kind of empire. But then maybe people are not actually coming there because we are actually listing this kind of estates in different kind of partner sites, and that's where people actually are. We have no control over those layouts. We just provide these kind of data streams. And maybe we print out leaflets that combine a lot of these pieces of content. So maybe when we are working in this company, we are thinking as content creators about developments, about buildings or flats, about areas on the quality of life experiences you can have there and the demographics that these are relevant for. And that will be the content model. So our thinking, when we are kind of creating this kind of strong connection, this bond between content creators and the end user, is making sure this pipeline is about what makes a difference to these groups, and everything else, we just make sure we automate that. We make that just go away. And today, this is the topic, and I really appreciate that you care about this. And I think there's a lot to do in this area that is not being tried yet. So thank you, and have fun.
4. Structured Content and Sanity
Structured content is a great thing for editing content for both apps and websites. It challenges the idea of content being tied to pages and encourages thinking of content as separate entities. It allows for more possibilities and the ability to use the same content in different mediums. As developers, we want structured content, but implementing the tools to manage it can be challenging. Sanity provides a solution for creating structured content and offers a clean interface for editors.
All right. So, we thought we could take a minute to ask you all if how does this relate to your professional lives? Is it something that's recognizable? Any reactions to different points that Simon raised? Feel free to do it on sound or drop a comment in the chat if you prefer that. I mean, right now, I'm being tested with getting a CMS set up in React for my company so I definitely understand the needing to make it easy for people who don't know how to write code, letting them like edit a website, add blog posts, stuff like that. Yeah, I would suspect that most of us in this virtual room are probably tasked with something similar, like that you're making, probably making mostly websites, I would guess. But you need to make it possible for someone to actually change the content on that site without without you having to push some code? Right. Necessarily, right? It looks like someone's typing in the chat, too. The anticipation. But yeah. I like to connect the analogy to to game design. It's not it's not super obvious when you think about CMSs and so on. It is kind of like the same thing. Yeah, we need. So in the chat, we need a simple development tool to give our clients the possibility to manage content for the apps we develop for them. Is that kind of like actual mobile apps or web apps or both of them? Both. Oh, yeah. So there you go. I agree with that. Hi. Yeah. So let's let's let's dive into the structured content first. Because if you're going to make something that like, that's people edit content for both apps and websites. Then I guess it becomes super obvious why structured content is a great thing. Because those are two different mediums with quite different constraints and possibilities and so on. For a good while, I think web developers has become used to thinking about the website as a collection of pages, and maybe posts. Those are the default content types you get from something like WordPress and so on. If you look at a lot of developer tooling, you tend to see the pattern, like you make pages and you have page builders and so on. Structured content is kind of like challenging that a bit by asking you to think about your content as this decoupled separate thing in itself, and not something that's only presented on a page. And Simon touched on that when I talked about calling this real estate company, right, like they can see their world through projects and developments and so on and services and all of those things can be content types. Yeah, I also think you know, that's just sort of the reality of the society we live in too, right, like we don't very rarely do we just live on websites, right? Like a lot of our information is on like other platforms like social media and like searching and they're even in the physical world, they can be on kiosk and all sorts kiosk and all sorts of things. And if it's the same information, it would make sense that you would want that to your content to have its own model so that you could deploy that from one place and have it go to, you know, any interface that you want, right? Whether it's a website, an application, a kiosk, or even like print, for instance, Right? Like. And I think like, as developers, this is kind of like preaching to the choir a bit, because we are used to very, or probably used to the idea of a single source of truth, right. And not repeating yourself. And what's weird about content and content on the web, especially is that like, it's, it's, it's it's a couple of decades ago, we started to like get databases, but all of the awesome things, the databases can do. Because for content, for some reason, we go like, be stuck into databases sometimes, or files, we don't get any of the value of a database. We can query necessarily because it's only it's HTML inside of a cell or something, right. So structured content is kind of like a way to get more. Possibilities from your content, because you can start treating it as data. And I think we will touch on that a bit today, but that creates for a lot of opportunity and makes it possible to actually use the same piece of content in both an app and a web page. A voice assistant and so on. So it's a pretty useful. All right. At For some reason, my Mac is. As developers, we want to create structured content, but we hate implementing the tools to manage it. I hope I have resolved the thing now. Yes, you're back. My Mac just unmuting itself. Yeah, yeah. Sorry about that. Yeah, exactly. Exactly. We want kind of like that database experience on our end, but like the tools haven't been there to actually make that happen. Of course, we are here representing sanity and that is like what sanity is all about. And hopefully it doesn't suck anymore when you use this tool. But yeah, I kind of like skipped through the slides here but I think if you have ever set up kind of like a data model in a database, this would be somewhat familiar to you. But sometimes it takes kind of like a shifts of perspective when it comes to content because you also will meet requirements from your teams and organizations. Like yeah, we need marketing landing pages. And then you can ask, yeah, but does it, we need to kind of structure it as marketing landing pages because what they consist of is mostly product information and this type of information. And when you start to kind of like see the domains of what the content is actually built up from, then you can start to kind of tease out content types and like embody them in the system. And that will also make it more intuitive for editors to like find wherever they want to change something because it makes sense that a product information lives in kind of like the product content type and not the product pages folder. So this is kind of like a foundation for, I think, awesome editorial experiences and it also makes it possible to have a cleaner interface, I think. Right. Great. Are we now getting into code? Yes, I think we should. Let's see if I can share my other screen. I will try my best to actually look at the chat, but Lauren, if you have an eye, you can let me know if there's something. I will, I'm watching. Yeah, so you can follow along. I think I put the GitHub repo in there or if you spun up a new studio, it should have the e-commerce data set in there. Yeah, so this is the repo. I guess I should maybe just spin up on you. Yeah. So hopefully you all have done this. Oh, not just, just uninstalled the CLI for some reason. I'm just testing something out. React advanced editor. So while we're installing, Sanity is, we call it the platform for search content and what it's actually is a hosted real time content lake we call it, it's kind of like a document store. And then you have this open source, Sanity Studio, which is kind of like what you, you can think of it as the CMS that you're building. And the studio, it's, it's a React single page application. So it's only like a client side application. There's no server component to it. So it will load in your browser and it will connect to the hosted backend. So that means that you don't have to fuss around with the database remote and local and so on. It is kind of just connects to the hosted data store. So, and everything in it it's real time. So that, that will be just synced in real time. And you can also have different data sets and so on. If you want to have a kind of a test environment and a production environment. And there's a bunch of other things also in this platform. You get a asset pipeline, so you can go like upload images and have haven't transformed on demand. So we can like request a certain width or a resolution or format even.
5. Tooling and Studio Overview
There's a bunch of tooling stuff to leverage your structured content. The fresh studio provides a bare bones, intuitive, and clean interface. It allows you to configure and include only what you need. The out-of-the-box experience includes functionality like review changes for document history.
And there's a bunch of tooling stuff that you can use to leverage your structure content in different ways. No, I installed the fresh e-commerce videos. With the sample data. With the sample data, I hope. Yeah, let's see.
Okay, so now I am seeded into the thing, oh, live coding, it's hard. Let me see if I can. No, did you upgrade to Monterey? I did. That was a bit dangerously. Right, so this is the fresh studio, and if I run Sanity Start inside of it, I'm sorry, I have to do this. There we go. Then it will start the development server locally so we can start changing it. And you'll see kind of like what's going on in this side of the editor.
Maybe can you zoom in a little bit? Like this? Yeah, there you go. Don't have a, it's just kind of a small MacBook. But let's open this link, localhost3333. I'll log in. Let's see if I have actual data. Yeah. Yay, coffee pulver. Yeah. Let's go. So this is kind of like the studio and it's pretty bare bones, that's the whole idea you shouldn't have more things than you need. It should be the only things that's relevant sort of because what happens with a lot of CMSs when they mature is that they keep adding features to them and some enterprise customer had a request and suddenly you have like two more buttons that you never use. So this is kind of like here we have it like you should configure it and put in only what you need and then it will be yours and hopefully it will be more intuitive and cleaner. That being said, there's a lot of functionality in the out-of-the-box experience. For example, I guess I should invite you, Lauren, but there's review changes. So everything you do in a document will be saved to history so you can roll back. So here you can see there were some changes from before. So it's, kind of like, if you are familiar with practice changes in Word or Google Docs, it's kind of like the same thing.
6. Document Types and Field Creation
The first thing is discussing overarching document types, such as products. In Sanity, the content model is created in code to involve developers and enable versioning and customization. The schema.js file organizes the schema types, including fields and content types. The product schema demonstrates the input type and fields. Built-in field types like array, block, boolean, and date are available. Setting up forms in the front-end interface is not possible, so it's advised to do it in code. Adding a post type involves creating a new file and defining the schema. The content is instantly available on the API and can be queried using a JSON query language.
7. Setting Up Document Types and Fields
We can set up a document type with a primitive field type like a string for a short description. We can limit the content using rows and add properties like 'hidden' as a Boolean. Adding a description is helpful for SEO and can provide guidance for editors. Sanity allows for more advanced content types like objects, which can be nested and include fields like name, bio, and image. We can create a separate author document type and use a reference field to connect it to the post.
So now we can like set up on you document type with kind of like what we call a primitive, a field type, like a string is kind of like pretty simple. I'm trying to look at the notes and like at the same time. So we can do like, why don't we do like a short description or something? Cause then we can show like how you can limit like by row or something, when you want to limit the amount of content that should be in a particular field or something before we get into validation. Yeah, like a short description or something like that. That's the we have an excerpt where you can name, right? That thing typically though, you want those to be a bit longer than just the single line. So we can go into the documentation and find that we have a text type and that's just kind of plain text, but it will give you a bit more space like this. But now we're thinking if you want to have something in between, right? Yeah. So if you go into documentation again, we can see that there's properties and properties are kind of like the keys you can put inside of these objects. And we have something called rows. So we can control them by how many rows there is. So let's say five. Well, it's smaller. I'll turn off Grammarly. We don't need that now. I know Grammarly is so intense, but we love it. Yes, got it. I'm with it. I'm finally like putting the docs links in here. And like, if you want to have kind of like if you want to make it possible to hide the posts for some reason, I can say hidden and insert a Boolean, for example. And that's another primitive type. And this is kind of like pretty basic stuff. Like to make it something that's actually maybe helpful for editors, maybe you also have like organization have kind of like a tone of voice guide or kind of like content guide, we can start to bake that in to the interface. So a pretty typical thing to do is to say like added description. And you can say something like make it informative. Remember, this is important for SEO. Like SEO is pretty important for a lot of organizations and it can be useful to remind people about that. There, you can see this description just came up. The same title, like. What are the best practice for title length for SEO nowadays? Short, it's usually short and somehow short and still discreeting. Yeah. Cogency. Yeah. Depending on where you work, it can, you can allow yourself to be a bit human in this Yeah. Not this too hidden if you want to preview, for example, if you have some kind of preview mechanism. Right. But it's also just one of those things too, where if you have a specific way or, you know, system in which, you know, your specific organization does things, the description is also a way of like putting, building in instructions and guidance for editors and best practices, not just like, oh, reminders about SEO, but specifically remember this is how we do this specific thing. Like that's why this field in particular, I think is super helpful. Right. Yeah, I agree.
So this is kind of like pretty basic stuff. What's pretty neat about sanity is that we, you're given almost like, you can express pretty much anything, I think, because we also have some more advanced content types or field types. Namely we have something called objects but let's say you can like, yeah, make an object kind of thing. Like a lot of CMSs give you kind of like a JSON type, for example, to paste JSON inside of it. And that is not super editorial-friendly. So we have tried to kind of like make it possible for you to collect, express these more nested and complex structures that you may want to have either because it's kind of like a requirement or the data comes elsewhere, but like translate that to reasonable offering interfaces. So what would be a good object structure to make here? I'm assuming you're asking me? Yeah. Yeah. Well, I think since we have posts, a good one could be like authors because we already have a person, right? Don't we have a person post type? We didn't make that yet, we don't. Right, but we can make a person, right? Yeah. And this is also an example of how you can kind of like develop content models pretty efficiently in this way. So let's make, this by the way, this is the classical kind of a mistake, you start off by making an author field, right? But let's just do that. Like author, we know that an author has different properties and bear with me, I'm just doing it in line of the posts now. Object, an object has fields, so this is kind of just the same pattern as we saw with documents. So they have a name, I guess. That's a string. Other things we want to embellish the author with? Maybe like a bio. Yeah. That's a great one. I guess that can be text. What else, maybe like an image? Okay, it can be a quotes photo, since it's an offer. Yes. That's probably good. It's inline, so we don't need a slug. Yeah, it's inline, but that means that we would have to fill in the author things for each post. Right? Yeah. There might be the odd chance that it is the same author for a lot of these posts, so it would make sense to, I don't know, have this as its own content type, I guess, or document type. Yes. So, let's say, okay, we found out it makes sense to do that. So, let's just cut this out of this thing, make a new file, call it author, and we can make this a document type. And then we can go into the schema.js, import author from author, add that to the array, save. And now it should appear as this author document type. Okay, let's go to Unsplash and find a person. Let's go with her. Yeah, she looks great. Oh, this is an iced duck. What? What? It's weird. Oh, right. Let's just copy this image and paste it. Right. And this is one of the things I like with sanity that you can just kind of like copy and paste an image and you don't have downloaded and uploaded and so on. That's pretty neat. Right now we have an author. But what about post? So what we can do now is to add something called a reference field. And this is where structured content really comes in, because you can make these connections between different content types. Let's still call it author. By the way... No, that's way better. Let's use a reference type. You can find it here in the documentation. And we can see that there are three required fields.
8. Type name and Array Field
We can create an array field to handle multiple authors. This allows for flexibility in case more authors are needed in the future. The array field can hold complex fields or object fields. We can nest fields within the array and the studio will adapt accordingly. When working with images, it is important to provide alt text and captions for accessibility and SEO purposes. The image field in Sanity allows us to add fields like alt and caption to provide this information. Additionally, we can use the options feature to make fields more easily accessible to editors.
Type name. I have those. And two, because it needs to be referenced to something. And it should be referenced to the document type called author. So now we can see that we have this new field that gives us this dropdown, and we can choose this author. And if you look into the data, you can see that the author has this type reference. And this would be the document ID of the author I just made. And to show you how this works, if we have post, I would have to collect both the draft and the published post. Just let's make that. Let's just publish this post, make that a bit cleaner. Then you can see that we have this author here, but the information isn't useful, so we can kind of prove, prove that it works by joining in that data and then here, you can see that we have the author documents. I can even do stuff like selecting only the field we want. And what's really cool, I think about objects is this was sort of quick, you know, use case, but on a grander scale, you could have had like an actual person document type and fed in all of the person data into, you know, this author thing where you could just choose from all the different you know, this author thing where you could just choose all of the people, cause not all people are authors, but some, but you want to have all of those people available in as an author. So that way you don't have to, like, you can just kind of transform data that you already have into something else. Yeah, that's, that's a pretty good point. Like authors is probably a bit too specific. Right. So, I'm going to just do that. Oh, you don't have to change. Okay. Let's leave it at this. so the mistake I refer to is that we tend to assume that there's only one author, but they, and then it'll go two or three weeks and then there's the, the thing where you need more authors, right? Because someone wrote something together. And that's where the array field comes in handy. And this is a repeatable field is sometimes called. So what you can do then is to just move this author reference field inside of this array. It has an array of like types. Let's see what happens. We got a new field and we also got like this and on field found because we removed the field it doesn't delete the data. The data is still there, but the studio says like I don't recognize this data in this document. And this is kind of like. Uh, pretty, pretty normal when you do. This development, like ideally you should maybe have planned out that content a little bit more beforehand. But if you just want to connect like this, that's also certainly possible. Um, this isn't this, this is pretty easy to, to kind of like, uh, um, recreate because we just have one document. But if you had like a hundred documents, uh, there's a pretty simple way to script that. I'm running a migration script and collect and move that data around. We won't go into that now. But yeah, but I will just remove this field for now. Um, we can go in here and we can enter. Like this one reference. Uh, Um, you can also do like this. It kind of does make sense, but it's a good showcase to show you some validation out there. Yeah. Yeah. So this is the array field. Um, a ray field can collect, uh, hold also complex. Fields or object fields. And this case it's a reference field, but you can put in anything you can also have an array, but an object field that has an array and so on. We can go and nest that down and the studio should be able to adapt. Right? Yeah. Hopefully. Are tagging along maybe where are we? Should we go into building out the the image for a little bit? Yeah. Let's do that. Right? We can do. Do you want to do like the logo one? Or do you want to do all text and caption? We can do all all text and caption on the author photo, maybe. And let me see. Yeah. Okay. Right. So We had this photo. And if you like something that has become, or it has always been important, but now it's kind like important for more reasons is that all content, software, and all photos and images on the web should have all texts. If you don't have it, Google will punish it for you. And you will also exclude a bunch of people who can't necessarily see the photo that you have. So it's kind of good practice to always have all texts. And you, sometimes we also want to have the, the option of actually having a caption, right? And those can be, those should be, it should be possible to make those different like different strings. Sometimes an old text is more descriptive than a caption and so on. This image field it's called image. It's kinda like an object field with some special properties. So we can actually add fields to it. I can say alt and that's string. If I say no, there should be another button appearing here where I can, yeah, add this thing. And if we want to caption, we can do the same. And then I, some, I, when I do this, I sometimes like my editors would say like, I wish those fields were more easily accessible. So if I want to make them more access, easier to get to, I can add this option thing and a lot of the built in fields with sanity has an option with different configurations you can have like when I'm setting this up, I can just you can have one of those are highlighted it's not the most obvious phrasing, I can type when I'm living, but just go and copy. Paste. Like Oh, haven't we document that? I don't know. But I can spell it for you. Uh, no, of course. Yeah. It's kind of like in the fields options. Um, so we have Oh, options. Yeah. Okay. Well now we have this field here. Um, and it seems like an, actually need to have title there. This is a small bug that we found. Right. That's funny. Cause I, I guess I've never done it without putting the title there. Yeah.
9. Image Fields and Validation
We can add options to the image fields themselves, such as hotspot and cropping, to allow authors or editors to choose the most interesting part of an image. The studio provides tooling to make implementing these features easier. Validation is a crucial aspect, and we can use the 'required' rule to ensure that certain fields, like alt text, are filled. We can customize the validation error message to provide helpful explanations to editors. Additionally, we can set maximum character limits for fields like titles and slugs.
10. Validation and Field Types
And again, that, again, I keep bringing up the slug, but that's obvious. You would definitely want to use maybe a validation, a unique validation there, perhaps, depending on what you're doing, but slug is usually a good place or something like that. Yeah. I think even I think the slug, the slug is also, like, somewhat special thing or like on field. Some some CMSs will just kind of like, just use a string field for your slug. But we made a built in type called slug. Oh, that's right. And it had some options. So if you just like do, Oh, I'm doing something wrong. Yeah. Um, so this is kind of like, it looks like a string field, but you can see it at the has this kind of like object structure and this is, this is future proofing to support historical slugs. We don't do that out of the box now, but like, that's why. Uh, but you can also set it to have some options so you can choose a source for example, so if we would choose the title field, then we get this generate. So we can, like slugify this field. Um, and it also has this is unique property. So if we want to make sure it's unique across all your posts, we can. Uh, add this, it takes a function, right. That's, that's, but there's some example code here to actually make it, uh, to, um, to, to make that happen. And you can also insert your own slugify function. If you, um, if you want to do that, if you have some custom, uh, requirements.
I think we are halfway in. At least yeah. Yeah. Yep. Yeah. Cause I think we go for another hour hour. Yeah. Yeah. So any questions so far has this been kind of like possible to follow. Yeah. Are we going to cover later in the video, showing how this, these objects go from this to being placed on the page by developer? I didn't plan to kind of like show how to implement it because it's pretty much, it's pretty much getting kind of like JSON data. Okay. If like, if we have time, I can kind of like show you maybe like a mini proof of concepts, then next or something, but it's, it's pretty straightforward. So if you like, if you connect to this, the, the GraphQL API, it's kind of like the same data that you get out from a GraphQL API with fields and, and values if that makes sense. I don't know. Yeah. I don't know too much about all your backgrounds, but, but it's kind of like what's, what you are used to in the React world everything is JSON. So, yeah. Right. Should we go into initial values? I'm looking at you, Lauren. I know, I think so. Yeah. Yes. Let's do that. Let's let's look at vendors and we can talk about. More field options, right? Take me through it. So let's say so in vendors, if you have vendors, for instance, maybe when you're coming up and you're thinking about what fields should go in your document type, for instance, and what your content model should ultimately look at look like. Sometimes in terms of editor experience, you might want to use data, or you might in terms of editor experience, you might want to build in some fields for consistency or that help consistency. And one of those things might be, let's say your vendors have specific regions, right? Well, that's not necessarily a string field that you would want people to have to type in all the time because regions don't really change. If you have vendors, they probably come from, you know, if you have six regions that your company deals with, they're not going to change. So you probably want that to be something that an editor or content person just selects all the time. And that way you don't have to deal with inconsistent data of, you know, upper lowercase things, misspellings, all of those things. So then you can build that string field to be, you know, sort of a drop-down instead of just a text string. So we're going to show you how to do that.
11. Building Dropdown Fields with Initial Values
To create a dropdown field instead of a text string, define a string field with options configured as a list of predefined values. Set the initial value to automate and save editors time. The initial value property can be set at the field or document level. Initial values can also take functions or promises. Initial values are powerful and can be used for various purposes, such as setting default values and automatically inserting data from external sources.
So then you can build that string field to be, you know, sort of a drop-down instead of just a text string. So we're going to show you how to do that. Yeah.
What's useful when you kind of build these for fields and so on, is to start by thinking about the, what is the data type I want to end up with and this, in this instance is actually a string, right? Yeah, so let's start there. So, it was region, the type was string. But as I said, you want to kind of constrain this to just some, some specific options. And what this string field has in its options? Configuration is something called list. And here you can build a list of redefined values. Now I'll do a bit of cheating and just copy paste it. Like that. We're rapping here. It's, it's awesome. By the way, this studio is responsive. It also works on, on your phone. So here we have this list. And then this string field was coming up as a combination of all the values I had mentioned, with all the names and all the conditions. This springfield was transformed to this dropdown. There we go. How you have kind of like constrain that to only be. These regions and here you can see that you can have collect a title. This is the, the editor view. And you can have collect its own values for your data. So you can say for example, United Kingdom. And so this says United Kingdom, but it's UK in the actual data. So now we have consistency.
I guess, like let's say that your e-commerce you usually have vendors in a certain region. In a certain region, like most times it has like it's, what region should we go for, Lauren? I mean, probably like the UK, right? This is like a London based conference. Yeah, let's say UK, like that is like 98% of the times the vendor will be from the UK. So let's automate and save our editors some time. And we can do that with something called initial values. Some people call them default values, but we call them initial values. So you can add this initial value property to this field setting and we can say UK. That should work, I think, I hope. And what happens now, if you make a new vendor document, you can see that this field is predefined, as United Kingdom or UK. It's also possible to do it on the document level. So if I remove this, and I already say that this was also removed, because now it's kind of in this new document state, you can say initial value, and then we can just contact insert the, the object data. So we can say region UK, and this will be, this will work the same way using it's maybe a pro, Oh, it's just me miss typing it. Yeah, there you go. Yeah. But then we can also say, title. Vendor. I wouldn't really recommend having initial balance for string fields because it's easy to forget. Because it's easy to forget to change them if they should be changed. But it works. And what's good to know that initial value can also take functions or promises even. So if you want to look up a value from elsewhere, you can actually return a promise to this. So it will come like. That's something from an API and I'll insert it into the document. Let's say like a practical example is for example, post. Let's say that you like like blow is come like. Like one, like eight of 10 posts will be written by low. And sometimes the CEO will write a post. But to optimize this for low, we can. We can also put this as initial value. But this is this is and this is an reference. And so what's what I usually do then is to kind of make this initial state, I guess and go into inspect. And then I will take this object and just copy paste that into. Natural. Oh, yeah, let's let's do this first to see collected distinction. So now put it put that into the author reference field inside of the array. So if I make a new post. Nothing is there. If I say, add item, it will just add an item. But add item, it will automatically be this data. So that isn't exactly what you want, right? We want that we want this data to be there when we make a new post. That means I need to move this. I can move it to array, I guess. But then I just have to remember to make this an array too. So if I make a new post, it should be translated to this data. I didn't even know you could move it to an array. Yeah. So the, like initial values is, it's pretty powerful. There's a lot of things you can do with it. Like you can use, you can use the, the, the browser APIs as well. Like the browser can ask about your geoposition, for example. So if you want to like automatically insert the, the geolocation of where you are, when you make a post, you can, you can do that as well. I want something for those complex... Yeah, don't. Yeah. You can have... Press me. There is videos. There is a video for that as well in the guide. But that's initial values. For example, initial value true, if you want to have it automatically hidden. So you don't have to remember that. Do you show how you can also set initial values for image fields maybe? Yeah, we could. It's kind of like the same principle. So we have this author thing. Let's say that we want to have this placeholder image.
12. Creating a Gallery with Array Field
To create a gallery, we can use an array field to hold a list of images. This allows for flexibility in creating a gallery or carousel. The array field can hold complex or object fields, and we can nest fields within the array. We can customize the field configuration and reuse it in different parts of the schema. Document types can be customized and grouped as needed, and the back end adds special fields like 'created at'.
So how I would go about doing that is... I guess I would go to Google Images and Person Avatar. and find something that's pretty neutral. This one, maybe. Yeah. Copy that. Paste it into this. How does that work? It's working. It's an SVG or something. Oh yeah, it could be. I was holding the. SVG doesn't play nice with the copy thing yet. Anywho, so now I can't upload this image that I can go into data, and I can copy this proto data like that, and then I can paste it into the initial value. So now we should be able to make a new author, and it has this preset. Yeah. And we can do a quick, we can add on alt. On. So you could see that this is pre filled. Yeah. I mean like this would be pretty useful again like because we turned. And we had author as a separate object, because maybe if you're using person data maybe this author image is a different image from the person's actual thing so then you could have it totally like you just have now a different image, even though it's the same person maybe it's the same person information but we're just going to change this image. Great. Yeah, and now also see like potential because we have kind of a pretty advanced image field going on here. Yeah. And currently it's inside of author. And, but it makes sense to have kind of the same settings elsewhere. Mostly at least. Again, we kind of did this in the start, but I want to show it again, just to kind of like give you the sense of how you work this in real life. So now I will just copy paste the whole thing, the whole photo field. And I will make this figure something. Sport. And then I will go and change some of the things like the name of the figure. I will maybe not have this initial value thing. And then I will keep the rest. Yeah. And then I can go into schema. And figure from figure. That's to our array. And what I can do now is to go back to the author. And I can change this type from image to figure. And this is the name that we defined it could be anything I could call it I could have called this taco and referred to it as taco. It's kinda like it's up to us, but it's good to make it something that's kind of like obvious. And then I will go and delete his fields because I don't need them anymore. I will keep the initial value, because I still want this in the context of the author. I don't want that anywhere else, because it doesn't make as much sense. And now I should be able to save. And nothing should kind of change. Yeah. Yeah. patterns right now you can use it anywhere. That means that if you want to have kind of like main photo or main image for the post, because we don't have that right, then I'm gonna go in here and we can say main image, type figure and have it be a main image and we can reuse that field configuration here. So this is kind of like keeping it dry. In a way. I think one can like built out image field, that you can change, which if you change that there you can take that anywhere, and it's for defining our own types Can you say more about that, I'm not sure I understand the question, but what specifically is for defining our own types. Yes, it is. So it doesn't need to be document types over always it can be collected specific few, like you can be anything like, okay, you had to go like, if you have a string field that you're like you can even import that into the schema js and referred to it. Yes, I see. Yeah. Yeah, yes, I get it. Yeah. Hopefully that makes sense. Yeah. Yeah. Usually like I try to distinguish in like between these types and like document types is normally like these type of things like figures you would never actually see in like in the studio, it's just something that you would sort of reference document types it's like a helpful document type, but we call them object types. I guess. Yeah, that's true. If you collect squint the bit a document type is, it's kind of actually just an object has some has some special features, like it will be listed in this list, and the back end will add some fields to it like created at, and so on. So, conceptually it's it's kind of like just objects, all the way down. Yeah. Because the the Jason document is an object right. And by the way, maybe we actually have time for that like this document lists, like these pains are also totally customizable you can change them and you can make your own document groupings and you can say this old products by category and so on. That's kind of like something you can access in code and change as you want. And. Right. So now we like we did go through initial value. And we have, again looked at like, we call this hoisting like like lifting up the content type importing it to Js and make it like preferable elsewhere. So what's interesting. Do you want to have conquer gallery. Right. So you have product, I don't think it has gallery already. I don't think so. Right. Sometimes that you want to have a perfect gallery right doesn't even have an image, or you actually have a good beginning in here. Oh yeah and the product area. Yeah, that's true. Yeah. And the gallery. If you think about it again like start by thinking about data types, it's kind of like a list of images right. So it's, it's an array. Of course, this is the easiest way to make a gallery or a carousel or whatever you want to do.
13. Image Field and Customization
The image field in Sanity allows for easy selection and manipulation of images. The studio provides a preview feature that can be customized for different fields. You can map content to different parts of the preview, and even use a prepare function for further customization. This level of control ensures a tailored and efficient workflow for content creators.
And here you will have the image field. By the way, let's do a small detour, because one of the hardest parts of kind of setting up a common system, having some like you want to fill stuff with content to kind of have something to try it out with. When it comes to images, that's kind of a pain. Sanity comes with a bunch of plugins. If you go to our site, you can find... Oops, sorry. You can go to Tolson slave plugins. You can install them in the studio, by typing in sanity install. This is kind of like just NPM install. We also have some under the hood. But we have some called asset source and splash. Because you can add more asset sources and you can even write your own asset sources. If you have kind of a custom dam or look at digital asset manager, you can make an integration towards that. Or you can do an integration to unsplash because it's just so practical. So now we installed the unsplash plugin. And if we reload the studio. Now we should be able to select and splash. And splash and then I can just select this and get a bunch of images pretty easily. But now I just use this image field right, this is the basic image field. And we know that we already have a figure. So why not just use that figure thing. So here we have the, all the fields we want right. And then we can go. This is caramel. Oops. Right. Delicious caramel. Boom, there we go and then we can make sure we have the most interesting part. And so, here we see that we have this entitled thing going on. So, the studio makes the kind of best effort of preview previewing things that are inside of objects and enlists and so on. If I have a build called title. Let me take that, and so on. But sometimes it can find something that sensible, and you end up with this and title thing. But here we can collect it makes sense here, maybe to have caption as the preview. Oh, there we go. It already found caption, but let's say we wanted to have the default as the preview, right? We can also overwrite how this preview works. Let's say we want to do that for all the figures. So we go back to this figure type. And then we can add a new property called preview. And it works... There's documentation on this as well of course. But it works by having you select some data inside of this field. And this is the object field. Select. You can map some content to different parts of this. Kind of like a UI element. What you typically have. Here you can see that because I... Because this autosaves when I remove focus. Now we can see the preview disappears because it's just an empty object. The name of this is all. And the media. I'm not sure how that works actually instead of the image field. That's an interesting, interesting little. Big at least got that. Is it maybe asset. Yeah. Yeah, I don't know if it's not obvious but no, but it works. So that is kind of like how you can map different fields to this preview. Sometimes there's a subtitle available I'm not sure if that's the case in this. There we go like you can also add some subtitle to this. Sometimes you want to have even more control over this preview. You want to do some string manipulation or whatever. And you can also do that with adding this prepare function. And the prepare function takes the this select object. So now we have access to title media and subtitle. And here I use collect object destructuring. So another pattern it would be to do. Props sorry const that and then you can return again type of media so terrible do like that you will see up. This is the data right so I can say whole text I can just return these yes this is how we can like customize it even more and again like you don't have to do it but it's pretty neat when you want to do it and there's a lot of opportunities especially if you sit down with your editors or your content team and talk about this there's a lot of these opportunities to make this just better and more customized to what they actually need and want especially if you have kind of like larger content teams that needs to be aligned you can kind of bake in the direction and so on that that people need. To make the best content and so on. Yeah. Their whole workflow, basically. Yeah. I actually want to make this. Actually, I caption. This old. Here we go. Here you go. Okay. Small pro tip, by the way, when it comes to this. Like this pattern where we have an array of images, I hope this works. Let's see if it works. Because say layout. I think you can say grid. Just realized. Maybe it works. Hopefully. Yeah, there we go. So now you have kind of a better view for a gallery thingy.
14. Deploying the Studio and Syncing Data
In this part, we learn about deploying the studio, inviting users, and syncing data between local and remote versions. The studio can be hosted anywhere, and multiple studios with different configurations can be connected to the same content. Each client should have a separate project, but a single studio repository can be repurposed for different projects. The sanity JSON file contains the API configuration.
15. Deploying Code and Driving Multiple Sites
You can deploy the same code and studio for different clients with different projects and billing. Driving multiple sites depends on content modeling. You can create a site document type and reference it in posts to query data. The tool is adaptable to your needs.
So that means this can also be kind of like inserted with environment variables. So that means you can have one Git repository that deploys to multiple like Netlify projects and each Netlify project has the project ID of your client. So that means you can have the same code deployed the same studio for different clients and they can have been different projects with different billing, even plans and so on. So that's one way you can look at it. And in terms of driving multiple sites, so if you have like localized sites or you have an advanced organization that has like a lot of properties, like we work with Unilever, they have like 26 localized sites over the whole world and like 26 full web sites that's mostly a matter of content modeling, right? So there's a lot of ways depending on what you need you can make that happen. So you can, for example, make a site document type that holds kind of like all the information like all the global information of each site, and then you can make a post that reference that site and you can start kind of like querying the data that way and we can build out, you can customize this list to have kind of like all the sites listed out and all the relevant content to the sites based on references, for example. So that's more kind of like, not that more advanced but slightly more advanced topic that we maybe can have another webinar on but it's certainly possible. And it's all for like, we have tried to make this tool adaptable to whatever you need, basically.
16. User Roles and Conditional Fields
There are built-in roles and custom permissions in Sanity that allow for fine-grained access control. Conditional fields can be used to control what editors see based on certain conditions. For example, fields can be hidden until a specific condition, like the presence of an image, is met. The hidden property can be set to true to hide fields, or a callback function can be used to define more complex logic. The callback function provides access to data such as the current user, document, and parent. By leveraging conditional fields, editors can have a more tailored and efficient editing experience.
The next question is about user roles. Yeah, so there's some built-in roles that comes on most of the plans and then we have something called custom permissions where we can get super fine grained with like, who should have access to what? And that's an enterprise feature, but basically it lets you define like this group of users should only have access to posts that has the main image set. You can make rules like that. You can make super expressive rules. So yes, in short, yes. And if you want to make kind of like a, more like a home grown version of that, you can of course kind of make these multiple studio configuration and only expose the things you want to expose to certain users. That's a bit more on you, I guess. And it wouldn't prevent them from making those changes through the API if they knew how to do that. But that's kind of like the way to maybe get around that. But it also takes us to conditional fields, I guess. Yes. Yeah. So, did we have a good case for that? Sorry, I don't have notes in front of me. I think we did. I mean, like one of them was we could show not showing the product variants before there's a default variant, or not showing image alt fields before there is an image, which I think we kind of, yeah. Yeah. We can start with that. That's gonna become a more simpler case. Yeah. So let's say, so when you do structure content, you tend to end up with a lot of fields, right? Because you are trying to describe the shape of your content. And, a lot of times the fields aren't always relevant if a certain condition hasn't met, kind of. So you can control what editors see. And so, for example, you don't really need to see these fields before you have the image, maybe. So let's make that happen. I just wanted to remove that in a little value. And I guess also image. Oh, I'm looking at the remote. There we go. All right, so what I want to do now is a hide this field. If there's no image that. So I go back to figure and then I go into these two and I add a property called hidden. And hidden can take a billion so you can say true to hide it. And this is useful when you like we are in e-commerce now, what we, like what a lot of people do is to sink. A e-commerce data or like product data from Shopify and augment that with like their custom content. Um, and then you have a lot of fields you don't really want anyone to change because they are synced from Shopify. So one way to kind of like make them, um, um, hide them from, from editors is to actually just say hidden true like I've done now, so now the old text is hidden, um, but this can also take a callback function, so I can say. Um, return. True. This is the same. This is the same thing that I had, but it's not super useful. The clue here is that in this callback I get some data. So let's look at what data I get. So now I'll just log out the data I get. This probably not. So here we can see it out in the hidden callback. I get current user, I get the document and the parent and the value. Um, no, there's no, nothing in this document. So let's say Knut. Oops. Oops. Um, and then we can see it out. The document has Knut in it. Um, and now I can start to make logic on this. Uh, so what I know is that if I insert a photo, or I can, I can actually just show you, right? So when I have a photo, it will have this photo property with assets. So what I can say inside of this, uh, and by the way, this also takes something called parents. So we can collect CD parent. Field that this field is in and the parent is the asset field. So I don't have to go into the document actually to find what I need. I can go into parent and I can see that assets is kind of like the thing I want to look for. So I can see if, if I set, if that's true, then I want, then I don't want to hide it. So the logic here is a bit inverse maybe because of your hidden is true. Then it will be hidden. If, if hidden is false, it will show. Right. So if assets is true, then this needs to be false. Let's see if we can do it kind of like false-ish things here. So if I what correctly now it should show. Yeah. So now it shows because I have an image here. So if I remove this, I guess, asset isn't completely removed. Oh no. Doesn't it break have to do like this? What did I do wrong? No, it's called, isn't it? Oh yeah. So it's props. Good, is props asset. Good one. No, it's, it's not. It's I'm now I'm losing. It's it's the demo God, slash just live coding. It's hard because two things I think it's, it might be it. Yeah.
17. Conditional Fields and User Roles
And so it's parent dot asset. There we got it a bit too faster. Right. Now it should work out. Oh, no. I think I have to, yeah, there's something else nested in there. This happens every time. It's it's the demo God, slash just live coding. It's hard because two things I think it's, it might be it. Yeah. It's undefined because I'm, I'm straying from what I should be doing.
18. Rich Text Editor and Portable Text
In this part, we learn about the rich text editor and portable text specification in Sanity. The rich text editor allows for easy formatting of text with options like strong and emphasized. Portable text is a way to express block content in a JSON structure that can be queried and serialized in the front end. It enables mapping different parts of block content to React components. The data structure of portable text consists of an array of blocks, with each block containing children and spans. The clinical library in Sanity makes it easier to define and map different parts of the text to components in the front end.
Um, questions, I guess you, if you have questions, you put them in the chat, but I also don't want to kind of like just go too fast. Yeah. And we're a relatively small group, so you can unmute your mic and ask them to, if you would like, do you want to do the product variant one to Canoe sure. Um, let's do it. Yeah. So what we want to do is to hide it. It kind of like makes sense maybe in this, because there's a lot of things going on here. So here we have this default variant and we have variants. Oh yeah. So you want to hide this field if nothing here is entered in, right? Right. Right. So, all right. Then we need to go into the variants field configuration. Let's see. Hidden. I guess we need to change our password. We need to have value so we can show it if there's anything that has been written in the Iranians. And then we need to go to document because these are considering fields. So, if there's a value, don't don't hide it. Right. Right. And if there's a value in document and then I use this optional training, so we don't get a count read the full product variant of undefined if documents for some reason is undefined then we take this field and look for that I look for that. Yup. That should be it, right? I think so. Yeah. So now we shouldn't be able to see variants. Nope. Yeah. That's correct. Unless we say, pick lunch, some Norwegian chocolate. Um, there'll be a variance. There we go. Good job. That was a quick one. Um, right. I wonder if we did it for conditions fields. I wonder if we actually have time to go into, uh, you can go either into the rich text field or into structured builder, um, what's do the rich rich text field. I feel like that maybe. But you want to do structure builder? No, it's we. No, I think, uh, maybe we'll check this more useful. I think so too. Yeah. At this point at least. Right. So, um, I guess post is the most obvious one because what is the post if we don't have actual content? Yes, so rich text is a huge topic. Um, and for over 20 years or so, we have done rich texts. In CMSs by having some kind of markdown or HTML editor going on. And if you have ever tried to move out of a WordPress site, you know, that that can be kind of a hassle because plugins has kind of like inserted a lot of. Uh, I call it junk, like a little of like mark up and like class names and whatnot, into kind of like the content and maybe people have copy pasted some stuff from word. I guess WordPress may be does a better job with that stuff now, but like you can find a lot of things and set up that HTML, that isn't helpful. Um, so one of the core design principles when we built sanity, it was like, we should never store HTML in your content back end, um, not only because it makes it kind of like hard to break it, but especially now, when you're doing react, if you get HTML through the API in react, you either, we have to collect parse it and kind of break it down to make it malleable, uh, or you have to use like dangerously set in their HTML. And then you can like lose control of what happens inside of it. And you have to collect, set this. Yeah, passes a side and so on. It's, it's, it's a mess. Um, and so when you have something like react, you want to have use your components and you want to have data as props interdos components, and that also counts for rich text or block content, because people not only want just formatted rich texts, they want to have, to be able to sit, sit in like images and maybe a call to action. And newsletter sign up, like YouTube, YouTube embed, whatever. Uh, so in order to make this happen in a sensible way, we made a new specification for black content called portable text and what portable text is. It's kind of like a way to express. What content, like, like, like what you have in motion or, uh, or a Gutenberg, I guess, and so on. But like embed that in Jason and a Jason structure that you can query and so on. And that you can come serialize near front end and map different parts of your block content to different components in react. So, uh, what you don't want to, like, you don't want editors to have to write Jason, right? Uh, so we needed to make an editor and that's where I'm going with this. How to make that editor happen. Um, and what's interesting is that block content is again, the data type. It's an array of objects of some certain kind. Uh, so to make a rich text editor instead of the San Jose studio, you say a buddy, I guess. The type is actually an array, but it is an array of blocks. Let's see what happens. So if I say array of block, what you get is this rich text editor. Um, it works like pretty much as you expect. You can make things strong or emphasized and so on. And you can, it also comes with this assumption that you want to make a link. So for editors, this is familiar. Um, for you as a developer, let's look at the data structure. This makes, so this, um, here is the content that I just made. It's a bunch of Jason. And that, this looks a bit daunting the first time you say it, like how should I even wrap my head around this? It was for me. Uh, if you can like take it bit by bit, it can like, it's a, it's it's, it's it's kind of logical because what I have here is, um, and like, it's a, it's two blocks, I guess it's two paragraphs. So here's the one paragraph and here's the other paragraph consists of children of spans. So here we can see, uh, the first span is hello, and it is marked up as the strong. And then we have world, um, which is marked up as like emphasis. And then we have the explanation point was what she isn't marked up. And in the second paragraph we have kind of like, here's a link, um, the link has this reference to something called the mark definition, which holds our link data. Um, and what's interesting with this is that this is like, um, if you have a front end, we have a clinical library that makes it more easy to define it. Um, we have a clinical library that makes it more easy to map different parts of this text to components. So in your front end, you can say you can kind of like make a map that says if you have a mark def call Link, then you should insert, uh, this link component. Um, use the age graph data for the actual link, I guess. Um, I can maybe show that a bit later, but, um, um, this also makes it query for this data so you can kind of like, now you can say, it's gotta cancel. Give me all posts that has a link with Google as the age, ref property and so on, or give me all posts that has at least more than, um, eight spans that are emphasized, so Harry can start to see, collect what database logic you can bring to stretch content once it's actually structured.
19. Customizing Editor and Rendering
Sometimes you may want to restrict the options available to the editor. Customization is possible, allowing you to create your own values and customize the rendering of different blocks. The power of repeated patterns is evident, as we can reuse objects like the figure object for various purposes. The difference between API CDN requests and API requests lies in caching. API requests connect directly to the backend and are not cached, while CDN API requests are cached and provide the latest data. Custom renders for pipes are possible, and React can be used to customize the rendering.
Okay. Um, sometimes you want to come like restrict what options your editor should have here. Maybe it shouldn't be possible to use bold, and then you can start to customize this as well. Um, so, yeah, this, I haven't, this, I haven't actually done for a while. So if I go to blog content, Because I'm a station here. You can see all kind of like the different, um, properties. So I can say remove that only leave emphasis and now it should only come like, give me the, oops. Yeah. I only have the emphasis, um, and we can make also, we can make our own, we can, if like it doesn't need to end up in HTML or like web page, even, you can end up anywhere so you can say like highlights, maybe you use this to collect, print a book or something. I don't know. So you can also make your own just, um, customized values. Customized. I'll use. So. now you can say, no, this is highlighted, but there's no like we haven't inserted collect how this should render. So it's called hidden, but, um, if you look into the, to the can see that it's marked up with highlights. Um, to make this block content, we can just add more items to this array. So I can say, uh, type figure and save. And then we can also make this a bit larger. Then I have this plus button with the figure. And then I'm going to insert images like this, I'm can drag them around and so on. Uh, so that's pretty obvious, like, uh, uh, on the image, but you can also make your own. Um, so let's say we wanted to have a call to action component. For example, uh, a CTA. Uh, that's an object. It has some fields as a title. Yes. Or. That would call it. Um, it has an URL. Yeah. That's a pretty simple CDA I guess. No, we have this CTA. That's actually make this editor of friendly. Call to action. I think maybe. We can do this. I'm not sure what a useful emoji for cold action is. Yeah. When you finger think this works, or, um, maybe I have to return it as function. I think you, it's kind of like a react thing. Yeah. Yeah. Cause otherwise we have to import. Yeah. So, uh, there we go. So you can use emojis and so on, um, or like a rack icon library to also customize these icons, which you should because that's nice to have every like have, um, So this is a cold action block. Right. And again, if you go into the data, we can see that we have, here we have this kind of like neat structured content. And this, this will be kinda like a simple to map to, um, call to action component in your front end. So if you are familiar with collect MDX, it's kind of the same principle. Um, except you don't have to actually remember to write that component code inside of the, the content. But you got to collect this data that you can map to props in your RAC components on the front end. Yeah. But we also still, again, like see the power of like repeated patterns, right? Like we made that, we made that one figure object for each of the figure object and now we've used it like four or five times in like, you know, different ways. Exactly. I can see a question here. Like, what, what's the difference between API CDN request and API requests? Um, so, uh, the difference is that, uh, API requests are, they go connect directly to the, the backend. Um, so when you're like, um, they aren't cached. That's the different like CDN API are like a cached, uh, API that goes around, like, where we have collect edge nodes around the whole, the whole globe, um, and I API requests, like they are going to direct it to the, the, the database if you want. So when you need, when you want to make sure that your data is super fresh, like the studio is like the studio wants the latest, freshest data. It will be connected to the API. By the way, the studio usage aren't include like that's free. So that doesn't go towards your quota. But when you have a front end application or a website, you usually want to hit the CDN. So when you make a query with GraphQL or a Grok you, from, from your application, you usually want to hit the CDN. So you have this cached content and, and make sure that you get it from the closest server of the server closest to you. So that's why we also find that there's a lot of more CDN requests included in the plans as well. Hopefully that explained it. Can we implement custom renders for the pipes? Yes, you can. I can show you a super simple example of that. Since we are at React Event London, I assume you are familiar with React somewhat, at least. So, a simple fast and loose way to do this is to import React. And then, you can do some interesting things. I would like to actually... So, it doesn't keep scroll precision. I just want to cheat a bit and put this up there. I don't have to scroll. So, let's just delete this. So, we have the... let's say, I want to put this. So, scroll precision. Let's delete it. So, we have this. Let's delete it. It didn't work. That's OK, Case. Let's say, I want to customize this with React. Then I can do... let me think.
20. Customizing Preview and Rendering
You can customize the preview component and make it your own using the Sanity UI component library. The library provides primitives that can be reused to create custom input components. You can also use Sanity UI to create a string field that shows the character count underneath. It's not drag and drop, but it's easy to get started and customize it to your needs. The Sandy client allows you to fetch data and render it in the front end. You can query all your published documents without needing an API key, and the client provides methods like fetch and block content to react.
Again, it's preview, select, petal. I can actually call this whatever. So I was caught URL, then I can say, component and give it a component, I haven't actually made this components. I have to make it as well. Const props that's just call it print data. Let's see if this works. Yeah, there we go. So here, you can see that kind like I took this preview and I replaced it with a custom rack component and I would just kind of like stringified the values and printed them out as come like this code. But I can also do like. I don't know, those are actually work. Can I say, I'm not sure if this works. But, Yeah, I don't know. Uh, you are all. Uh, I guess targets blank. Yes, we have to do that. No. Holy. I'm not sure if it actually works because yeah. Yeah. Sorry. No, this is me. Um, because of the, um, Hokus thing. Maybe. Yeah. Yeah. It did. Yeah. So, um, uh, if you, for example, want to have kind of a YouTube embed thing, what could make sense is to kind of like actually just render the YouTube that I frame inside of this, for example, but this kind of like shows you how you can start really making it your own. And what's nice to know is that if you are venturing into this thing, uh, we have something called Santi UI. Uh, so the studio is built from this component library. So here you have all the primitives, uh, that you can reuse. So let's say, um, let's say I wanted more of a native field field for this, uh, maybe card. Then I could do something like this. We got a mindblown emoji in the chat. Finally, it's pretty great. Yeah, it's pretty great. Then we can insert this and I can say import card text. That's the only ones right from Santa UI. Santa UI and this should probably just work, I hope. Yeah, right? Yeah. So no, yeah, this comes in a way, but here we can see kind of like there's some padding and going on. Yeah. Yeah. You get the gist. It's pretty great. I mean, we have like in our, in the sanity studio, like over our site, we have all sorts of stuff rendering inside of there, like we've got cold blocks. We've got some other stuff going on in there. Yeah. And we also mentioned, you can also make your own. Input components. That's kind of like, it's a bit more work, but if you go to Santa, I, for example, I think there is a, there's a tutorial for making your own custom input and we give you kind of like red components that takes care of all the hard things so you can make a custom inputs that supports presence, like that. You can see that other people are in the field and validation and everything and wrap that around your customer input. So here you can find kind of like how you can use Santa UI to make. Yeah. I guess some string field. It's just a simple example, but let's say you want to make a string field that shows the character count underneath. Then we could kind of like use this pattern to make that happen. Um, you could re-purpose that field across the whole city. Or if you want it to like, hopefully you get connect the sense that yes, there's coding, it's not drag and drop and click, but it doesn't take a lot of time to get going. And yeah, it's something that's useful and even start to customize it to whatever you need. Um, since I spent some time explaining portable text, I can also show you how maybe a code example of how you render it in the front end. Um, so if we go into the mutation again, hopefully there's some documentation on presenting portable text. Yeah. Here we go. Um, let's see if I can find. Oh, I know there's one for just react. Just playing react, right. Yeah. Here we go. So this is a, call it a minimal example of both college fetching data and making it happen. Uh, so what happens here? Um, this, this is the Sandy client. Oh it, Oh, we need to modernize this. I see. Um, but it's, it's pretty much the same today. So, um, here we have the client, um, takes a project ID, take the data set name. Uh, be, have an eight by version. Um, we followed the stripe pattern. Um, so you can just put in the current date to get the latest version. That's out. And then you can also choose if you want to hit the CDN or not. And that's it. That's it. To, to query all your published documents. Um, unless you have set the dataset as private, but it, it, it tends to default to public, um, so you don't need an API key and so on, uh, unless you want to access, uh, draft content, uh, and you should never put an API key in the front and in ways, but that that's aside. Um, so here we have the client that. Um, the client comes with a bunch of methods. One of them are fetch where you can give it a clock query. Um, then it will return the article you asked for. And then we have something called block content to react. And this is the library that's useful if you have portable text.
21. Block Content Field and Image Customization
The block content field takes your blocks and requires serializers for custom types like CTI CTA. The code example demonstrates how to connect blocks to CTA and figure. Images in Sanity have various features like image analysis, aspect ratio data, and low-quality image placeholders. Parameters can be used to control image format, quality, and other properties. The documentation provides detailed explanations and tooling for image customization. Join the developer community for support and to share your projects.
If you use this block content field. Um, um, block content takes your blocks and this is the array. This is the body array that we have. And then it takes something called serializers. So if you have your own custom types, like we have, like the, the CTI CTA type, then you need a serializer. Um, um, here we have a code example, but if I were to collect and set this into our example, it will look something like, let's see. Um, and then I want to oops, this tomb Chrome keeps getting in the way. Uh, and I can say something like import React from. Yeah. Oops. Um, export almost serializer so types that's kind of like blocked pipes. So that's the stuff we put in this array. So figure and CTA. Um, so that means we need. Uh, bigger CTA and that takes kind of like the node. So instead of node there's our data. So then we can say, um, this CTA returned that, uh, uh, uh, dead because want to like walk out, uh, and give us an H ref node, a trough, maybe I should look at the data just to keep you. No. Yeah. There you go. It's, it's not a trap. It's actually URL. And then, uh, take the title. There we have connect maps, this block to this relatively simple CDA code. Right. And for the figure, Oh, this is really, this is really challenging me, my front end skills. Um, Oh yeah. Thank you. We will run this code. So, but the figure that would be figure, I guess, um, maybe there's an image tag. Let's say that we have the URL. Oops. Uh, we have the OLT. Uh, and then we have, Oh, Hmm, we, I'm just messing this up and then we have, uh, uh, the good old fake caption, right? Node caption. And of course, uh, in real world, you would make this more responsible, not responsible and responsive. Yeah. Um, uh, yeah. So like we haven't touched on this, but like images, uh, you have a bunch of stuff, uh, available to you. Uh, so to give you one example, um, whenever you upload an image to the content, like, uh, we do an analysis, analysis of that image. So I can show you here. Um, so let's go to, um, so here are the recent images. So, uh, we look at, like the file. We, we, we translate beta into actual data. So you have kind of like a image palette. So you can kind of get the sense if this is a dark or light image. If like, if you want to superposed text on it, you can kind of like use this information to, to, um, control that text. Um, and, uh, um, there's kind of like this, let me see or even like all the things you can do. If it's like, cause it gives you all the aspect ratio data. Yeah. I was just looking for the, um, L kip and dirt hash stuff, but, um, any, we also collect, save a string that makes it possible for you to, um, have this pre, uh, preload thing. And any ways, yeah, here we go. So there's a, like a low quality image place or other. So you can use this in your CSS. Oh yeah. It's, it's super small, but it can use this as kind of like before rolling the image that is smooth transition. Um, And you can also enable like access data and geolocation and so on. Uh, if you want to, um, what was my point? Yeah. And also, uh, if you want, to make it responsive, you can also, um, that's a sadness image from our studio. Right. So this is now, uh, or it's like, so away time. Like it's, it's pretty high resolution. Let's say I wanted to have the two hundred pixels wide, so I can just request that. So I can request whatever. Um, let's say I wanted this. Uh, this is a JPEG. Um, I can also like make the asset pipeline and return that P automatically if the browser supports it, but I constantly say formats should be PNG. You can't see it, but it's actually a PNG, but you have to believe me, and so on. So there's a lot of parameters. You can't control. Here. Um, I can find everything inside of the documentation, of course. There's also like tooling that makes it easier to get what you want. Yeah. So there's documentation that explains all the parameters. You can blur the image, you can crop it. You can, yeah, do a bunch of things. So that's useful to know. Right. I think we have like 10 minutes left. Yep. Do we have questions? Yeah. Like conclusions, questions, or whatever. I hope this was useful. I guess we have been so lucid and so clear that there aren't any questions. All right. So, yeah, we have this is kind of tip of the iceberg kind of situation, there's a lot more things you can do. Hopefully, this has kind of like tempted you at least to try this out. If you do try this out, do join our community, like developer community. We have a slack where we have at least 9,000 people who ask for help, who offer help. The share kind of things they've built and so on.
22. Joining the Community and Project Scalability
If you want inspiration, join our community. We have regular meetups and people looking for jobs and posting jobs. Sanity allows you to spin up projects for weekend experiments or for content infrastructure in a company. It can scale with you, and I already have hundreds of projects in just 8 months.
So, if you want the inspiration, you can go there as well. People are looking for jobs and they are also posting jobs. There's a lot of things going on there and we have regular meetups and all that stuff. So, you are super welcome to join that if you want to.
Yes, and Sanity. We build Sanity to, you should be able to spin up a Sanity project whenever you have a weekend project. If you just need some JSON in the cloud, you should just run Sanity in it. Make yourself a new project, it's fine. When you actually need content infrastructure for a company, you can do the same and it should be able to scale with you. It's not only for this huge project, it can also be just to experiment and so on.
I have hundreds of projects. I have so many already and I've only been here for like 8 months.