skip to content

First look at Astro 5 beta

One of the most promising web frameworks is looking even more exciting with the features landing in v5. Ben Holmes, will give us a guided tour of the content layer, actions, typed env vars + more in the Astro 5 beta.

Full Transcript

Click to toggle the visibility of the transcript

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

JASON: Hello, everyone, and welcome to another episode of Learn with Jason. Today on the show, we are getting into one of my favorite subjects, Astro, and they just had a big release. We are getting a first look, guided tour from Mr. Whiteboard himself, Ben Holmes. Ben, welcome to the show. How are you doing?

BEN: Hey, it's good to be back.

JASON: I'm excited to have you. This is going to be a good time. I'm noticing now that you don't have the whiteboard in the background, which is, are we in a pivot? Are you distancing yourself from the whiteboard?

BEN: Oh, you know, I'm in the cottage lodge, I can't bring it with you when you're off in Tuscany, you know. It's tough first world problems. I could go grab the whiteboard, honestly. [ Laughter ]

JASON: No, it's totally fine, we'll just make the whole stream into a whiteboard for you, I think, is probably the way to go. Before we dive too far into anything, let's start by doing a intro, for folks who aren't familiar with you and your work. Do you want to tell us about who you are, what you do?

BEN: Sure. I'm Ben, you may have seen me as BHolmesdev around Twitter and other places, kind of clumsy handle, but I've got it consistently, so we'll take it. I do a lot of YouTube content around all things web development, and my main focus is Astro, I'm a full time employee at Astro, over two years running, it's crazy to say I work on an open source project at a company with a full time salary. So yeah. It's really exciting to get to do that. Still is. And I'm here to talk about 5.0. I actually wasn't super involved in any of the features we're going to talk about today. But I did a crash course on everything and it was pretty usable, per usual.

JASON: Pretty usable being pretty high praise for a beta.

BEN: Pretty good. Yeah, better than the 1.0 beta, if anyone was around then, I'm still apologizing for that day. That was a crash course on everything about how do a release in open source and also don't postpone a 1.0. Just get it out the door. As fast as possible. [ Laughter ]

JASON: OK. So you've been with Astro now 2 years. What, so you've been there since basically day one, right?

BEN: Not totally day one, I think I joined like 6 months or so in the project originally started with Matthew, Fred, and Nate Moore. And there's like the first commit on the repo that just says magic thing.js, and that's all it was called. Magic thing. No one had a name for it. And it became Astro, I was building another framework at the time that was taking 11ty, which is still an awesome static site generator and trying to do something similar with it. But Astro was doing a way more focused vision saying let's just make a templating language, make it feel modern, typescript first. Let's build what people have been asking for, yes. You misspelled slinkety, no, that is how you spell it. Just making sure. [ Laughter ] Our SEO was amazing if you could spell.

JASON: So good. So good. Yeah. No, I love that. OK. And I remember, I think we did, you came on to talk about Slinkety, right?

BEN: Yeah, I did right before I joined Astro or somewhere around that time. It was very new to me to be anywhere near the developer space. I was just like drowning in podcast and YouTube videos through college. These people are cool. But I'm just going to do my regular dev job and just sit on the sidelines. And then, all the a once, working on Astro rushed into getting involved with everyone.

JASON: Absolutely.

BEN: Everyone's really friendly.

JASON: OK. So you mentioned that Astro it was doing what you wanted to do with Slinkety but at a level you felt like was worth pursuing. So let's talk a little bit just in a high level for folks who maybe aren't familiar. What is Astro? Why would somebody reach for Astro?

BEN: Yeah, and it's the same tag line since day one. Just with a lot more features. And that's Astro's the framework for content sites. So that can mean your portfolio, that can mean the marketing page for a very large industry. These days, Bloomberg, Porsche, a few others have used Astro build the landing pages and splash pages for new announcements. We're also good at stretching content, think blogs, or entire news outlets like Bloomberg. Documentation, we have a separate framework called Starlight that applies Astro in a focused way just for documentation. We've been taking that built for content sites and finding all of the use cases the community wants and really tightening down. How can we make markdown really good? How can we make docs really good? And now we're saying how can we make CMS fetching really good? All of the things people are trying. Dynamic rendering, with server rending with all of that stuff. That's improved in 5.0. So just taking the vision of content sites and stretching it as much as it makes sense.

JASON: Absolutely, yeah. And it's been, it's no secret that I'm a huge Astro fan. I've been using it for everything, teaching people about it. I've got workshops and courses and all sorts of stuff happening with it. I think it's great. And so, it's been really fun to watch how at the beginning, it sort of felt like Astro had firmly planted this flag that said, we're here to handle your content. And that sort of inherently planted the seed of, all right, so this is for a marketing site, it's for a blog, but, you know, I wouldn't really use it if I have too much dynamic stuff, too much user input, et cetera, et cetera. But then steadily, through the course of each release, feels like you've been tearing down those barriers where we've got features now to handle user input. We've got features to handle, we've always had interactivity, but it feels like even more advanced through time. So when you say it's a content site, where are you starting to draw the line now for Astro?

Yeah, we're just pushing it steadily forwards. But being very careful to keep that vision instead of saying, you know what, we're the framework for every website ever, and you should use it for everything. Once you do that, you really lose focus on what you're good at. And it starts feeling like it's a master of none. So we're trying to be really careful with that. Going incremental with it. But yeah, I would say the line, the line is definitely moved forward on the interactivity server side stuff, actions was the feature that I built for the past few months and headed up with the community. And that is a way to build backend endpoints in a really friendly way. No more writing response.JSON and trying to parse it out. Actually building something a lot like RPCs but with even more opinions, even more helpers on top for errors, et cetera, so if you want to have a blog that also has a newsletter submit, if you're adding those extra bits, it is a lot easier to do. Another thing is authentication. Up until now, static site generator for a lot of people. But sometimes, you have internal documentation that needs a middleware, that needs authentication, that needs checking cookies and storing that in SQLite or somewhere else. Even for content, you need server rendering, you need some places to store backend data. You probably need to have backend interactivity for doing post form submissions, et cetera, let's keep building that piece so you don't feel limited by what Astro can do. It's still the use cases you're thinking about.

JASON: Yeah, absolutely. On that point, we don't necessarily need to dig deep into this, but this is I think a reasonable question to ask, which is will Astro ever try to seriously compete with WordPress? Or do you consider it to be a serious competitor to WordPress?

BEN: Yeah, it definitely depends on the audience you're speaking to. If I'm talking to a bunch of devs that hate using WordPress because it's PHP and old school plugins, then Astro's a serious competitor today. Because you can use JSX, you can use all of the modern tools, you can also use content layer, which we'll be trying out today to fetch from a headless backend, which is really nice if you want to manage content in one place but actually style and theme your website with modern tooling. So all of that is available to you. But if you're like a WordPress agency that is mostly working with designers and copywriters, Astro still requires some hands on approach. You're using your terminal to create Astro and a new project. It is developer focused. But if you're in that audience and looking at headless options, then, yes, Astro is definitely what you want to try out. And plugging into WordPress engine, again, to have the headless experience, keep your WordPress, but use a modern frontend, that's something we can do.

