Learn About Islands Architecture With Slinkity
with Ben Holmes
Partial hydration lets you ship zero JS by default. In this episode, Ben Holmes will teach us how Slinkity lets us use any component framework to build low-JS dynamic apps on the Jamstack.
Resources & Links
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 have Ben Holmes. How you doing?
BEN: I'm doing great, yeah. Good to meet you.
JASON: I'm super excited to have you here on the show. It's been a lot of fun watching you kind of develop in public and build your own visual language for sharing your updates. I see you brought your co-star, the white board, with you today. (Laughter)
BEN: It's my ride or die.
JASON: (Laughter) So for folks who aren't familiar, you want to give us a little bit of a background on yourself?
BEN: Yeah, sure. So I -- oh, shoot. I'm getting a lot of audio feedback right now. Sorry. Yeah, I'm not sure why I didn't hear it.
JASON: Do you have the Twitch on with audio enabled?
BEN: I don't have the Twitch pulled up, no.
JASON: Let me check on my side to make sure I'm not sending anything back to you. Shouldn't be sending anything back to you.
BEN: Okay. Let me see here. Now I'm hearing myself. What am I missing? Oh, are you seeing anything?
JASON: I'm not getting anything through on my side, so I'm not sure where it's coming from.
BEN: My neither.
JASON: Did I get contacts? I did not get contacts. I just don't actually need my glasses. I just wear them because everybody wants to look cool. But then I started playing with new lighting setups. I was getting weird shadows. So I was like, you know what, I'd rather have good lighting than look cool. I see Jamon is in the chat. Are you still getting feedback?
BEN: Let me try. Yes, I am.
JASON: Oof. Are you -- oh, let's see. The captioner is hearing echo from Ben as well.
BEN: Oh, wait. I muted your computer sound. I found this option, and now I don't hear myself. Is that working?
JASON: Hey, all right. Is that good for you, Rachel?
BEN: I think we're going to roll with it.
JASON: All right, everybody. We're going to kick in here. Ben, did we answer the question?
BEN: We've answered nothing.
JASON: We're going to pretend like nothing happened.
BEN: We'll roll with that.
JASON: So for folks who aren't familiar, do you want to give us a little bit of a background on yourself?
BEN: Absolutely. So I'm Ben. I use whatever front-end framework looks the shiniest. I've been doing web development for a while now. Just kind of soaking up every podcast and side project that I possibly could. Then eventually, started rebuilding my personal site and my challenge was I'm not allowed to use any frameworks at all, but I need to pull off single-page apps, I need to use cool templating languages, I need to have all the good stuff, and I have to build it by hand. The journey was -- I don't recommend it, but it forced me to learn every node API in existence to write files to the system and all that. So I eventually realized 11ty does a lot of it for you. I start going deeper. You can add your own extensions, use whatever template you want, register inside of your 11ty app. The rest is history after I learned about all the things 11ty can do. Undocumented things that 11ty could do at the time. So yeah, just kept plowing on that. Ended up maintaining an open-source project. It's my first one. I learned how to npm publish in July. It definitely started to take off more than I expected. So, I guess, thanks for that. And I'm feeling out how this stuff works as I go.
JASON: So in July here, you learned how to npm publish. We're now not even seven months from then, and you are pushing toward -- are you at 1.0 on Slinkity?
BEN: Oh, not even close.
BEN: I don't know when it will be. It depends on when we're comfortable with the features. When you build a feature, you think of two more. So you have to stop yourself at some point and say this is probably ready to be stable. But the main thing was like, we got to support every framework. We can't just be a React plug-in thingy. So in general, our goal is to make this slot into any 11ty project. And we can get into details of Slinkity, of course, but it will definitely take time to feel out when a 1.0 feels good. But, yeah.
JASON: So you mentioned that you are somebody who uses every framework under the sun. I think it puts you in a good position to answer a question that usually comes off a little bit biased because everybody's got their pet framework. So what -- like, why would you reach for 11ty versus a React meta framework versus Svelte? So how are you reasoning through -- like, what are the trade-offs, and when do you change what the trade-offs are worth to you?
BEN: Exactly. It's like we've made getting into web dev so easy that it's never been easier, to finding a starting point at least.
JASON: Somebody quote tweet that right now.
BEN: It's a tough one. Everyone has come up with the cleanest way to do things, and there are so many clean ways now. And I guess the reason I liked 11ty at the time was -- well, I was trying to build things with my bare hands. I like the idea of -- I guess I'm more of a weapon dev enthusiast. But I feel like 11ty lets you start with the absolute primitive tools if you want to. I originally call Slinkity the static site generator that grows with you. Too many words. But the reason was you start with HTML, and then you can apply some CSS with a link tag. It's all pretty simple. And if you look at the build folder, you understand your build folder. At first, it's just kind of copy/pasting the HTML you're writing. Then if you're a beginner, you might learn markdown, for example. And you put in the markdown file. You see, oh, it becomes an HTML file on the other side. That's pretty simple. Then you can start thinking about I want to apply layouts around this. Then you can start getting into templating syntax. Then later down the road, if you decide, like, now I'm building dynamic things and I want to use React, Vue or Svelte, or whatever I've decided to learn because they're all equally good at solving the problem, like I need an interactive thing on my page, you should be able to pick that up. That's kind of where the 11ty timeline stopped. You got to go set up Webpack or something yourself if you want to go any further than I have a markdown file and CSS. Even SaaS is something they don't help you with out of the box. So let's bring in a cool little bundler called Vite, which helps you with SaaS. You can say insert React here, here's my component, then you can see it appear on your page. You can learn about hydration and server rendering and all those other fancy words as you go. But that's generally the point. As you learn more tools, you can just keep throwing them on. You don't have to -- there's not a point where it's like, I go from 11ty to Next.js. It's like going from a salad to a burger. There's a middle ground. I can have both and progressively move up.
JASON: You're on dangerous ground here, Ben. We have strong opinions about burgers on Learn With Jason.
BEN: Strong burger opinions. Okay.
JASON: The islands architecture is challenging that assumption, right.
BEN: It is. And I feel like there's a lot of sort of approaches in this space that are trying to challenge it. Also, I see your comment, Austin, on the side of my face. I'll face the camera here.
JASON: (Laughter) Now that you're making a point, it's like, let me tell you what we're missing.
BEN: Yeah, it's like finally recognizing there's a spectrum in the first place.
BEN: Don't worry, man, it's an MVP. We'll fix it. No, it's fine. No, I know.
JASON: But yeah, so I'm really excited about this. So in specific, let's talk about Slinkity. So Slinkity has been making a lot of progress. It is kind of becoming somewhat legendary because you've been doing these videos where you have somehow made a whiteboard a kind of co-host to the effect that the whole time we've been speaking, the chat has been trying to get the whiteboard to have a moment to speak on its own, which is incredible, right. So how -- I really want to get into actually using Slinkity here, but let's take a quick second to just pay homage to the whiteboard. Let's talk a little bit about where did this even come from?
BEN: It's a good question. I'll speak for them. It started with when I first sort of put out the npm project into the ether. I would shout out web dev for just saying ship something. I almost sat on this for another few months because I didn't really know what it was. In the end, it's like if you get it out there, sure, you don't have that many GitHub stars, but it's public, and your to-dos are also public. So people will eventually jump in and start helping with it. It's also good for you to have more accountability. So all of that, I decided to ship. And I still have pretty much nothing except iMovie and a reasonably nice microphone that some Discord server recommended to me. So with that, it was like well, all these tech products have these really flashy -- like, they're very well-produced videos of the logo comes into view, and it sort of opens this door and shows these code snippets, but they're flying at you with a transition effect. I'm like, I don't want to make that because it's not ready for that.
JASON: You know what I really --
BEN: So I have a whiteboard in my closet. That's what's happening.
JASON: I have a request. I have a request for you to do practical effects with the whiteboard. Like, just roll it and lean it and give yourself the flying-in logo. So it just kind of comes into view.
BEN: My board just flies into view. Oh, my god. I need a green screen. I know that. I'm going to get it.
JASON: A green screen is definitely worthwhile. I have had a lot of fun with green screens. Yeah, maybe I let Chris Biscardi talk me into making some poor buying decisions, and I have a whole lot more gear coming. So I'm going to try to make even sillier things soon. Okay. So, Ben, I feel like we've been talking about this. Now I just want to see it go. So let's -- you ready? Do you want to teach some Slinkity today?
BEN: Yeah, let's try it out.
JASON: All right. Let me switch over to the other view. Here we are. We're in the other view. So before we start, I'm going to make a quick shout out to our live captioning. We have Rachel here from White Coat Captioning today taking all this down. It's on the homepage of the site. You can find that at learnwithjason.dev. And today is a day to celebrate because we've got new sponsors, everyone. So Netlify is still sponsoring, as expected. But we have added Nx. Nx is a very cool way to do mono repos. They've put a lot of work into their tooling, into a CLI that makes this stuff so pleasant to work with. I do not like working with mono repos most of the time. With Nx, I've actually enjoyed it. There is an episode on Nx if you want to learn about it. We had somebody from Nx on the show. And I will find it. Here it is. So you can find that right here. Get on there, see how it works. It's very, very cool. And we also have Backlight. Backlight is a way for you to build a design system in code. It's really nice. It's really easy to work with. I really enjoyed it. We also had Backlight. We had George from Backlight on the show. And this is another tool that you can use. So welcome to both Nx and Backlight as sponsors. Really appreciate it. It makes the show more accessible to more people. With that, we're talking about Slinkity. So here's the website for Slinkity.dev. And we're talking to Ben, who I need to pull up your -- Ben Holmes dev.
BEN: It is bholmesdev. I guess there is a BenHolmesdev. I didn't even try for it.
JASON: All right. Go follow Ben for all your whiteboard related content. I've reached the end of things I know. What should I do next?
BEN: Lovely. So, well, we haven't really even said what Slinkity is. But what we're going to do --
JASON: That's fair.
BEN: We're going to set up a Slinkity project here with our new npm init command that will give us some nice frameworks to try out.
BEN: Yes. This is something that 11ty has been policing for a bit. You kind of just have to start with a directory and go. But you can learn so much from an init. It's so much fun to answer some questions and you got a project. So I threw one together. We're going to be demoing a canary build today. It's not the official one. So I will warn you. This is not ready to use on your sites yet. That's because we have a lot of bugs to work out, namely production builds do not work properly. So we're not going to demo production builds with this today. But the stable version is ready to go if you like React. So --
JASON: Oh, my god.
BEN: We're going to keep a running log of any bugs found today. But I'm sure there will be many. So let's go ahead and set it up.
BEN: All you need to write -- taking a breath -- npm init Slinkity@canary.
JASON: That's it? No flags?
JASON: Okay, here we go. Okay to proceed.
JASON: What is my project called? I'm going to call this let's learn Slinkity because that's easy for me.
BEN: Nice. And with this, you can select which you want. You can pick and choose or use none if you just want help with your CSS.
JASON: Let's make it happen.
BEN: If you hit enter, you get some simple instructions.
JASON: Okay. Npm init.
BEN: And don't forget to have fun. That's lost on people. So we note it here. This will take a moment. You can use any tool, by the way.
JASON: All right. Did we get through here? Good. Everything -- we have things. So I'm going to open up the code. Got a few things to look at. There's Vue, React, Svelte all in the same code base. And I believe the command was npm start.
JASON: So Slinkity serve incremental.
BEN: So it bundles quite a few things. We need the dependencies for every framework as well as some renderers that we can look at in the config file so you can set them up yourself.
BEN: And with this, we have a cool little site using the same theming you might expect. And three slinkies. Each rendered with a different framework. We should probably label which ones they are, but we can look in the code in a second. If you want top press these buttons for the next hour, I don't blame you.
JASON: This is a good demo. I like it.
BEN: It's so much fun.
JASON: It's so much more fun than, like -- I know the easy one to show is a counter, right.
BEN: And there are counters if you go to the pages. Just ran out of steam. So if you click on these, these are entire pages that are rendered with a component. These aren't using partial hydration, but we will walk towards where you can use any of these as a language and partially hydrate any other component inside of that template. Which is wacky to think about. That is very experimental. We'll see if it works. But we have a demo of Vue and demo of Svelte. All rather similar, but of course they're using the frameworks that are labeled. Once we get production builds working on this canary, you would deploy with these commands here. And Netlify is our simplest example, of course. So we've included those instructions and a Netlify.toml file. Of course, you can use whatever you want. It's a static site. There's no servers to maintain with all of this. So, yeah.
BEN: That's what we're looking at.
JASON: All right. So I'm ready here. I want to learn more of this. Also, there were two questions in the chat. Let me answer the first one. Why the folder area on the right side of the screen? Let me show you with a quick example. When I am working on code, I like to collapse the side bar. When it's on the right side, it doesn't bounce my code around. That's why it's on the right-hand side. Then Brian, this was not a question, actually. This was just a really helpful thing. He's noting you can add Slinkity to an 11ty project after the fact. So this is not something where you have to start fresh.
BEN: Yeah, and our docs explain that, actually, on our quick start. You can either use npm init Slinkity, see all the cool features, or you can -- if you go to the package JSON, you can see that all we do is we just install Slinkity alongside 11ty. 11ty is a peer dependency. They're both dev, yeah. So Slinkity is just kind of another attachment. At the moment, we have a special CLI command. So you see the start script is actually Slinkity serve incremental instead of 11ty serve incremental. So I will say all the flags pass through to 11ty. If you're already using 11ty serve incremental port whatever quiet, like all their flags, you can just find and replace 11ty with Slinkity, and it'll work the same. Including with the browser sync server. So that works as well.
JASON: Oh, nice.
BEN: And beyond this point, we're working to even ditch the CLI and just have Slinkity be a plug-in. Because the nice thing is it can slot into an existing dev server, which is actually what we're doing. And it'll just manage the live reload events for you instead of letting browser sync do all the work. So with that, there's a couple issues on the 11ty side that we're resolving. But they're all small. Once they're ready, we can ditch the CLI, open up the door for 11ty serverless and all of their fancy features. But for now, you just have this little CLI command to get going. But the vision is this extends 11ty. This isn't some new meta framework.
JASON: And this is just kind of standard whatever we want. We can do edits, save it, and it shows right up. That is -- I mean, we get all the things that I like about 11ty. I'm editing, getting live reloads, all those good things. So if I want to write React, this is straight-up React. There's nothing magic here. The only thing I'm seeing that looks a little bit magic is this front matter export. And that's pretty straightforward. So this just lines up to my markdown basically.
BEN: Yes. And I will say the thesis of this is that they extended our plug-in ecosystem. In Astro, you can support any component inside of an Astro file. But with this, you can support any component within any other page, like markdown or a React page or Vue page. Or you can support it as the page template itself. So as long as you tell us how you get front matter out of this component, so we can slot it into 11ty's big old set of data, then you're good to go. You can use whatever you want. So in the end, once this gets really stable, you can turn any file into an Astro file, if you want to think about it that way.
JASON: Interesting, okay. All right. That's very -- I mean, I love -- I actually love this. I think that one of the things that is really promising about this approach is that it gives me the things that I liked about Gatsby, which were, you know, I already know React. I had to use it for work before I started building my own projects and stuff. So when I went to build my first personal blog that wasn't -- I think I was on Hugo forever because it was so fast. But I didn't really know what I was doing, and I managed to break that site. So rather than learn Go, I decided to rebuild it in a language I knew, which was React. Gatsby presented this way to just create a page and then it was a static page. This is so nice from the standpoint of, like, I get this mental model of a file is a page, so file-based routing feels really familiar. I'm not learning an extra templating language that kind of side chains to React. Which is maybe my one gripe about Astro. You have to have like an Astro page. Then you load a React component into it. I think they might have changed that. But this feels good. This feels familiar. So all right. I'm on board with this. And if I want to change it -- so I'll go over to this React page. It says React to this.
BEN: So if you want to know kind of what it's doing -- because I feel like some people in the audience might be like what the heck is front matter. In general, it's a way to export data for other layouts to be able to access. So here we have a few things on the top, title and layout. Layout is something 11ty picks up to figure out what layout file do I use. You can find the layout file inside of the includes folder. And if you used Next.js or something, includes is basically components. They're all junk drawers, just with a different name. In here, you can see title being slotted in because when you expose it on front matter, all the layouts up the chain have access to that title. So no need for React Helmet, for example. You can just whip up an HTML file and manually insert all of the things that you need. So that's all we're doing here, really. And you can even dynamically change the browser title.
JASON: That's really nice.
BEN: Layout specific, and of course hydrate is our special sauce. That allows you to -- if you want to hydrate the entire page on and off but avoid hydrating layouts that are used outside of that page, you can just flip on the toggle for the entire thing. Or you can choose to partially hydrate within it.
JASON: So I want to try something, which is -- so let's take a look here. Let's look at the dev tools. I want to see what's coming in from the network. How do I get more of these to go away? There's too many things.
BEN: I know. I'd love to know. Oh, I'll remember to hit that. You might need to refresh, actually. I know there's more than this.
BEN: Absolutely. So if you head back to that page, just delete hydrate eager.
JASON: Just delete it altogether?
JASON: Get out of here. Okay. So I'm going to refresh this.
BEN: Oh, check the dev server. I've noticed issues with this on the recent build. Yeah, restart the server.
JASON: Here we go.
BEN: We're working this one out.
JASON: Trying again. All right. Let's try this again. Uh-oh.
BEN: What's going on now?
JASON: There it goes. Okay. I think it just wasn't started yet. Let me restart the page here. This is the browser thing. We're not bringing in React or any of that stuff. The trade-off is that our counter doesn't work anymore. So we don't have a, like, functional React component. But everything else in here -- like this is -- what is it, a details element. So we can do, you know, interactive-ish things like that. We just can't have buttons with state and everything. Everything else just works, though. That's really exciting to me.
BEN: Yeah, exactly.
JASON: So when we publish, like if I run a build -- actually, can we try this real quick? I'm going to run a build.
BEN: So this will -- as I mentioned, production builds are messed up with Vue and Svelte and stuff. Canaries be canaries. But you can run npm to get a stable project, if you want to see how that guy builds.
JASON: We can do that later. We'll deal with that later on. But yeah, so we have the ability, once this builds, it won't include the browser sync. Does it include the other two files?
BEN: The other two?
JASON: There was a client and MJS. So let me look at -- let's clear everything, reload. Oh, it's dead. Try again. There it is. So we've got this client file. This is giving us back -- yeah.
BEN: What this is doing is it's loading SCSS on the fly. So we're actually loading the grid background and everything you're seeing. So just to make the dev server faster, it loads it as this sort of chunk that will turn into a regular CSS file in a production build.
JASON: That's this piece. Oh, interesting. I didn't even catch that. You're just throwing SaaS right in here.
JASON: And in build, it'll do a replacement.
BEN: Exactly, yeah. It'll generate a CSS file and update this link here to just say CSS. And the only other interesting thing is that root. We're referencing a file that's outside of our output directory. We're not pass-through copying our styles or anything. So this basically says go to the root of my project. Back out of everything and load it straight from here. So it's a little helpful alias because 11ty works with build folders.
JASON: Yeah, that's dope. This is cool. What I like about this is it tackles a few things that are not hard, but they're hard enough. If I'm trying to get up and running with a framework, my least favorite thing is when I go to try a new tool and I follow their guide and then I'm like, okay, great, I'm going to use -- like, I want to use CSS modules. So I swap it out and it's weird. Then I have to go do some googling. Then I've unplugged that. Now I want to use this thing. That goes weird. Then I find out it's because you have to use this special naming thing or install this adapter. So you find yourself in these tiny little holes that are inconvenient when you get set up. You only have to set it up once for the project. It takes you an hour, maybe. Then you forget how it works. So then on your next project, you have to do it all over again. What I love here is that this is just kind of -- it just kind of goes away. Like, oh, just include the SaaS directly and Slinkity will take care of it for you.
BEN: Yeah, it's not even us. It's Vite. We didn't do anything to get that working, actually. The most important thing is just make sure the pipes are set up. We're the glue between two very large tools. We also support Vite configs. So if you're configuring post-CSS, want to set up Tailwind, super easy to set that up as well. And yes, this is worth mentioning.
JASON: Yeah, I did an episode with Sunil where we talked about ES build, which is the underpinning in Vite. This is a very good episode if you are interested in why this is exciting, why it's kind of honestly a game changer. It opens up a whole new generation of dev tooling, which is what we're seeing as Slinkity and Astro and all of these tools are starting to be built on top of Vite that just add incredible Dx. And they're fast. Like, Vite is so silly fast. And that is -- yeah, anyway. Go watch that episode. It's a good one.
BEN: That's a good one. Yeah.
JASON: So what else do you want to show off here? What should we make sure we cover in our next 40 minutes that we have together?
BEN: Yeah, there's so many things. Well, I assume that you're more comfortable using React than Vue or Svelte, but I will at least ask which of the three do you want to use to build something?
JASON: (Laughter) I'm most familiar with React, so we'll probably be fastest there.
BEN: Makes sense, yeah. It's like sparkling or stilled? It's cool you can just use whatever you want, if you'd like. But I at least wanted to show this to everyone. If you're a Vue developer, yes, you can render a Vue page. You can also use scope styles. All of that was written with a scope style tag at the bottom. So you can scope them to just that page, just your component, et cetera. And that's kind of it. So from here, I mean, we can do all sorts of things. I was thinking that maybe we could build sort of like a basic store front of T-shirts that you could purchase.
JASON: Okay. All right.
BEN: Yeah, and that's the repo that I mentioned to you to clone. It's just a few assets we can plug into this guy. So we have some data.
JASON: Got it. I have that open to the side so I have some things ready. Do you want me to copy things over?
BEN: Yeah, I'll explain kind of what to copy where. Yes, and I did detail on the read me as well.
JASON: So I have data and images.
BEN: Correct, yes.
JASON: A lot of possum related things. Always exciting.
BEN: Yes, I'm excited to get them all on the page for the reveal.
BEN: These are 11 tees for 11ty that we put together.
BEN: Oh, yeah. You better believe it. Going to shout out some people in the audience that helped come up with the ideas. But as long as I can make the worst puns possible, I think – possumble -- we've done our job.
JASON: Oh, my god. This is going to be the first episode that I have to leave early.
JASON: Okay, I'm ready. I've recovered.
BEN: Let's do it. Good. I haven't. Let's copy in a few files. So we can copy that images directory into our -- we can actually copy it a couple places. I say put it in public. This is something we've wired up to pass through copy.
JASON: Let me grab all of these.
BEN: Yeah, grab them all and put them in images.
JASON: So I'll just drop that one out.
BEN: Cool. The second piece is going to be a data file that reaches for all these images and wires them up to some routes. So if we check out data, take that entire underscore data folder and put it under source. This is an 11ty-ism, by the way.
JASON: Okay. So we've got our 11ty folder.
YAML, YAML, YAML, YAML, JSON, JSON
BEN: Nice. Also, can you find and replace underscore assets with images? I meant to do this before the stream. I forgot.
JASON: Okay. How about I just do this.
BEN: Yeah, yeah. That's how I like to do it. Perfect. Okay, cool. So that will reference all of the images we have in there. Then public will be pass-through copied to our build output. And the last thing we need to do is configure 11ty to understand YAML because it doesn't understand it out of the box.
BEN: So if you don't mind, there's an 11ty.js file in that other directory. We can replace our current config with this.
JASON: Replace it entirely?
BEN: Yeah, sure.
JASON: And the data extension will do the YAML load. Then we have a pass-through copy folder, which is what you were saying. And we have a source input directory. Interestingly, nothing in here about React, Vue, Svelte, anything, that's all handled by Slinkity transparently.
BEN: Yeah, exactly. 11ty is kind of the data layer, and we are the Vue layer sort of extending the templates that they have. So we stay out of your way if you got a cool 11ty setup. So, yeah. And you might need to install js-yaml so that we can actually convert it.
JASON: Good call.
BEN: It found the G zip, which is interesting. I guess it looks that up.
JASON: Who knows. It might have been a peer dependency too.
BEN: So now we load YAML. At the moment, it's not going to do much because we're not putting the data anywhere. So what we can do is you can make like a new route in source. Maybe delete the markdown and make a new one or make like a storefront.md.
JASON: For the index, you mean?
BEN: Yeah. Or actually, we'll use JSX to demo that. If you want to replace this file with a JSX version.
JASON: Got it. So I'm going to index.jsx. Then we'll do some basic things. So the first thing I want to do is I can export a const called front matter. It was a capital M like that?
BEN: Yes, it is.
JASON: Then you called these 11 tees. Is that how you did it?
BEN: Sure, yes. Perfect.
JASON: Layout is layout.
JASON: Okay. So we can start there. Then export default index. Or I'm going to call this storefront, so if we get errors, they will be clearer. And I'm going to start by just saying -- all right. Start there.
BEN: And one last call out. You need to import React at the top of the file. I'm taking you back in time. I'm sorry. It is necessary.
JASON: Ah, okay.
BEN: This is because there is a snippet -- and we put this on our docs. If you want to put this at the top automatically, you can set up a Vite config to do it. But by default, esbuild doesn't do this because it's a Babble thing. We're not using that anymore. So all sorts of things.
JASON: Oh, interesting.
BEN: So it's interesting, but it's like, eh. You know.
JASON: Uh-oh. I screwed something up.
BEN: Storefront is not defined. Okay. Oh, const. You know.
JASON: Nope, I got to do it as a function. So let's just clean that up. There. That should do the thing. I know how code works. Geez.
BEN: All right, cool. Now we got a file. Very cool.
JASON: And, hey!
BEN: This will be the storefront. Okie-doke. You can see it generates a heading for us with the layout. Now we have a basic page. So of course, our storefront doesn't sell anything.
JASON: I doubled these up. Shouldn't have done it. There we go. All right. Now I'm ready. Shouldn't have done that, adjusting each one. All right.
BEN: So now that we have this, it's probably worth loading in our T-shirts. So what's nice is all 11ty data is on props right now. So you can literally destructure T-shirts.
JASON: No way. Come on. Oh, that -- okay. Game changer.
BEN: Yeah, it's just there. Boom.
JASON: So what I can do to show this is we can dump --
BEN: JSON stringify null. I memorized it for the stream.
JASON: My favorite debugging command. This right here is worth the price of admission.
BEN: I love it.
JASON: Having the data automatically injected into the props is just chef's kiss. Beautifully done.
BEN: It feels good. Yep. And if you want to type it, you could change this to a TSX file and have fun. I won't judge.
JASON: Cool. All right. I am not going to subject y'all to watching me write TypeScript.
BEN: But the option is there, if you like that. So yeah, global data comes in. Front matter is available as well, if you want to pull in the title and layout for whatever reason. That's how the cascade works. You can have a directory of data as well.
JASON: That is really nice.
BEN: The caveat, of course, is if you're -- this is a non-hydrated page. So we're able to just pass them all to you blindly. But if you were to hydrate the page, you have to be specific about which props your page needs so you don't ship an enormous bundle of information for hydration. So that's a thing.
JASON: Oh, yeah, yeah. Because as an example, I have learnwithjason.dev, where I ship all the episodes with the transcripts as part of the initial build. Because each page needs the transcript. But if that got bundled into the episodes page, it would be like a gigabyte worth of data. So I have to make sure that doesn't get included in the data that goes to that particular page.
BEN: Yeah, and we can try that if you want. Because I think it'll be something people sometimes use. And if you were to -- like in the front matter, say, hydrate. You could create an object that takes in how I'm going to hydrate. Then you specify which props are going to be passed.
BEN: You could say mode.
JASON: And eager means as soon as it's ready.
BEN: Yes. In Astro, it's load invisible, I believe, are the two that they have. But for us it's eager, load right away, or lazy, which is load when it scrolls on to the page. So now or later are what we support right now. Then the second argument to this is function called props. This takes in the same data that you see just below. You return the bits of data that your page needs. So here we have T-shirts, and you can just return.
JASON: So you could do something like that.
BEN: Exactly. And if you wanted to get --
JASON: And if you have a monster piece of data in here, whatever it was, the full text of a novel, I could have that but not ship it to the front end.
BEN: Exactly. So if you had, like -- you want to show all your episode titles but not the transcripts, just map out the episode titles. Then you're not shipping any transcripts.
JASON: That's a good point. So a way that we probably really would use this is, you know, maybe we don't need the images or something. We only need the slug. So we would just say, like, T-shirts, data, and then we could do T-shirts.map and get the T and just return, you know, whatever we needed. The title. So this is really, really nice. Okay. I'm going to actually pop this out, though, because we shouldn't hydrate until we need it. So let's keep it static.
BEN: Sure, I love it.
JASON: And now I need to set up a div. Actually, you know what we're going to use, we're going to use a section because that's more descriptive. All right. Then I can do something like, let's go T-shirts. Did you have code written for this that you wanted me to pull in?
BEN: Not really.
JASON: All right. So let's go T-shirt. And what I'm going to do is for each of these, I'm going to create a div with a key of -- there was a T-shirt.slug I saw. Why can't I spell T-shirt today?
BEN: Yeah, it's a funky one.
JASON: Then go with this. And we needed T-shirt.name. Then we want the images. So for the images, we can go T-shirt.images.map. We'll get an image. For the image, we can do, like, an image source. It's just a string. So just image. Then for the alt, we'll set up -- we'll use the T-shirt name because we don't have an alt.
BEN: Yeah, that's the best we got. I'm sorry. I didn't describe my images. But here we are.
JASON: We probably want to link to this. Which I'm not going to do just yet because we haven't figured out how to do that.
BEN: Yeah, we're going to try a little pagination to get that going. But here they are. Our beautiful, amazing T-shirt designs. Oh, they don't stop. Some are just full body if you're into that sort of thing. Others are more motivational. I'll shout out Ben Myers for anything is possumble because that is a fan favorite.
JASON: So upsetting.
BEN: I actually did register 11ty.fans. I might need to start a storefront.
JASON: It possumtimes be like that. Oh, boy. Excellent. Yes, all good things. Very, very good.
BEN: Yes. So here we are. We have T-shirts. But maybe we want to link to a page to purchase said T-shirt, if you want to shamelessly wear one of these shirts. So what you can do is we can set up a new file in our source directory. This will paginate all of our T-shirts. You can use JSX again. You can use whatever you like.
JASON: Okay. I'm fast with JSX, so let's start there. And I'm going to import React from React. I'm going to export const front matter, and that's going to be a layout of layout.
BEN: For those wondering, yes, you can set a default layout. But it's an 11ty thing.
JASON: So we need to figure out how to do the shirt title based on the shirt name. We don't have that yet. Then I'm going to export default function, and we'll call this shirt view. In this, I need to return -- we'll do another section. That'll have the -- actually --
BEN: Yes, I see what you mean. So we'll figure out computing the title, which should work. Yes. It works the same way that you do normal 11ty data.
JASON: I'm going to have to lean on you here because my 11ty pagination data is copy/paste at best.
BEN: Yes. I have to pull it up on the side. (Laughter) It's a tough one, but I think -- let me try doing it from memory and see if I nail it. That would be amazing.
JASON: Okay, all right. Let's do it. All right, chat. Let me get bets in the chat on whether or not Ben is going to get this on the first try.
BEN: Bet against me. Keep your money safe.
JASON: Oh, everybody believes in you.
BEN: All right. Let's see. Pagination. Yes. And data, I think. T-shirts in a string. Size one. Generate one T-shirt for each. Alias, T-shirt. Cool. That's pretty much everything. And then after pagination, comma, you can put a permalink to put it on the right route. And this is a function. This is a cool thing we support. So we can construct whatever link we want to based on data. So data is what comes in here. You can destructure T-shirt, actually. Then you can return a string. That's like insert the T-shirt.slug. Then closing slash. Do not forget that.
JASON: Trailing slash.
BEN: Very necessary. Now check our terminal output. It'll tell us what pages got built. Oh!
JASON: Look at it go! First try.
BEN: I'm so happy.
JASON: So let's go back and link to these and make sure it did what we want. And I'm going to do -- we'll do an href. Ah, celebratory boops. That's how you know you did something good.
BEN: We got it.
JASON: Okay. So what we should see then is when I go back out here, these are all linked now. If I click, we get our shirt details.
BEN: Wow, look at that.
JASON: Look at that. So, good things are happening. That means, then, if I go into my shirts and I get my -- so I should get my shirt as the detail I get.
JASON: That's right because that's what we aliased it to do.
BEN: I can't see the code anymore. I have faith.
JASON: Oh, let me get it up here. Then what we need is first we're going to go through the T-shirt.images.map. That'll give us an image, and I'm going to return image source image. And the alt of T-shirt name. And a fat curly brace. So that should at least get us started. If I click in here, good. And it's showing us the right thing. Oh, my god. I just realized that's a possum inside there.
BEN: Oh, yeah. I was waiting for that. That's my favorite one. I'll be honest, that's my favorite one.
JASON: All right. So how do I get a custom title?
BEN: Yeah, so you can make an 11ty computed key inside of this object we have here.
JASON: Inside this one?
JASON: Or this one?
BEN: Yes. And this is a flag for 11ty. Then you can say title again. This is an error function as well.
JASON: Just like this?
BEN: Yeah, basically the same thing. I don't totally know if this works, actually. This would be an 11ty issue if it doesn't. It might though.
JASON: Is Zach here for us to drag? Hey! Look at it go.
BEN: Wow. So cool. Yeah. And the cool thing is you don't need 11ty computed for permalinks. If you want to avoid it, you can do it there.
JASON: Nice. Very nice. And so here's the other thing that I wanted to look at. We are not hydrating this, but if we wanted, say, a cart or something or an add to cart thing here, can I -- I want to build a new component that just for now what I'll do is it won't actually work, but let's say add to cart.jsx. And this is going to export const. Add to cart. And what it's going to do is -- oh, wait. We got to import React.
BEN: And it'll need to be a default export as well.
JASON: For any component?
BEN: Yes. I had a shower thought once of, oh, my god, we don't support anything other than default. Like, oh, no. That's an issue to log. But anyway.
JASON: Okay, all right.
BEN: If you use it as a short code specifically. If you were about to say like, let's hydrate the whole page and use it, yeah, you could use a named one. But we're going to try using short codes to partially hydrate. We'll see how that goes. But yes.
JASON: Okay. So then what I'm going to do is set up a little function that says update added, and what we'll do is when you click this, it will set added to true. And down here, we're going to return a button. That button is going to say added -- it'll add to cart. Otherwise, it'll say -- or wait, I did that backwards. It'll say -- okay. So this is a component that I want hydrated. Then on click, we're going to call this update added. So now we've got an interactive React component. I want to use this. So I'm going to do the things that I know how to do best, which is import add to cart from -- and is this the right way to do it?
BEN: Yep. Totally can.
JASON: So then I want to add to cart.
JASON: So what I've done now is I have my button, but it's not working. So I want to make this hydrate.
BEN: Behold. So we have two options to do this. One is the stable way and one is the super cool way. Let's try the super cool way first and see what happens.
BEN: This is something that I threw together last night. So we're going to see what happens. But it's not going to be something we document or recommend. So let's go back to our other page. Or let's go back to the code. So there's another prop that comes in here. It's called undercore, underscore Slinkity. This is kind of a special object that contains all the helpers you might want to use inside your component. So with this object, you can destructure off another thing called short codes.
JASON: I actually don't remember how to destructure again.
BEN: Oh, it's just colon and then another curly. Yes.
JASON: All right. Yes, okay. My brain was like that's possible, right?
BEN: You can do that. You can go deeper, yes. It's really confusing when it's like you do this with TypeScript and then you realize I'm not using TypeScript correctly. Oh, my god. It gets me every time. Okay. We have our short codes. And with this, at the top, I want you to declare a const. It's going to be const add to cart, maybe. And capital A, actually.
JASON: Isn't this going to conflict with my imported add to cart.
BEN: We're going to remove it, yes. We're importing it in a new way.
JASON: Oh, I understand now. I understand.
BEN: No problem. So now you can say shortcode.react.
JASON: Like that?
BEN: Just lower case react. Then in parentheses, the name of our component, which is add-to-cart. And this will go --
JASON: With no --
BEN: It auto resolves. No problems.
JASON: Oh, well, I see.
BEN: So now you have a brand new add to cart that has now been inserted kind of as an island. So if you go back to our page, you should see it again.
JASON: Let me reload.
BEN: Yes. So this is not a hydrated component. This is just a component.
BEN: So if you want to hydrate it, drum roll, please. Let's see what happens. In the component itself --
JASON: I don't know what I'm doing. I'm sorry.
BEN: I'm not sure either.
BEN: Can someone clip that? I need that.
BEN: Okay. So now we have our component import as a short code, which means we can choose whether to hydrate it or not.
JASON: Oh, wait. So I can just --
BEN: You don't need to export anything from here.
JASON: Oh. All right.
BEN: Yeah, you can choose. We probably should have looked into the markdown example from the starter a little bit more. But in that example, it showed how you can insert React into markdown where you could say React, name of the component, whether or not to hydrate it, and then any props that you want to pass through to that component, if you want to pass through some data. So we're going to do exactly the same sort of thing. Inside of shirts.jsx, we can say add to cart, and on that guy, right there -- actually, no, you can do it on the component.
JASON: On the component.
BEN: You can say hydrate equals either.
JASON: Okay. And that's going to be the whole thing.
BEN: That's the whole thing. Now if this works --
JASON: Wait, I did it wrong.
BEN: Wait, what?
JASON: Is it yelling? It's not yelling.
BEN: Let's check our console. We were getting an issue. All right.
JASON: Target container is not --
BEN: It was working on my machine. I tried it on someone else's last night and realized, ah, shoot, I almost had 'em. So in theory, this would hydrate the component. Good to know that's not quite working yet. But we will do it the other way.
JASON: Put it on the board.
BEN: Put it on the board. Hydrate -- (inaudible). Okay, cool. Amazing.
JASON: Hydrate equals diedrate. (Laughter)
BEN: I will post on Twitter the second this is working. So we can hydrate the whole page if we'd like, sure. And now we'll need to do a few things here. So first off, we shouldn't have access to these props anymore. We need to use the props function we were using earlier to supply the T-shirt. So you can do mode, eager, props, T-shirt. Now we have that.
JASON: Okay. So then I won't have this one anymore.
BEN: Yep, you can remove that and import your component as you were before.
JASON: Add to cart from add to cart. Then this doesn't exist anymore, so we can take that off.
BEN: So now we've hydrated the page with just our T-shirt and should be able to use it. Yay. So, yes, this is your option to hydrate which pages you need to hydrate. Of course our homepage remains static. So any visitors coming to our site are just going to get that page instantly. But you used JSX the whole time. You didn't have to compromise and use something else you're unfamiliar with.
JASON: Yeah, and I think this is sort of what we're after, right. We're looking for that good balance between you've got the flexibility of using the language that you already have. Because I think the pushback that we'll hear is, you know, if you've got a company that has a larger dev team and they're working on an app and the app is -- you know, it's all behind auth. You're not -- you know, nothing can be statically rendered because it's all handled with sensitive data. So we can't have that sitting around in a static cache somewhere. So they're using React. They're using Angular, Next, whatever. As you're building that out, you say, okay, but for the marketing site, we want you to build, like, a more performant site, and it can all be statically rendered. You can't use React. They're like, no, we're going to use whatever we know. So that's why you're seeing, you know -- it doesn't make sense for a team to ship a static website with Next, but because they're building the app in Next, which it totally makes sense to do, they're saying I want to use what I already know. What I like about this is that it takes very little mental shift to move between write a component for Slinkity and write a component for Next. And the outcomes are drastically different in terms of, you know -- and you're serving different goals. For an app, yeah, I want all the server side props and the ability to do these extra things. But on a marketing site, I don't really want server side rendering on a marketing site. That shows to me we've overcomplicated the design somehow. I want static, a little bit of interactivity. But I want that experience of working in JSX, in a language that I know. So I think you've opened a door that I really like, which is using the right tool for the job without forcing someone to throw out their existing toolbox.
BEN: Yeah, exactly. Yeah. You should be able to use the same primitives you already have because most of it boils down to we have a system of components we'd like to use. But for things like material UI, if you're reaching for that, there are certainly components in Reach UI. Like, I want to use -- or not Reach UI. I love that one. In material, I know they have a component for grids and flex box. It's like, I'd love to use these layout components to just build a site really quickly. Now you have the option to use all of that guilt free, basically. You can use all these layout tools to craft a static site, and then piecemeal, choose which parts actually need hydration. With that hydrate prop I was mentioning earlier, that would be possible. And there are more problems to work out, like sharing state between components. I remember excitingly tweeting you about how that could work. Deadlines are hard. But it is something that I really want to see happen. Where it's like, I hydrate just these like two components on the page, and they both share some state. Where it's like, this guy saying something, and this guy responds to it. Being able to do that across your site, because that's where things get more app-like.
BEN: So the ultimate path forward is like we've kind of trashed the dichotomy of I use either this or this. Now it's a spectrum. Our only goal is to get people as far up that spectrum as we can using this tool here or something like Astro, which is in a similar vein. So that's kind of where we're going with it. All while, like -- there are a lot of people that use 11ty. There was like a comment from white panther earlier about islands architecture is cool, but it's used in small scale and playground projects. It's like, when will it be the architecture my team uses? I mean, our best answer is, well, if your team already uses 11ty, we just give you superpowers. So if you want to keep using your stack, you're good. So at least on that end of the spectrum, it's kind of just letting them keep the tools they have and keep leveling up. But for someone trying to come from Next.js down to a tool like this, it's a tougher sell until we work out making it as app-like as we can with shared state and single-state apps and stuff like that. So that'll be a tougher one that'll take a long time probably to work out in a clean way.
JASON: And I have a suspicion that we're actually going to see the things grow together. Because I think that, you know, the presence of Slinkity and Astro and Isles and Solid JS, these different frameworks that are opening the door to different, more performant ways of delivering content are putting pressure on the Gatsbies and the Next.js and the everything frameworks that are shipping a lot of bloat in favor of interactivity and developer experience. They're getting pressure put on them by these new and emerging frameworks to set better defaults. And we've seen a response from companies where they're trying to. You know, I saw the Next team talking about having a zero JS option. I know they've had that in experimental for a while. We're seeing discussion from other framework authors. If you follow -- Ryan was on the show talking about Solid. Do I have this one open? Yeah, here it is. So this is Ryan talking about Solid. But if you follow Ryan on Twitter, he's always engaged in these really thoughtful conversations with framework authors across the whole spectrum about how we can push the envelope forward, how we can improve the ecosystem at large. What I like is it felt for a while like we had just given up. We were like, ah, whatever. We'll just build everything in React and Next and the web is good enough. We're done building for the web. Esbuild and Vite blew the door off that. Now everybody is like, oh, we can build something better than Next. We're seeing that innovation happen, and we're seeing the pressure. And it's good. We want Next to improve. Next is only going to improve if there's somebody pushing it. So this is like that good ecosystem pressure of innovation. What you create, they'll see. What they create, you'll see. We'll all take the best ideas and see what comes out of it in a couple years. I'm really confident and hopeful for just how good everything is going to get that stays on top of this in the space.
BEN: Yeah, I totally agree. And I actually had like a -- it turned into a two-hour conversation with Ryan where like we blocked off a little lunch talk. It was like, oh, my god. There's so many problems. We got to solve them. But yeah, it's interesting because he maintains a component framework that's based on JSX. It's like, does it need a home? Do we need Next.js for Solid, like a whole new framework for it. But it's emerging during this time where we're getting more and more framework agnostic with our ideas. In Slinkity, we can whip up a Solid plug-in, in like 30 minutes, and suddenly you can build your entire site with Solid. You can insert it into markdown, do whatever you'd like. So it's like, I'm not sure if we need framework-specific site builders anymore. Well, you do for certain things, like heavy apps. But even for that, Remix is talking about supporting Vue and Svelte down the road. So maybe that's not even true. But the problems that you have are like you want to fetch data in a nice way, and then roll them into a static site. So if you build a solution to fetch data and expose it, like we showed here with front matter and 11ty data files, it's like why do we need to resolve this problem for every UI framework? The data part and the UI part are decoupled now. We've decoupled the Jamstack inside of itself. I know they talk about decoupling. Now we've double decoupled. So it's like, oh, do we need framework stuff anymore?
JASON: Yeah, and I think what's exciting about it is that we're starting to look at things not as, like, you know, you go, oh, I only build with Next or I only build with Gatsby or I only build with Angular. We're starting to become more pragmatic. I think that's a good sign of maturity for developers. We're not looking at anything as a silver bullet. We've made this joke on the show before. Silver bullets only work on werewolf-shaped problems. So you have to look at the goal and the outcome you're trying to achieve, and based on the constraints you have, what tool is going to get you the best outcomes with the best experience of working on it and the most maintainable future. All those things. You make different trade-offs with different inputs and outputs. That, to me, is exciting. And the fact that the ecosystem is growing in a way that allows us to make those choices without having to wholesale switch our stack, that to me is very encouraging. Because it shows that we're starting to think about this more maturely. We're not saying you have to go all in on one tool or the other. You should go all in on the ecosystem.
BEN: Web dev has gotten so easy that it's gotten harder.
JASON: Yes, exactly. Right. It's such a good way of putting that. What I'm excited about is it feels like we've diverged to explore, and we're starting to find an opportunity where we can converge again into a new set of primitives that make life easier for us. With that, do you have any additional resources or things that you want people to look at if they want to take next steps?
BEN: Yes. I'm honestly going to shout out go to our GitHub as soon as you can, and look through our contributing guide in our issue logs. I have looked through all the contributing guides that other projects have and tried to take the best pieces into it. So it's a good onboarding experience if you want to try a new repo. We explain everything in here, including how to set up a local project and debug as you're, like, messing with Slinkity. Does my project still work? We explain all of that. So you can kind of get onboarded there. I'm also trying to be as receptive as possible on our Discord channel. It's a channel within the 11ty Discord. So I don't have a direct link to it. Or I think it's in here. It's in this contributing guide. If you just go to the 11ty Discord, there's a Slinkity channel. And in there, we're like sort of discussing ideas, RFCs, whatever else. Definitely encourage you to hop in there. I know issue logs are scary, but Discords are kind of friendly. If you want to get involved in the project, I recommend it. I feel like we're definitely in the phase of we're appealing to other developers, and we want to get their input as much as possible. So if you want to contribute, it's a good time to do it. And our docs page is written in Slinkity as well. If you want to work on our docs, improve the styles or describe new things that we didn't describe well enough, it's all right here. Also, shout out to Thomas for this reskinning because it looks so cool.
JASON: It is very, very cool.
BEN: So much fun. Yeah. The retro theme, it's got to come back. And the hot pink, like, yeah.
JASON: All vapor wave all day, baby. All right. This is so much fun. Ben, thank you so much for spending some time with us. I'm really excited about Slinkity. I'm excited about the corner of web development that it represents, and I'm excited about pushing the industry forward. So thank you for doing that. Everybody, please remember every episode of Learn With Jason is live captioned. We've had Rachel here with us all day. Thank you so much, Rachel, for being here from White Coat Captioning. And we have new sponsors today. We've got Netlify. Keep on keeping on with Netlify. Then we have Nx, a mono repo tool, and Backlight, a designs system tool, both jumping in as new sponsors. Thank you both very much for joining up. It means a lot to me, helps me keep the lights on, helps me do more and more fun things with the show. So thank you. While you're looking at things on the website, go over to the schedule. We have some bangers coming up, y'all. We're going to do a headless CMS content editing experience. We're going to look at things like shareable previews and fast search and stuff that you maybe thought you had to trade off if you switched to a headless CMS. Then we just have things, things, things coming. Fully typesafe APIs from end to end. Then we're going to learn about Neo4j. I'm excited about that because that's a graph database I know very little about. Just tons and tons coming up on top of that. So make sure you go over there, add on Google calendar, follow on Twitch. You can subscribe on YouTube if you watch the replays instead of the live edition. And you can always follow on Twitter if you want more details as episodes go live. With that, we're going to call this one a success. Ben, thank you so, so much for spending some time with us today. Any parting words?
BEN: Uh, oh, I wasn't prepared for this.
JASON: You want to kick to the whiteboard?
BEN: Yes. We only found one bug today, and that's a success. So, thank you for coming, fellow Slinkity Stans. Trying to start that name.
JASON: Thank you so much. We're going to find somebody to raid. See you next time.
BEN: Take care, y'all.