How to use Rich Text in a Headless CMS
Join Bryan and Tim from Hygraph as they explore how to use a Rich Text editor in a Headless CMS. Learn about features and ways of implementing them in your front-end! Ask us any questions in the chat and join the community: https://slack.hygraph.com
Transcript
[Music] W every time that intro hits I'm like so soothing I I'm ready like it's it's 10: a.m my time I'm ready to go back to bed is it exactly this is like the best yeah I'm at 4 pm here but I'm good now it's always fun right when we always have these discussions and like oh no we have to go live let's click and then we just continue the discussion that's how this goes that's we're we're vibing right that's is isn't that what the kids say nowadays I'm I'm too far away from that but I'll take it exactly I'm there too I I I am not one of the kids I'm I'm not uh um Steve bashim meme with the skateboard hello fellow oh boy yeah ex young people yeah exactly this is Uncle Brian and Uncle Tim talking to you about rich stxs in hatless cms's did you know did you know that I am probably one of the biggest Rich Text Geeks out there really because I kind of try to stay away from them because they're so kind of complicated and they almost always do what you need but the moment it really needs to happen they tend not to and so that's also why we have this stream right we need you to actually explain us all the things and because they're different in hatas than they are in let's say more traditional sense of things here's the problem Tim not all headless treats it differently and that promise of headless in a lot of ways right oh man the broken promise of hatless comes back hunting me all the time I even wrote a block post on it once it it is very much like it's very easy right to to break the promises that uh that headless brings us but like so real fast because I'm I'm also like a um The Geek is coming here we go no I'm just kidding yeah rant time right like that's that's what I do I basically just do rants oh there we go uh but like the idea of Rich Tex and why we call it rich text right because a lot of people who been in the industry for a little while uh would probably refer to it differently right they would refer to it as whsy wig which if you're not old like me you might not even know what kind of word that is uh it's not even word that word it is it is an acronym right what you see is what you get right whsy wig which sure yeah um and it kind it dates back to like early early cms's especially around like WordPress error stuff um and literally what you would see is what you would get right you would you would enter content into this like Big Field you would then it would generate HTML in the monolith CMS pump it out into what the front end that's attached to it because back then like you it wasn't the same yeah and it was what you got right but is this also the Dream Weaver era where you would build websites like that almost to a degree although I wouldn't I mean you could definitely consider dream itself almost a wiy wig editor since SP out the HTML code but maybe bigger than that um remember that photoshop did it too you had a little slice tool where you could kind of slice it and it would make you HTML but it wouldn't like extract the text and stuff and before before Adobe bought Dream Weaver right because Dream Weaver was macr media I believe before that yes I remembered that time before they bought it they also had fireworks uh which was kind their own like the only thing I ever used Dream Dream Weaver or fireworks for were doing image Maps uh oh yeah exactly dating myself real hard there yeah yeah yeah me too but uh but image Maps image Maps were were a thing they were really difficult to deal with um but like Dream Weaver and uh and fireworks made it actually pretty easy to deal with um but yeah you could consider that wiy biges although when I used to have to teach web development and use Dream Weaver I refused to let students use the graphical side of Dream Weaver yeah exactly we used it for a bit but then we like we just went to code because it's there was more fun to be had somehow well and also just it oh look look RZ just said it Go C was essentially a big what you see is what you get editor right yep and low is right you did like we could go into fdp but we probably won't the fun thing right is almost any stream where I get to talk about history of web whether that I've done on on like the compressed FM podcast like that that podcast went off the rails because like we got really into like the old school stuff but it was a great conversation I love this thing but yeah it's it's very much like I don't know understanding the history of where we got to where we are is is important um but when we're talking about rich text right we came from this era where literally what you saw was what you got and then the Headless era if you lock in your Rich Text Editor to Output just HTML that doesn't work in places that don't support HTML it doesn't it doesn't work exactly it doesn't work in a lot of ways and I think anyone who has used the old WordPress API like before before Gutenberg but when they were still like playing with the idea of headless like it's just it's just this horrible escaped string of HTML and that's like I used to uh run a team at a small agency and we had our own Cs and we used tiny MCE oh I remember that bad boy one of the big players right that was like the the wizzywig editor uh but it was just pure HTML we stored it as an HTML string in the database and spit it back out yeah and so it's just unsafe ex accessible stuff that you would put in essentially exactly I just remembered I worked just before I started at startups my last agency project was with Adobe AE M but it was their hybrid Atlas oh let me just say hello to NG welcome um and so they had like this what you see is what you get stuff a little bit and what you could do in their CMS is kind of drag and drop stuff into columns sure and then guess what came out of their headless API in Jason pure HTML pure HTML pure HTML in divs and and one output of one page was minimum 5,000 lines even if you didn't use these divs if they were empty they would come out it's all this fun stuff about what is what you see is what you get what is Rich Tex is it layout how much HTML do you put in did you paste it from word and now you have the most ridiculous HTML in there like it's it's all over the place yeah anything that is GNA output HTML is a mistake uh oh we start off wrong today I like it oh yeah oh yeah no no sugar coding this like it is my website my new website uses Rich Text output HTML from hgraph so kids you can do itbe when we dive into code the example that I have that we're going to work through because when you're prototyping absolutely no big deal we output HTML for you um but it's what the default HTML output is and that is by no means what you want and it's absolutely not what you want if you're not building a website with the data coming from hgraph exactly because that's so cool about hatas and Rich Text is that it's not always for HTML it might be for you know a bus stop digital sign or for a kiosk or for some I remember building a checkin Kiosk for KLM flights yeah which had data come out and it had i6 back in the day but it was not HTML it came out differently and then we had to you know but they they did edit it in and what you see is what you get style thing and you and you want in in many situations you want like bold and italics and all the different little things that you get out of Rich text but you want to be able to control the output and you want to be able to I'm a big fan of when we talk about headless I like to talk about remixing like obviously if you've seen me talk about like content Federation in the past I love talking about remixing but what Rich Tech text and and keeping that as data allows you to do is remix it any way you need to even if you want to what we're going to do today render the rich text in two different ways on the same page for very specific reasons you absolutely can FC you have one piece of data and then you can use it in multiple ways on the same page on different pages wherever it needs to be um but you can control every bit of the output or let's say you want to like um toss it into make an RSS feed you might need the output of that to be different like oh 100% it's just like simplified or all the The Styling out of it because it's atom or whatever you want to call it or XML or yep and so maybe with that that's a lovely bridge I'm not here talking for you but hopefully this fits do you want to like explain what that thing means like going from I'm just editing I adding Bol and I have a link and I have an image in there or whatever can you explain what it's called when you go from that that rich pipe what you can see on the screen here right now to this Json structure what is that exactly so so what it is is and I am by no means a computer science person right so I'm I'm not that style geek but uh the the actual like term that you'd be looking for in terms if if if you want to do more research on this is actually an a uh I should have relooked up the acronym for the stream uh you might want to Google it to your it is a style of of object tree um get the actual it where's the definition there we go it is an abstract syntax tree and it's just a way of storing data in a proper way that makes it more easily accessible by code in in various ways uh and so what it amounts to is all of this lovely information in this content field right we've got a paragraph that has a bold tag we have a link inside of a UL we have a headline in H2 all sorts of stuff in there when we go to say our API playground let me get rid of some of this real fast and we look at the content and we say we want the uh Json implementation of that it comes out as this this is ASD right so each of our posts has a Content object the content object allows you to pull in right we could come down here we could actually get this as HTML right I play this again and let's hide the Json and here's that you zo just a tiny bit yes by the way if that works H this this interface might make that a little yeah there we go yeah I can I can adjust some things so we can see it a little bit better like here's the HL representation yeah and it's not bad right paragraph strong tag here's an actual anchor the anchor has a title like by default a lot of lot of decent stuff in that um but it's not necessarily ideal and so we can actually take it and re-represent it as Jason as data and so we have here you might have some very specific accessibility rules or some anything like that where you want control or you just might not like what comes out as H or we we have a video on the YouTube channel where I I add tailing classes to everything right because you could Pros tag around it with their typography stuff but maybe you have very specific classes you want to add to everything and you yeah you want that in your HTML um so when we look at here we've got a children array that's directly on that Json that actually represents each of the items inside of that as an object and then if it has more things inside of it it goes deeper right so when we look at it that first paragraph which was one paragraph of text with one bold inside of it is a type paragraph and then it has multiple children the children are the very first word in there which is just the word a and then we go into another child which has more information which is it's B equals true and the text inside of it is content there's no children inside of that so we don't have to go further and then we go to the next child which is just the rest of the paragraph So now I know in this representation I have one big paragraph with one other tag inside with content split on either side of it so there's a lot of things I can do with that and we have some some tools to help you get through it because you you don't necessarily want to build your own as like tree traversal JavaScript library it's a little intense to do that yourself yep like doing that though but it's pretty intense I don't like doing it I I don't think abstractly in data I'm a visual person in a lot of ways like my my background was in in uh in design first and foremost but you see we have all this and we can use it to then transform it into HTML or transform it into any number of things um so what we can maybe do is is kind of go into the example that we're working with today um this is just a very very simple like blog layout uh it actually mirrors a little bit of our nextjs blog uh which we have as a starter um but we got two blog posts and inside of it you can see we have all that HTML so the the rendering that you saw inside of high graph here is that thing with the with the buold tag and right now in the code which I already have some set up we're using 11y because I want to show it in in as Vanilla Java Script as possible so that we can kind of see how all this works what's happening currently is I'm making a fetch request to uh to high graph right we're using uh graphql request here's my endpoint you should probably put it in an environment variable but that's not a big deal for this and then basically I'm looking to get all my posts I'm getting the slug the title and that content and you can see that I'm already doing I'm getting the Json but I'm also getting the HTML and then all I do is I export that out and that's what 110 wants we won't get too far deep into 11d territory but what ends up happening is we go over to our post and and I get the data in this front matter and then I spit out whatever I need to as template language so for now we're using the HTML yep from that post Okay cool so I mean if I wanted to like use Json you know I I come back over and like an object now just you can use Jason stringify to show people the Json I guess I could I'd have to I'd have to code that's not built-in filter in oh yeah inity you probably have to make like a filter with a pipe like in the templ that would be liquid NJ or that sort of thing and one of them actually has it but I'm not going to like yes not for now it's fine I think I'm in liquid I think liquid's the one that has it might actually work oh wait that was that was HTML I need Jason Jason no I think it's if I if I look at my just says it'sing it's just not yeah exactly not it's not a built-in filter there I've built that filter before it's a super easy I can imagine yeah exactly um so yeah we go back to object object but we don't want the Jason we want to roll our own version of this so what I want to actually do in our stream today and I think it's totally reasonable in the next 45 minutes is I want to convert all of this last words I know I have cheat sheets Tim I have cheat sheets on this monitor over here will be fine I have all the code uh in fact if anyone wants oh I don't have to GitHub Page open anymore uh let me pull up my notes real fast if anyone wants to see the finished code it's not as pretty as what's currently here but I'm posting in chat from the hgraph account yeah I also put it here as well so you can have a look there that is that is like this proof of concept we're gonna build a table of contents for our blog posts based on the headlines so we need a few things for that we need each of our headlines to have an ID and we need to build a table of contents um both of which If This Were pure HTML would be a pretty big pain right I could actually take this HTML I could use a a JavaScript library like Cheerio I don't know if you're familiar with Cheerio oh dude D you're taking me back Cheerio is an mpm package that takes an HTML string and then treats it like jQuery so you can s i just gonna say doesn't have I think it has the jQuery bars or for HTML in it what's the name again you use everything right the dollar sign parenthesis all of that is J C syntax I love it it's good um you shouldn't use it you don't need to use it uh but it would still be a pain to grab deveral in not GS in memory that's what it does so we could do that and then find all the headlines and then in memory create an extra string with links put it above it's pretty painful but kind of fun to do but don't do it please i' I've certainly done that sort of thing before like I've built my own static site generator and that's kind of some of the things you have to do when you do that because yeah who hasn't built a static site generator who hasn't built their own CMS it's just what we do as devs um however we're not going to do any of that today because all all the stuff that we have is ready to go and what we're going to use is one of high graph's Rich Text uh packages so I'm going to link this in chat as well um so while you do that what's super interesting here is that you don't have to write your own EST interpreter and write all your HTML yourself you just use the one that that high graph built yep use that and then only adapt the things you want to change maybe you want to change the links that was one of the questions actually in our community the other day like how do I change this hey I see around it can I change that well if you just change the link there you go so we give you everything and you only change what you want but today we're going to go slightly deeper because we're going to interpret that Json make it just render the thing and then add stuff on top um to link to the subheadings yeah and so we're we're gonna take this in phases right so first and foremost in in this uh package um there is a pure like as to HTML renderer which which is what we're going to use today because it is the very basic right you can you could use this in any JavaScript framework we also do have a pure react version as well you get a react component many of the things we're going to do work the same way you just pass it into a component instead of passing it into a JavaScript function and then there's also the ability to get your types obviously if you're using typescript we're not going to do that today and then if you need to take HTML and convert it back into there's a package in there as well because you don't want to do that either that is a terrible thing that's probably harder because HTML is not strict yep that's why xhtml died because HTML is pragmatic it's liberal it's very complicated to work with but it's a beautiful thing don't get me started on HTML we'll just talk about HTML the rest of the time be careful so that's there but the the little bit of homework I did beforehand is actually my pack Jason you'll actually see I've already installed the rich text HTML renderer so you just run npm install gra CMS Rich Text HML render and you get it same for the react one you would just have it be rich text react render right you have few as well by the way just pointing it out because I love VI uh let's see yeah we have an example of view but I don't think we actually have uh component but this would be how you use the HTML renderer to make view work sure yep uh so yeah so the first thing that we need to do instead of just having our posts come back through as just the pure data that's coming out of hgraph we actually need to transform the data to do that so I could do it in line in my export down here and again this is some of the syntax like in this file is like what 110 wants it's actually a commonjs package they're reworking it into es esm modules now um but before we do that I'm actually going to write a function to do all of it for us keep things a little bit cleaner keep it a little bit tidier uh so I'm going to create a function just out here in in the world I'm going to call it add content it could really be anything uh and I'm going to pass into that actually needs to be an async function oh yeah because it somehow it has to await something yep and we need the post and then we're going to do things to the post the post being oh I should turn off let me turn off GitHub co- pilot uh so why is this an async function because it's not doing like ax gos or stuff or is it just is to keep the build process as fast as possible we're going to do like there are two posts in this one right but we're going to do it literally for every single post so if I've got thousands of posts I want I want to not block the thread so you want to do one then the next then the next then the next well I want it all to be happening behind the scenes too we we're just gonna await all this yeah it'll it'll yeah yeah and the nice thing is you know 11d um in the data files all on build right it's kind of nice it is all 100% on bu that's the thing about 11d we're building HTML we're sending it to a CDN and that's it so quick tip kids if you do this in next or next or spelt kid don't do this at runtime in the client because you're going to send a pretty big bundle and a CPU hungry piece of coat to your users do it in SSR or on build like this with 11d yes yeah this is this is this is definitely one those times where your server or your build process should handle I it's not the worst thing in the world because again you're only dealing when you hit that page if you hit that route you're only dealing with one post at that point um this is just the with 110 we get all of our posts at the beginning do it all because it's we're we're building exactly in your various front-end Frameworks nowadays you could potentially do it I just yeah you want it to be SSR or build time preferably all right so the thing that we're going to do here here first is that we need to take the content that we get from the post that Json content and we're just going to start by passing it into the function that we get so before anything else since I've installed that uh package I need the as to HTML converter right so we're gonna grab from Rich text to HTML renderer the as to HTML string method and we're going to use that to convert everything so in my ADD content function here the first thing we need to do is grab that I turned off copil it's still on it seems I don't know we'll just we'll just it's telling you exactly what to do it seems that's pretty Co it's telling me the wrong the thing I don't want to do right now oh really oh it's I don't a I don't want to mutate my object I want to I I want to keep everything clean but also I want I'm gonna want to do more stuff with okay what I'm getting so uh we'll start by just getting a const and that's going to be from our post we've got the content. Json but we actually want to go one step deeper in that because I know that we have that children array oh yeah exactly we're going to be working with our uh children right that's it's bring your kids to work day today uh con content equals that there we go so we've got this new so you have to do one step in yes which again you don't have to do this you you can do in you know one line one liners more often U but I'm just going to call uh this const uh I'm gonna start by calling it HTML and we're going to await the function which is the a to HTML string uh and then don't listen to co-pilot here everyone that's not what we want we pass this an object and the object is the content it can it'll also have renderers and a couple other things as we go forward but to start with we're going to to pass it our content and just for explicit n the explicit nature I'm going to say content colon content in JavaScript I could just say content it would infer that properly but we have a property named content it needs the array of children exactly I was reading chat uh oh yeah yeah me too this is super cool thanks nimit for putting this stuff on this is absolutely the right way of doing it you you can use HTML that we output you absolutely be doing it with Jason it's a little extra work but it's going to give you flexibility I'm hoping nid you followed it here it does exist in the docs it's great exactly um all right and then all we should have to do at this point is I want to return back out of this it's actually kind of helping right now I do want to get all the things I had from the post so everything that came in I'm gonna put back out but then I also want to and I'm actually gonna ignore what it's saying here I want just an HT HML I want the HTML to be in there and later I'm gonna have something else so I need to ignore that part of my cheat sheet so now HTML already exists right so do you over it doesn't already exist uh what it currently exists in the in the thing is post uh content content all right you're right sorry all right no worries a great question there are some confusing aspects when naming hard um all right so now what I need to do is I need to take the all the posts that I get from this and I need to run it over this and again I don't want to mutate I want to say const um it's trying to help me but posts with content how is it understanding this so well this is wrong ignore co-pilot sorry it's trying its best uh but it doesn't actually know this um and then we're going to await uh sorry we're going to take posts and we're going to map over that now it knows what's going on we're going to map over it using our add content function right and mapping is going to take every item in the array run it through this function and output that into this new variable again we don't want to mutate the posts array we want to create a new array that we can then export and that's exactly what we're gonna do we're gonna export that instead of posts shouldn't you await this function uh let's see no function right uh we are awaiting and and this is you know perhaps it doesn't actually need to be an async function up here if this is an Asing function I understand GitHub copilot now because you have to do a promise all to await everything in a map yeah there are problems with that I wrote this code eight nine months ago actually uh there were issues with that and I think they were they were 110 issues um oh really well let's continue and see right now it's an function it shoots off and it doesn't wait for it who cares if it works it works exactly uh and I think there there's some magic behind the scenes in 110 that's taking care of on that too don't vote me on that but I think that's the case interesting okay cool been been a bit for me I have to I'll have to go back and research I'm gonna write this up as a blog post so I I'll make sure that I think about that for the blog post exactly cool yes so we've got post with content and that is now what we're going to Output from the data file and then inside of our post. HTML to double check something real fast if I can remember how to use this over here just to make sure yeah um so what what 110 does is it doesn't actually care about what I call this return statement right it just cares about what my file is named and it actually creates in the global data layer a variable called posts so there some black magic going on what's that there's some black magic in 11 for this it's nice it helps you it it it is by default it wants in the global data to uh to name the variable based on the file which I like I'm I'm an 110 stand um but we do need to change this right this is no longer what we want this is the HTML that's coming from high graph what we want is that new piece of data that we added to our to our object called HTML and then we come back over and nothing has changed and that is absolutely as it should be I'm going to double check that we didn't an error yeah cool wow I'm amazed this away this Asing fun just deals with that but there might be some magic behind the scenes then again like 11 11d is taking care of some things behind the scenes there that's nice cool there was there was weirdness in the way the 11d dealt with async functions um and so that's that's why a lot of this exists but like this isn't cool yet right I wrote all this I wrote how many lines uh 10 lines of Code 11 12 line or 11 lines of code right all to do what I got out of the box already that's obviously not what we're here for right like let's not write more code to do the same thing let's now expand that so that we can do more stuff so the next thing that we need to do is we want each of our headlines uh requirements project setup Etc to I'm going to add an ID to the HTML and I'm actually going to wrap it in an anchor tag because a lot of these like when when you build like a table of contents anyway like if you go to our docs right now you hover over a headline and you can click and you can get a link directly to it it helps with sharing it helps with like long Pages a lot of things so we'll start with that right we will re uh render the each headline in our data U sorry I'm just sending something to nimit but I'm not sure when I do a chat it actually goes to LinkedIn interesting interesting yeah so uh nimit if you actually open source your project feel free to join our stream and perc what you've done we love that stuff that's what I wrote to you but I think it went to YouTube rather than to LinkedIn it works sorry to interrupt but yeah I'd love to see it too just even even if you don't want to come on stream I want to see see it share it oh we 100% want to see it but everyone wants to see it too uh actually we want to everybody to learn about the cool stuff you're building y all right right so so next up I actually have some cheat some cheat codes um that we're going to use just for just for Simplicity um so what we need to do is we actually need to go through the data that we're getting back and we need to identify the children that are one of the headers so all the all this all this knowledge is also available in the documentation and in that GitHub repo you can find all the information that we're kind of going through but one of the things I know about the structure and I and I learned this because I I didn't read the docs first uh but I learned it because I'm a console log developer I console logged the entire array I found what I needed to know and I and account went forward with that uh but I've created a couple little helper functions and the first one is this idea of is a child one of the headers and I you could do this in line uh but it's kind of a long like or statement right if the node which we're passing in the child that we're passing in each child has a type we saw it in the data right type paragraph type let's let's look at that real fast let's go you like console log it in and have a look at it it's cleaner here so that first child is a type paragraph uh inside of it uh it's just some text but has a bold but let's go and find here type bulleted list um type heading two here's our first heading we go so each of our headings is heading one heading two heading three heading four heading five heading six roughly equates to H1 through H6 right um so what we can do why does ASD do H1 or P or Li for this why is it named like this that's an absolutely wonderful question add like it's just only like let add a bit of opinion here why not yeah it feels like graph q a little I don't I don't know an answer although I would say when you get into all the tags right type P sounds weird like if you're just looking at or type type a um yeah it's not a great look at that point like it's not very explicit if you're just looking at the data as a human it becomes a little bit more obfuscated a little bit harder to understand yeah I can imagine if you want to go from this to let's say um a word document or something or some other format then suddenly this starts making a little bit more sense and again this this also corresponds I think I'm speaking before I I look uh to look at oh yeah there it says heading to yeah so it's also a little bit easier when you're looking in here what are the things in the rich text field and how do how do they equate yeah um so that that's what we're going to do that's what this little teeny function does is it checks that type on each of the children that I'm gonna pass to it and checks to see is it heading one heading two heading three heading four heading five heading six oh yeah there we go cool if yes return true right and we're good um so I'm going to at the top of my file we're going to check we're gonna bring that in right so const is header require that file right just want that function again this is just to keep my code a little cleaner and because I've got even more than a cheat sheet I've got cheat codes we like it yep all right so the next thing that we're going to do is we're going to take sorry I'm having to make sure I'm doing this out of order to the way that the the the stuff actually goes um I want to check through the content with IDs or sorry the the content and I want to filter it based on is header so I'm going to take my content and I'm going to find uh const content with headers um actually no I don't need to do this I'm sorry I'm getting all all out of whack here uh all over the place I know well we actually need to do is before we get to that that's how we're gonna actually create the next thing of of stuff we need to specially render our our headers and we actually have things built in for that so I'm going to create custom renderers for each of our headlines so out out here I'm going to make a new function const renderers and that's going to be an object and for each of our headings we're going to actually use a new set of of content here right so I want my my headline to now also have an ID on it which we're gonna have to add in in a second and we want to wrap each of these let's do a little bit of uh vs code Wizardry here oh Magic an anchor tag that has an href that goes to pound sign um pound sign interpolation of ID guid yeah yep uh so we did that for all six of those but Brian you might be asking where do those IDs come from that's why I was getting confused with my cheat sheet we need to give an ID to all of our nodes um so I have this other cheat code which is using the uuid um package which just creates you know specific IDs over and over again that's all it's here for is to give me IDs um so let me grab that as well isn't this like one of the most used npm packages ever anytime I need an ID I use it and I assume that's the same for almost almost everyone else basically everyone yeah exactly so I'm gonna add that that function up here and then we're going to map over the content and we're going to have a content with IDs so we're going to take that and yeah I think that's actually what I want let me double check so we are not going to mutate anything and we're just going to keep it clean all the time exactly never never mutate when you can just rewrite um so now I always mutate though I have I need to learn this I always M you certainly can but side effects you never you never know when you're gonna need the clean data true true um so now instead of passing in here for our content we're actually going to pass in the content with IDs which all this does is it is it literally goes through every single every single node and as data it returns back everything that was on that node as well as a new ID oh so every node also the bolt stack everything for now I check for headers but like it's fine it doesn't really matter I guess for now it's super fast it it doesn't really matter in terms of this style performance anyway like this is all also um it's all build time if I were doing this in in frontend code right uh potentially even server code I would absolutely only run the but it's it's data traversal like computers are good at that yeah exactly and it's on buil so who cares yep so we're gonna pass in as our content this is why I explicitly said content callon content before content is now content IDs and we're going to pass as our renderers you can see all all of our packages are typed so renderers we know exists and that going to be again I'll be explicit the renderer variable that we put up here by default we have a renderer for every type that you get from our Rich Text so all we're doing here is we are overriding some of these things with our new renderer so theoretically I have a pretty spicy question though oh no why is it called H1 now and don't ask that question Tim I don't have a good answer for you on that question uh in fact I'm pretty sure I wrote this the first time this is where I broke the first thing oh 100% I can imagine I think I think it's with Dash do this right you cannot do that you cannot no you cannot exactly well with with quotes around it but it kind of sucks yes and and it becomes it becomes I mean consistency is important would it be better that way tedious you know yes but like naming is also hard uh so theoretically there are no errors so we should be able to come back oh that's kind of okay I got a small issue somewhere in my actual HTM you know what I didn't do remember everyone when you open a tag in HTML you need to close it so let's do our magic vs code I'm holding down the option key on Mac here uh which I assume you would hold down the ALT key alt or something uh but it lets you basically select multiple lines and do the exact same thing on every line uh and I also need to come back and finish typing my uh my anchor your link yeah exactly there we go I do there we go oh wait so for the header one you give the header the the you give the header the ID and you add a link around the header itself specifically this is for this specific piece of functionality right we don't need this for the table of contents we what we need for the table of contents is ID equals the ID that we gave it exactly okay and you could do this in any number of ways I'm using but you could also take you could slugify each of the headlines yeah that's probably the better way of going uh but in like in 110 I'd have to do it's more complex than we need for this we're just adding IDs to everything essentially in the simplest form you wouldn't need the a tag around the child inside the header right it's just to be able to click it and it's nice exactly and and really what what we might do right instead if if we were doing something fancy would be we'd have the headline and we'd have like you know the like SVG icon for link oh yeah exactly like show that on Hover and there's all sorts of like cool fancy stuff we could do there some clever stuff yeah this makes sense thanks yeah uh so now all these are linked right so you can check in the in the URL up here these are the the URLs the the IDS that we provided and they jump you down right they're jump links so now I could share this link if it weren't Local Host and get it where yeah awesome so at its simplest we have created uh renderers for every headline and you could if you needed a custom a custom renderer for uls right you could create a custom renderer for uls and so what else other than ID and children could you get back in a renderer anything of the whole Dom node so you're not getting a Dom node at that point right you're getting no not yet not yet it's just you're translating it to a string right so so this this renderer is an HTML renderer so we don't have one that would render to some other like to XML so if you needed that you could write a custom renderer for each node and you'd have you'd have in the as to HTML you'd have a render that would work for this sure okay thanks yeah and and that that's kind of how it works also in the react one right behind the scenes um so yeah any any of the pieces of data you can create a custom renderer for because I'm thinking like this children property here in the header one function for example I imagining that it's Jason yes so what's happening here this is this is where it gets complicated when you code this like code this yourself code an a translator yourself exactly yes I'm going children then runs through the as to HTML converter again there will be a type on that and then if if that type matches one of these renderers it does that but that one also has children and if that children is more than text and has a type it runs through it again and again again that's crazy you send the string and that string is interpreted by this ASD render as a bit of HTML and a bit of Json and it takes out the Json and then recursively runs over that that's crazy but lovely for us though when I thought about how to build this which we had when I started we had we had this package and i' I've thought about this multiple times right like through the years at various companies it it literally broke my day my my brain for a day and a half like I I wrote something that kind of worked uh there's a lot of thought that has to go into it and yeah you you have to recursively run it and yeah there's there's a lot that goes into it this basically abstracts all that complexity and says when I see a type do this pass it to children you don't pass that children like if we want every headline to be the same right yeah exactly then then it just doesn't do anything yeah exactly well it would do something it would render an H1 with the ID with the anchor tag that has the link to the ID with the word high exactly want to change things I could yeah true but this is kind of nice for the react folks because they they re they always send children to things yes kind of fine it feels the same and when you think about it when you're thinking about this sort of thing like what react is doing at that point is basically recursively rendering things exactly you pass the children in and then you do something with the children sometimes the children are are more react components right yes just sometimes it's HTML monke all the way down like or Turtles all the way down whatever it is um but yeah okay let's not go into how we render react let's not go and let's not let's not talk too much about the actual as uh traversal because it's it's for the Nerds but this works y you you want somebody else to talk about that not not this is how you work it um all right so this is stage two right stage one we got our content re-represented with HTML that we could then customize stage two we customize all the headlines to have ID we customize every node inside of our data with an ID and then we surface that ID on the custom H1 through H6 tags that we render with an anchor tag around it and an ID on it so when you're building a table of contents on a page all you're really doing is Prov providing a series of anchor tags and those anchor tags equate to one of the IDS on the page this is just like basic basic HTML when you have an href that has a pound sign it looks for an ID on the page so as long as there's a matching ID the browser will automatically push the user down to it and that's the basics of what we want for our um our table of contents yeah so let me go back to my chat this where things could get complicated but I also have more Jeep codes available as well um all right so we have our content with IDs we are currently Translating that into HTML I am no longer going to touch this we don't need to mess with this HTML anymore what we need is to render from our data another set of HTML for our table of contents yeah so what we can do is and this is where we where we get into other stuff right where we get into the uh the header function that I included earlier and for those of you who missed it when I got myself confused I've uh required in this is header function from our utility file uh which again was one of my cheat codes that's just looking at that type and checking if it's heading one through heading six and if it is returning true so that we can filter based on that so what we'll do is I want to get all my headers so const headers and it's really going to try try to help me here and I think it it's almost right it's almost right uh I want to actually use it on content with IDs though get the content with IDs because I need that ID right y content without IDs I can't link the two together because I don't have that that connector so content with IDs we want to filter through that and then we're going to use the is header so this is going to sry go on this is going to look through all the all the children and only return children that match heading one heading two heading three heading four heading five heading six as their type so it's going to look through all that filter based on that or statement that is in the return statement for this and then return back in Array and just so we can see this I will actually console log develop here we'll return that and theoretically here are all the children there we go for the two posts here's one post worth of children I guess and here's the other one right so two posts this one has three heading twos the other one has a whole bunch um so filter at its simplest uh I can now create a set of anchor tags to do this however I'm gonna take it one step further because I forgot I wrote a special mpm package for this uh wow yeah fancy I again cheat codes uh wrote table of contents Jason I think I wrote that maybe maybe I finally found one that worked for me um sorry no nested to you can see I tried it the the one that's still in the in the 0.1 release right not this this one which somebody else wrote but didn't actually meet my needs this is actually going to look through all of this and create table of Json that I need for my table of contents because that's actually super complicated right because every section the the data that we get returned is not nested in that way so I get these headings and you can see from my data like three heading TW is no big deal but if I want to indent my codee I need to check and say all right here's heading two here's heading three heading three should be indented underneath heading two right I'm creating that sort of flow through my table of contents and that's actually as it turns out complicated uh and not honestly super easy if you want I actually have in in here also this kind of file where I started writing it and I wrote it and all this moved into that thing but like yeah you don't so you're kind of just parsing it and looking at s and then exactly and then returning a nested version of it is basically what's happening there okay so all this is just to get nested to three four stuff like that yep um all right so the next thing that we need is we want to actually run it through um run it through that so let's see we got const we're gonna want the Json and we're going to take that headers that we get we're going to map over it we're going take the header and then we're going to return back and I actually need all this in parenthesis because I'm doing an impc turning it yeah exactly um oops the syntax sugar of new JavaScript is so nice it is very nice it can be confusing if you don't understand it uh so in this case I'm taking all the header data and I'm using the spread function right I'm spreading that back in so that it's not one layer deep uh and then I want to I have to go and look at that and create the text for it right so this is actually going to we we'll console log this as well so now uh oh something's not quite right you can see I'm I'm reshaping this right in a different way exactly you're just adding the text now but it somehow doesn't find the value of the first child yes looking real fast see how I broke this content with IDs filter is header headers Json headers Max app we take the header it is not value this is again everyone GitHub co-pilot is super helpful in manyways don't believe what you read do you think if this was typed that it would have worked that it would have told you maybe but I'm also mutating right like I'm I'm I'm changing right now I'm creating a new set of types basically yeah exactly see now we've got that and again I'm making else for us to render I'm G actually run this through um through that function that I created so instead of that we're actually going to go and we're going to say I want the to array because I I honestly don't want to generate this in JavaScript so I'm going to say await or generate Json which is that function that uh I'm just now including from that right so generate Jason from that that package that I wrote and pass into that my headers Jason right header Jason and so that's going to generate the Json that I need to render in my front end and I'll show I've got more cheat codes for that too so now instead of doing any more HTML and JavaScript which is actually an anti-pattern to 11d 11d wants most of this done in your templates so that's why I'm doing it this way if I were doing this in react uh or in like next or next review I would probably do this in JavaScript I would take this and I would render it a different way yeah what I actually want is I want to pass that new array into uh my data that I'm passing to 11d all right so we go back into post. HTML and again I have a cheat code which I'll actually walk you through real fast I have an include which is my Toc include and this is actually a recursive template uh which you can do in 11d and it is much more the 11d way than say generating all this in JavaScript and so what I'm doing here is I'm creating a an unored list I am looping through all of the items uh that I that I'm getting through on that first level I'm assigning a length to it there's there's some behind the scenes stuff going on here and then I'm creating a list item that list item has the anchor to the headline and then if the length of the children in the array which again I'm n all of this in in a new set of stuff if it is greater than zero I am going to then do the include again so I'm going to include be a lesson to just use JavaScript because you have to learn all this mean it's such if you're anity developer though this is way more comfortable than than the JavaScript in node because he let this is all closer to I I worked in a syntax like this uh what year is this uh 15 years ago I've been working in like this for over over 15 years because yeah this is liquid it's also nju syntax those are both based on the Ginger 2 templating language from Jango uh which was my first big templating language and so I've used this forever 11d has it available uh if you are a Shopify developer you're probably you know this right if you know liquid you take data and you Loop it in your sleep so again it's all about what you're used to and absolutely if I were doing this in react or something else I would write this in JavaScript instead yeah I would say probably jsx or TSX is the closer to JavaScript because if you do this with few it kind of looks like this to be fair yeah okay fair uh it's almost not the same but it has a same Vibe let's just say template languages are always uh opinionated in some way it has they have to be uh so then what I'm gonna do is I'm 11d syntax again so I've got that file in my includes I want to include it which is a template tag that I have available in 110 stop helping me GitHub co-pilot uh I need to say include the file to. HTML we were able to implicitly know that it's an includes that's an 110 piece of functionality okay cool I can change that if I want to but it requires configuration and then I want to because I know this include is looking for something called level I want to pass it a level parameter and I want that to be the TOC array that I'm passing into this right Toc array so if I've done all my homework properly because again I knew that we had an hour I'll save this in and here are all the H2S oh yo which I can click on and then if we want to see it more complex let's go back to the homepage let's go to my content Federation blog post here they are nested this is crazy time box King y preparation I think I think Nikki yeah um but here here's here's the takeaway right this is obviously this table of contents thing is a is a more complex idea uh and it's really complex because nesting if all these were H2S super easy right I would I would have just used the like the regular renderer for that uh but because I wanted to show in because I want to show the slightly more complex thing we do that uh so the thing I want everyone to kind of take away here is that not only can you uh take the Json that you get from high graph's Rich text or really any Rich text that has data built in right has some sort of as built in you can redo any of the rendering to HTML right so in this case the thing that we did was we took every headline and we converted it to have an ID and an anchor tag around it but then also you can use it as pure data in whatever npm package you choose to use it in whatever data need you have for your content you can pass it in as data and be good to go so what we did here right is I Rema this to what my mpm package needed whatever mpm package is out there that you want to use for whatever purpose not table of contents for whatever purpose you've got you remap the data that you get because it's pure data super easy to work with in JavaScript and pass it to the package and the package can do whatever it needs to do in this case it generated HT it generated a new array for us that 110 could deal with but you could do whatever you wanted with that data if you wanted to pass it to react native you could do that and do some random stuff there if you wanted to pass it to some sort of function in a serverless function that Ed like Adobe PDF generation you could generate PDFs out the data that you got in whatever way you need to you can just pass this data around in any way you need to yeah I've used this stuff in in if it's a slightly simpler version as if I get an image out of this thing I don't want the the default image renderer from whatever this HD to HTML package I actually want to Lazy load the image and do a bunch of fun stuff with Cloud andary yep so I have a function to just grab a source of an image and do a bunch of things to that image tag that says loading equals lazy or patch this through the cloud Ander CDN instead but I've also had to do it when I was working in a nextjs project when it was still 12 so it was like a like a jam stag site well next has this really cool link tag that actually prefetches a bunch of pages for you while you rehydrate the page but when you get a link out of Rich Text it's just a normal a tag so what I did is actually with this functionality I made it into a nextjs link tag so while when hydration happens um all my links would be prefetched and everything was much faster and so you can use it for these like day-to-day things also exactly like if if if you wanted to I I'm trying to remember if our react actually no it wouldn't because it's not P pure react right exact the react renderer right is not going to give you that link functionality next and so so if you need that you can then have all the anchors you can do a a type check get the anchors in that array and render them to the link to do the preeing just like like Tim was saying for for n as well there are some gotchas there of course because especially back then what what I ran into is like okay when does it hydrate and when do you do this thing do we do you do it on the server so then your HTML is created and pushed to the front and then it hydrates and it starts prefetching or does that happen in like a more mix like with Nu back in the day especially it was a you never really knew when it was SSR and when it was client it was kind of mixed and so in next I didn't manage to get it done but in next I did nowadays next is closer to next so it's it's all like server render when you choose but those kind of things are like the real use cases um that you might see every day versus when you want to do something like super special like Brian just did but we've had recently in our um awesome Community where people are starting asking questions about rich Tex things like when I paste this in Rich Text a I want to get that same content rendered into HTML and then back into ASD and then go into another Rich Text field that is for example if you have something very specific that you're dealing with that might need to happen and you can use this stuff for that right it's quite flexible well saying it's easy but it's flexible the real interesting thing for me on that was not only were so that that was somebody using the rich text renderer not on the website literally using the app SDK in HRA to do a different editor experience inside of HRA by using pretty intense and awesome I will also Post in chat uh here's a YouTube video I created a while ago uh that is it covers a lot of these Basics again but covers it by adding again the Tailwind um classes to all the rich yeah exactly uh which I'm just I I was lazy today and this is literally wrapped in the pros right so if we go my layout uh I've got uh you know main class Pros right so it it does all that work for me but if I wanted custom uh Tailwind classes for all my all my rich text that would be how I'd go about it exactly awesome and so we are coming up on the hour oh we are over the hour holy moly we're one hour one um I think this was one that for like if you're like using stuff every day this one is going to be one that at least would help me a lot and I've been lazy and just use the HTML that comes out of high graph and you know what it's pretty decent HTML I've had experiences with other cms's that I won't name now where the HTML that came out by default was horrible so I've had to then do it for now it was actually decent anyways um we encourage you to try these things out and if you have questions you can actually follow us on slack or follow us join us here in the community and nimit who was just in the chat is now actually in slack asking questions which is awesome and he will now come on the stream um sometime soon to show what he's been working on a beautiful thing I love that that's exactly we love that stuff and so um lots of all of the things we've been discussing are actually written down by our lovely Romina on our dog page page and you can find a lot there and if you don't find it come back to slack ask us and we either add it or we just help you right there that tends to be what happens um so I'm going over all my ctas Brian do you want to do the signup CTA yeah we don't have one so obviously when you go to that link that that Tim showing right there at the bottom right apps.com signup uh one things you can also do is we have let me let me share your screen again real fast because yeah go go go here's my problem I just like talking with people um so let me let me pull that link up real fast you're gonna see the absolute Ridiculousness of my high graph you have a lot of project dude but you won't see any of this if you're signing up for the first time but you will see this so the data that I use today if you're interested in playing around with that data the basic blog uh starter here will give you everything you need for that there's also a repo for using it in next um which I'm going to convert to 11 because I'm like three quarters of the way there after preparing for this um but you can see there's GitHub repo there's versell deployment and you just click add project and you get the data schema and you get all the content that that was in this project already and you can start playing with it yeah so we have a ton of starters you can just click on and go and it's all there and there from code but also like high graph setups with all the schemas models content added already it's all in there right so it's it's easy to get started we got H graphx which is like a a streaming platform that also includes like mucks and some other things going on we've got Tim skin care uh demo which if you've been paying attention to this stream you might have seen with goth goth skin last week I think last week yeah that was crazy check YouTube they're all they're all there as well but all those are available inside of the app uh and you can do that by signing up and checking them out all right um thank you so much for your time um Brian absolutely I forced you to do a CTA but now maybe I don't force you and like do you have any last words R text is not HTML it's data use it as data use it as HTML but know that you can do more and I believe in you I love it and that also makes me I'm gonna have to change my website because I use HTML rather than the Json and all this fun stuff I'll be honest the nextjs starter that I talked about with the basic blog it it uses the HTML because it's something I didn't want to like dive into but I might be converting it soon we should probably but the thing is if the HTML that comes out is good and it's not like weirdly opinionated or accessibility doesn't work of course you can do it but when you use high graph the way it's kind of meant to use at skill for your company you're going to do this stuff yeah anyways um thank you everybody um for joining and we'll see you next time happy coding cheers
Related videos

How to personalize e-commerce with Relewise and Hygraph
Tim Benniks is inviting Christian Bennich to explore state of the art e-commerce personalisation with Relewise Join us to learn how to connect Relewise to Hygraph and elevate your digital platform experience.

Adding serverside rendering to Astro with Tim Benniks & Bryan Robinson
Tim and Bryan are taking a static Astro e-commerce shop and converting it to be server-rendered. They're using the newly empowered site to push data from the user to Hygraph via GraphQL Mutations so tune in!

Exploring the Composable Commerce Accelerator by datrycs
Are you ready to revolutionise your commerce strategy?