JASON: Absolutely. Excellent. Let's talk a little bit about the specifics of the release this week, which was Astro 5 beta.

BEN: Yeah.

JASON: I got a chance to try out actions. Those went stable in 4 point something, right?

BEN: Yes, yes. Because I wanted my own week on Twitter. And I made sure that was launched first. [ Laughter ] Then 5.0 can come later.

JASON: Good, good. And that's the right way to do, right? Plant a little flag and say, no, this is mine. Let's talk about what's in 5.0, then. You mentioned then content layer. So at a high level, you made it sound like that's letting me hook into things like WordPress and I think I saw some announcements about different CMSs, I'm going to try to remember names and get them wrong. I saw one a minute. Can you talk a little bit what that is?

BEN: Content layer is expanding on what some Astro users might know, which is content collections. That's something that we launched over a year ago at this point. And it was a very focused tool just for working with git based content. Markdown, JSON files, all of those fed through content collections, you could check the front matter to make sure every post has a title and description and build the site efficiently. So if you're working with markdown files, it's easy. But obviously markdown only goes so far. If you're working with copywriters, they're not editing a markdown file. They're not cool enough. They're going to Sanity or WordPress or somewhere else and writing their content over there. So we need a way to pull them what they're doing, pull it in the Astro project, and handle all of the pieces you would want on top. Fetch from WordPress, a wait fetch, WordPress API, work with the data. But you have a lot of issues with caching, for example, if I'm in the dev server, every time I say, it's going to fetch WordPress, again. That's not going to work, I'm going to get rate limited or some other problem. I need a way to deal with that. And also, on every build, you need to refetch WordPress and rebuild the whole universe, again, not something you want. We wanted something that makes it easy to fetch but has a layer on top for caching and to reference related content. And that's something we're going to show off a little bit today, too, if we have time.

JASON: Yes.

BEN: It's taking a basic fetch call, adding caching on top, and it's not doing it in a complicated way. There's no GraphQL layer in meticulously choosing objects, it's just a function. You call it, turns an array, and you use it. That's really what content layer is all about. Fetch from anywhere, cache it.

JASON: This is one of those things, feels like this is a deceptively complicated problem to solve. Because every, everybody wants this. We want to be able to say, I want to use my framework and load in my content from wherever that content lives and I don't care. But I want it to be easy to work with.

BEN: Yep.

JASON: Every time we've seen somebody build a solution for this, it ends up feeling a little overwrought. I think this was the downfall of Gatsby, for example. Gatsby went all in on GraphQL, everything became a GraphQL plugin. If you were into that, it made it simple once you got everything in. But loading data into a Gatsby GraphQL layer was an absolute nightmare. And we haven't really seen an approach that doesn't feel that cumbersome. And a lot of frameworks have taken the approach of, you're a dev, figure it out. And we see user land tools. Everyone's reaching for something like a prisma or another ORM tool to wrap around whatever their database or in the case of Tansack query, reach around the API for whatever tool they're using to get the benefits of caching and so on and so forth. But it still very user land and very bespoke.

BEN: Yeah.

JASON: That's one of the things I struggle with the most when I'm working on different projects is that each project, when they take this sort of user land approach to things, you don't get the benefits of working with a framework, right? This is why people like Rails, it's why people like Angular. When you step into one of those projects, it looks exactly the same all the time. That was the initial appeal of Gatsby, it was going to give you that consistency. You know where data comes from, you know how the plugin system works. It was just too much work, right? Do you think Astro's, do you think you've threaded that needle?

BEN: Yeah. And it's a very, you know, delicate topic. Because there's definitely prior art of solutions that felt overengineered, that didn't feel easy to use. So some are skeptical, like, OK, content layer to wrap around the fetch call. What's going to happen if I install the notion API loader. And then it goes out of date with the notion fetch API and I have to fetch it. That's always going to be an issue. There's only so much you can do. And the best you can do is make an API that's simple, documented, something you could confidently use yourself, no tooling on top or working with just a get in a set function in a store that is all content motors are. And they return in an array of data and there's no GraphQL on top. We recognize the cons that can come with wrappers. And the best way to do it is make sure it's easy to use and uses standards as much as possible. In order to make sure we thread the needle, those are two design considerations that are part of it. And I totally agree with you on the framework not doing enough for you versus doing too much. That's been like a kind of push and pull because the comparable option is Next.js, which is very much on the other side of everything's an integration, everything is userland. And it's led to a beautiful collection of libraries and solutions that no one would've thought of before. But it also, an analogy I gave was kind of like Dora the Explore episode where she's like, and you want to use Tansack query, but if you don't know that, you're sitting there, just tell me the answer. We've been asking this question for three or four years, why isn't this built in? And it's a design consideration. It really depends on how you want to build things. Astro decided we were going to be a focus tool for content sites, we're not going to be general purpose framework. And when it's shouting in the face, we'll try to build it in. Building actions. We waited for every framework to play their cards on how form data should be sent and JSON should be sent. We took the best parts and built around. Content layer, the same. We waited for the community to fetch things every way to Sunday. We looked at Gatsby. We actually have Matt Kaine on our team that formally did work on the Gatsby project. So we had a lot of perspective coming in. We didn't do it too early.

JASON: Yeah. I think that, that slow to act can be frustrating for folks. I know that there was rumblings of a content layer at the beginning of content collections. Why don't you make it work for everything? I think I was one of those people in the Astro Discord being like, come on, give it to me now. But I do appreciate it. Because standardizing early can cause such a pain later on because then you have to remove features. And it's so much easier to add than to remove features from a framework. And as somebody who has felt the pain of having to maintain frameworks of we added a feature. So we'll just continue maintaining that forever as an alternative code path.

BEN: Yeah. Yeah. And that's, it's been surprising to people, I did this on Astro 1.5 and boosted it to Astro 5, and it worked. I didn't do anything. Of course, it gets harder and harder the more you go. We're running into that now with importing ZOD and other corners from like, oh, I wish it didn't work that way. The best thing to do is deprecate slowly, do majors every 6 months not every 2 years. So if it's a break, it's a small break. Choose the healthy choices to make sure if you do need to break an old pattern, it's doable. And don't even add new pattern until you're certain you need it. Otherwise, you've got the feature 2 people use.

JASON: What else is new in the 5 beta?

BEN: Content layer is the big one. We also have environment variable checking. It doesn't sound glamorous. But there is a lot of nuance to checking environment variables. Like, will this be used on the client, yes or no? Is it secret and needs to be encoded? Or is it something public that you can just slap in the build directly? All of those are things you can configure. We also let you validate if it's a string, boolean, or autoparse. It'll also fail to build and show you exactly what environment variables to add so you don't need an ENV example anymore. It's just there in the config.

