Pagination with Astro and Hygraph
Want to learn more about pagination in Astro and Hygraph? Join Bryan and Tim on their mission to asynchronously load more content via pagination or a load more button. Astro rocks!
Ask us any questions in the chat and join the community: https://slack.hygraph.com
Transcript
[Music] hello everybody we are live and let's just not talk about that intro because we love it so much but every time we're like ah I was literally controlling myself we're talking about it now by not talking about it but I was controlling myself not to say anything because I'm sitting here just like I have this like very slight headache we talked about a little bit earlier and that was just a nice soothing intro into it it made me feel a little bit better exactly and we have already your first guest hello Romina welcome for joining welcome to join do we have this on Apple no I turn it off yeah it's all good oh boy we have Alex in the house dude I'm gonna see you next week in Amsterdam how are you welcome so Alex is actually bu working with Nu and so you're in an astro stream dude Astro yeah anyways we're just bantering that's how we start these streams we like this my favorite part is is we got next person in the audience not only are we working in Astro but when we do our front end for it we're going to be doing react so it's it's like completely like oh yeah yeah okay so Alex is going to be Astro and react Brave yourself yeah um anyways so like we were just saying we are going to have a look at if you um build a Blog you have a lot of posts you tend to want to not load everything at one go even though hgraph is fast enough to do it it might not be the best thing to do for your user experience and who we have here react with as yeah exactly we're going to do that and so essentially what we'll be doing is we're going to use Astro number Astro 4 the new version and high graph with graphql and so the very interesting bit here is how to figure out bination load more things like that with graphql and Astro and react with Island architecture I think I've said all the things now In fairness I didn't actually run my upgrade script yesterday so we're not using Astro 4 but it's fine it's all like this part of it is all backwards compatible it's not a big deal we're not using any of the fancy features in Astro 4 uh all right at some point I should upgrade this uh this demo into Astro 4 but it all it all works out in fact why don't I kind of show what we're what we're working with here yeah let's go for it so the fun part about this the the backstory here and and there's there's some other content we'll share about this as well so you can kind of like see it in other ways but the I made this demo last year uh actually around this time maybe a little bit little bit later um when a certain uh social media platform was going through a time of uh of trouble and many developers were fleeing said platform which will remain nameless for the moment it's a micro blogging platform right oh yeah crap you're right so I was trying to like uh like capture the Zeitgeist and and uh and like talk about what was happening uh but I made like a micro blog using High graph um and before you go on isn't it the everything platform now though I don't want to talk about it Tim it makes me too sad makes me too sad anyway platform that I'm still a part of and yeah yeah all sorts of stuff makes me sad um anyway micro blog short blog post you know things that you write in perhaps under 240 characters perhaps not because it's your platform it was kind of this zeist of like own your own space right which I still fully support like honestly if I wanted to like blow this out I would make this also have maybe an API route in it that when you post could actually like trigger and like post to other platforms there's a lot of cool stuff that you could do with it none of that is important for today none of it is baked into this as it stands uh but we have a starting point for the code and we have an ending point so right now what we've already gotten to is displaying all the posts that I currently have in high graph on the homepage of my micro blog there's only seven posts I actually that number isn't um isn't dynamically generated that's actually just an H1 inside of high graphs Rich Text um just so we can kind of see the order things um but what we want is this to be expandable right we want this to go forward and be able to handle hundreds of post so one of the things that we have to be aware of when when you're using almost any system but specifically High graph is when you're querying your content we actually do have a top limit on how many you can get at a time because we want to protect our user base when we can right if you query a thousand posts in a front-end script that's going to be slow and a problem so we Max it out at a 100 uh by default the uh the query which we'll look at look at here in a second uh starts at 10 uh but what we want is to for a certain number of posts like here we have three posts we want a load more button right so when I click that Astro is going to go fetch more posts and this also makes initial load time much much quicker we don't have to pull data from 100 posts we pull three and that makes the load faster those three those first three and again this goes into the power of Astro this page is static HTML and then we hydrate that load more button to have frontend functionality and then when that click happens that's when we fire the query to go get more content so when we're doing this we're not querying a huge Jason and then only showing three we're only showing three and then allowing the user to opt in when they want to select more uh which is a I think a much better kind of pattern and what Astros Islands architecture really gets into in a lot of ways all make sense yeah yeah that's the exciting bit I love because maybe because I'm old school I come from the time when we didn't have that much JavaScript but it's all surface side stuff right but then it wasn't fast because it was whatever some PHP with SQL you know and so then we moved into this like I I love the the the complicated combination of having static stuff that you then hydrate and do stuff with and that's also probably why I like n so much because that's completely native to n yeah um and now Astro is doing it in a slightly different way Nu is like catching up again it's like this whole you know a party the frame work as much as there's competition right that competition breeds creativity and we get we get the best part of framework kind of getting shared in a lot of ways hopefully not the worst part we sometimes see that too though uh we have seen a bit of that but that's not for today is it exactly not the topic of conversation for today um so yeah we can we can maybe even dive into code here in a second but just kind of show things off real fast this is all within hgraph all these posts are what's in there uh when you dive in to edit one of these you can see the actual you know six that number I mentioned is just a oh you just hard typed it like that that that's fine because again when I was working on this and kind of showing it off originally I needed to like in the in the content that I made around it before uh one of the things you also have to think about when you're making the query and I'll show that is you don't want it to be ordered by the original date right so actually one of the things we've got and this is in my index. asro uh is when we actually query the posts we're actually ordering it by the created date in a descending order so you know it's that reverse chronological order so I in the original content I had around this you know we bring it in but oh no the old post is first what are we going to do we order by uh and by the way all this is built-in functionality inside of high graph's you know native graphql API so like I can go into the posts here and you can see I can actually do that order by select from a list of things I can order this quer bu and be good cool um and we'll get back into the API playground we'll we'll craft our query uh inside there later on um but the first thing that we need to do is take a quick tour right let's look look around things let me hide the terminal we don't need that um so this is the index page you can see I've got a Pages area you can see each my posts technically has a page as well we don't need to really dive into that that's just how I can have a link for each one basic functionality yeah sure uh but then the index index page is where I'm waiting and I'm getting this is just simple fetch request uh going looking at my high graph endpoint and then I am making that query that query's got the post ordered by created at dat descending I'm getting we just did a stream on this last week and I'm already breaking my own rules right I'm getting our Rich text as HTML rendering this but that's not the purpose of this demo so let's just do it as HTML and and remove the code that could get in the way of that and then you know getting an ID getting the slug for it and getting that created that date as well so that I can display it um oh let's do this real fast too I'm going to close this finished product before I start trying to make changes to it and it not going live ah yeah that's a good move always good but that's where this this is coming from as well oh yeah exactly now I was just ask wanted to look at this like you're not using any modules or live liaries to query graphql here it's literally just Fetch with a post and a body and that's how you can do graphql as well if I were making this like more extensible and making this into like something that I was actually probably going to use long term I would use something like a graphql request npm package that's what we use in a lot of our demos but I also like to point out like you don't need you don't need Apollo you don't need gra graph Q requests a fetch request with a body is all you need to do this you post to our end and you send it the query and you're good to go exactly that's nice to see you can kind of just not go the complicated route and just do it the way you know how and some sometimes people ask us like hey you know do you have an SDK for your uh for your API with graphql like yeah it might be nice to have an S for some things like maybe mutations wise but like yeah for querying you don't really need it um imag for typescript though like if you wanted to get types and generated types from your queries or from introspection we could potentially do that on a CLI or something but there are packages that just do that so anyways talking internally about developer tooling too and so like CIS come up sdk's come up and there there might be some things in the future there but uh but for the most part you can get most of your needs met with either one of those you know external packages or just you know fetch request uh and I'll say like as we go through this there are lots of uh efficiencies that we could make in terms of the code uh that I have not optimized right I don't I don't want them do it because it it I like keeping all this together so we can actually see what needs to happen and everything's kind of co-located uh but yeah so so one the things that's happening here is we're actually using Astro's front matter uh every page can have front matter in aastro file and we're putting all these queries up here and it is a top top level async function right so all of this can use a weights and I don't have to build that into um into how I don't have to like make an Asing function this is an async function as soon as I say a wait which is super handy in a lot of ways yeah in fact I'm putting a weight here and then I'm putting a weight here because I'm doing the Json function too so basically What's Happening Here is I'm getting the data there's a data object on that and then I'm destructuring the post array off of that and then all my template has to do is Loop through the post in a map and return a component and this component is a very very simple component it's post. asro and it is just a div inside of it we are getting our content in HTML and we're setting that to the HTML of this div set what is this I've never seen this before is this an astro thing it is an astro thing uh I think in the in the view world right we'd call this a directive uh we can do a F Fe dhtml this is true oh that's the same okay and so like on this right in in the react World this would be where you would do like was it underscore underscore dangerously set in HTML yes equals two brackets and then say HTML equals they really don't want you to use that that they well overall you really don't want to use that in many many ways um however we have native HTML coming in we want easy right yeah sure uh and then we're just saying that time and putting a link directly to the post with that time I am doing a little bit of things to actually format the uh the um time and date I'm taking the created at date and time from high graph and I'm running it through just simple date JavaScript functionality to create the date string that I want and the time string that I want and then I am putting those here in uh in the anchor and that all corresponds to this right Friday January 13 2023 it was roughly a year ago that I was working on that look at that um and uh and there's the time that these were made at and you can see they're all the same because I made them pretty much in one go um so yeah that's that's like the absolute Basics that's where we're at but we need to do a few things to get this ready for uh for the dynamic issues right that we're going to run into the first is we need some sort of front end for it um Astro is going to allow you to do like vanilla JS in a in a variety of ways but if we want to use the islands architecture and we want to really set these things up in a maintainable way for the future we're probably going to run into a uh into a framework and so I've already done this but we need to add um react to this and actually set Astro up to know what's going on with react so if I were doing this from scratch I'd say MPX Astro add react and then Astro in the CLI that they have will actually do all the installation I need on that and what ends up coming out of that is in the config file it would install uh the Astro react package import it here and then add it as an integration here you can see I already have a Tailwind in there too that's where the styling is coming from on these this is so nice and easy isn't it it's crazy yep and when when when you want Tailwind you literally run MPX at Astro ad tailwind and it does that for you as well they put a lot of time and effort into the CLI and it works really really well so yeah that's what you would run I've already done it so we can go ahead and start using react uh so the first thing that I want to do is I actually want to move away from uh the post putting this native stuff in that post component in Astro and I want to do it for a specific reason when we get more into the architecture of things the post body for these the content of the post I need to be able to use that in react as well because we're going to be adding these dynamically later on and I can't use an astro component in a front-end framework so the very first thing that I'm going to do and I have already done it uh is I need to convert the content of my post and I'm just going to do the content into a react component into jsx so you can see here I have a post content component that is very similar to my Astro component right as we go through it we are getting off of the post that I'm going to pass into it the content the slug and the created at dat we're GNA have a date string and a Time string which we set in the front matter of the other one anyway and then um we return jsx and you can see hey look div dangerously set in HTML equals there we go we're changing methodology here right we're changing framework and then we still set a time and we've got the anchor and all the same stuff but now it's a react component using jsx instead of um instead of an astro component so let's go into our post and let's actually bring that in so let me make sure I'm doing this the correct way uh so at the top here before anything else because Imports go at the top we're going to import that component import post content uh from post content right yeah and then what we can do is replace all of this with the post content component and then we'll pass into that the post object that we're getting from from high graph which is post uh and then we don't actually need any of this JavaScript here anymore because we're doing that in the component now oh yeah exactly and now you have to close the the the bracket I do I do good catch on that all right so let's save that in and in theory nothing should change absolutely nothing should change other than actually let's let's prove that it worked though and say hi inside of each of these yeah just to be oh we go so what Astro is doing here is it's actually there's no there's no front end code happening right now this is all being rendered in the build so this is all still HTML there's no interactivity here yet but we used jsx weed use this other framework to build it in our build process so it's essentially just using it as a templating language for now exactly and you can use that with Vue you can use it with solid JS and a few a few others right yeah cool but we're setting that up so that we can use it dynamically in in the front end as well so the next thing we need to do is actually paginate our data so we have this we're ready to go but we don't want all of our data coming in in this query anymore we only want a certain number of posts coming in I'm going to set this to be about three uh because I think that with seven posts that gives us three pages worth it gives us a little functionality but obviously when you've got hundreds of posts 10 15 like figure out what what is the right ratio uh for that load time right the optimized Json to be delivered there and to do this I'm actually going to move us back into high graph and we're going to use the API Explorer because we're no longer going to be using this post query any anymore what we're going to use we going into territory I've never used like I've not seen this I've been at hgraph for a while but that's just the breath of functionality we have is sometimes hard to cover yeah and when and when you aren't doing like this is specific functionality honestly around pagination or around loading additional content whether that is you have more than a 100 posts and you need to do something with it or you actually want to do pagination uh so you'll see in our query Builder over here right in our explorer that posts is a query singular post is a query and then there are two other queries right next to it so we have post post version posts you know plural and posts connection so post is gonna get you a singular uh po a s singular document with a like a an attribute right I'm gonna search for an ID search for a slug and get a singular post post version is a query that lets you get a version of a singular document so if I wanted to see the draft version that has a revision five you know five versions go I can get that in that way it's a little helper function posts is what we're already using it gives me back an array default of 10 documents but up to a 100 documents and you can do all that ordering stuff you can specifically filter you can also do first and last and some other stuff and then we have this idea of posts connection this is using What's called the speay connection specification which is a way of doing graphql pagination and what this does extra spec on top of the normal graphic spec or is this the way graph wants you to do this basically yes uh and me not being a huge graph U nerd I'm not in the I'm not in like a working group for any of this right that's not that's not who I am uh I'm more than content to use it and not fully know why they wrp this way but this is also again why you don't necessarily need like an SDK when you're using graphql if these kinds of things are baked in uh so if I wanted to page andate and I didn't have this post connection I could technically do that a little bit in this basic post query I could say give me the first three posts and it would only give me let's actually give uh an actual set of data here uh title do I have title yeah slug slug there we um so here are the first three right and then I could also use this skip argument and I could say give me the first three after those first three and here are the next three right and then if I needed to like I could continue adding I could keep continue going so you could build passation functionality with that it's not super easy and there's a lot of a lot of functionality that once you start going down that path you start rolling your own code for yeah you don't want to do too much like local stuff in your front end with too much ifs and elses and loops and we don't want to have any of that absolutely like you need to know like where the last one was you need to know where to get the next one you need to know is there a next page right or how many pages maybe how many pages might be nice absolutely like if you were doing like full full pagination we're not doing full pagination we're doing the load more I do have a link for yall later on for that though uh so we're going to use this post connection query so what that's going to give us let's go ahead and say first our first three right and we got we want to have that same order by right order by created at descending yeah so what this is going to give us is additional functionality so we had this new page info object on it what page info is going to give us is the end cursor the start cursor the has next page and has previous page so let's look at that real fast let's just check to see if the page that we're on has a next page when we only are getting three so yes but if we were getting the first 10 it does not have a next page I only have seven items in my array so this builds a huge piece of functionality for us that we don't have to worry about because we only want to display a more button if it has a next page so that's really important we also need to know the end cursor for each of these what this is is the ID that we can use to get uh the next set of information okay so a cursor is to indicate to get another set of information like a starting point off that list or something yeah so what I can learning as we go here I love this by the way so instead of using skip like we would do in the uh in the other kind of methodology what we can also do is we can do after so after is going to take a string that is one of these cursors so basically in my code one of the things I will be getting back is the end cursor so that the next time the user clicks the get more button we'll use the end cursor and say give me the next three after the last one from the last set again all this is functionality that you could theoretically build in that front end but that sounds terrible um so we have this idea of has next and and the end cursor both of which we'll need in the end but we also need to get our data right we need the actual posts as well so alongside our page information this is where we go into like graphql territory like our posts query abstracts that away from you you don't have to think about edges you don't have to think about nodes but in uh in this world we're sticking to the specification because it gets so complicated so fast the going edges and noes makes a lot of sense so the edges are each of these kind of page sets so we can get the cursor and we can also go into the node and the node is where our post data lives so we'd also need again the slug I think we were getting the ID before the created ad and the HTML from the content so now the oh yeah you're putting it on first 10 maybe that's oh I'm sorry I also had this after blank which we don't want yeah exactly and yeah we do also want you know first three there we go saying after blank and then it was like hey there's nothing after blank yeah there's nothing after blank exactly whatever that is uh and so you can see here we've got our edges uh the edges are basically um each of them will each of these sets will be a page and the edges are the posts that are coming in and then the content of that post is in the node so we could actually say good so I'm just learning as I go I can see now the cursor is actually the same as the ID of the post so it's literally just saying this was the last post you queried that's the ID and so for so actually this one and this one are different but this one so let's look s1z right so we come down here yeah there we go yep that's that's how we're gonna tell the next quy what to do exactly oh it starts to become easier now because I was somehow thinking that a cursor ID signifies your first three posts as a group or something yep but much easier if it's just an idea of the last thing you asked for exactly I don't need to know you know the the chunk I just need to know the last item uh exactly again like I think in the back end again not being like a super big like graphql you know person you could do it the way you're you're describing it where like the chunk has a cursor um but I think this way is more performant in the back end like as it's actually doing that query uh you don't have to group things together you can just yeah like we'd have to save that there's a whole bunch of stuff I don't like I don't work in back end we don't have to get into it this actually quite easy for us to use now yep uh so this is pretty much the uh what we need but I'd like I like to name things because that's just kind of who I am so what we can actually do is we could say that instead of this post connection I want this to be known as a page and instead of the edges I want this to be my posts array and then each of these on it instead of being called a node could be called a post so when we save that our post connection is now page post array is now an array of posts and each object in it has the cursor and a post so I can actually I don't think the correct term is casting but I can basically cast this information under a new variable uh and have it available in a better human readable form so what I can do is I can grab all possible this is so cool sorry I keep interrupting you because I'm excited that's yeah and and like the great thing is this is this is native graphql right this is just how graphql Works uh all of which is built into a native graph API with high graph so I'm going to change out my query here to be this but we need to make a few other changes as well uh we want to have these be uh programmable right I want it to actually be a variable instead so I'm gonna add a variable to my query in graphql uh called actually do I need cursor on this one I do not uh yeah I do need the cursor why do I need the cursor oh this is on the more button sorry cheat sheats uh I just need to know the size right we don't actually have a cursor on this one I need to know what size for this to be and the size needs to be an INT um and then what we can do is we can actually change this out to be the first of size and then in my query after I add the query in this object I can add my variables uh property as well which is going to be an object that has whatever Dynamic data I want in this case a size I'm going to create a variable called page size uh this is maybe a premature optimization but being able to change it on the Fly is really nice so we'll have a page size variable here that's equal to an integer of three this is still graphql Native like all of this yes like there's no any of this and in many like other like uh uh uh packages right in graphql request or in Apollo you would structure this slightly differently but when you just make a fetch request you send it with adjacent object that has your query and your variables as properties exactly super nice and then we need to make some other changes down here real fast we need to um instead of getting the posts now from data data which is my favorite thing to do data data we need to get the page that we are receiving yeah right because we we changed the way that that functioned we now have this page variable and then from that page variable we need to get the posts right so now instead of post we need the post I think I call it post array right array yeah exactly yeah uh page. poost array and I think that will work uh and then we we Loop through that right and we display a post for each of them yeah to me this is always mindboggling with jsx or TSX whatever this one is this is not this is this is Astro it's its own flavor oh wait this is Astro but still there's the same thing here where somehow a map always needs to return to something to a variable but it's not doing that now so to me that's always slightly oh we're gonna console lock the yeah I I I changed things from how I structured it in my cheat sheet um yeah never do that right that's a terrible idea uh save that it's about content field well it's because it's not getting to where it needs to be so my page my page object uh which is on this so I'm getting page uh has post array and the post array isn't is an array of objects they should do oh I'm sorry this is also uh because remember we we changed this up here too right now the post array each of them has the cursor and the post data I probably should have called this post data right to make it a little bit more clear uh naming is the one of the hardest things we do in Dev so save that no more errors let's get rid of the console log and again we should have no changes other than we should only have three posts there we go it worked yep magic so now we need a more button right we need at the bottom here only if there's a next page display a more button so we can do that with a conditional and a component so to begin with before we make a component out of this we're just going to check to see if the page has a next page and display just a quick like H1 down there just so we can see it so we'll check to see if page page info which is again what keeps that information yeah in the in the connection spec has next page which is a Boolean it'll be true or false if it is true display an H1 and this is where our component will eventually go so we save that in you can see down here it's true and if we go back and we say give me the first 10 for a page size we will not have that H1 at the bottom anymore because it's checking against that thing that we get from our data take that back to three all right and here's where the fun begins um because here's where we get into react and here's where I hope that my that my react uh brain is functioning today and if it's not I have a component already built or out time I have a component already built uh so I'm going to create a new component that is called more button. jsx and you can see there's a more. jsx there that's where the other other component ah yeah yeah we'll only go there if it this doesn't work if if I if I fail at my job today know that I didn't fail at my job yesterday and 10 months ago and we we can get to where we need to be exactly we're good so we will start by being very very simple here this is one big uh react component at this point so we're going to export a component and that component will be a function called more button which will take do I need to pass it anything I think I need to pass it something I think it needs the cursor right to know what it will it will need multiple things actually but for now uh we'll just have it be like this just so we'll get our kind of feature parody with where we exist right now yeah and then we're g to do a whole bunch of stuff up here do a whole bunch of react uh and then eventually we will spit back out jsx right so we're going to return some jsx and to start with let's have it return our H1 right exactly this is the component so we'll save that it's nowhere yet uh but what we can do is we can come into our index page and now instead of this H1 we're going to use that component so we need the more button which we'll also need to import at the top so import I really love the way you do this because I learn in small chunks because this gives me overview first simple then you add a little bit more then you add more because if you just go everything in one go and you don't know why if it's breaking you don't know what broke exactly and this is this is not the way that I wrote it right I wrote it in a very nonlinear path uh but it is hopefully the the good way of learning that's at least what I've what I've found in the past so we have a more button uh but we also need to do a couple things on that more button this will work and it's down here right but let's say I want to console log something and this is this is kind of getting into Astro knowledge at this point let's say when when in the browser I want a console log in the browser right so I'll save this we'll open up the brow browser and let's refresh the page just to confirm nothing is happening in the console but you might have noticed every time that every time we we load that page in the build it is functioning as that console log and that's because Astro thinks this is just we just want to build HTML from this it doesn't know that this is a client side component serer exactly yep so we need to tell it what to do for the client and there is what's called a client directive in Astro and there's a whole bunch of different ways to do it you can do it on load you can do it on the first idle thread you can do it I don't know what media does if I'm being honest uh you can do it client only so that this would not be generated in um in HTML yeah um which we don't have to worry about right because we're doing this conditional we're saying if the data has a next page we need this so I don't want it I want that button there if it's supposed to be there I'm going to do client VIs visible this will defer the loading of this component until the it's using it's using native JavaScript behind the scenes I can't remember intersection Observer intersection Observer yep so when it hits that right it builds it builds this component it rehydrates the component this component will exist as a load as just a button style right but it'll rehydrate to get this and there's probably something to be said with the fact that I might want this to be client only because of that like the functionality won't actually work I'm not going to get into that today but that is probably exactly we could have an idealistic conversation about that if needed exactly and now when we come back over we also get it in we get it in the build step and in the browser so we get both sides of that in fact I think if I said actually just to just to show something else to see I'm kind of curious so I I reload the page nothing's there I scroll down then right so it it hydrates when it's needed not before it's needed which is great for performance on the front end I have a tiny spicy question for that can you check how big that little JavaScript is now that ASO actually put in for this intersection Observer because I kind of feel like maybe that's kind of a lot to put in to make that work that's absolutely astute observation um let's see of course not sure we can see that because it's Local Host and stuff right yeah um loading react and its own little island thing and it's a hydration engine so there must be something relatively big coming in let's yeah I can't it looks like 3.1 kilobytes yeah that's I think we're fine again this this builds up right like like we're gonna put more fun this is you know very small basic functionality that we currently have we're just displaying HTML which I would never do client side anyway um so we need to do more with it to make the job worthwhile um so we're gonna do a few things and here's where we find out if I am actually ready for this there there are better ways of handling State than what I'm going to do today uh but we're going to make it as as simple as possible as we go through it cool so what we need to do is get some react functionality rolling so we're going to use uh use state in react and we need to set a few different pieces of State you could do this in one big object my brain on something small like this I keep them separate again I think it helps kind of in the learning process uh we need a state of posts which is also GNA give us a set posts uh method as well and we're GNA use use State and when I hit enter on that you can see VSS code gave me the import automatically that's nice and this is going to be an empty aray array to start off with because we want our post to be an array we also uh Tim as you pointed out earlier we do want uh the cursor and we are going to want to dynamically set the cursor because we're gonna want to update that when we click it right we update it to set the next cursor so we will have a cursor State as well and my fingers are a little cold uh and we're going to use State again and this time we're going to set a variable in our component that's going to be called current cursor this is what we're going to pass in from where this gets loaded in we'll set that in a second but we'll set we'll go ahead and say up here in the props coming into this current cursor is something that we're going to need yeah and then uh we're going to also need to check if has next is a thing and we're going to need to know about loading State as well so we're going to set two more variables H let me just copy these in actually that'll be faster yeah it's easier lot lot typing is boring for everyone has next has next we're going to have that set to True by default and then loading set loading false so a couple small things that we're also going to add into our props uh we need a size and I need a default I'm gonna set a default size on this but when we actually pass this in as a prop it'll get overridden I just want to put some Protections in there and then I'm gonna put this in all caps this is a weird constraint on um on Astro in that because this is so deep down some of the environment variable stuff doesn't work exactly as you'd expect it to so I have an environment variable in my page for my endpoint URL yeah I can't actually access that here um I can't remember the exact reasoning but I went back and forth in like a GitHub issue on it maybe it's fixed in four I don't know but it is something that we can pass in the endpoint right that's not a big deal on this but it's is running on feet so I imagine you can do an import of that if you go to back to the page you might be using the same there I am uh so that's actually how we're we're getting it up here it is importa and that at least in this version of Astro that does not work in the react component okay good to know so we this this was probably three hours of developing this demo last year was I was like this should work why doesn't this work it doesn't work yeah some sort of translation layer that just gets Lost in Translation I guess Lost in Translation um all right so then let's see here we need to do a little size equals one rather than colon one in an object this is how the prop functionality work works here oh okay you can actually see I bet I think it will yell at us here if I do this right oh wow okay I'm just literally learning react as we go yeah it's when to use equals versus when to use colon still I get it wrong the first time almost every time wherever I am love but it's BEC it's because in this in this kind of setup right we're actually using the argument syntax I don't even think this is necessarily react we're you the the the fact that we're passing in an object and then this is a destructured one but if it's destructured it still be a column in JavaScript that is I am curious about that and whe and whether or not that's the case I don't actually know uh now that I'm thinking about it because like it isn't in this state we're in an argument set and arguments typically are going to be equal to set of default value but we are inside of an object inside of an argument so function so anyways we could go on a tangent and find out or we can make this work let's just make this work we're good yes all right um so let me see what the next piece of disclosure I want is let us uh actually get our data right so we're gonna have a function to get our data and that's going to be a get more function and that's going to be an async function and then when this starts to go I want to set loading to be true yeah till the end of this in which case I will then set loading to be false right and then I need to get the data from high graph that that we need right so I'm gonna set a response and that's going to be an await because we're in an Asing function and we're going to fetch again using the native fetch API and now copy paste I'm gonna copy and paste this because this is way too much typing um paste this in where did I start the copy riveting stuff I know um all right const fetch all right so a few things that are happening here that we need to pay attention to um the end point is coming from our props again that's that kind of weird Astro stuff I deal with we're gonna need to create a query um and then we're gonna need to set the size the size is also coming from here and we need to set the cursor and why is my and the cursor needs to be dynamic based on this right so the current cursor gets passed into my state here okay it makes sense and so you get the cursor from the state basically absolutely it's a good question though why are we quering from a button shouldn't the button ask the thing above it hey give me this set rather than the other set that you just gave me the thing above it is not a front-end client-based thing yeah it's Astro SSR yep well uh the right not even SSR it is static HTML because I'm not using SS are in this project oh this is true this is true it's just a renderer it's yep if this was full react you would have a parent parent component with a context that you would fill with the data and it just trickles down to all the things right that's what you would do so we're we're low on time but philosophical tangent real fast and why I actually really love uh the idea of islands architecture to me when react was created oh like was it a decade ago it's somewhere around that right mid2 um sorry Eric look at this trigger me the promise of react right was that react would be like the the front-end template functionality for little pieces of the web you'd sprinkle JavaScript throughout your application but you know what happened react ate everything for exactly the reason you just said Tim right the state kept having to be passed up further and further until it was the entire application so yes I could actually make this all one big react component but then on that client load when when like the entire list of things loads it would then rehydrate the whole page it wouldn't be an island necessarily anymore your performance is out the door essentially because everything get not terrible but yeah it's it's a slippery slope might say oh yeah because then add CSS and JS and then you lights out basically uh I just did a quick copy and paste uh for my query right the query is uh pretty much identical to the to the index page except for now we also have a cursor the cursor is going to be what we use for the after again that's that same functionality that we worked in in the in the playground uh the fir we get the first size you know first number and then we're still ordering by created at descending we want to keep that consistent then everything else we haveo though okay this makes sense yeah cool so that's that's the query that is being passed in here and then the variables are the size and the cursor that we have set here so we have this get more function so we need to use it in some way right so we're gonna come down into our component we're still going to keep this fun this is a component piece because I'm enjoying that uh but this is also now going to become a fragment right uh because I don't actually want to add a new wrapper a fragment is just going to put all this HTML or all this into the Dom as these pieces maybe at some point I want to be in a wrapper but for now I'm good so let's check two quick things right I'm GNA copy and paste these in actually so first we want to check to see if we're currently loading if we are loading let's put a loading area and then if we have next we want to or sorry if we has next because you know yeah naming um I want to it's fine yeah it's just the the uh former copy editor in me is just it gets upset uh yeah so we're gonna have a button the button has some Tailwind classes on it and it has this on click and the on click is the get more function that we just wrote yeah exactly cool cool and then I think and we'll see if this if this Progressive disclosure uh methodology works here if I save this I think we're good uh and we'll actually see both the button and the loading actually we won't see the loading quite yet or will it more okay this okay cool this what I expect yep because I I'm not telling load more to go away right but this means that our functionality is in fact currently working in the front end so after let's see back up after all of this runs on this kind of get more functionality uh we need to do some cleanup work as well so let me make sure I'm in the right spot let's close that and when we get this back uh we need to set our Cur sorry set our loading to false oh yeah that's the easy thing for us to do because that's gonna get rid of that that loading display ex but we also need to do a few other things we're getting this response back and just like we did on the homepage we need to get the Json and we need to get the data off the Json so Jason await response we're gonna J jsonify the response that we get from high graph we're going to grab the data and then we're GNA split the data into a couple pieces the pieces we need are the posts array which is I think what we called it still and the page info right and we're gonna get that off of the page I did rename that uh did I rename it here I did not rename it here so post connection let's keep it like this yeah let so it works cool um so we're destructuring all of that and then what we need to do is we need to get our set posts uh functionality right that method that we got from UST State and the weird thing here is we're gonna have it be an array we're g to destructure where it currently was because we want all the posts to continue being there from before and then we're also going to append at the end the posts array that we get back ah so it's the old one and the new one you put together in your new state yes and and the reason for that and I'm going to do that right now is here we're going to map over that and this is where it was important for us earlier to um set this post content as a jsx um component as opposed to an astro component because we want to be exactly the same in HTML and in this react component so a few things happening here we are looping through the post array which is set via set posts and will be nothing if it doesn't exist right if it's a blank array we're going to take that post we're going to grab uh the cursor of the post as the key because react for a list wants everything to have keys and then we're gonna have the post. poost for each of those so in theory I save this come back over here click get more something's gone wrong sure ah console it console Lo we're good oh that's a 404 I think fail to load oh you know what I know exactly we haven't actually put this together properly on the index page we only have client visible we need to pass it the props that we need right yes of course so a few of the props we need we need the page size I think we called it hold on let's put these side by side real fast all right so we need page size where's my here we go yeah we no size size is equal to page size which is a variable that we set earlier and again that's why I said it as a variable so we could use it in both places we need the current cursor which we're getting from page info where are we sorry I'm just making sure page. page info yeah page. page info and that is going to be the end cursor on that okay yeah because that's going to set it so that we can get everything after that and then we also need that endpoint right so endpoint as a prop is going to be um process. nope not process. EnV what is it inv V it's uh let's just go copy it so we don't mess that part up yeah this one the whole thing import meta endpoint again there's lots of abstracting that could happen here we could make this much cleaner um but we passed that in and again this is where we get into it right if I didn't pass this in the react component actually wouldn't have it available because of the way the things build exactly this is there okay we have some errors but that's fine right it actually went and fetched it and then post content post content is not defined what is because I didn't Define it Tim I absolutely did not Define it there you go import post content uh do you know where it is comp course yeah from let's see components post content there we go yep always import there here's those here's these and now we're getting an error because we don't know to stop right there like there's a whole bunch of stuff that's like oh yeah because when you click again now it might not work anymore because you can see it's actually repeating too um because things get confused at the point that because the same key and so it doesn't know what the Yeah the hydration and all that stuff is complicated now yep so we need to do a few things with our uh with our other set functions right because we're actually we're not updating the cursor um it's actually pulling the same information every single time which is a problem so I'm going to use a couple new uh Set uh methods right set cursor and set has next which are two things we set up here right yeah we need the set cursor to be the page info and curs of the new things that we got and we need the next to be the has next page of the new page that we got so we save this I check my cheat sheet just to make sure that I have everything I need which I believe that I do now we just do a full Refresh on the page just to double check get more four three two get more one and no more get more button nice so real fast just to make everything a little bit better let's get rid of that H1 and Tim we are done 55 56 minutes is perfect and just to just kind of show this functionality and why that that setting a few of those things uh made sense let's set our page size to one and or sorry one go through again seven six five nice three two one none great so all that via the power of of the islands architecture none of these were loaded in until the user wanted them right the user needed to want them um so yeah that is that is not I'm G not say simply pagination right pagination is never like super simple when you have all these concerns to think about but it is definitely uh with the connection specification with Islands architecture it is what we want when we want it exactly and what I kind of like about this is the fact that you made a little island only of the load more button however that also gave it some form of complexity because yes you had to render the first stuff but is just HTML you cannot reuse that rendering thing anymore you have to then render in a new chunk that's just below the lot more button so to me my brain was a little like oh where are we going with this but the fun thing right is that originally you know post looked like this and theoretically right I should be able like easily but if there were classes on this I'm moving to jsx and everything like Astro lets class equals work jsx can't and so it's class name so you have to do all that translation yeah so I don't know when I I'm my brain thinks in few and next right and so when I see this let's say I'm in n and I'm not in Astro with like putting on on the island and stuffff Y I could that's this could be so much simpler though this is my but that's interesting to see because this is just as good it just takes a few more steps but it's also really easy to reuse again yeah in theory right I wouldn't have to use isin architecture for this I could write vanilla JavaScript to do all of it but the amount of regular JavaScript to do it you could have done that yeah but ring and like the one thing I love that n has that probably react has it too but I'm not sure or next they have rather than used State you can also use something like called use async data and so that in using async data you know this is a hook in which I'm going to do something async but whatever comes out of those or out of that function like set the set State thing you just had like the post and set posts from that you get um because it's an async action that you do you have a a success or a data property um a fetching property so it's if it's loading or not an error property but also a refresh property so what you can do it has a cach key of what you have currently and then when something changes you can change the parameters and just hit refresh and it refreshes the whole tree below that just what you can say what it is and so you could write this with one of those functions and a little post render and I use more button where you just click and it just bubbles up and says refresh this query it's it's it's I don't know 20 lines but the big difference here and this is what I should stress even though I'm a fanboy it is doing lots of black magic and that's the big thing if something goes wrong you're gonna have a hard time like ask the next creators which I do all the time and they're lovely they always help but there's lots of magic there for DX purposes the thing is in this you are so open you know exactly what's going on and this is move into the framework that you are work with too which is which is nice yeah so there's just good things in all sizes all shapes and sizes I like it and I just like I actually quite enjoy I mean this is this is messy right now but I quite enjoy Astro templates you can't use them like oh if I could write write write this and have it be a client client side stuff I would because I actually really enjoyed the like the very firm like HTML feel of of Astros templates um yeah you use them for C side yeah no but it forces people not what I love about the island thing is that you actually have to think about the fact this is going to be an island I'm going to add some client site here rather than what we used to have previously with nextjs and Gatsby and stuff where it just automatically hydrated everything all the time so much extra bundle size so much stuff that you don't even think about right and in here you're kind of forced to think about it which is great so you're adding some stuff here I see um on the screen um so we have this this is a YouTube video that we have on this on our YouTube channel that you can actually go to and see this in much more detail and there's also I'm adding this right now um there is so this is one style of pagination right this is like this load more functionality and this is actually what you see in so many tutorials across the web nowadays however it is not the only style of pagination and who's in who's in chat they wrote a a great post on doing pagination in the traditional sense um in next which actually when we paired a little bit on it we couldn't find like this style of information on on using next like every every pagination article on next was load more functionality and like this idea of like having uh having like the buttons at the bottom of a page and like having page one two three four five all the stuff you would get from like a traditional maybe e-commerce feel uh couldn't find information on it you see here one two three next previous all that um like because we were trying to figure like there were a couple like hiccups as we were trying to figure it out no information available like it was ridiculous uh and so they put together a really great article on it it is both a continuation of a series uh but also just a good Standalone how do you do pagination and next the next graph well combined with pagination that's that's an interesting one so um Brian we did this in an hour and you showed a lot actually like this was great so I want to thank you for your time and I think it's time for some CTA Now isn't it ctas are always fun aren't they so I'll do the first you can do another let's see if if you feel like it though so sure this is the first so we have a really really lovely community and we love how many people are in there how often people ask questions we have all these things like a little get started Channel where you can just without the pressure of thousands of people ask any question you have and so if you're trying out all this stuff in hgraph and you're trying to figure out your next G are Astro please just join us on slack hyra.com and just ask your questions I I willine I will pause CTO real fast because I actually really enjoyed this comment from Louise right an interesting stepup challenge would be to dynamically change the size of pages based on how many can fit in the viewport you absolutely could do something fancy that would break my brain a little bit to try to figure out the the first step right that's not that's not just like a step up that's a jump up the first step would be can we dynamically change the size with aop drop down on the page absolutely that changes that variable yeah figuring out the sizing of everything you absolutely could do but it's it's a little bit more than a step up but a really cool idea I like that a lot especially in the micro blog I honestly Louise is this a next stream let's let's keep that in mind I love this idea it's quite hacky though but it's cool you can add another Island to look at the oh I I'm already doing it okay wait you can do it Tim I that's that's a lot of brows JavaScript that I haven't written that style in a long time but it's absolutely possible I've been dreaming reading and writing with that stuff for a long time when I worked at agencies me you've been at startups a bit longer but I've had these crazy things where it was still Jake wary time where we had to do all that stuff all the time anyways H yeah pull pull the next c yeah you go for the next I'll put it on the screen which one do you want I just surprised me here we go ah yes uh you might want to sign up and and actually use hgraph um app. hyra.com signup is a great way of doing that we actually have a whole bunch of starters you can pick from um Tim wrote a great one that's an e-commerce store low uh worked on the not hgraph FM which was a music streaming site but a a movie streaming site based on some the code there a lot of cool functionality you can play with you can get content immediately um so yeah definitely sign up give it a shot and join the slack community that was Tim CTA and ask questions that you got as you you find them yeah and just one thing I decided to say with this also is that our free tier is like super free no that's not the right word super free I don't know what that means super free no but it's also um there's a lot of features you can use like almost everything you can do with free tier like there's production projects I've been using like with a lot of things in it they're all for free and so then the last one I'll take this one um because Romina our lovely colleague is in the chat here and she's been writing all the time on our docs and we're getting it better and better so if you have any questions either go to the community or just you can find it in the docs and I think we're good yeah any last words um you know La last week it was very like I don't know there was like uh HTML when HTML makes sense extend it with Islands I don't know something like that okay that with that bombshell we'll just this is it yeah thanks thank you everyone for watching and we'll see you next week 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?