Skip to main content

← All videos

Middleware Magic: Personalize and Visual builder in a complex setup

May 1, 202555:12
Live · ContentstackComposable architectureCMSAPI designPersonalizationFrontend

Join us for a deep dive into creating Rich Digital Experiences with Contentstack when faced with existing complex architecture. We will walk through how to use middleware and proxy servers to implement Visual Builder and Personalization.

Transcript

[Music] Oh, fun music. Such music. I don't mind it. Oh, it's a little indie. [Laughter] Oh, what is that echo? I don't know. But we just had music on our intro. That was fun. Um, we are actually live and we like it's funny, right? We're always live mid conversation. I guess this is how it goes with us. It's always about the pipes. So, welcome to our stream everybody. Hey everyone, how's it going? How are you today? I'm pretty good. It's getting warm here in North Carolina. How are you? How are you doing, Tim? Yeah, it's getting finally not raining and storming. It's finally kind of sunny now. And I get the the sun from there. So, a bit later in the day, it's going to be hot in this room. Ah, but that's luxury. We want this. Yes. It's good for the plants and trees and us. Oh, man. It's exploded here. Like this is a super lush place where I live and then it it tends to rain at night and sun during the day. So it's ex literally exploding in green. It's cool. Awesome. Well, welcome everyone to um content stacks pulse for developers. We have a great stream today. We're going to be talking about middleware magic and talking about what it likes to implement content stack when you have complex architecture. Um, we're going to take it back. We're going to go old school. We're going to have a little bit of diagram drawing, some whiteboarding, if you will. We're going to show you some code of implementation, and then we'll show you um demo a little bit about what that looks like on the front end. So, you want to take it away, Tim, and we'll start. Sure. Yeah. And so, let me just share my screen. And so, we're gonna just This is an empty canvas right now, right? But we can actually draw some stuff. So what I wanted to go over together with you today is just basically like a little bit of a history lesson on how infrastructures and architectures used to work for websites and then what happened over time and where we are kind of now and how you would have like because actually what's interesting is like a lot of teams now have coded themselves into a corner a little bit and if they still wanted to use like super complicated fancy things like visual builder and personalization in that new setup that they've created. That's sometimes not so easy. And so I want to go over that today and how you would do it. But let's first talk about how we used to do it, right? Yes. So back in the day, and you know what, this back in the day, well, should I zoom a little? Might not even be that back in the day for some, right? So we used to have this. Well, let me just make that a stroke like this. And so this is basically your back end or CMS let's call it CMS right and then your front end it's actually kind of like super connected to that right and so this is a lot of the times what you would see and so all your Adobe site coursees you see they still exist WordPress aqua Drupal Drupal that's a right so all of those still work like this and So essentially the CMS and your front end are together and you know what's fun? They're actually a web server on their own. This whole thing is like you just deploy this to some server and you hope for the best and you need to do lots of like if there's an update to the CMS or your back end or your piping you have to do a bunch of complex stuff, right? And so this is all good though but this is not really what we see now and anymore. You have some and sort of with that configuration architecture, right? You also get a lot of times the code is in your content, right? So there's no separation 100%. And so what they kind of did because there is some really nice stuff in here because you just get so much out of the box because the vendor of this software decided for you how that front end works. So the opinion of the people building that CMS or web framework is seen in the front end that you get and that's in WordPress quite often plugins with jQuery and rendered HTML with PHP and you can do per you can change it you have to make your own theme and stuff but it's quite challenging and so with that in mind we started to see this right this I have to see if I can actually type front end separation, right? And so you would actually just have exactly this, but it started to be more like that separation of concerns. Exactly. And so sometimes it would even be like this, even more fancy, right? You might have this going on, which now meant that that CMS has little a little bit less um what do you call this? They're not in charge of everything anymore, but they're still the center of the universe. Yes. But front end can now suddenly be well maybe I want to go next.js or few or maybe I want to do an Angular front end and I also want to have like a mobile site that is in like React Native or something. And then so now I actually have all this stuff to deal with. And so now I can use that same content for multiple things which is pretty cool, right? So we're starting to see what hatless means here. All that stuff that people keep talking about hatless. I cannot believe I'm still explaining this. This is like we're talking I don't know when I did this first, but it's probably like 2012 or something. But it's still a thing because I think 40% of the web is still here. Yeah. And then slowly but surely you start to see more purists and like that pendulum is swinging from like more this direction, more that direction. And so what you started to see is this whole thing is pretty cool, right? But then you also saw that not only the CMS is there, but there's actually multiple things. Yeah. External for data. Yeah. So, it's going to be a little bit like the com the start of the composible era where you would have your CMS. Let me just copy this here. Oh, I don't know why this is not connected to my little box, but here you go. And then of course you have that same front end with these arrows that would do stuff. Um, however, suddenly that CMS couldn't do all the things anymore because it's a headless CMS. So, you might also now have some search or something or something else like um maybe what would what would you see here mostly like maybe a dam like images? Yeah, a dam. You could see like e-commerce like a py maybe like some kind of product database maybe a commerce engine something like this and of course these two would talk back and forth because you need to know stocks but you also need to get product information stuff like that and maybe the dam is going like this though and then the CMS would offer it to the front end but you would still maybe have your other front end. Yeah, your omni channel. Exactly. Well, or multi- channelannel, whatever you want to call it. Yeah. But especially when this goes like this, you see how many arrows are happening now, maybe even the other way around. You see what is happening, right? Composible is kind of complex. And so what this is pushing for are basically lots of super complicated front ends. And that's a thing that's actually pretty important because if you push all that knowledge and statekeeping and data management and mapping of data into this these front end developers now have to become a lot better at their job where normally backend developers deal dealt with that here. Um, low I think we might have a comment. We do. We have a question. It's from Catalyn. Is it possible to get the nested reference with the SDK content stack with basic setup? It seems that it's not working but only for first level. You can definitely do that. Should we quickly go there because I think we can just go to Yeah, let's just go. I want to go to the SDKs. So, we're in the content stack documentation right now in the docs. I want to go to Well, okay. Not [Laughter] there. Here we go. Um, can I not just open this? Okay, here we go. So, this will So, we're going to go for references, right? So, let's go to the API reference here. And I'm just going to search for reference because I know like when you have a reference to something else and you query for that thing, you see there's a reference but you don't get its data, right? So yeah, you have to dstructure it. You actually have to tell it give me also this reference of the thing you're connecting to. And Cataline, if you want you can make that an array as well. So if you have 15 references with 15 different things, just say what the name of the reference the item is that you're referencing or its ID basically or what do you call this like its type. So when we have a blog post and a brand if a blog post is connected to a brand if you include a reference brand you get it and then there's also multiple depths I think you can even go with there are yeah but the main thing is like you have to dstructure the reference right otherwise when you do the initial query you will just get notifi this is a reference but if you want the actual content of the reference you need to do the include reference yeah so um Kathleen I hope that helps Uh, feel free to ask more questions though. Um, can you are you still Oh, you already closed it. We'll find it in uh I'll find it and drop the link in the chat so you can get the actual documentation link. I just I just did it. Excellent. All right. So, quickly go back because these like references happen in here, right? But your front end still needs to get it. So, when we are in this, all of that gets super duper complex. And we kind of don't want that because the more complexity in your front end, the more it's just going to be harder to move fast. And also, if you want to change one of these boxes, your front end code needs to change, which it's not something you want to do all the time, right? So, what we started to see is, let me just copy this. There's lots of companies nowadays which is basically number four. It's composable with basically a safe zone maybe right safe mode. Yeah. Which is essentially this. They just put something here um which has all the logic. So the front end doesn't need to change if these change. So these arrows are different now. They're going to be like this. Just bear with me while I while I draw this. Yeah, there's just many arrows. Like composibility is complicated, right? It is very complicated, but it makes sense because organizations are complicated. It's not realistic necessarily that you would have all of your content and your data in one place. There are lots of different external sources you would want to use. Exactly. And the more complex and the more big companies get and you're going to see um this type of stuff happen more and more. Right? So the safe zone is basically built to make sure if I change this and change this um it doesn't really matter what happens with my front end. It still kind of works. And the funny thing is it's never really true because your front end still has some sort of assumptions. But this is what we started to see a lot especially with bigger customers that kind of needed that safe zone right so let's call it the safe zone or you know what let's call it what it actually is middleware yes yeah this is actually a middleware this thing and so this is interesting right and now we're going to see a bit of a switch because what you would see in these composible era products is that these blocks started to get smaller and smaller in scope, right? And so you would have a dam, then you would have a search, but then you would start to get like just a payment provider. Um, and you would start getting all these like smaller and smaller chunks that back in the day would all just be in your CMS, but now they're all going to be pushing towards here, right? All of that happens. And so this is actually pretty hard to deal with because you're going to get procurement of all these elements, right? You have to buy all those, then you have to have SLAs, then you have to have support. This is costly and complex. And so now let's see where we are in number five. Now we are in basically composible DXP. And what's funny about this is that this is harkening back a little bit to this era. Yes, a little bit. But original separation of concerns. Yeah. But with a different way. Okay, so let me just copy this whole thing again because we see a lot of folks that still have like this middleware bit going on, but now whatever is here is different. So this is still there, front ends are still there, but this is now starting to actually be a bit more like this, right? So there's a little bit more of cross-pollination somehow. Yes. Between these systems, right? And so there's lots of like this going on with integrations and um whatever else. So all of those are starting to become closer together. Um and you start to see that some companies are actually being very clever. They're just going to offer those things out of the box, right? Which are your composible DXPs like content stack, right? If you wanted to have let's say personalization that actually also comes out out of this little content stack box now. And so maybe not a commerce, but you could do a pin in here, right? Yep. And so the interesting thing is these are still separated boxes. There are still arrows all around. They still talk to one another, right? All of this is still happening. Um, however, they are built like this whole headless thing. Yeah, this is when you start getting into federation. Uh, oh, what happened with that? Yeah, that was weird. And so this is still built like these boxes, but just one company makes more boxes. Yeah. And so data and content. Exactly. And so you kind of buy in one company, but you get all the boxes. And if you don't like the search, then you just put your own search or whether you just put it there, right? And this would just go like that or it would only do it from here, right? And so this is a really interesting concept that we're seeing here. And then sometimes these also work like that where they directly talk to the front end because potentially search is one of those very interesting complex ones where it's an index database and you somehow have you need that front end thing directly to talk to it rather than through your whole middleware because this is maybe slower. So you see all this complex stuff but this is kind of often there. Of course, what content stack loves to have is this where the front end just talks to this big box, but that's not always the case, right? Oh, did we just lose that box? I think did you delete it? There we go. Yeah, my bad. And so, you see this is kind of an a complex drawing, right? But this is actually very realistic for a lot of people that we talk to. And so the what you start to see is that these companies like content, these composable DXPS are starting to build a lot of really cool stuff that makes them a DXP like visual building, personalization of your content influenced by other sources and things, content federation, um integrations, but there's so much going on and what you could do in an ideal world is not have this middleware layer and just deal with it like directly. Right. Right. Um, however, that's not always the case because this site here, this content stite, this keeps building even though you might have decided a few years ago to do this, right? And so now what we see and this is what content stack is I think personally excelling at at the moment. That's why it's working so well with content stack is we build all these services in a super agnostic way. you can use everything in this box on on its own as a separated product that you can just talk to from here directly if you wanted to. And so with that in mind, having this middleware layer, but you still need to get a specific draft for like a live preview or a version of an entity for um let's say personalization. We just it's just an API and you just change something in that API and it just works. where if you look at a lot of our competition, they chose there's one way you do it this way. If you have a middleware layer, bad luck. You have to change your whole architecture for this. It's very opinionated. Yes. And we try to be as agnostic to whatever as possible. That's why we have so many SDKs. That's why our APIs are 100% um coverage for everything. It constantly keeps working. And so I built a little project here. I don't know why it's on the left, but there you go. It somehow decided it didn't want, you know, just do like this. It feels like Anyways, um this project actually has personalization working through that middleware layer even though it needs to talk directly to the CMS to know based on this cookie I need that version of like an entity or an entry, right? But it also works with live preview and visual building where you would normally be like, "Oh, but your SDK connects directly to content stack, right? How would I even do that in my middleware? And so a lot of our um prospect customers, people we talk to, they all have this setup. And so this was a very long intro into let's actually show you something and code a little bit to to know what do you do in this box to make all that front-end magic work with your system. Yeah. And it was long, but I think necessary. It's good to see one where we've come from and the evolution of this, but also to just level set like where are we where are we now and potentially where we headed. Exactly. And so that's why I built this little app. And so when I actually say okay so my role is actually a developer and so now this page has become a developer page. And so when I refresh there's actually now personalization going on. We can have a look at the cookies for example. Let's see if that shows. And so, well, it's it's a little bit small, but this now shows you there's a cookie specific for the variant of a page it needs to show. And if I say, well, let's make that marketer. And I go back to my cookie, you see that's a different number here. If I remove it, I go back, it shows nothing. And this is just to say, hey, we can show you different things, different variants of an entry in personalization. Or you can basically do something like with a query parameter and now it's showing yet another one right and but this one is not maintained. And so what this means is if you want to do personalization the whole request of the page is sent to the content stack personalization engine. It says hey do I have query parameters? Do I have cookies set already? Do I need to refetch you this thing that I was already personalized for? And so you can have a bunch of different experiences to based on whatever attribute you send for a specific user for an audience. Um you can show different things and so it sorry go on I was just going to say before we move into the code can you quickly show in the stack what those variants look like? Oh yes of course yes let's go. And so um it's this one. And so essentially what we've built in content tech is really quite cool. So we have for each entry, this is just a normal homepage. We have different variants of an entry. And so you don't even have to use this for personalization. You can just also, you know, use a different variant of an entry based on something in your codebase. And you can just decide, oh, I need this variant or that one, right? And so we just now connected this to our personalization that says, hey, if this attribute is true for this person, they are probably a marketer. So, let me show you the marketing content version of this entry. And not everything is different. So, we're only storing like um how do you call this? Like a delta of the change based on what is different from the base entry. Right? So, it's super small and super fast. And so, what you have to do is somehow in your API query say give me that variant versus the other one. And then it has to look at the cookie or query parameters if you want to do it really for personalization because you might have a CDP that says hey this user is VIP and so you have to know that and then tell content stack give me that version of the page specifically for VIPs or for developers or whatever and so yeah and that's really perfect for like you like talking about VIP like a lot of organizations have loyalty programs right and so you would want to serve a person who's part of your loyalty program a different content than a firsttime visitor. Yes. Who is not in the program. For example, if we go to our academy, um this website, it takes a sec to loads somehow. Okay, let's go. Yeah. So, right now, this just shows you the most popular things, but when I actually I won't do it now, but when I actually log in and look at my profile, it's it's Ah, here we go. There you go. So, I can say maybe I'm a leader. So, now my role is different, right? So, now I'm going to show you different things on the front end. You see most popular for leaders. This is actually a different entry that we're showing now based on my role and different content. Yeah, exactly. And so, you know, see what's possible. And so when I go back to developer and say save and now I go back to the homepage it actually shows me developer here on the screen and like most popular for developers. This is completely different content here. And so that's a very interesting concept of personalization and that's basically what this project has. And so if you have this middleware layer, suddenly you have something complicated to deal with because you have to send all this information to the middleware and this middleware needs to deal with that information go to content stack says give me this variant and go back and then give it to your front end. So there's just a whole extra step. And additionally, if we go to visual builder here, if I want to actually visually build this thing, and I also want to do that for personalization, that has to work the same way, right? And so here you can actually see your audiences like this and then work with it. And like lots of times when we do a demo for this, there's no um how do you say this? there's no um explanation of what that would do with a middleware because actually when you do this visual builder um what you're actually doing is sending data to a draft API and even if I don't save this is still stored and I can still see it now it renders this is my web page it just rendered like that right so there's lots of headers and specific um you hashes that we send to content sec that says this user is allowed to not save but still see this data on their own website. So lots of stuff that we actually just deal with in our SDK without you having to know. But if you have a middleware that doesn't work because our SDK talks directly to content stack. What do you do when you have this middleware? Yes. Right. Normally visual builder just talks directly to the CMS draft API. Very specific stuff. You don't even have to save. He can still see it. But what do you do when you have this block in between, right? And that's what today is about. And it took us 26 minutes to get there. Yeah. But I kind of just um let's not save this because we don't want to destroy this stack. Like I kind of just um and it's the same for this one basically. I kind of just want to show you know what happens in the code here. Yeah. Let's jump in. Maybe before we dive in though, where where do you want to start with this? What is the best way? I think now that we sort of given an overview on the stack side, like let's actually take a look at the middleware code and walk through that a little bit. Of course. All right. So, this is a next 15 project. Let me just show you the package JSON which is just the latest of everything like it's let's see next 153 and it uses app directory. So this is literally just if you install next you get this and we just added these right the content stack um delivery things. Interestingly enough you might not even need this delivery SDK because we're using a middleware. I should actually remove this though. Interesting. Anyways, you find mistakes in your own work only. What would it look like? Always what this this API route here is essentially going to be able to live anywhere, right? So, what we're showing is essentially we have a front end and then this middleware is this middleware route that I have here just because Nex.js is actually a full stack tool. I I build it like this for the demo. So there's a little bit here and a little bit of the front end. So this route can be anywhere on the web. Just think about that in your mind. And so what this is doing is just it gets a URL from the request that you query and it gets a whole bunch of information from that URL and based on that it will actually query personalization and it will query the API endpoint of content stack and then return all the data that it needs. And so all the knowledge that you need for personalization plus live preview or visual builder actually happens in this route here in this middleware. So the front end doesn't know about any of this. It doesn't have the API keys nothing. It just queries this thing. Give me data please. And so um go for it low. I was just going to ask like also I think it's important to talk about like why someone would have this architecture right? So if you're coming into content stack for the first time and you have middleware like what are the reasons why someone would have middleware exactly this let's say let's let's remove this one for a second so let's say you have a lot of different smaller tooling that does a bunch of stuff and maybe you might even have multiple CMS's right that need information which happens a lot it happens a lot more than you think. And maybe you have a CDP. And so what this means is, you see how many arrows I'm starting to get, which is not too bad on its own, but it means that this front end is now very complex. It needs to be able to query all those things. It has to interpret all its data, change its data, and then show something on the front end. And what a lot of people have gone through is the pain of let's change this dam and then oh crap I made a bunch of assumptions in my front end so I changed the dam and now I have to do three months of work on my front end right that happened kept on happening and the more like this is a simplified version of it like there's people that have like multiple of those and there's legacy boxes and there's dark corners of content right random custom databases that live in a server under someone's desk I've seen Yeah, the scripts where do they run? And so this is so the one reason for for a block like this is to actually just separate the concerns from the front end to the to all these services. And so then after that is another one. Let's say you have a really really really busy site and these boxes they charge you a ton of money for every request that you do. Well, maybe you make one of those boxes here, those middleares, and you say, I'm just going to catch whatever is on here for like a day, right? So, this one can, you know, bounce on this middleware, and only once or twice a day, I'm just going to ask the CMS for my data. So, you can cach your own stuff, right? And there are actually companies building middleware specifically for that reason. Like, there's a SAS company that is literally only doing that to to just make all that stuff into one API. And so there is a place for these things. And so now that these boxes are starting to become more fancy like this, how does that then still work with this middleware? That's where we are now in our presentation. Yep. Great. So um let's have a look at that code again. And so maybe let's not look at all this fancy code yet, but maybe go here. Maybe I can make it one smaller so I have a bit more overview. So essentially what we're doing to render the page, this is just some um JSX, right? Um React code and here I have a function to get my page and this is an ID of a page in content like a UID. And so essentially this is now set up that it actually has live preview working. And I've done it in this way specifically because this now has a state and it runs in the client. And so this code with that state for the page is done because of this when I type something you see directly it goes here without refreshing that iframe. It's just super smooth. Whatever I do because you're taking input input from the front end. Exactly. So what is happening is that this iframe with my website in it is connected to the CMS through um some sort of fancy connection and every time we change something here an event is fired goes here and that event is called on entry change and every time a change is happening we actually call the back end and say give me that data or that draft endpoint of whatever I'm doing here right now. And so when I do that in the client side, I can just query the data, set the page state with JavaScript in the client and rerender the HTML with React. It's super nice because this is like very smooth. Oh, very smooth content this way, right? you can do all these fun things and um the content editing just like even if I do this and I choose another image file like this is super smooth because I haven't refreshed it I haven't had to wait all that this is why live preview is so cool and this is also why this one works so well where it's even in line and I can do it in an even nicer way right and this is just literally just working and all this all these changes that you just saw while I is typing that works because of this event that constantly fires on change. I query the data from the draft endpoint, set the state and render the page again with reactivity in React. Yeah. And like setting it up this way, right, and you know implementing live preview or visual builder like content teams can test out their content, right? Like that's really why you would use live preview or a visual builder. And sometimes, you know, you put something in as a content person, but you want someone else to look at it, too. It's not just you reviewing it and seeing it. And so, like, this is the best way to do that. Oh, that might be a nice plug. It's not actually out to the public yet, but you will be able to do some work here and then share the state of that to somebody else and they can see it without logging in. Yeah. But that comes later. I cannot say more. Yeah. Don't tell anyone who told you. It's very interesting. So basically this helps us with that live preview. However, I have that middleware, right? And so this get page function actually is just querying that middleware with a bunch of data that it has. And so to be able to do this live preview, the specific thing you want to see for your user editing something without hitting save, we need to have a hash specific to you in your session to be safe because we don't want other people to be able to do that or interject or see your stuff. And so for our API to know, hey, we're in live preview and this is your session and this is you and you're safe to change it. We have to send that hash. And our live preview front end little code has that hash for me. So once that is here, when I do the get page, I grab that hash. I grab the the entry ID I'm content editing, which is this one here. Right now, it's hardcoded because this is a demo. Normally you would maybe query by URL or whatever. Well, yeah. And I need the page type. And so what I'm doing is I'm calling my middleware and I'm giving it all this information. I'm just adding search params, right? So it's going to be um I think we can probably Oh, that's very big. Um let's see in the network if I change something what it shows. I'm not sure that's going to work. Um, yeah, I think maybe if I just go to the local host, you can probably see. Oh, yeah. So, it's querying my middleware now. And the query the query parameters here are page and that UID. Well, right now I'm not in live preview, so you don't see this. But if I am in live preview, you have that hash and that's also then sending that. And I also added that any other query parameter I'm sending it also sends that because if I wanted to do personalization like the persona is unicorn because you're a developer and a marketer. Of course you're a unicorn. Yeah like me. That needs to go. Sorry I said like me. Yeah this is you. Not me so much but mainly you. So this needs to go to the personalization engine that says, "Hey, did I detect a query parameter on this thing that signifies a certain audience?" This could be like a UTM tag, right, for a campaign on LinkedIn or something. And then if somebody clicked on that campaign link, you know, you want to show somebody specific version of a page. Well, that's why I send that information also to that URL, to that middleware. So it's sending a bunch of query parameters based on whatever. And if I actually set this attribute to developer, there's now a cookie. Well, that we just looked at right in this application. There's this where are my cookies? There's this content select personalization cookie thing. This is also in that event in that context of that request that we're sending to the middleware. So the middleware can actually see, hey, do I have cookies? Do I have query parameters? Am I in live preview? you give it all the information possible and then from that with all the information it has it can start to do its magic and so now we can go back to that route and say okay I'm getting the search parameters from that request that you just did so I'm looking for my live preview hash my entry ID my page type and then um basically if there's live preview if that hash exists my endpoint is going to be Right. If there's no live preview, I just get it from the CDN. You just want the content delivery. Yeah, exactly. But if there is a live preview, I want to get it from that very specific draft API where it will that unsaved stuff comes back. So, we just change the host name that we're sending it to in the API call. And so, then we need a bunch of headers. We send the API key, the access token. If there's live preview, we also send the live preview um hash that we created. And there's also another live preview token. Do you see how many tokens and keys we have? This is security people. We need these. We need to be safe. And so absolutely this will already make your live preview work because if we just ignore the personalization for a second, what we do is either we query this draft API endpoint for live preview with whatever things we need to send to the API to get stuff back or we send it to the CDN. Right? So it's going to be I want a content type page with the entry ID, the one that we just sent in the query parameter. and for this environment and I want a few you know extra dimension things. This is just the API call to get stuff back and we either send that to the draft API or the CDN edge and then it returns and then you know it's all fun and games. It works. Does this make sense? It makes sense to me. Let us know in the comments if you have any questions about this. Real quick before we leave the middleware code, can you scroll back up to the Turner operator and can you talk a little bit about that? I'm obsessed with them. I love them. I think that they're great. Not a lot of people use them. Sometimes they do, sometimes they don't. But I love basically it's this. So if we are in live preview, which is essentially that search parameter, right? If we have live preview, then my host name is going to be um basically draft API URL. Oh, oh yeah, there you go. I'm just going to type it like this, right? And then else if I'm not in live preview, it's going to be my CDN URL. So it's it's cached in super fast. And so this URL allows you to get data back that's not saved. You know, stuff like this. Right now, that endpoint will return this weird title. And the CDN that we just looked at, this one will return whatever was published before, which is this. And so this you can hit a thousand times without actually having it breathe heavy because it's just a CDN edge. It's super fast. And then the live preview one is just for you because you're live previewing. And so that it's kind of fast. Yeah. Enough because it's just you, right? API. Yeah. That's what this does. And so that host name is now different. And so based on if there's live preview or not, we query this different host and then this is just the content stack delivery API, right? We want the page for that specific UID for the environment that we have saved in our you know environment variables. And this is basically just if you this is essentially calling content stack from the API side rather than the SDK side because the SDK would do all this for you. You don't even have to know. Right. But again you have middleware so we need to Yeah, you have middleware. So I could potentially run the SDK here too if I wanted to, but this is just cleaner because these middleares are basically backend code. And so using an API, this works well, right? This is nice. And so now let's talk at personalization because in the end, the only thing we have to do to get a different variant of a page is send a header called X content stack variant ID is blah blah blah. Right? So variant ID is either base or both or marketer or developer. Right? In our case, this is kind of signified with numbers. But essentially give me the marketer and you see this is different copy now. And the only thing that you have to do to get that different variant is just give this header just like you give a header for the API key or the live preview token whatever add this header and you get a different variant. And of course in you see that typo again it's always something um actually if you did this with the SDK this is much simpler but the SDK literally our SDK does this code yeah for you. And so this is where personalization comes in. And so we need to actually figure out the right URL for our endpoint for personalization because we have an API. We need to fetch from the API endpoint from our personalization project. Um you basically have to initialize it and fetch your manifest of what variants even exist, right? For which entry types, for which page types, which variants do I have and how many do I have to combine? what is in my cookies, what is in my query parameter. So what you do, this is the personalization SDK, you know, that's an npm package here. So what this does is I initialize it with my project, my personalization project and the request that was sent. This request contains all the query parameters and all the cookies that that the user has. And so based on this smart stuff is coming. And so it gets whatever varants exist in our manifest. It gets it back from the SDK. It's super easy to do it that way. And then it has to like compute it into like an array of multiple potential um variants it can show because potentially this homepage can show five variants of different entries on the page and it can be a combination of multiple, right? And I didn't do that for this one because it would get complex fast. Right. And this is really just a proof of concept, right? Exactly. And so you figure out what varants to show for the entries that we have and you just add that to the header of the thing we're querying. And so we essentially reverse engineered our SDK in this code here to do exactly what the SDK does as well. And that's where and that's where your middleware sits. And so in this middleware, you can do a bunch of other stuff, right? When I get back my information, I can now map that data to something completely different. So my front end still understands it. And so if you for example have a CMS that's not content stack here and your middleware is there to map that data so your front end doesn't have to change. Well, in that middleware now, if you change your CMS to let's say content stack and you add personalization and all that fun stuff, the only thing you have to do is change that middleware with a bunch of this type of code. And I assume when you do it in production, it's a little bit cleaner than this. But this Yeah. And you would have like error handling too, right? Because that's I don't think people talk about error handling enough. Give me a break. But yes, there's almost not even if else's here. Let's be fair. Like I literally just return stuff. I don't even check if something exists. Let's be honest. But as this is just something I wanted to like code something in like not a lot of this is like 60 lines of code that essentially just replaced our SDKs that would talk to content directly. Now you can talk to our middleware. So now it's just front end to middleware like give me stuff. Middleware is clever. Find stuff from all these different places. Maybe personalized stuff. Maybe map some things. Maybe it goes and updates a search index here and then it research it and then it returns it for you. Suddenly your front end looks beautiful. And we've had prospects and customers and and folks we talk to that don't have one middleware but five. Yeah. And all these middleares talk to another like legacy system to figure out user data, change some things around um concatenate strings together with hey name, welcome blah blah blah. And that name then comes from another middleware. Like all that stuff exists. The bigger the company, the bigger the dark corners of data are and the more poor DevOps people they have that have to deal with that stuff, right? Yes. You know, and there's like again that custom database or custom that is that only one person knows about. So like this. So there's some really awesome custom stuff around here that maybe this will just talk to directly. We don't know. Maybe they did it even worse and it just goes here directly to the front end. Yeah. Everything exists. And so what content stack's job is up if it's up to us of course is make all these services work agnostically from each other because we just made this thing work with visual builder without using our SDK at all. We just used an API call and if you did it with the SDK you might have less code and it's more magical but it kind of just works. So when you start from green field of course you want to do that but we still need to make it work in all these different angles. with all these different boxes, right? And I saw recently one of our colleagues implementing personalization in I think it was Salesforce Commerce Cloud where they have something called cartridges and they cannot install npm modules. Oh, so he couldn't use SDKs. So he fully just API called all of it, everything. And so it's possible because we are a composable DXP. It's a headless system where the API manages 100% of all the features that we have to offer and then we add SDKs on top to help you. You can do all this stuff with the CLI as well. You don't want to, but you can because all these things do all the things like like how how else would I say this, right? Yeah. And from like a data accuracy and content accuracy perspective, right? it would make sense that you would set things up in this way either by using the SDK or if you have middleware doing that because if you have a PIM for instance there's a reason why you have it right you want to keep your product data and your product information and inventory in a system that is tailored to doing that right and you just want to pull that information out rather than dumping it all into you know the CMS MS or somewhere else and then changing that and then sending it back. You always want whatever system you have and especially if it's a PIM to be the single source of truth for that product information or that particular type of information. And interestingly is sometimes like our CMS could have an integration with that BIM where in the CMS you can just search your BIM and select something. That's one approach. But you can also just say my BIM goes to my middleware and my CMS goes to my middleware and let them figure out how it's connected in the code or you do it all in your front end. Like there's so many options. Like if you if you look at the screen again like that BIM thing can be like this or it can be like that or it can be like that. And there's like let's let's be honest composibility is not exactly easy. Right. And so we're here to help as content stack for DXP um to just offer you all these different hooks you can use. um we just have to give you these kind of live streams where we show everything so people start to you know start to vibe with us and come up with their own ideas because the moment we do workshops with developers and we show this stuff you really start getting like twinkles in eyes and like oh yeah I can connect it like this and you really see the connection in people's brains like oh that's how you do it and that's why those type of live streams and we need to write this stuff in these drawing boards like this like I love whiteboarding because this. I know. I love it, too. We don't do it very often, though. We should get back into it. Um, yeah. So, if anyone has any questions about the stuff we just covered um in regards to middleware or really any content stack uh related questions, we're happy to answer them. You can type them in the chat now or you can join us in uh the community. I clicked the button before you. that's fine. Um um but you can join the community. You can ask us questions. Tim and I are in there. Some other folks from Content Stack as well as the rest of the, you know, Discord developer community for Content Stack. We have lots of other events and things going on. Um, in addition to that, I want to talk to everyone and let everyone know that we just launched a new community author program. So, you can sign up and um, apply for that to become a content stack author where your article like a tutorial guide or if you have a conceptual um, article you want to write about, we'll get that on the blog. Um, you will also be compensated for that. So, if you're interested um in applying to that, we've just put up the URL for that. Um it's dub.shcsauthor. Um so, if you're interested in being an author, contact us. You can either click that link to apply or you can talk to one of us in the Discord and we'll be happy to help you out with that. I think the moment you posted it, you got like immediately so many people who wanted to do this, right? It's super fun. Like we want to create cool stuff with people, not just us. Like we're also just developers. Like we want to see what other people come up with. You know what you have in mind to build. If you have like a super cool subject you're really into, let's say media management or images or delivery, whatever, write it. We will put it on our blog if we like it enough and we will work with you to get it to like the level we need. Exactly. there is sort of this mentor and knowledge exchange that happens with a program like this. We will help you get it ready and also a lot of times you have an idea that you want to communicate or something that just helped you that you learned while working with the product um but it's not necessarily in the format that someone else can go and replicate that. So we will help you tailor and structure your article in a way that makes it easily reproducible by someone else because part of this is like us all coming together and sharing our knowledge and helping each other and helping other people who will come. Exactly. With that bombshell, we're done. We're done. Was an intense hour, but I loved it. Yes. Thanks everyone for joining in. We'll see you soon. Perhaps we'll get into some PIM uh integrations at some point soon. That could be interesting. I'm actually working on something now and I'm kind of figuring out what the nicest way. So, we might show that. Yeah, that would be awesome. All right, folks. Thank you so much for tuning in. Thank you, Tim, as always. Good time. Same here. We'll see you next time, everyone. Cheers. Bye. Bye. Bye.