JASON: I love that you played this down. It doesn't seem like that big of a deal. No, this is a huge deal. This is, I think, environment variable management on any team of more than three people has got to be one of the most painful things I've ever dealt with. And every company I've ever worked at. When I went to IBM, I remember one of my first experiences there. I walked in the office and said, OK, I need to get the local dev environment set up. Somebody copy/pasted 150 line.env file to me. And it was like every secret in the company. Just plain text in my Slack just thrown in there like, yeah, just copy that into your own environment. And I was like, this feels bad. There's got to be a better way to manage this. But then, we start reaching for ways to manage it and it ends up being, it's a lot, right? You don't know which ones you need, which ones are there. We used it years ago and it's not used anymore. Those little checks, those little quality of life improvements that are like fire up this code and says here's your list of actually use environment labels. Oh, my goodness. That feels like a huge, huge change.

Yeah. And we do have required in optional, as well. If there's anything you don't know about. I know. It's just everything you could want. It took a surprisingly long time to build out the whole feature. Shout out to Floorian, a new maintainer building amazing things for a long time. He led the feature beginning to end and it turned out really good.

JASON: Love that. Anything else we want to talk through before we start diving into some code?

BEN: Uh, I don't think so. Yeah. We can feel it out.

JASON: Let's do it, then. Let me drop us over into this view. And I'm going to turn on this banner, turn on this banner. And actually, before I talk about Ben, just look at his face and pretend he's not there yet. This episode like every episode is being live captioned. We have Diane here from White Coat Captioning, thank you, Diane. That's made possible through the support of Netlify who has been sponsoring the show for going on 5 years now, thank you very much, Netlify. And we are also doing a little pair programming today using Tuple. So Ben has control over my screen, can send us links, can draw on it, do all sorts of fun stuff, which is going to make our lives a lot easier as I go on. If I get confused, he can jump in and fix it for me, which is nice. Thank you, Tuple for sponsoring the show. We're talking to Ben. Get over there, give Ben a follow on whatever platform BHolmesdev everywhere. And we are talking about the Astro 5 beta, which was released a couple days back. So make sure you go and check that out. So this is as much as I know. So Ben, if I want to jump in and get started here, what should my first step be?

BEN: Yeah, we have a new set of 5.0 beta docs that show you how to create a new 5.0 project. So I believe it's in the blog post somewhere. I can also send you a link to the docs.

JASON: Let me hop in right here.

BEN: You can use PNPM, to go faster.

JASON: I've never used it.

BEN: Really? It's the only thing I used since open source. Became a common practice in the Vite community. I don't know.

JASON: Let's get in here and I'm going to actually, I'll let it make the directory for me. Create Astro and that is going to the next branch.

BEN: Actually installs the Next.js app. Yeah. Big pivot.

JASON: You want me to use the sample files or go empty?

BEN: It really doesn't matter. Working with a lot of data, not a lot of styling.

JASON: Typescript, I'm making assumptions.

BEN: Sure, sure.

JASON: I guess.

BEN: I hit enter, enter, enter.

JASON: That's usually what I do and I realize, I should probably ask in case Ben needs me to do certain things here.

BEN: Fair.

JASON: This gets us NPM installed. Let me open up this project. And I'll close this one. My VSCode updated. And it's so tiny, what happened? Let me change my profile, this is bad.

BEN: Profiles.

JASON: Yeah, they're great. Profile. Here, there we go, this is the one that's legible. So inside, I have the standard that I would expect from an empty Astro site. Which is an index page and then, over here. I can see we're in the Astro 5 beta .1.

BEN: That's all you get in an Astro project. One other thing, if you can uninstall this guy for me, it looks like we were getting some autoformatting issues earlier. Bay to software, right?

Cool.

JASON: And then just fire it up?

BEN: Fire it up.

JASON: Let's do it. We're rocking. Going out to here. Not the log in page, just the regular page. Let me make this left half, we'll make this right half. And we can we can be rocking. This all looks great. I see we've got types generated. I like that your CLI is helpful. Always so nice. Hey, did it break? Go here. We've got a lot of chat going. Double checking. The all PNPM strike force. [ Laughter ] Little love for Tuple. Let's see, somebody stand in for yarn. [ Laughter ]

BEN: You're lucky I'm not a Bun evangelist, this would get bad.

JASON: Great. Feels good to remove the dependencies.

BEN: That's a type checker. We'll get it working. Don't worry about it.

JASON: Yes, we are good. We're ready to rock.

BEN: I'm going to drop us right into a little example here. I was playing with a cool way to showcase content layer and APIs at once. Maybe we build an announcements page that link to a bunch of videos we want to showcase or something like that.

JASON: Yeah, yeah, yeah.

BEN: In order to build that, we might want markdown files for the announcements and pulling YouTube videos from the YouTube API to try out content loading from another source.

JASON: Let's do it.

BEN: Let's start with the easy one, which of course is markdown so you can see how to do that with the new content layer and any changes if you're an Astro user. To do that you can make a file had inside source content/config.ts.

JASON: Content/config.ts. All right.

BEN: Yes. And in here, we're going to make a new collection. So I expect all of the auto imports to just work. We can try doing like announcements as a collection name.

JASON: Is it called config? Or do you you define them outside of this, don't you? Yeah, announcements. And that's defined collection, right?

BEN: Define collection, right. There it is.

JASON: OK. Just a little bit wider.

BEN: And no problem. This accepts a schema as it always has. And a schema defines what front matter stuff is going to be in a markdown file, for example. Or it could be the fields that come from like a CMS. So this would be an object. And let's say every announcement has a title and we'll set up videos later. We'll just start with the title for now, maybe.

JASON: OK.

BEN: The second thing, a loader is what we're going to add. Alongside schema, you can also add a loader. And we have a few built in ones. Before, you had to specifically make a directory that was inside of content that had like a top level structure. So if you had blog posts, content/blog, all of the blog posts go in there. You couldn't have nested folders, couldn't put them in a git repo or something, had to be there. We have opened it up so you can glob anywhere on the file system, anywhere, really. Now you can call glob, and this will be another magic import that comes from loaders, yes. You can call glob, and this is an object that takes in a base, which is the path. You can say you have source/announcements if we want to put them there, they could go anywhere, though.

JASON: How would I do this?

BEN: It'll be root relative. If you do yeah, if you do that. That should work.

JASON: OK.

BEN: And then, the pattern would be like star.md or star star if you wanted to allow nested, it's, you know...

JASON: Yeah. Good old glob.

BEN: It's a lot like Vite glob or any of those tools. And that's all you need, really, the last thing will be, though, well, I just lied, didn't it, export const collections, and that includes announcements.

JASON: And that is going to be an object that includes announcements.

BEN: Yeah.

JASON: OK. Show this builds out our collections, and that's the entirety of the file. So this is the default behavior of content collections that we all remember, which is before we would've called the announcements and looked for a folder called announcements. This is doing exactly the same thing, we just get to put it anywhere we want now.

BEN: That's the difference, yeah. And there's also a file loader, as well. If you had, like, I think we set it up where if you had a set of authors. Every author will be a separate JSON file or separate YAML file. But now you can have one JSON file and reference a whole array of stuff in there, you can also say file, authors.json and it'll make a bunch of entries out of it. So that's a nice little addition if you were asking for that.

JASON: Clarification, the Z is, we're importing zod directly, correct?

BEN: Yes.

JASON: Good, good, good, nothing fancy, just odd. OK. We have our collection. I've created a folder for our announcements at the spot we are globing. Now I can create an announcement?

BEN: Yeah, sure.

JASON: Did you have a particular angle you wanted to go with on these?

BEN: No, my test data is garbage, let's come up with something together. Let's do it.

JASON: What's something we both like? Actually, why don't we do white Word announcements? I imagine you've got a list of good models and probably spend a lot of time in YouTube watching whiteboard reviews.

BEN: Mm hmm. [ Laughter ] I have one whiteboard bookmarked on Amazon. And I think, oh, did I take it down? Because I migrating my website. It's down. It linked to the Amazon page.

JASON: That's very funny. Very funny.

BEN: Yeah, I guess we could say, you know, new whiteboard just dropped, now wide screen because I only have

JASON: OK. Wide screen, and we know we need you know what the feature is that I would kill for is auto complete on the markdown itself now that we have a schema for it.

BEN: We have that.

JASON: You have that?

BEN: I don't think it works with content layer, but if you're using content collections, we have that now.

JASON: Oh, my goodness. I want that real bad.

BEN: I know, you know

JASON: Let's see. Whiteboard now in wide screen.

BEN: Love it.

JASON: OK. That's one.

BEN: Yes.

JASON: Let me do one more here.

BEN: Why not?

JASON: How do I rename? Double click, right? And this one we'll do touch screen.

BEN: Oh, my god. Technology's progressing at a rapid rate. [ Laughter ] That's crazy.

JASON: OK. I'm ready.

BEN: OK. So now we've got some announcements, and we can go ahead and render these. And I was thinking, this is a good way to show off our new server side rendering setup. You don't have to do this.

JASON: Sure. Let's do it.

BEN: If you wanted to do incremental rendering, ISR headers, all of that, those work. I've been playing with this recently. If you wanted to do that, you could make bracket whiteboard or bracket ID, actually. We'll just be like rendering out to an ID. So something like that.

JASON: All right.

BEN: Dot Astro. And here, this is a server rendered page that fetches an announcement instead of having to do get static pads and all of that stuff. You can do that. And I think it's pre render instead of rendered.

JASON: You're right, you're right. Does this, I think I read somewhere, and this may be incorrect that you've combined like hybrid and static mode. It's just always in hybrid mode because it's static by default and you can export the prerender, is that true or is that future?

BEN: That's right now, yep. The whole reason we're doing this, actually. I wanted to show off. You can just turn off prerendering and you don't need to play with outputs.

JASON: So good.

BEN: Yeah, to fetch an announcement, you can... am allowed to type? Is that a thing you can do?

JASON: Yeah, click in.

BEN: Oh, let's click in. Enable keyboard. Very cool.

JASON: None of this is my fault.

BEN: You don't have emotions, but I'll make it work.

JASON: It does get a little weird because I'm streaming five different directions, so the network struggles a bit.

BEN: Yeah, if you don't mind auto importing that.

JASON: You got it. This will content.

BEN: That's the one. And that's plucking off the parameter. And that should be params.id, I guess.

JASON: Right, because we called it ID and not announcement.

BEN: Yes, and this is a cool little thing you can do, if you want to say if not announcement, you can return, this little guy right here, return Astro.rewrite 404. And that will render a 404 page if you have one. So if you want to go make a 404.Astro that would probably help. I think you get an infinite rewrite loop because it's a dynamic route.

JASON: I gotcha. So we make a new file 404.astro and this one

BEN: Busted.

JASON: We'll make it actually valid HTML, I guess.

BEN: Love that. OK. And I saw this error and I reported it to the team. Restart your dev server, it should not be throwing that error. You are allowed to do this. If it's one of those slugs like whiteboard dash wide screen, that should work.

JASON: OK. Now I go to whiteboard, wide screen.

BEN: And we've got a blank canvas.

JASON: Which is what you would expect because we haven't output anything yet.

BEN: Sounds good. All right, now we have our announcement. You can, of course, get the title straight away, so if you want to do announcement.data.title. That should have the title and it's all type safe.

JASON: Hey, and what was the other one? It was touch screen.

BEN: I think so.

JASON: They're working.

BEN: They're working. And if you want to render the post content, you can call the render function, this is slightly changed from the old one. If you see a weight render, render's now going to be an imported function.

JASON: Oh, interesting, we're going to await render, and that comes in content, right? Like that?

BEN: That's it. And it'll return a content component the same as the old one.

JASON: OK. And I drop that right here.

BEN: Drop it right there.

JASON: If I can spell it right. There we go.

BEN: And now oh, I know why that is.

JASON: That broke because

BEN: You don't have a layout or anything. So it's literally not encoding things.

JASON: We could grab

BEN: Yeah, it's what you need. The cool thing about Astro, it's just an HTML file, so it's kind of do whatever.

JASON: Kind of is what it is.

BEN: It is what it is.

JASON: So now, we've got... we've got content collections rendering, and that is pretty dang neat. I go back between the two and reload because I was hitting the cache page. Look at us go. That feels good. Feels like what we were doing with content collections before. This feels better. Yeah, it was sort of a magic thing, right? Instead knowing I'm importing the render function and wrapping that, I think, it feels correct. So, I want to do something weird. I want to get something not marked down into Astro.

BEN: Let's do weird. Let's do weird. So I'm thinking full YouTube API loader. That actually pulls in some videos. That showcase. I don't have any wide screen whiteboard videos.

JASON: I guarantee we can find.

BEN: Oh, I have a I was going to pull from actually, wait a minute. I was going to say, we're going to pull from a YouTube play list, but I can add whatever you find to this play list and we'll be good. .

JASON: Wide screen, here we go. Perfect, perfect.

BEN: Yes. Let's do it. [ Laughter ]

JASON: Why not? So this one needs to go into the list. Let's see, I'll put it in the private chat here.

BEN: OK.

JASON: And then, we need a touch screen whiteboard.

BEN: Oh, my god. It wasn't supposed to go like this. I've got to go make a play list now. One second.

JASON: I'm here to complicate your life.

BEN: Yes. Here we go.

JASON: This is not a TV, you're right, it's a whiteboard.

BEN: This is not a TV. All right.

JASON: Before we dive in, there's actually a good question that's worth answering here. What's the advantage of doing it this way with get entry versus creating the markdown in page in pages?

BEN: Gotcha. One of them is going to be checking. If you want to have title description et cetera, checking they all work and they have the same schema. Another one is going to be if the markdown's coming from somewhere else. A different repo you can fetch from. Also, putting it outside of source, you can put it there, as well. A lot more flexibility on where it goes. But otherwise, if you don't care about front matter and you don't care about where the content is, you can still put it in pages and expect it to work. It is nice to have it all to work with. Having the layout prop and passing front matter to a layout, it's more explicitly we're writing an HTML document and rending it ourselves. At least to me, it's also kind of a developer experience win. But we know people love their markdown in pages. So that's still a thing.

JASON: Yeah, and I mean, it still works.

BEN: Yes. I think our blog example does this.

JASON: We can just hit, there we go.

BEN: There it is.

JASON: We still have access to this, to the markdown. But yeah, for me, at least, the major advantage has been the type safety of it. I know what's in here, right? I have details, I know where it comes from, and when I get into the announcement.data, I don't have to go look at it. The other major thing for me has been turning on the strict mode for these.

BEN: Yeah.

JASON: Where I will do this because a major problem that I've run into in every markdown blog or docs or anything is that front matter sort of becomes this nightmarish outgrowth of everybody's weird ideas over the years, and we have things like somebody created categories once. We never got around to adding categories to everything, so we don't actually use them, but they're still there. I'm not sure if you need to use them or not. People copy and paste them anyways and you never clean it up. So having the strict mode on, we know what's allowed and we throw if you add stuff that's not allowed. And that way we keep the front matter to just what's being used. And I think that's to me, that's the worth of price of admission.

BEN: Yeah. Yeah. It's kind of like people who comment out code all over a repository. I might need this in the future. We have commit history.

JASON: We just copy/paste the function and rename it.

BEN: Yeah, that's good.

JASON: Like, config old. [ Laughter ]

BEN: Config int. OK. [ Laughter ]

JASON: All right. So I did, let's see, we've got a couple YouTube videos that are going to be attached to our whiteboard setup, I hope.

BEN: Yes.

JASON: How do we actually get these in?

BEN: Yeah, let me show you what to do. First, as you might imagine, we probably want an API key to talk to YouTube. And obviously, that's a reason to show off environment variables. So

JASON: Indeed, it is.

BEN: I will send these in a chat in plain text. And if you want to add those off screen, that'd be cool. [ Laughter ] And we talked about environment management this will check them, but sending environments to your friends, I will say, if you've ever used Doppler, it's this amazing CLI tool that lets you log in and pull environment variables without having to send them around or sort them somewhere. I recommend that whenever you're working on team projects. You can also say Doppler set up staging and now you're connected to the staging environment variables.

JASON: That's really slick.

BEN: It's really nice. Nonsponsored. Yet.

JASON: OK. Do you did you send these to me in the chat?

BEN: Yeah. One moment, actually. Go ahead and do this. Copy that. And I'll send it slightly securely here. This one time secret.

JASON: Where is this going to open? It's fine. We're fine. OK. I'm off screen and creating a .env, right?

BEN: Yep. Put them in there.

JASON: I have created a .env. And for the sake of making this easy for me later, I'm putting both of the .env keys into my clipboard. Closing this because I have it copied. Good. And then, pulling this back over. We've got the .env here and we have access to two secrets now. These two.

BEN: Yes, perfect. I thought you were going to paste the values. I was like, wait! [ Laughter ]

JASON: It wouldn't be the first time.

BEN: Same here. If we want to set this up in a nice way so that anyone can clone this project later, you can go to the Astro.config file. YouTube chat, no. [ Laughter ]

JASON: All right. So Astro.config.

BEN: And there's a new option called env. And you call env and make a schema object in here, we can define what sort of environment variables are allowed.

JASON: Like this?

BEN: Yeah, so there's env schema and these keys.

JASON: What is happening right now? Env schema and then, I think I was hitting command X instead of command Z. I ate all of my lines of code there. And then we have, I think I broke I did. It was YouTube

BEN: YouTube API key.

JASON: Key and YouTube API secret, right?

BEN: I think we've got play list ID. I was going to pull down from the specific YouTube playlist, we can make a different one. But this will just pull my videos to shamelessly plug them.

JASON: OK.

BEN: And we'll work from there. Now, you can combine some information about these. If you call env field, that's the name of it and it should have a magic import here. And you can say .string on the end of that. This is kind of like a oh, not without yes.

JASON: Got it.

BEN: And inside of there, you can pass some information about the visibility this takes a little object.

JASON: Takes a little object.

BEN: And it has those two important things. You've got the access level which is secret or public. Secret keys are just going to be encoded as process env, and public which would replace the environment variable into your build. Which is the default for client stuff. And then, the context is exactly that.

JASON: So I autocompleted my way through that. Did it know it had to be server because we set access to secret?

BEN: I think so, yeah.

JASON: That's cool. Very cool. So if I set it, then, to access public and go to do my context, choose client or server. That's cool. I guess this one doesn't really matter because the play list ID is a public thing. But we could just make it secret anyways, right?

BEN: Yeah, you can do whichever.

JASON: We'll keep it secret. Keep it secret, keep it safe. Goes on the server. OK that's, I mean, I like this schema for .env is already kind of making me happy here.

BEN: Yes, the nice part, though, is going to be importing these. It's not on metaenv. It's not. Just type YouTube API key right now. And hopefully, yes. There they are. And those will be type string. And you can just use them.

JASON: Oh, it's beautiful, and now we don't have to do typescript, expect error. We don't have to cast as thing.

BEN: Exactly. It's great.

JASON: I'm very happy right now. That's wonderful. Oh, somebody asked me to keep it public to show the difference. So yeah, let's

BEN: Why not?

JASON: Let's make it public to see the difference.

BEN: You have to probably open your dist folder to see the difference. As a user, they come from Astro server same way.

JASON: Got it. There's no real difference in the YouTube play list ID, this one shows as being a string, being a string, functionally, they're not the same. If we set this to context of client, does that mean that when I try to, if I try to use this in like my public template or something, is it going to let me? It'll throw an error if I try to use a server one?

BEN: Right. Exactly. That's what it'll check on.

JASON: Interesting. Very, very cool. I'm following. So we've got our environment variables, type safe environment variables, yes. And now, we should be able to import from YouTube, right?

BEN: Totally, so writing like a YouTube API that parses all of YouTube's crazy garbage takes time. So I went ahead and wrote that sort of off camera and I'll see if I can add it in I'm trying to do it with the Tuple, let's see, if I do this. Yes. That's typing. Cool. I have so much power.

JASON: Look at that, shared, copy, paste. I love it.

BEN: Look at that.

JASON: Let's look at this.

BEN: Let's look at that.

JASON: I see why you copy/pasted this.

BEN: There's a bit of stuff to make sure you fetch it, but I could put this on NPM so you could use it. I could totally do that.

JASON: So walk me through what's happening here. We're building a URL, I understand that part. This looks like the Astro stuff.

BEN: Right. So instead of using one of the off the shelf loaders like globed or filed, we're creating our own loader here. A loader can have a name so if you have an integration that wants to add a loader for you, it's totally ready for that. So we're inviting the community to go build these things. We're just creating one here called YouTubeler. Still has a schema, and we implemented load ourselves. This is going to get called whenever a build is kicked off and your deserve server starts and you can do anything you want inside of here as long as you use that store object to write values, all of those will appear inside of the collection you set up. A store is really simple, it has a getter, a setter, and also some stuff to look at the values or other things. If you've ever used a map or just a basic object, it's that, just a place to store things. So you can also have caching and other niceties when you do future builds.

JASON: Got it. Yeah.

BEN: And you saw up there, it was walking through the pages because the play list might have more than 50 entries or something like that, that's the maximum page limit on YouTube. So I'm just walking through and putting them all on here naively. Because if it's a playlist, it's controlled. And I put a warning there if something is really unexpected, but it doesn't error, not super important. And down here, it's going to fetch from YouTube, it's going to walk through the items, and then, we're going to write it to the content collections API. Parse data is going to parse the schema, put it through the schema it has set up, and it's going to store it that way it's cached and ready to go. And you might be wondering why can't you just return the data? What's the store? Why is there a store? What is happening? Well, the nice thing about a store, you can choose when it updates. So for example, if I wanted to get a little more clever and say I only want this to update every week because I only upload once a week, then you could set that up in here and store little metadata property with when it last updated. If I make a ton of changes over and over, again, it's not going to fetch YouTube on every build. Only once a week as I'm working on my project. And your dev server's only going to run on startup, and while you're working, it's cache the whole time.

JASON: Is that something that I is that just I pass that into store? Or that sort of a user line implementation?

BEN: That'll be user land. There's documentation on how to build your own loader. And it is pretty low level, I expect it to get friendlier if we see a lot of people building their own setups. But there's a documentation guide on how to do meta properties. One of the properties that come into load you can say meta.set date.now. You can check against it next time it loads, if date.now is greater than one week, no op and don't do anything. Total control. Because we also know there's a ton of triggers that could happen, like maybe you had a web hook and only wanted to build what it had to be called and that triggered the build. That's something you can do. If you have a CMS and constantly making changes on your website, it shouldn't have to redownload the CMS stuff. It should only update the CMS stuff when the web hook has triggered. So those granular things are possible. But you set it up.

JASON: Cool. OK. And just looking down here, we're looping over, we're setting stuff, and down at the bottom, this is object schemas, basically, just making sure that what comes back from YouTube is fulfilling the pieces we need to actually use this.

BEN: Yep. Totally and down there, I'm doing a transform to make it look nice for our app. YouTube has some snippets weird, but this is usable.

JASON: Yeah, and this is actually one of the things I should take more advantage of where you have a gnarly some kind of gnarly API response. And what I would do is define the parts of the schema I want and know it's going to be terrible. When you can put it at a top level of what you actually use.

BEN: Yeah, and it is definitely nice to do that.

JASON: Great. Now that we have this loader, we are exporting something called YouTube loader. And so, if I can make some inferences here, what I do next is I would set up my YouTube collection and the way that I'm going to do that is I'm going to have a schema. And does that schema get exported from the loader you just sent me?

BEN: Right, there's a little nicety where you can say loader, YouTube loader in the schema part will just be inferred because we provide it.

JASON: Oh, for real?

BEN: Yeah, that way if you're using a plugin from the community, it's a little nicer.

JASON: OK. I did something wrong.

BEN: Oh, just call it. YouTube loader function. I could have just returned the loader, but whatever.

JASON: OK. So now we have YouTube?

BEN: We have YouTube, I think.

JASON: Let's do the, like the Hello, world, of all of this const YouTube equals a way to get collection and it should auto complete for me. It's not for reasons I don't understand.

BEN: Did you add it to your expert const collection in the config? Oh, you did.

JASON: I did. Something's not saved. What did I not save?

BEN: Yeah, something is unsaved.

JASON: Saving all files.

BEN: Oh. Perhaps.

JASON: So back out here. You have awaited the collection and then, I can just, this is what I always do.

BEN: JSON null.

JASON: Indeed. What did I call this? YouTube null 2. Now, show me the stuff.

BEN: I think it's on the home page.

JASON: I screwed something up. The thing I did was does not exist or empty, which means I'm missing a piece here somewhere.

BEN: So we have YouTube right there.

JASON: Should I turn it off and on, again?

BEN: Turn it off and on, again. Collection YouTube

JASON: There it is. Something maybe I saved things out of order and tricked it.

BEN: That's good to know. I do know that some of the live updates are it's caching too much and it should update when the config file changes. All right. Cool. Beta software. .

JASON: Here we go. We've got a bunch of this is a YouTube play list that you put together.

BEN: Yeah.

JASON: I see what this is. So we've got everything that we need here. And this is so much nicer than the typical YouTube output, which is

BEN: Oh, for sure.

JASON: How do we want to use this? How do you want to do it?

BEN: I actually wanted to get a little fancy and let us reference YouTube videos from an announcement post and display all of the videos related to an announcement.

JASON: I don't know why when you said that what came into my heart was a very proper, like, let us reference YouTube
[ Laughter ]

BEN: Are you not entertained? [ Laughter ]

JASON: OK. I want to do that. And the way I have done this in the past, I would show you, I would say video and it would be a v.string, and make the YouTube video ID and I'm doing full, I don't know I frame from YouTube. I'm just throwing the YouTube embed up on the screen. If I want to improve this and make this, this to be one of these, how does one, how do?

BEN: Yes, you replace Z string with reference videos. And that's it. So reference function.

JASON: For real?

BEN: Yeah. That guy and videos as a string or

JASON: Or YouTube since we called it YouTube.

BEN: Exactly.

JASON: So now, this is going to yell at me. But I can come back here.

BEN: And you could make it optional.

JASON: But why would we do that? I'm going to toss one of these on each one. I'm making inference that's the YouTube ID?

BEN: That's the one.

JASON: Save that, get on here. OK. And so, now it matches and when I come out here and we go to whiteboard touch screen, it fails?

BEN: Is that the right route? Do you have a title? The collection announcements does not exist. What have we done?

JASON: What have we done, indeed?

BEN: Interesting. I have not seen that.

JASON: So, my VSCode is cursed.

BEN: Maybe.

JASON: Over the course of this computer is probably 4 years old at this point, and I have installed literally everything on it. So, I'm probably running like 25 or 30 extensions in VSCode, I'm sure that my VSCode does unpredictable things that others don't. However, that being said, I don't know why that happened.

BEN: We will look at that, I think. It was there and something messed up when the error was resolved. I wonder if you trigger an error, it reloads, something doesn't get reset. I don't know. I was going to say, only 25. I have like 50.

JASON: I mean, I'm actively resistant to extensions and I still have that many installed. I hate stuff. I don't like stuff, Ben.

BEN: I know, I switched to Zed and I have 5. And my life is beautiful.

JASON: That's the other thing. I drove Adam into the ground. Before I switched off. [ Laughter ]

BEN: I love that.

JASON: OK. So we theoretically, then, we have our video. If I wanted to show some details about it. I can go to announcement data.video, and is there stuff in here? There's stuff in here.

BEN: Yes, however, however, because of efficiency reasons and it might be cool to change this, there's like an extra function to call to fetch all of the related data. But it's very easy.

JASON: OK.

BEN: It's very easy. You're not having to do a full fetch with zero type safety, et cetera. Let me try typing it myself. If I do this. And I assume you would use an array. I'm a fool. OK. If I do video entry, announcement data video, that should get the video. And there it is.

JASON: Indeed it does.

BEN: Yeah, there it is. And it'll reference if the video doesn't exist. So you don't have to think about any of those things. But yeah, I don't know, whatever you want to do with the video. For now

JASON: We parse this out to plain old video.

BEN: Yes, perfect.

JASON: I could get data.snippet.title?

BEN: Yeah. Oh, interesting, that's the wrong inferred type, I think. Because that's like the YouTube type is it typing it based on the input? Why did mine not do that? I tried this earlier. Interesting.

JASON: This is my superpower, I'm going to find something weird.

BEN: You found a very weird thing because we know that title's a top level thing. That's the schema we used. I wonder if when I changed it to be a schema on the inside, it doesn't work anymore. Let's find out.

JASON: So by saving it, though

BEN: But now, wait. Yes, that's the title. So that worked. It's taking the input when it should be looking at the transfer. Matt Kaine, you're watching, you told me you'd watch, go fix that.

JASON: Did you fix it already? Is beta 2 out yet?

BEN: Where is it? I don't know.

JASON: No, this is great, though. So we have our video schema is being pulled out and it's missing the transform.

BEN: Yes, it's inferring the input type and not the output. It has all of these fields, so if you want to put in an I frame or something, you could do that. If you wanted to show the thumbnail and make it a link, you could do that, too.

JASON: Got it. This is our embed URL. Why don't we yeah, why don't we do that real quick to show show the power of data? Is it a straight up I frame? Is it source?

BEN: Source.

JASON: And we would put in the YouTube data. or no.

BEN: We keep changing names.

JASON: This is my fault. Embed URL, was it capitalized?

BEN: That's the one, yeah.

JASON: Do we need other things for that to work? Or is that going to

BEN: I think it'll work.

JASON: Look at it go. Look at us.

BEN: Wow.

JASON: So, I mean, this is, this is you can just see the gears are turning for me on how KWIBLG quickly I would be able to clean up some of the things I've had to do where like you said, I'd have multiple things, I've got weak references where I'm putting in an ID but it's just text and there's no way for me to validate that it actually exists. So that's actually a great question. What if it doesn't? And I'm just going to add some junk to the end. Reference to it is invalid. Beautiful. This is exactly what I've always wanted. Is just, I don't want to have to do a full blown database, but I also want some of the benefits of like joins in a database.

BEN: Exactly, yeah.

JASON: Very, very cool. I love this. This is great.

BEN: I'll actually say, that's where Astro DB kind of came out of, or some of hour thoughts there. Because I was building references at an offsite. It's actually been in content clutches for a long time. And Erica, who works on language tools and other things, she said, if you're going to do references, I also want sort ascending. I also want these other SQLite features. And then, we started thinking, what if content was a database? What if all of these things worked? We're not quite there on the vision, but there's definitely dreams of like what if the content store is actually like a SQLite database that's storing all of this stuff? Can we make it faster? Can we give you even more features than references? Because as soon as you start thinking of things at least a prisma database, like a friendly one where you can say post references videos and a post has an array of videos, that's just nice to work with. I don't want to say join and then do a reduce to turn the join object into a nested array. I just want to feel like I'm working with objects.

JASON: Right.

BEN: That's mostly what we're getting here.

JASON: Yeah. And it does feel pretty nice. And the things that are from my perspective, I guess my wish list would be that the data just expanded the way that I would expect it to. And then, maybe Astro just has some parser magic under the hood to know that if it's not used, don't bother including it.

BEN: Yeah.

JASON: Or any of that kind of stuff. But then, there's a couple questions in chat. And chat, now's your opportunity. You have roughly 15 minutes to ask questions if you've got them. First one is, can loaders be chained?

BEN: What does that mean?

JASON: I feel like the answer is yes in the sense that we're doing references. Right? So we can load things. I guess maybe the other way to interpret that is can you have a loader that brings in something and then based on that information you loaded additional things? So, for example, if I was loading Sanity data and the sanity data had YouTube references, could I load my YouTube list based on the Sanity data to get in the related data?

BEN: Yeah. That definitely means you've got to control which loaders run first, and I don't know if we guarantee it. But I know that, that store object we were looking at, that YouTube loader, it has a store and you can also call .get on that store. I don't think you can get other collections, but if you could, that would be a way from a loader to go to the store and check if another collection's already there.

JASON: I guess the way I would approach that if it were me today, if the data was fully dependent, I would consider that that to be one piece of data. And I would probably run the load here and use whatever to kick off another loop and throw whatever result of that is into the store like my custom data loader. So there's definitely a userland way to do it. It looks probably like API wise probably wouldn't make sense just yet. But definitely, definitely ways to work around that if that is a need that you have. I would maybe also encourage anybody that starts thinking in those directions to try to think about how you can decouple those pieces so you don't have lots and lots of independent data. This is one of the things that made Gatsby really unwieldly to use, having to put things in order like that. If you don't have to, don't.

BEN: Yeah. Yeah. Again, it's why we make soft steps towards the API you're looking for. And if things are missing, it's probably intended or we just said we're not going to implement 10 things, we're going to implement 2, and if enough ask for 3, we'll walk towards 3. There's definitely pros and cons. I'm live thinking, what if things are interdependent? And what would that look like? Yeah, I agree. Especially because store.set can be called as you're walking through things YORKS uh can set new data as soon as it's discovered. Like you don't have to return one big array and write a magic map to make one big array in memory. Here, I'm setting in the store every time I walk through a new page. Walk through 50, store it, walk through 50, store it. I don't have a big items array with thousands of entries, I'm offloading it as soon as I have access. That would probably be a way to deal with interdependent stuff. They can be as nested as you want. Go crazy with it, it's a document.

JASON: Right. And is this running on the server side? So I guess to put a finer point on this, is this being rendered like at request time? Or is this being built once and then stored for the Astro site to reference?

BEN: Right now, it is build time with a catch. So everything runs in build whether you're prerendering or not. And you can invalidate it using the caching strategies I was talking about. Like storing the data so you can say if it's a week old, let's go ahead and refresh this cache of data and that gets triggered anytime you build the site. You might have a web hook trigger a build, the build checks the cache and invalidates the cache if it needs to. That would be the full flow. You're not rebuilding the whole website, only parts of the cache that changed. And that's really good for content. We have run into issues with server rendered e commerce sites. Where I have a product catalog that changes every five minutes, different stocks, different other things. If you're in that group, you can't really use a content loader because you're probably not going to statically render any commerce site every single time. We have talked about run time content loaders, we just haven't shaped the vision yet. We've been thinking in terms of static right now.

JASON: Yeah. Yeah. And that's one of those things that feels like, why would you build it when something like Tanstack query exists as far as a runtime loader. But I think that's also something I've seen Astro do well is you just imported Zod instead of the your own schema checker. So I think there's a lot of opportunity there for, you know, whatever the right solution is, may already be built and maybe Astro just needs to give us an opinion on how to do it.

BEN: Yeah.

JASON: I'm really excited about this. I think the sleeper hit of this is the YouTube, like the environment variables. What

BEN: It is a sleeper hit.

JASON: What a killer edition and there was a question about that earlier which was in the Astro config, somebody asked, what if you forget the context? And we get our answer immediately, you are not allowed to forget the context.

BEN: Yeah, you've got to know where it's going. [ Laughter ] Pretty good choice, I think.

JASON: All right. I'm going to put out one more call for questions for anybody who's got it. Did we get to everything you wanted to cover today?

BEN: That was everything I wanted to do.

JASON: Where should people go if they want to learn more and get involved?

BEN: Yeah, if you want to learn more, you were talking about the 5.0 blog post, that's a good showcase of all of the things we talked about, so content layer is super detailed in there. We talked about the community details, the ones I know about are WordPress Engine, there was an agency that rebuilt their whole stack from WordPress to Astro and loaders came at the perfect time for them and they built a WordPress engine loader, which thank you.

JASON: That's amazing.

BEN: Notion, that's another community one. Really cool. It connects to notion databases. If you have a table of entries, you can convert that to

JASON: You just changed my whole life.

BEN: I was trying to get it working, I was like, too ambitious.

JASON: I link to so many Notion pages because I can't be bothered to write the handling to get Notion data into an Astro site. But if you have solved that for me, everything's about to change.

BEN: Nice.

JASON: Server islands go stable. These are great. I think we talked about maybe trying to get here and we didn't quite get here. That's OK. Should we talk about these for a hot second? Just to give everybody an idea?

BEN: Yeah. I mean, server islands, it's annoying that the code is so simple, but you can put it on any Astro component. And that'll turn an Astro render into a fetch call for the Astro component. If you had a statically rendered shop page and it has all of the information about a product, but you have the user's cart or maybe a profile log in if there's need for that. You could just put that little part of your Astro site in a server island. And while everything else is prerendered, just that little part will be server rendered. Smartly take your component, turn it into an endpoint and it fetches.

JASON: And from a practical outcomes, this is a, in my opinion, simpler way of handling what the RSC or the react server component's flow is trying to solve which is we have the majority of the site is not dynamic. Like you've said, you've got your home page. The only thing dynamic on the home page, is your little user icon. The one I like to think about is Google. Well, not that Google. This Google. Here. Right? None of this is really dynamic. Like they could rebuild this once a day, except for this part here, my little user thing. If I can make this part server defer, then all of this is cacheable. They can serve exactly the same thing to every single user and then asynchronously render this. And I get kind of the best of both worlds here. I get a personalized page and I don't have to wait for the server to build all of these pieces despite the fact they've never changed.

BEN: Exactly. And it doesn't have to be static stuff either. It's kind of a way to choose caching strategies a little more granular. Instead of saying all of Google needs to be dynamic with no cache. You can say, the home page is cached for one day. Or it's cached with like ISR, on Vercel because I'm fancy. And in this one little corner is cached once a week. Or never or whatever you wanted to do. Instead of having a global cache header, you have component cache headers, and that's super powerful as soon as you're trying to figure out why is my lambda so expensive? Let's go ahead and be more granular and choose where cache headers go.

JASON: I do think that's one of the things, this is a problem that you solve when you have this problem, right?

BEN: Exactly.

JASON: In the vast majority of cases, I don't have good reasons to use server islands or, you know, React server components, any of that stuff. In most of the projects I work on, I find that being a solution in want of a problem.

BEN: Same.

JASON: It's an issue you hit when you hit it. And when you it it, it hits really hard. But make sure you have it before you start adding a lot of custom. Because when you add custom caching headers, you added a layer of pain to your life.

BEN: You did.

JASON: Now you have to manage, remember, train the rest of the team to not accidentally break your site. So just choose your pain judiciously, I guess. There were a couple of questions about the loader. So I've linked to this thread. But there's Storyblok, High Graph, Notion, Astro Feed Loader. Oh, that's really good.

BEN: Yep.

JASON: Is there a link to the WP Engine one?

BEN: I don't know if it's public yet. I just had a one on one with their team. And I was like, wow, and they're working on it.

JASON: So people should follow you, then? And you can share it when it's ready.

BEN: I will be live. That's a good plug. Thank you. That's exactly what's going to happen. [ Laughter ]

JASON: Can a server island accept props?

BEN: Yes, it can, and they're encrypted with a build key. So if you have any problems being passed from the server in, it can contain. Always be careful if you're passing down specific user IDs or environments. Use Astro env in order to do it properly or do an auth check in the server island, as well, so people can't just ping the island with now authentication render, anything. You need to think about it like a separate endpoint, because it is. With that, you can pass encrypted props, check whatever you want and it works.

JASON: Excellent. All right. So that is our time. I'm not seeing any other questions. So I'm going to say, if you've got more questions, make sure you go follow Ben, get into the Astro Discord if you get on the Astro site, up here at the top, you'll see there's a link to the Discord, jump in there. It's super active, super helpful. Definitely a good place to hang out if you are using or learning Astro. And also, you can get into my Discord, if you want. There's fun stuff going on in there. I do a lot of Astro stuff. So happy to talk to y'all about it. This episode, like every episode, has been sponsored by Netlify and live captions, we've had Diane here from White Coat Captioning all day. Thank you, Diane. We've also been pair programming today using Tuple. So thank you, Tuple, for sponsoring this and making the paired programming experience a little bit better. Make sure you go and follow Ben. Make sure you check out Astro. And check out the schedule on the site because we've got a whole lot of really good stuff coming up on the show. It's going to be just a jam packed month. So many good things coming on. Might even have some surprise appearances on my Tuesday streams. I was talking to Matt Kaine about coming on. He said he had hot takes about content layers. And I didn't have any Thursdays open, but I'm always down to listen to Matt be very Britishly salty. [ Laughter ]

BEN: It's been great. [ Laughter ]

JASON: All right, y'all. That is it from us today. Ben, any parting words for anyone before we wrap this one up?

BEN: Oh, I never know what to say. Keep whiteboarding, keep coding. Try Astro. And follow me on Twitter.

JASON: Love it. Thanks, y'all, we'll see you next time.

Learn With Jason is made possible by our sponsors: