skip to content

Set Up a Better Content Editing Experience

Using a decoupled CMS, we want to add shareable previews, fast search, and keep a great DX. Ondrej Polesny will teach us how Kontent by Kentico, Next.js, and Netlify make it possible!

Full Transcript

Click to toggle the visibility of the transcript

Captions provided by White Coat Captioning ( Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.

JASON: Hello, everyone. And welcome to another episode of Learn with Jason! Today on the show we have Ondrej Polesny. Thank you for joining us. How are you today?

ONDREJ: Thanks for having me. I'm excited to be here today.

JASON: I'm thrilled to have you back on the show and we are talking about something that is really, really interesting. Before we talk about what we're gonna talk about. Let's talk about you. For folks who aren't familiar with your work, can you give us a bit of a background on yourself?

ONDREJ: Sure, I'm a developer for Kontent by Kentico. I have been doing that for four years. I'm familiar with the APIs and the things that developers want. I used to be a consultant before then. So, I kind of speak developer and also business users. So, I sometimes find myself to be a bridge between these two groups. Which puts me in a nice position. And yeah, my daily job is pretty much discussing the solution with developers and helping them and making sure they have everything they need.

JASON: Love it. And, you know, I think that one of the things that's really interesting. And I've had some conversations about this recently. It feels like there's been a huge rise over the last few years in this idea of developer experience being a top line business need. And I'm kind of curious your why do you think that's taken such a front seat in so many company's minds?

ONDREJ: The thing is, without developers there are no websites. And I think the larger the website is, the better the experience needs to be. Because I see it in a front row seat, yeah? Also partly responsible for our corporate side. And despite having all the tools at hand, sometimes it's really frustrating to find the thing that you're looking for. So, providing a great developer experience is actually the deciding factor if someone is gonna like your solution or not. Because they can -- developers can be made to use your solution, right? In enterprises, the decisions can be made by other people. But developer experience actually if it's good, it means that the developer will like their job. They will stay happy in the position. And the quality of their work will be much better. And they will also recommend you further, yeah? So, I think that it's --

JASON: Yeah.

ONDREJ: It became really important factor of many as a solution service.

JASON: You know, it's interesting that you say that. And I feel like it's been -- it's been interesting to watch. Because, you know, I come from a very corporate background. Like I was in -- I was at IBM. And while I was there, you would kind of see that decisions got made in a -- a way that was maybe traditionally corporate. Like, you know, an SVP or somebody would kind of talk about what solutions they wanted and then you would just kind of get told. Like, this is the way that we solve these problems now. But even while I was at IBM, we started to see that shift. We would see individual teams saying, it is way too hard for us to do this job with this tool. We want to use this tool instead. And that push of developers saying, like, I want to use the tools that I want, we saw that it -- it was a big source of turnover. People would leave and say, I don't want to work on this legacy stack anymore. I don't want to be here dealing with all of this cruft that I know could be easier if we were using the right tools for this job instead. And it's fascinating to me to see that shift has been taking place where the power of decision making has shifted to individual contributors. Where if f they go into their org and they say, the way that we want to work, the way that we want to be productive is with this tool. That carries so much more weight now. And it's really become a deciding factor. Like I know that people will choose their job based on whether or not they get to work with tools they like. And given how much of a -- like an employee's market it is, companies are now heavily incentivized to be providing the right tools. That means that companies are gonna switch to the tool that developers want to use. For uses a businesses that want to get companies to buy our services. We have to provide the experience developers want or they're going to strong arm their bosses into not using us anymore. We depend on being useful and pleasant for developers to work with. It's so cool to see that happen in the market. And it feels like it kind of aligns incentives, too, right? There's another part of this. You work for a headless CMS. There's another user for your product. Can you talk a little bit about content editor experience?

ONDREJ: Yes, following up on what you said, Jason. I think it's a great thing that developers now get more say in what tools are going to be used. But on the other hand, I think that developers are not that demanding, yeah? They don't want the code to write itself. Yeah? They are not unrealistic in their expectations. And I think that's really a great thing. Because it's -- to provide a great developer experience, it's really not that hard. Yeah? You just give the developers the good API. You give them the good documentation. And they are happy. They are not gonna -- they are not a team that's going to be complaining about every single thing. They want a happy path and if you can provide it to them, they're going to be happy. Shameless plug from your way here, Netlify is doing a great job.

JASON: Check is in the mail.

ONDREJ: You talked about content editors. They have trouble working with headless CMS. 15, 20 years, they worked with WYSIWYG editors. They worked with basic HTML. They didn't know how to achieve certain things. They were used to building for the web. Now give them headless CMS, hey, it's decoupled. You can write websites for mobile apps, for even printed brochures or some other channels, they are confused. They don't know what to think about that. And they are so confused about the tools that they are missing that they start not to like it. Yeah? They go into a headless CMS and they see everything is structured, but they don't see the benefits. They don't see that they can change things only in a single place to have the single source of truth for all the channels. They don't see it's gonna save their time. They only see that they are limited. And what they need to do. Yeah? And, of course, we now talk a lot about multi-channel, about having a single piece of content everywhere. But the truth is 80% of companies still use website as their main channel. And they -- the content editors are building for that channel. Now when we took their good pursuance from WYSIWYG editors. They have an awful experience when they can't do things they were used to. It's the same with developers, we like to learn stuff. But if it's too hard, we tend to not like it at all. It's the same with editors. It's a huge step, it's a huge mind shift from that point of view.

JASON: Yeah. You bring up something I've always found interesting. This is gonna take a dangerous turn towards the sociopolitical and I swear I'm going to bring it back safely. When you look at how power dynamics work in groups, you typically have a group that has outsized influence. And then the other groups that suffer under that outsized influence. And what I noticed is that in the -- in the previous iteration with big companies, what you would see is that the leadership teams tended to be made of business people, of sales, of marketing. Folks who thought about things on that scale. And as a result, the tools they would choose were the tools that suited their needs. So, you would get something like Adobe Experience Manager. Or you would get in smaller companies, WordPress, right? And it was because they provided these very content editor-friendly solutions. For someone who worked in marketing, it was really great. They could go in and edit it exactly and see a preview and get it live right away. But the developers who didn't have as much influence in the org just sort of got left holding the bag of like, well, that's not really what this tool is for. But we like it, so, you have to deal with it. And the wheel turns. Developers are now a lot of leadership across companies. We're seeing more and more startups and more and more mid-size companies are now developer-run. We've got huge companies like Twilio where, you know, their whole thing is about developers, right? So, the choices that they're gonna make are about what makes developers happy. But we want to make sure we don't repeat this mistake of having developers you get exactly what you want and everyone else deal with it. We did make this mistake. Look at the evolution, we switched to Git-based workflows and asking marketers to open GitHub accounts. They'll write mark down. It's not prohibitive to somebody. It's not the way they want to work. It's not prohibitive to me to work with WordPress as a templating language, it's just not what I want to do. And what I find interesting is with these focuses on developer experience and content editor experience coming from, you know, the -- the like Netlify's really focused on the developer experience and we've got these API-driven headless CMSs which are really focused on the developer experience. Kontent is providing that sort of thing which is what we'll look at in a bit when we get hands on. But you're also thinking about that content editor experience. What does it feel like to edit this website? How do I make these changes? How do I get a preview in the stuff that was present in the content editor-focused tools which is sometimes absent when we only focus on the developer experience. And the other thing that's interesting about this, we also lose a third tradeoff which is a dement to the user experience. Sometimes all in on the headless CMSs, developers make tradeoffs because they don't know the tool and they're not comfortable and let things happen. That leads to bloated pages, slow loads, things like that. And the content editors are doing something in a WYSIWYG. And they don't know they added a 15 second page. It takes 12 second to load. You didn't optimize the image. How would you know that? You dragged and dropped it in. We're starting to address that and make these experiences automatically good for developers, content editors and users. I would love to hear a little bit how you're thinking about that. How do you balance these tradeoffs of developer needs? Content editor needs? User needs? What are you keeping in mind whether you make these choices?

ONDREJ: This is really hard, Jason. It's really hard to find that line, yeah? When you look at developers who start, you know, thinking about content model, for example? Yeah? All they see is database. That's what we were taught. That's what we were doing in the past. We were optimizing MySQL databases and learning about NoSQL databases. Transferring that into a content model, it's gonna fail really quickly. And some agencies and some developers, this would be the CTOs, I've learned the hard way this is not the way it's supposed to be done. But I think that there's still a lot of confusion and a lot of searching into finding the right balance between the three groups that you mentioned. I don't think that the traditional -- the legacy CMSs make a really bad experience in that sense. Because they do a lot of things automatically for you. Yeah? And I think that there are still very good use cases. Like I know a lot of people around me who are not that technical. And they successfully run WordPress sites. And it's perfectly fine to use that from my point of view. But when you get to a certain point. And I also have a friend and she has a food delivery business. And I think she is that the point right now when a single information is used on multiple places. Then it really makes sense to start thinking about the content model as a whole. And start thinking about the content editing experience. Because otherwise you can easily find the content editor working on a Friday afternoon, night, trying to just change a very simple thing on ten places and forgetting three others. Yeah? So, I think there are use cases for everything. And this, you know, searching for the fine line is different for every project. It depends on who is on the project? What's the budget of the project? And a lot of other aspects.

JASON: So, what would you say are the -- I know that the requirements are always gonna dictate things, right? And that's our job as developers is we reach deeper into our maturity as developers. We have to get really good at measuring tradeoffs. Because there's no perfect solution. There's nothing that's going to solve all of our problems. We're always weighing pros and cons here. But there are some things that are hard to make optional. What would you consider are the non-negotiable pieces of a content editor experience that we need to be keeping in mind when we choose a headless CMS or a CMS solution or any of these approaches as developers?

ONDREJ: That's -- yeah. That's a good question. But maybe for the wrong person. Because I'm also a developer.

JASON: Well, that's actually kind of why I'm asking. Is you know, you are a developer. I'm making choices for myself as like I want the CMS that's easier for me, a developer, to work with. But as someone who is working, you know, at a CMS, I imagine you're also hearing from content editors. We need this feature, we need this feature or we won't switch to your platform. So, what are the things that you're hear something I'm a developer. I'm weighing these tools and I find one that's perfect for me. As I'm assessing whether or not I'm making the wrong trade offs for the rest of the team, for the content editors, for -- let's stick to content editors. What are the things I can't trade off for a content editor for a developer experience?

ONDREJ: It depends on the team. We are focused on enterprise. We are providing enterprise-level content editing features. Granular role setting when you have a country site and a global site. Very nice translation workflows to make it easier for the editor to translate things. To make it easy to reuse content, yeah? Because if you can't easily reuse content, what's the point of having even a headless CMS at all? It's multiple workflows. Because for every part of your content model. And we're seeing a lot of projects that are not just about websites. A lot of people think headless CMS is only for websites. But we see a lot of large clients that are solving totally different needs than websites, yeah? And the, you know, the granular workflow, having a specific workflow for a specific piece of content is really important. Yeah. And then one, you know, interesting very basic requirement that I hear a lot is how do I use the system without touching a mouse? Yeah? They just want to be quick. They want to use keyboard as much as possible. And some solutions or not market, they just don't have that -- that nice keyboard-only experience.

JASON: Sure.

ONDREJ: So, that would be, yeah. But again, it depends on the editor team. And I think that the editor teams, they usually put the highest priority on things that were not working for them well in the previous system. So --

JASON: Right.

ONDREJ: You have to be kind of careful watching for these.

JASON: Yeah. No. That's really fair. And some of the things that I think of just in my own experience of trying to move teams through different things. I've done everything from putting people into GitHub directly and saying, just edit markdown because that's what we have time to implement right now. To we're gonna implement headless WordPress because I know you like the WordPress experience. So, use -- you continue to use WordPress the way you always have. And I will make sure that the headless side will make the developer experience good that way. Some of the things that I've noticed repeatedly come up are being able to preview changes so that there's like a review process there. And being able to quickly see what's going on inside of the CMS. So, I think if you open it and you're presented with a dashboard that's like, here's a pile of unstructured content. Like we just pulled everything into one big pile and you have to sort it down to the different content types that are available and stuff. So, clear navigation toward where they're trying to edit. And a -- a good review workflow seem to be the things that are hard to get right in a headless world because it's not fully integrated the way that something like WordPress as a monolith is. I think that -- those are the things that I've noticed. And I know that that's -- now is that something that you have -- would you say you have kind of figured out a solution to that workflow is with Kontent?

ONDREJ: Yeah. What you mentioned is really the basics, yeah? I kind of see them as a total industry standard. And those, you know, you mentioned the previous, those are absolutely essential. Because editors, they don't just, you know, schedule something or publish something and go home, yeah? They always need to look at how it looks like if they haven't made some horrible mistake or anything. So, the quick previews are an absolute must. Then there are things like content collaboration, yeah? Good workflows that you can -- you don't have to ping your colleagues on teams. But you just add them a task and you're sure that they know about it. Simultaneous editing. When multiple people arrive for a single item, how do you resolve the conflicts? But those are really the basics. Yeah? And I think that the Jamstack, one of the things that it brought apart from developers that were really enthusiastic about it were the -- from editors. Now they were facing preview builds taking 10, 15, 20 minutes on every site. I think that's where the preview problem originated. And, of course, they are just looking for the same things they had with the traditional systems. So, it's our job to bring them as close as possible if the primary channel that we're delivering content to is website.

JASON: Absolutely. And so, today what we will be talking about is -- is the context of websites. But I agree what's really exciting about using a headless CMS is that you're not jumping between systems. Well, this is our app CMS, this is our website CMS, this is our internal CMS. We now have one system that can feed content to everywhere because multiple properties can consume that API where it's kind of hard for a monolith to generate three separate properties. At least in a kind of standard out of the box workflow. And I think that's really exciting. So, I think maybe -- maybe it makes more sense to just start actually looking at this. Because I feel like there is -- there's a ton of abstract stuff that we could talk about here. And there are a lot of ways we could go with this sort of discussion. But ultimately I think the most impactful thing we can do is show people how it works. I'm going to go ahead and switch us over into pair programming view and you can walk us through how to get started with a really good content editor experience.

ONDREJ: Sounds good.

JASON: All right. Now. So, before we get started, let me do a quick shoutout. We have Amanda from White Coat Captioning here with us today. Thank you so much for being here. And that is made possible through the support of our sponsors, Netlify, Nx, the repo tool is a new sponsor, and backlight Dev for building design systems is a great tool. There are episodes on both in the Learn with Jason backlog. Check those out if you want to learn more. And we are talking today to -- if I can get to your Twitter profile. Ondrej. Yes. Head over there, make sure to give him a follow on Twitter. That's all the information I have. What else? Where do I even start? What's my first step if I want to get into Kontent by Kentico?

ONDREJ: Yeah. The first thing you can do is two to You see the Google device for us. So, it's fine.

JASON: Yeah.

ONDREJ: And you go into For Developers. You'll find a link to sign up.

JASON: This is a good callback I think to what we were talking about. Like these are experiences -- also these buttons are fun. These are experiences that are really important for like we have to address both. And what's interesting is if you look around, not every CMS is doing this. A lot of CMSs are optimizing only for developers or only for marketers. And so, that's kind of what I was talking about with the -- like there are some table stakes things that need to be true for both groups to have a wonderful experience. And, I'm excited to see that we're already starting out by saying, look, we know that there's two groups that are gonna use this tool. Which group are you primarily identifying with? I'm a developer. In here. Here?

ONDREJ: You can go to the developer page, go to the sign-up. But today what I actually want to start with is I'm gonna invite you into an already-existing project, yeah?

JASON: Gotcha.

ONDREJ: The basics of creating models and content. It's not that interesting for developers. So, I'm gonna invite you to a project that already exists.

JASON: Okay.

ONDREJ: Just tell me the email that I can use.

JASON: Yeah, let's use Like that.

ONDREJ: Okay. I'm gonna make you a project manager.

JASON: All right! Yet another career privet for me.

ONDREJ: Okay. You should receive an email quickly.

JASON: Okay, I'm watching my email on the other monitor.

ONDREJ: You can also fork a repo that I created just for this occasion. People in the chat can do that as well. If they want. The keys are all in there. I'm gonna send you a link through the chat. It's a Next.js site. It's based on a website that I'm sure that you know. It's accessible at A very cool site. It has a lot of nice sound effects.

JASON: So, we are gonna be rebuilding -- or we're gonna with working with Okay. Great.

ONDREJ: I really like that. Probably some of the effects will not work because I just wanted to port as much as I could to Next.js. But yeah. We're gonna be looking at a Next.js site. We're gonna be looking at GraphQL today. And hopefully it's gonna work.

JASON: Okay. All right.

ONDREJ: It's not that many packages.

JASON: All right. So, I'm gonna open this up and then I'm gonna go back to my email here. So, there's the code. And here is my invitation to access the project. I'm going to copy this link, bring it back over here. And okay. Let me do this on another window so that I don't show everybody my password. Okay. Setting my password. And... okay. Now I'm gonna sign in. Just one second to... is this the one that was just created? Yes. All right.

ONDREJ: The project that's called Jason. Just make sure you're in the right one.

JASON: Okay. So, I just got logged in. Got my password set up and everything. I have to register to join the project. Cool. I can do that. I am a developer. Sure.

ONDREJ: Perfect. Now we can just dismiss this.

JASON: Okay. And we should be there. Okay. So, now I'm in the project.

ONDREJ: Right. You can go to the content model to take a look at the content types that are in the project.

JASON: Okay.

ONDREJ: So, they are based on the Jason AF site. I'm not going to go through probably all of them. Just so you know, these -- these content types are pretty much one-to-one mapped to components on the website. Yeah? So, this is a place where marketers would go in, they would create their landing pages based on components that you prepared for them. And without your approval or any other adjustment in the future. Yeah?

JASON: Okay. Gotcha.

ONDREJ: Let's take a look at one, for example. The section hero. So, that we know what we're talking about. You see here, this is a first line, there is a second line and there is taglines that directly correspond to the hero banner on the

JASON: First line, second line, taglines. And the reason we need multiple.

ONDREJ: Exactly that. Yeah. Because of the button. That switches them. So, that functionality will be preserved and you see that when you go back to the content type. The taglines is actually linked items. And if you open the little icon, the settings of that element, you see that the only allowed type is tagline.

JASON: Got it.

ONDREJ: But there don't have to be any. It's not required. We can kind of tweak around these elements. We can always adjust them so that editors always know exactly what you want from them and it also streamlines the UI for them.

JASON: Gotcha. Very cool, very cool. Okay. So, we've got that set up. And then if I go back -- let's go to the content model again. And down here, I saw there was a tagline. So, I can open this up and this is some text. Great. And so, these are the content model. I'm assume for I want to look at the values, I go to content and assets?

ONDREJ: Exactly. Yeah.

JASON: Okay. And also -- let me make this bigger so that -- like I'm on a smaller screen. So, this more -- if there was more vertical real estate, I assume all of these would be visible, right?

ONDREJ: Yeah. They should be available. Yeah.

JASON: Yeah. It's just -- I have my -- my screen is like way zoomed in for visibility and stuff.

ONDREJ: Yeah, that's nice. That's all right.

JASON: I actually like that this is -- this is thoughtful about vertical spacing and not like smashed together. Because I've definitely built a lot of websites and not thought about somebody with like a short window and then all the pieces are on top of each other. Because some are bottom-aligned and some are top-aligned and I never thought about it being too short. Props to your design team for thinking through that.

ONDREJ: In the past, we had to solve the differences between browsers. And now that browsers behave, we have to solve for the different devices and screen sizes.

JASON: Infinite view points. So, here.

ONDREJ: In the content repository, you see all those in the project currently.

JASON: Okay.

ONDREJ: If you're an editor, look at this, it's not easy for you to understand what's going on there. There are some ideas, there are some taglines, there are some bios, whatever that means. The important thing is that there is the first item in the list, the website, is the container for our website, yeah? If you open that, there is a field called content. where it can start composing your site. Yeah? It's composed of components.

JASON: Got it.

ONDREJ: This is the hero image. There's the bio section. There's -- if you go down, there's another section called teaching. Yeah. And you see all the content is kind of here. But so, the content writer can come in, they can compose their page as they see fit, yeah? From the components that we prepared for them.

JASON: Yeah.

ONDREJ: But yeah. This still looks nice. The important thing is that you still get all the publishing workflows here, yeah? You see right now the page is published, you cannot change anything here. What you can do is you can create a new version or you can unpublish the page. It directly tells the editor that their actions have consequences. That they see what they want to do. The first thing that I totally forgot I wanted to do. Is if you can go to project settings.

JASON: Okay.

ONDREJ: And go into environments. It's the second item in the menu from the top.

JASON: This one.

ONDREJ: Yes. Then here you can see that we're on production environment, right? And let's imagine this as a working site, yeah? We don't to want change -- if we want to play with the website with implementation and we want to change the content, we want to change the content model a bit, it's not a good idea to do it in production.

JASON: Sure.

ONDREJ: So, what we can do right now is we can clone the production environment into something that you want like a development or whatever name you can think of.

JASON: Okay.

ONDREJ: And what this is gonna do, it's gonna do a complete clone of the project. You as a developer can play with the content. You can adjust it to fit your needs to test something without actually compromising or editing something in production which could probably have disastrous effects.

JASON: Okay. So, I'm in -- oh, it's down here. Cloning.

ONDREJ: Yeah, it's creating the environment. That should take only a second because we don't have that much content in there. But in the meantime, maybe we can take a look at the implementation.

JASON: Sure. Let me get this. Or actually, we already opened it. So, it's over here.


JASON: And we have got some components. We've got some pages. Here's our index page. And this looks like where we want to be. So, let me look at this index page and we're pulling in our menu, footer, all these pieces. We've got Apollo client. Great. So, we've got some GraphQL coming our way today. And this looks like Next.js.

ONDREJ: Exactly. It's a Next.js starter. You can use GraphQL you can use REST API, whatever you want. I'm more of a REST API kind of guy because I like strong types. But I figured you like GraphQL a little bit more. So, I wanted to do this with GraphQL.

JASON: Sure, sure, okay.

ONDREJ: Yeah. So, there is the large GraphQL query that actually contains all of the components that we are -- that we know that can occur there, yeah? That doesn't mean that they will be there. But it means that if an editor adds them there, we will have their data. And then if you go slightly lower, there is a quite simple implementation of the linked items resolver. So, this only maps the data to a specific component. So, we have four sections. Hero, bio, teaching and newsletter and every one of them have their, you know, corresponding content items in the headless CMS. So, this is the code that actually maps them together.

JASON: Got it. And that is coming through on here. We're getting our linked items here. Right?

ONDREJ: Yes. But we can look at that through the GraphQL explorer. I think that nicely shows the structure of --

JASON: Oh, yeah. Is that in here?

ONDREJ: No, it's not deployed here. But in our docs, there is a link to a tool that you can use. So, if grow to

JASON: All right.

ONDREJ: And go to API reference.

JASON: API reference.

ONDREJ: Yes. And on the left side, there is a delivery GraphQL API. And if you go down to section called explorer, GraphQL -- exactly that. That's link to the tool that's available online. And what you need to do is just add there the project ID. You can get that from the project.

JASON: Is this -- uh-oh.

ONDREJ: Oh, yeah, you need to remove the GraphQL from the URL. Just -- yeah.

JASON: Oh, got it. Okay.

ONDREJ: Yeah. And you need to go to -- back to the project.

JASON: I think that -- that link is broken. Heads up.

ONDREJ: Yeah, yeah, yeah.

JASON: Okay. Back to the project.

ONDREJ: And you can either go to settings or you can just grab the project ID from the URL. It's the first -- yeah. That's the one.

JASON: Okay. And I'm gonna need the rest of the GraphQL API endpoint. Which is --

ONDREJ: It's It's in the docs but this is probably faster.

JASON:, like that?

ONDREJ: Yes. That should work.

JASON: Okay. And here I get my query. I'm actually gonna use the explorer because this is a little bit easier. Let's just get the bios for now. Because that will be easier than trying to -- we got linked items. And we'll go items. Oh, wait. How is this? Is this right?

ONDREJ: I have a window over that. Can you move the window a bit to the right?

JASON: Oh, yeah. Let me shrink this up.

ONDREJ: Yeah. Perfect.

JASON: Okay. So, if I go into bio.

ONDREJ: Yes, if you want all the bios. This is for getting only the one if you know the code name. If you want all the boys, there's a bio_all. Right beneath.

JASON: Bio_all, text, HTML.

ONDREJ: Because it's a richtext editor. You can have all the kinds of images and other things. These will be all the bios in the system. You have multiple versions of them, small, medium, large. All of them are displayed now. And the type is actually a taxonomy item. No, it's not a taxonomy, it's a multiple choice. You just need to go into items. Type items and look at -- no, you were there.

JASON: I was here. Type, items.

ONDREJ: Type, items, system and code name, or name. Whichever one you prefer. And it's gonna --

JASON: Here we go. Got it.

ONDREJ: This is a short -- it's a defined structure. But as soon as you, you know, get the habit of using these elements, there's a lot of flexibility in all of these.

JASON: Yeah. And what I think is interesting about this. If I close down the bios but I want to go to my section bio, then I get in here a link to the bios themselves. And then I can, you know, get the HTML and the type code name here. And then -- oh, do I have to --

ONDREJ: In here, you have only again a single section bio, right? You have to provide the code name if you want to use that one.

JASON: Okay.

ONDREJ: Or you can use the all.

JASON: And so, what I would have here is I know this one here -- oh, is each of these its own bio?


JASON: I have the section bio.

ONDREJ: The section bio should be somewhere -- the section bios is inline -- there are two ways. It's a single linked item or only living in the scope of a single item.

JASON: Got it.

ONDREJ: Here we're looking at the website page. And the section is actually an inline component here. It is not anywhere else.

JASON: Got it.

ONDREJ: Sometimes it doesn't make sense to reuse some content. Like if it's specific for a website or for a specific landing page.

JASON: Cool. We get our section bio. And then each of the bios is gonna have a text as HTML. And then we would have the type as a code name. And this brings us --

ONDREJ: Right.

JASON: It looks like this one doesn't have anything in it.

ONDREJ: Right now there are no section bios. They start as components. You have to start one section up.

JASON: Oh, I understand.

ONDREJ: That would be the WS home page. All the way down. Yeah, there it is.

JASON: Okay. So, then I get my items.


JASON: Get my content. And this is gonna be MT.

ONDREJ: There is the HTML. And in the HTML you get all the components as objects. And then you need to resolve them. The CMS doesn't know how you want to resolve this. In the case when you're not working with websites, the structure will be a bit different. So, here you can actually get the -- the HTML. And then you get all the data of the components and you can put it together in your --

JASON: Okay. And it looks like I have to limit this a little bit because my query is too complex.

ONDREJ: Yeah. There are -- sometimes whether you -- when the query is too broad, there is a limitation on how many items it can give you back.

JASON: Okay.

ONDREJ: But that usually means you're trying to do something that's not helping you. But here if you go into items, content, linked items. And you go into items. So, here you see all the sections that actually can exist there. Yeah? Because the content field or the content element is limited in what kind of sections the marketer can add there. The GraphQL gives you the possible data that can occur here. Okay? So, it's then up to you to define which items you want. So, in this case, it will be section bio. You can click on bios.

JASON: And get the -- just the URLs of the photos.

ONDREJ: Yeah, that works too.

JASON: And that gives me...

ONDREJ: No, still no content here?

JASON: Nothing there. Let's go back to the bios. Because we know those work. Let's go items and I'll just get the type. And that looks like it's too complex. Do I need to limit this query?

ONDREJ: That's weird. Because the content item is definitely there. Let's try to get only the -- yeah.

JASON: Must be within change?

ONDREJ: No, no.

JASON: One in 20. Do we need to filter somehow in

ONDREJ: Maybe it's good if you used only the home page and use the code name only the home page in there. There's only one with that name. Maybe it's complaining about that.

JASON: So, just like this?

ONDREJ: Home page, yeah. And just to test, just do a system.codename. At the top, yeah. Just to see if we get some results here. Must have a sub-selection. Oh, yeah, you have extra content in there.

JASON: Turn off content. Okay. There we go.


JASON: So, now I have that. I can go to content. I can go to --


JASON: Linked items. Oh, HTML. Yeah, let's get HTML.

ONDREJ: You have extra linked items there. Yeah. So, this is the section that we currently have in the page.

JASON: All right. Nice. Okay. And so, each of these is then linked to a thing. And so, if we got these as like items.

ONDREJ: Oh, you got those as components. So, the linked items are the ones that are usable. But the components are the ones that are inline. Right? So, you can get here --

JASON: Okay. I was looking for the wrong thing. That's what was going on. Okay. Let me get the type. And we'll see, items, system. Code name.


JASON: And now we get --

ONDREJ: Now we get.

JASON: We get the home page, we get the bio section and each has a short, medium and long. You have already solved this by going through and saying for each of these on the home page, get the components. We want the hero section, the bio section, the social links. And then you just kind of dug into each of the sub-sections that we needed.

ONDREJ: Exactly. Yeah. And in this case, I also added system code names and system IDs for some of the items that I'm gonna show or we're gonna show later.

JASON: Okay.

ONDREJ: But yeah. These are all the data that we need potentially if the components are there for the sections that we want.

JASON: Got it. Okay. All right. So, then down here, we've got what starts to look like a standard page. So, we set the title. We've got our menu. Our main and then this richtext component is coming from... an actual component. All right, so --

ONDREJ: That's a component. That's actually taken from another content project. We're probably gonna be adding that as a -- as an LPN package. Because it's actually makes the parsing of the GraphQL response into components, yeah? But right now it's just a copy-paste from a different project.

JASON: Gotcha. So, if we look at this, it pulls in the ID. We get some checking here. And down toward the bottom. Here we go. So, we've got a richtext component. Pulls in all of these props and then out here does some thinking to replace the node with the right kind of node and then just outputs it as a div. Got it.

ONDREJ: Yeah. So, what's happening here is the object tags, they are actually replaced with your components. That's the only thing that's happening here.

JASON: Okay. Great. So, we can work with that. So, if I head back to my home page. Which was here. Then all right. So, we basically do the query. And then we resolve the linked item using -- I'm gonna collapse this one. We resolve the linked item here. Which does this switch and tells us which item to use. And that gets fed into this richtext component which gives us the ability to actually render each of these things.

ONDREJ: Exactly. Yeah.

JASON: All right.

ONDREJ: So, you see here that it's data.vs home page.content, yeah? It's the home page that we're getting from content. And dot content is the page that contains all the richtext that has all the components.

JASON: And going back to our query, we can see that data, WV home page, content.


JASON: Okay. I'm with you.


JASON: And so, is this ready to go if I start it up?

ONDREJ: It should be. The end file is there. You should be able to run it.

JASON: Okay. I'm just going to double check. Yep. Should work. So, I'm just gonna Netlify Dev. And this will pull in our environment variables and all the -- all the bits that we need. And look at it go! And it works!

ONDREJ: Yeah. It's only three taglines. But it should work well. Yeah.

JASON: Yeah. Hey, and you got the sound effects working too.


JASON: I just realized that I'm not piping the sound out right now so only I can hear this. But, yeah. Right? So, this is -- this is kind of the fun way of -- yeah. Just something that I get excited about is making weird noises. But so, this is great. So, now we kind of have this all set up. So, what if I want to go and start messing with this, right? Like I -- we -- I'm assuming this is pulling off the production environment. Is that correct?


JASON: Okay.

ONDREJ: So, you need to go into the environment file and you need to change the project ID.

JASON: Okay. So, environment. And I want to change the project ID which is going to be in here.

ONDREJ: So, yeah, you want to go -- you want to switch the environment first. So, it's a content direction. You want to go to development and then into project settings.

JASON: Into project settings.

ONDREJ: Or, yeah, take that from the URL. Doesn't matter.

JASON: And --

ONDREJ: All the way down. There's API keys in the menu. In the middle.

JASON: Got it. Okay.

ONDREJ: And there's the project ID.

JASON: Okay. So, I'm gonna do in here to the project ID.


JASON: And replace it. I have a plugin that I can't figure out how to turn off that masks these values. So, you're just gonna have to trust me that these are here.

ONDREJ: Okay. You should also change the preview key because that's different for you new environment. So, that's on the right.

JASON: This one?

ONDREJ: The primary, yeah.

JASON: Okay.

ONDREJ: So, this ensures that you also see content that's in draft, yeah? Otherwise if you use the project ID, that's a public information and the content can be queried from the APIs publicly. Yeah? But you don't want that to happen to things that you have in draft. So, that's for that use case.

JASON: Okay.

ONDREJ: And yeah. So, now when we look at the website --

JASON: So, let me restart it. And this will pull the new environment variables. Okay. And so, now something will have changed because we are not editing the content. But this content will be from the development environment, is that correct?

ONDREJ: Yes, that is correct.

JASON: Okay. I'm going to go in here and wreak havoc on this site. So, if I go into my -- let's go to the short bio. And we can say...

ONDREJ: You first need to create a new version because that content is published.

JASON: Oh, that's right. That is right. So, I've got this and then I can say... okay. So, we have a draft.

ONDREJ: Right.

JASON: Okay. And is this save -- okay. It says save. Can we --

ONDREJ: Right.

JASON: Review or do I have to publish?

ONDREJ: You don't have to publish because you already have the preview key there. Actually, you need to do one change because right now you're using the public endpoint for GraphQL. So, you have to change the endpoint.

JASON: Okay. And this --

ONDREJ: The same one, but just do a prefix of preview and dash. So, it's preview, dash

JASON: Like that?


JASON: Okay. So, we'll save. Restart.

ONDREJ: And maybe one more thing. In the Apollo client, we also need to add the header for the preview key. Yeah, you've got 401 which is correct because you're not authorized to use that project ID. If you go to index.

JASON: Apollo client.


JASON: Apollo client. Then I just need to set headers, right?

ONDREJ: Set headers. Authorization header with the -- it's standard. And the content preview key should be there.

JASON: Is that right? Let me --

ONDREJ: Yeah, that should work.

JASON: Content, preview key. Let's just save that. And I think that will just work. It does. And, hey! We are cooking with gas here. We got drafts. So, and this is really exciting because what this means is that if we set this up to be like a dynamically-rendered site. So, if we're pulling this from the API at load time, which for a preview site makes sense. We're not trying to optimize. We're trying to get the latest data. We can set up a development branch that uses the preview API and now our content editors have a place to go where they can immediately see changes and share them around for feedback and all of those things that we want.

ONDREJ: Right. But yeah. That's just the setting up the site, right? Now we get to the interesting stuff, right? So, what I wanted to show you today is two things. One thing is a smart link SDK that goes like halfway of a great user editing the experience. Sorry?

JASON: Sorry, I think we might have picked up a little bit of delay. So, I'm talking over you, I apologize.

ONDREJ: Okay. No problem. So, these two actually complement themselves. We have to start with the SmartLink SDK and then I'll show you how to look at the web spotlight. First thing went to look at is the smart link. Google SmartLink SDK which has a really good repo that's good developer-wise.

JASON: This one?

ONDREJ: Yes. And basically what you need is to small a package. That's the first thing that will be there. NPMI, SmartLink. And it actually adds one JavaScript file to why website that will do a little bit of an overlay of your website to provide editors with the direct links back to the CMS. Right now if you don't know the site, if I didn't give you the intro and you would see only the product, you would probably have to look around for quite some time to figure out how things are composed together. And how to change stuff. Yeah? So, this is designed to help editors not spend that time and be able to directly change content as they see it.

JASON: Got it.

ONDREJ: So, do we have it there?

JASON: Well, I -- so, I installed it.

ONDREJ: Right.

JASON: How do I use it?

ONDREJ: Now, if you go back to the docs. And search for Next.js this is a specific example for Next.js. Yeah. There it is. So, what you want to do is on the FTSX, you want to -- yeah. You want to import that.

JASON: And then we're going to use effect.


JASON: All right.

ONDREJ: And you want to add this.

JASON: Here.

ONDREJ: Right before -- yeah.

JASON: So, I need to import useEffect from React. All right.

ONDREJ: Right.

JASON: And then down here... just need to wrap the whole thing in page section?

ONDREJ: No. I don't think you need to do this. You already have that component there. You don't need to do that right now. But if go back to the code, provide a project ID so that SmartLink knows where to point their users. Yeah, I hope that the process is going to be available in this context. But we'll see.

JASON: Oh, yeah, it might not be, huh?

ONDREJ: If you don't have it available here, it's fine. You can remove the default attributes. We can define it in the document. That's all right. So, just remove the whole section.

JASON: Remove this whole section?

ONDREJ: Yeah. Just the default. Yeah. Exactly.

JASON: Okay.

ONDREJ: Yeah. And the important thing is that it's initialized now. If you switch to document JSX, that's the layout over the whole website. You want to do this onBody, probably. That's the wrapper around everything. And you need to provide the project ID and the default language so that we know where to point the editors. The attributes are also on the GitHub page. I will tell you so you don't have to switch. It's data-content-project-id.

JASON: Okay. Now this one's also not gonna have access to the process.n.

ONDREJ: This one should.

JASON: Do we want -- this one does have access to?


JASON: I actually don't know how this one works. So, I will take your word for it and make that happen. The other one was data-content --

ONDREJ: data-content-language-codename.

JASON: No spaces in

ONDREJ: Yeah, no spaces.

JASON: Lying that.

ONDREJ: This is just in case you have a multi-lingual site. When the editor is on the English site, they are editing English content and vice versa. The codename is default, actually not en in our case.

JASON: Okay.

ONDREJ: And this actually initializes the SDK for the whole website and tells it which project we're using in which language, right? And what you need now is on all places where you want to -- where you expect editors to change content, you need to decorate the elements with these attributes so that the SDK knows what kind of items we are looking at. Right? So, if you go -- we're probably not gonna do it on index. Because index is only like the master page. But we can take a look at the hero, for example. A hero component.

JASON: Got it.

ONDREJ: Yeah. So, when you look at that, there is a section class name so it's better to do it on the top level. Add a attribute there, data-content-component-id. We're working with components here, right? So, component ID. And in this case it would be -- because here we see the data are coming as data variable. And at the top where you see the first line, second line, taglines, those are the elements, right? Of --

JASON: Right.

ONDREJ: Of the content items. So, we're gonna use the same, but we're gonna use a system to get the ID, yeah? So, the system is a -- it's like a special element that contains all the system fields.

JASON: So, like data --

ONDREJ: dot -- underscore system underscore. And here we need that ID. Show that ID.

JASON: Okay.

ONDREJ: Right. And the next thing you to do is -- this actually sets the ID of the component, right? And on the places where you're actually rendering content, there is another parameter that you need to add that's data-content-element-codename. That directly corresponds to which element is being rendered here. Now, because we're using GraphQL, it gets easier here because the name of the variable corresponds to the element codename. So, we can just write first line. It can be just a string literal.

JASON: Gotcha. Let me copy-paste this to here.


JASON: Second line. And here. Taglines.

ONDREJ: Now, still one thing we need to do -- this is perfect, yeah. And one more thing we need to do is on the index page, we need to tell the SDK that we're using the home page content item. So, if you go down to the main -- main element. Yeah. There is the class name home. So, just add that data-content-item-id. And that's, again, gonna be data, dot. Yeah, vs home page, dot --

JASON: System ID?

ONDREJ: System ID. Exactly.

JASON: Okay.

ONDREJ: And one more thing, it's also gonna be data-content-element-codename because we're rendering from the element. So, just another attribute on the main -- yeah.

JASON: Data-content-component-codename --

ONDREJ: It's element-codename, sorry.

JASON: Element-codename. Is this one WS home page?

ONDREJ: No. It's just content. This is the element codename. The VS is the whole content item. But here we're only specifying --

JASON: We want this?


JASON: Gotcha.

ONDREJ: Now, when you save this, and go back to the site. We have the site set up as preview. Right?


ONDREJ: We should see the fresh content.

JASON: Okay. So, we're reloading.

ONDREJ: Right. What's going on?

JASON: We're missing an ID.

ONDREJ: On the main?

JASON: Let's --

ONDREJ: That's possible. We might need to add some stuff to the GraphQL.

JASON: WS home page. We don't have... yeah. We don't have the system --

ONDREJ: Right. So, just add it.

JASON: Is it supposed to be under the content or under the home page?

ONDREJ: No, it's under home page. So, the content is already an element. You need to do is on the same level. Yeah. Yeah.

JASON: Like that.

ONDREJ: Yeah. That should work.

JASON: Okay. And we reload the page. And there it is. And if I open up my elements here... we can see the project ID and then if I --

ONDREJ: Perfect.

JASON: Dig in a little bit on the main class, we get our content element ID, our content element codename. Things are going what we expected. We have valid IDs in there.

ONDREJ: Nothing is happening. You are in the preview mode. The last thing you need to do is add a query string, preview_mode.

JASON: Any equals true? BEN: , just having it there should be --

JASON: Okay.

ONDREJ: Okay. Anything happened?

JASON: I don't see anything happening.

ONDREJ: Okay. So, we must have done something wrong.

JASON: Extra attribute the from the server.

ONDREJ: This is something didn't.

JASON: Site manifest, we don't care about that.

ONDREJ: No, those are still the fonts. All right. Maybe we have something wrong in the setup. That happens.

JASON: Did we get -- let's see if we got the -- are we looking for like a specific thing to come in from content or anything?

ONDREJ: Yeah. It might be worth checking the app TSX, the code file to see if we have the query parameter right. This is usually the -- the issue. Yeah. So, it's not an underscore, it's dash.

JASON: Got it. Hey!

ONDREJ: Yeah, there you go.

JASON: Nice.

ONDREJ: All right. So, this already solves the first problem. Looking for items. When you click on that, it should take you to the right environment, to the right item. And, of course, the item is gonna be published. So, if you need to change it, you will again need to create a new version. But you have it there.

JASON: Nice. Okay. And then if I want to into this one specifically, I click taglines. And it goes --

ONDREJ: It's going to take you through a single item right now because it's still published. But if you create a new version, it should also scroll down to the taglines.

JASON: Okay. Let me create a new version.


JASON: And now we're at taglines.


JASON: Very cool.

ONDREJ: This already improves the editor experience a bit. So far what we've looked at, this is all available in the free plan and the SmartLink SDK and open source. Anyone is able to play with this for free.

JASON: Okay. Now I see this, it's saved here. I'm gonna go back out. I'm gonna refresh the page. Okay. Oh. I have to take off the preview mode, don't I?


JASON: Okay. So, we'll take off the preview mode. There we go. Off to the races. Like nothing. I mean, this is great. I love -- I love the -- the approachability of this and how -- how much, you know, it's there's this little bit of setup that we've done by tagging things appropriately by where they come from in the content management system is giving us that ability to just say, hey, content team. Like here is a thing you could do. And I could even build something that is like if I'm on the development branch, show a button up in the top right, click this to toggle preview mode on and off. When they click that, it would take them to this preview mode here. And then anyone who wants to can just go in and very quickly edit any of these pieces. And that's really nice. It's really pleasant to be able to work like that. And, you know, the -- I like that it just very quickly shows me, oh, look, we've got a draft version of this and we're working on a draft version of this. And each of these things is here. Yeah. It feels very like... I like how quickly we would be able to iterate as a team without anybody on the team ever needing to know how the code works. They just toggle between these two modes and make some edits and they're ready to go.

ONDREJ: One thing to note here is that even when it's preview content, it still goes through the Fastly CDN. So, it may take a few moments to appear on the website. If you refresh it too quickly, it's not going that. But there is a solution, adding a header to the request for content, wait for the new data. The CDN is going to wait for the content to appear. If you want to do that, we are going need it. It's where you set up the authorization header. Below there, it should be x-kc-wait-for-ed loading-new-content. So, wait for loading new content. And set that to true.

JASON: Okay. So, that'll -- that'll just tell it to wait for Fastly to update. Which that takes a few seconds. Is that right?

ONDREJ: Depends. What I experienced, yeah, it could be 1 second, could be 5 seconds. But it's really quite quick.

JASON: Cool. All right. So, then the next thing is you said web preview. Which I'm curious about. Because there's a button for this. Or web spotlight, sorry. We haven't looked that the yet. I'm very curious what this one is.

ONDREJ: First of all, we need to set up a query URL. Go into project settings. There are the preview URL menu item. And we're gonna need this to be available somewhere online. Because we will need to use HTTPS.

JASON: All right. Let's publish it.


JASON: So, I will... let me do... so, I'm gonna echo.env into Git ignore and then we can get add -- wait. Why isn't... why didn't that work? Dot env. Is it specifically not -- oh, it's because you had this committed. So, I guess it doesn't matter, right? We can just commit this, right?

ONDREJ: Yeah. That's fine.

JASON: All right. I'm just gonna do that. I will get add everything. Am I a contributor on this repo or should I fork it?

ONDREJ: Not sure if you are. I can make you a contributor. That's fine. Just give me a second.

JASON: I'm gonna fork it simply because I haven't set this up to use your account on Netlify. So, it will be faster if I do it this way.

ONDREJ: All right.

JASON: I'm gonna fork it. I would like to add a remote for the fork. Good. And then if I check my remotes, I can see that we've got an upstream of your repo and an origin of my repo. Good. So, what I'm gonna do, then, is get commit and we'll see work in progress. Setting up for web spotlight.


JASON: I'm gonna push that to origin main. And then I'm going it Netlify init in and we're gonna create and configure a new site and put it on mine here. And we'll say... content web editing. I don't know. We'll call it -- whatever. It's fine. Then our build is gonna be next build. All right. So, it did all the auto-detection that we want. Yes. Do we need a -- ah, we don't need that. Okay. So, what we've just done is we have deployed this site. And it's gonna be building now. So, if I go to Netlify open, it's gonna pop open the Netlify dashboard for us. And we'll see the site building. And once this finishes, which should only take a moment. Actually, I might need to -- I'm gonna import these... I'm gonna import the environment variables so that they're in Netlify. And so, this is a CLI demand. We can just run that. And you can see that it pulled them all in. And now if I do a Netlify eng list, it will show me all of my environment variables. And they're masked by default. But if I want to show them, I can spit them out like that. But now that we have those.


JASON: I think this is gonna fail because we don't have -- yeah. It failed because we were missing environment variables. So, let me go back and let's deploy again now that we've added the environment variables. And that should build and get us online at which point we should have previewable URLs. Give a little -- give it a little one of these. [Hold music]

ONDREJ: Yeah, I hope this is gonna go through. Because I haven't tried it myself yet.

JASON: I guess if this doesn't work, we can explore a little bit and see what is going wrong. But I think... no Next.js cache. That's fine. It didn't like something.


JASON: Boolean is not assign to believe type string.

ONDREJ: Oh, yeah, you need to do a string.

JASON: String, true. Fine, fine, we can solve that problem. Now you're happy. I guess I could have checked that. I assumed it just didn't like that name. Okay. So, we'll push that. And then that will kick off a new build. There it goes. And now I think we have a cache? This should hopefully go faster. Naw, it won't cache if there's a failed build because we don't want to cache anything that didn't build. So, this will take another minute or so and then we'll be off to the races here. Assuming... assuming. [Hold music]

Thank you for the kind words, earholesmcgee. I didn't think that name was gonna get me. That's a great, great name. I -- yeah. I appreciate you all. Chat, how are you all doing today? Thank you. I saw Alex and co, you raided a little while ago. Really appreciate that. Welcome if you're still hanging out. It is -- it is a -- it's a great Thursday. A little bit sunny in Portland which is, you know, new for this time of year. And don't you do that. Crap.

ONDREJ: Oh, it failed again.

JASON: Can be escaped... it doesn't like image. That's whatever. We don't care. External synchronous scripts are forbidden.

ONDREJ: Yeah, I was afraid of that.

JASON: You can't yell at us like that. Let's just mark 'em as -- we can just mark 'em as... where is my doc? Here. My document. Here, I have a solution. We'll just go here, here and here. And we'll mark them all as async. And what else didn't it like? It didn't like that. Do not use -- is it gonna fail on this, though?

ONDREJ: No, I think do not use should be... only warning still.

JASON: It's throwing us errors, though, which is not great. So, let's find all of those. Look for all of our links here. We've got... not that one. Here?

ONDREJ: In the footer maybe? Yeah.

JASON: Yeah. It doesn't like these. How about --

ONDREJ: Just remove them. Footer is not essential here.

JASON: That's a good point. Why don't we just do that? I'm just gonna eliminate these all together for now.


JASON: All right. What else do we got? We got all those ones here. That's fine. Menu. These are also grumpy.

ONDREJ: Yeah, same thing.

JASON: This one maybe we want to fix? Visit link? How does this work? It's like link --

ONDREJ: I think it's link to, maybe?

JASON: Href and then I think you have to drop one of these in there so it can attach to it. Is that right? I can't remember. I've never been a huge fan of this because it feels very chaotic to me. But we can make it work. Then we'll go with our closing link and I think that solves those problems. What else is in here? What else do we need? We've got all of these. The images we can ignore, I think. But we probably -- is it -- ah, you're gonna fail me on this. Aren't you? [Heavy sigh]-okay. Get the link and then we'll but the that link out here. And then we'll move this href up here. And then you're still unhappy? All the images I care less about. This -- I just want it to not --

ONDREJ: Yeah, I think it's a couple of times here.

JASON: Yeah. Let me just go and get this one. Fine. And then one more... and then if there's others, I'm just gonna delete 'em.

ONDREJ: Right.

JASON: Okay. All right. What else we got in here? Any others? Newsletter's fine. That one is... fine. That one's fine. These are all links. Those are all links. Okay. That should -- that should then fix it. Let's... use links. And -- yeah. This link -- the error that we're getting is a linting error from Next which feels like it -- ah shit, it's gonna break this one too. See, you made me share, Next! You made me swear. No un-escaped entities in which element, though? Photos.tsx.

ONDREJ: Or can we just get rid of the linting for this?

JASON: That's a great question.

ONDREJ: Moment.

JASON: Are you the linter? Where is the error? There's something that it's yelling at. Photos.tsx, newsletter.tsx? Is that where the problem is? What you -- what you mad about? I don't see where the error is.

ONDREJ: It doesn't like images. But if it's the error, let me see -- it's actually in the notice.

JASON: Oh, my god. Oh, my god. So, that was a very helpful hunting rabbit hole. I'm very glad that was turned on. So, let's get commit, fix, please the linter. And then we'll push that. And this time, I think, we'll actually get everything to work. Because that was, I believe, the last problem. Ah, crap. We might get one more.

ONDREJ: Oh, it doesn't like Rail.

JASON: Oh. I guess it wants me to put all this stuff over here. Man... just leave me alone! Leave me alone, Next! Let me do my thing. Okay, let's try this. Commit, one more try. Please, linter, we're just trying to code. All right. So, one more failure. But this time it's just the one error. Type error. Yep. Okay. Good. Fine. This is the one. So, everyone just --


JASON: Put this out of your mind. We'll just erase the last 5 minutes. This is working on the first try. You believe me. Okay. This one's gonna work. And then we're gonna have about 7 minutes to get the web preview in place. Did I completely hose us with the linter rabbit hole?

ONDREJ: A bit. But we'll see what we can do.

JASON: [Laughs] -- we'll go as fast as we can.

ONDREJ: Fingers crossed that the build is gonna go through now.

JASON: Yes. This one -- this one's gonna work.


JASON: Come on. Do your thing. Do your thing. Failing on type checking. Jeez. None of those failed!

No, this will work, this will work.

JASON: Yes! Come on.

ONDREJ: Yeah, it looks good. Looks good.

JASON: Do it.

ONDREJ: But I got to say, I like these linting things. It really helps you -- keep you behave.

JASON: I like them as warnings. I really don't like it when a linter is like, you used an apostrophe, I'm gonna break.

ONDREJ: And it's fine if the build takes a few seconds. But if it's a 5-minute build.

JASON: Exactly, right? If this was a big site with like lots of stuff. Because you know this is still taking a couple minutes and we burned a solid 5 minutes, 10 minutes trying to get this sorted. Which it just take use out of the flow of building. When it's something like, don't use links. Don't. Don't. Just don't do that. It wastes my time. Now I'm frustrated. Now I wish that we hadn't used Next. It would have been much easier to just warn me and I would have fixed it eventually. But now we have a public URL.

ONDREJ: Perfect. Copy that and we'll set it up as home page here.

JASON: Okay. Do I need to do anything else?

ONDREJ: Save that. Now we can go into web spotlight.

JASON: Web spotlight.

ONDREJ: Yeah. And what you see here, is we only have the home page, right? We don't have any other pages there. If added some pages, click the three dots on the left. You can create other pages here. Create new ones, link. This adds a content tree, the website content tree right in the CMS. If you're building a website from your project. Yeah? So, this is completely un-related to the content repository. This is -- you can pretty much build whatever you want here. And on the right, obviously, is your site rendered and it automatically goes into the edit mode.

JASON: Right.

ONDREJ: You can go in and change some content. Now, if you just click on something there.

JASON: Really nice.

ONDREJ: It should give you the possibility of the site editing.

JASON: oh!

ONDREJ: Over your website. And, of course, do we have a draft on this? Can you change this?

JASON: I think we do, yeah.

ONDREJ: Perfect. Yeah. Right.

JASON: Okay. Changes are ready.

ONDREJ: Yeah, but maybe because we were using get static props we need to do a rebuild in this case. Because we're not using the preview mode of Next.js. But --

JASON: It's not like a you just need to go back to the... oops.

ONDREJ: Yeah, like -- what we can do is we can -- on implementation we can change it to get server side props so that it gets converted into a serverless function. But otherwise you would need to run it as a preview -- through the preview API route in Next.js. Because right now it's previewed.

JASON: Right. That makes sense. So, to fix this for like our -- our public build, we could just change this to get server side props, right?

ONDREJ: Yeah. Not sure if the signature is the same. But that should help.

JASON: Yell at us...

ONDREJ: That one as well.

JASON: Get server side props results. Is that right? No.


JASON: Get server side props.

ONDREJ: It's get server side props, yeah.

JASON: Can't find name, get server side props.

ONDREJ: You may need to import it.

JASON: There we go. Now it's happy. And it likes -- I think this is -- this all seems right. All right. Let's try that one more time.


JASON: And actually, maybe we can just run a quick Netlify Dev to check it locally before we try to export it.

ONDREJ: So, I think that this is what the preview API route does anyway. Yeah. Okay.

JASON: Yeah. And I don't remember enough about the Next preview API to like turn it on. Because is it like a cookie that has to be set? Or what's the?

ONDREJ: Yeah. It's just one API route. I have it quite handy, the code. But if it works like this, I think we can leave it as it is. The setup is quite easy, but --

JASON: And, is that linked somewhere that we can send? Because we're at like the 3 minute mark here. So, I have a suspicion that --

ONDREJ: Right. Yeah. Like I have the -- yeah. Let me send the API route in the chat. It's from my personal site. So, you want to copy it over.

JASON: Yeah. Let me...

ONDREJ: This one is based on content, right? So, the only thing you need to do is just translate the code name that you have in the preview URL into the actual URL on the website. But otherwise, it's quite straightforward.

JASON: Okay. Got it, got it, got it. So, yeah, in this case we -- we would set it up to put Next into preview mode. What I have chosen to do is for the developer site, use get server side props. Both work. This one's probably like a little more set up and a little less code-divergence. If you want to use get static props which is probably the right idea when you get to actually deploying the site. So, here's this... that is almost done. And with it, post processing, it's live. Okay. So, then I'm gonna go back to web spotlight. And now it's doing the thing. So, let's edit that one more time. And I'm going change it back to Jason, right? And then we've saved that. Waiting for changes to be applied. They have been applied and so, we're now live editing. That is slick. It's really nice.

ONDREJ: And there's one more thing I wanted to show you, Jason. If you go back to the implementation, back to the -- the hero component. And where we have the data content component ID, just add a few more attributes here. Yeah. Below that. Let's keep it there. And let's add an attribute. Data content add button. Without any value. And then below add a data content add button, render position. And do a bottom.

JASON: Okay.

ONDREJ: And data content add button insert position. And make that after.

JASON: Like that?

ONDREJ: Yes. Hopefully this is gonna be all we need to do here. So, save it. And maybe quickly build that. So --

JASON: Will it work locally in preview mode?

ONDREJ: No, this needs to be deployed because it needs -- what this does, it not only shows the components below each other, but it also adds little plus icons there that the editor directly sees and can click on them and then content will pick that up. And we'll enable the editor to add new components right from, you know, the website UI. So, you don't have mettle with any restrictors. You just directly work with the site and add components this way.

JASON: Great. This is going to take another couple seconds. We're working from a cache. So, it's much faster. And this is going to hopefully just work on the first try. While we're waiting for that, I'm going to send folks to a couple places here. First, I'm gonna send everyone to so that you can go check out Kontent by Kentico for yourself. I'm also gonna direct you to Ondrej's Twitter. And head over. And a shoutout to our live captioning. We have had Amanda here from White Coat Captioning all day. Thank you for being here. And that's made possible by our sponsor, Netlify, Nx and backlight. I appreciate that. Make sure to check out the schedule while you are looking for things. There's so much good stuff. I'm not going into it because we're short on time. Lots and lots of good things happening. This is now done. Reload the web spotlight.

ONDREJ: So, fingers crossed. A bit down.

JASON: A bit down.

ONDREJ: Yes, below the plus button.

JASON: Interesting. Okay.

ONDREJ: We may have configured something wrong because there are some missing.

JASON: Okay.

ONDREJ: What this does is lets you open a dialogue to create a new component for a new linked item. Exactly the same as in the richtext editor. It's nice when you're adding stuff and directly looking at it as you're building the website. It brings the visual editor experience that editors are used to WYSIWYGs.

JASON: If we go through and get it all instrumented properly, I get an experience I can send to the content team. Where they see the website as it looks. But they get this ability to edit each section of the website in place and experiment with, you know, this is what if looks like, this is how it works. And then when they're ready, that preview is also available on the built branch. The deployment and develop branch or whatever. Where they can share it to somebody for feedback. So, we've kind of created using this workflow a really nice content editor experience. As a developer, we get to work in whatever we want. We got it use Next today. Could switch over to remix, Astro, Eleventy, whatever. Because it's all done through data attributes, which is really nice. And then we can also do a branch build of like production uses the the production key. We can do the reloads. This is powerful stuff. We have a lot of options here. We are out of time. I'm going to give you any parting words for anybody as we wrap this up.

ONDREJ: Yes. The last thing to mention, if you're not working with next JS or working, there's a way to send back to content to refresh when you're ready. It's prepared for folks that would like Gatsby or other popular frameworks out there. Otherwise, no. If there's anything that I can help you with, then ping me on Twitter. And yeah. I hope that your editors are going to be happy eternally. Like we are. Developers. Excellent. All right, everybody. We are going to find somebody to raid. Ondrej, thank you for taking time today. Thank you so much. We will see you next time.

ONDREJ: Thanks, see you, Jason.

Closed captioning and more are made possible by our sponsors: