Build a Toast Site Using MDX & Tailwind
with Chris Biscardi
Toast lets us build static sites using modern workflows, creating less complex, super fast websites & apps. Chris Biscardi returns to teach us how to build an MDX & Tailwind-powered Toast blog!
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 LENGSTORF: Hello, everybody. And, welcome to another episode of Learn With Jason. Today, on the show, we're bringing back Chris Biscardi. Chris, what's up?
I'm doing pretty good, other than the devil in my headphones, I had to turn you off. (Laughter).
JASON LENGSTORF: Good. Good. We're doing great here. Look at the chat. The chat is popping off. We got the all party Corgi Discord in here. We're very ready for Toast puns. There's a wish that all chat today is Toast puns, which I would say is that should be how it goes, all Toast puns.
In that case, maybe we should warm up the oven, here, and say, Chris, for those of who are not familiar with your work, could you give us a little bit of a background?
CHRIS BISCARDI: You ever get one of those questions where your blind just blanks?
(Laughter). So, I've let's see, I've been doing development, engineering, software, startupy work for 10 years now. Starting out freelancing, then went to Docker, went back to consulting. Build a design systems, did some work for Gatsby. Developed a weird specialty in Jamstack meta frameworks. So, like, yeah. And then I also teach people Rust and do a lunch of serverless stuff.
JASON LENGSTORF: So, not much, really.
No, I think this is great. Like, I've you know, I've been following your career for awhile now and one thing that I've noticed is you've got a great ability to not get stuck in, like, what is now and kind of focusing on what's possible with today's tooling. But you always seem to be looking one or two steps in the future where we could be if we actually pushed the tools to the full capability of what they're doing.
Kind of speaking of that, that's what it feels like what's happening when it comes to Toast. To use a sports metaphor, um, you're skating to where the puck is going to be.
CHRIS BISCARDI: Oh! Nice!
JASON LENGSTORF: I know sports. I can do more than one thing.
CHRIS BISCARDI: I know who said it. (Laughter).
JASON LENGSTORF: Um, but (Laughter).
CHRIS BISCARDI: I'm a sports person.
JASON LENGSTORF: I am also a sports person. No, I'm not a sports person. (Laughter). I do I do really like that quote because I think it kind of shows, like it shows I like that, as a metaphor, for strategic thinking. Because the thing that I've always disliked is when it feels like you watched tools kind of scramble to implement each other's features. I think that's something that bums me out. What's possible now and what if we did just one thing better, what could be possible? When it comes to Toast, it feels like that is sort of that's the gamble here. If we bet on the modern web, then we can have all of these benefits. So, do you want to talk a little bit about what those benefits are? Or, actually, talk about what betting on the modern web means first?
CHRIS BISCARDI: There's a design space of things you could build, right, and things that people could use. And, like, everybody not everybody, but a lot of people are over here, in this space, which is, like, built on top of Webpack and compiling it all to CommonJS and doing a bunch of common stuff. That's really, really wellexplored. Gatsby does it, Next does it. If I'm going to build yet another one, what is going to be interesting to, like, explore?
And that pointed me to this area of the design space, over here, that was just coming to I don't know? Maturity, maybe? We can use ES Modules in the browser now. It went stable this month. The idea we might not need to bundle anything at all is really interesting. And then, there's also, like, you'll hear it in any place that talks about, like, static site generators, build times are a concern. I think that's going to be a concern as long as the tools that we use are built in Java. Right?
JASON LENGSTORF: Right.
CHRIS BISCARDI: No. So, like, the idea, here, is there's a Rust core that powers everything and that the user of Toast doesn't have any ideas it's built into Rust. They should never have to know.
CHRIS BISCARDI: Yes. That is a "yes or no" question. (Laughter).
JASON LENGSTORF: So, does this open up for us? When we start looking at this, it sort of sounds like you're proposing where we can have our cake and eat it, too, here.
CHRIS BISCARDI: Yeah. I guess it depends on what cake you want. (Laughter).
JASON LENGSTORF: I'm a chocolate fan, myself. (Laughter).
CHRIS BISCARDI: I'm more of a blended cake person. (Laughter).
JASON LENGSTORF: Those rainbow unicorn cakes? Hey, what's up, Michael, for showing up. The baldbearded builder is here. I hope you've lighted a horriblesmelling candle. Check out his stream. (Laughter). Let me do a shoutout to
CHRIS BISCARDI: I'm glad it's them. I'm glad the candle's in their apartment.
JASON LENGSTORF: Same. My subscription for Socket Studio wore out. Looks like I need to go fix that. Oh, well. (Laughter). So, Toast is built in Rust and when when you're talking about Rust, Rust is like, I saw a thing come out the other day, that I thought was really interesting, was a comparison of energy consumption by language and Rust the only thing faster than Rust was C, which is fascinating because I kind of I kind of thought that in order to get something that performant, it would have to be ultralowlevel and very difficult to use, right? I had Prince, on the show, awhile back let me find a link to that episode and Rust did not feel that way.
JASON LENGSTORF: That's really cool. It's got a very nice error management. It's really good at telling you when something's wrong.
Thank you for the sub.
Gators is gifting subs all over the place. Thank you so much. Welcome to I've been calling it the "boop crew." So, welcome to the Boop Crew. Make sure you Spam those boops. You do have an opportunity to bury Chris and I in boops today. And Chris is tall, so it's going to take a lot of boops.
CHRIS BISCARDI: Remember the ball pits you used to hang out in?
JASON LENGSTORF: It's like that, but a little less gross. (Laughter). So okay. So so, like, talking about Rust, it could be here we go. We're done for. (Laughter). Talking about this is it. Okay, bye. (Laughter). So, talking about
CHRIS BISCARDI: How do you get up there?
JASON LENGSTORF: Chris is significantly taller than me. I think this camera angle doesn't really do us justice. You're back. Here's me, just, okay, all right, everybody, look at the top of my head. (Laughter). So, um so, when we're talking about Toast, we mentioned Rust. I think that that might immediately sound scary to somebody. But, I think it's important to call out, when I'm building a Toast site, what is my workflow? What am I actually doing?
CHRIS BISCARDI: It's very similar to anything like a Next Gatsby site. You have your create page and your equivalent call. You've got the things that you're used to, like, they might be called different names. Our equivalent of "create page" is "set data first load," for reasons I can get into later. You create a file and you get files.index.js.
JASON LENGSTORF: Cool. I think the easiest way to talk through this is to do it. As we're switching over, let me do a quick shoutout. We have live captioning today. You're able to see the stream, up at the top, and you can see the live captioning coming in here, I hope oh, no, did we lose our captioner? Oh, no! Uhoh, why is the captioning not working?
I'm going to figure out what's going on let's see. Let me reload here and see what's going on oh, here it is. That was just a reload, on my part, so I'm not sure why that was going on. Here we go. We're all good. The live captioning is working. Thank you, White Coat Captioning, for providing that for us.
Go and follow Chris on Twitter. It's @chrisbiscardi. You can find out more about Toast at Toast.dev.
I'm ready to Toast my first site.
CHRIS BISCARDI: How do you like your toast?
JASON LENGSTORF: I want it to be
CHRIS BISCARDI: We need a sandwich chart for toast.
JASON LENGSTORF: Ohhh, I think we do. Toast doneness chart. All right, everybody, find your toast doneness. None of that, whatever that is. I just want to look at the image. What is your toast doneness?
CHRIS BISCARDI: What's the X and Yaxis?
JASON LENGSTORF: It's a graph. The toast doneness is D6, like Battleship.
CHRIS BISCARDI: You sunk my toast!
JASON LENGSTORF: We got a vote for 4E.
CHRIS BISCARDI: 9J. These are not S'mores. (Laughter). You have to get a new toaster with 9J.
JASON LENGSTORF: I could go C5 to C7.
CHRIS BISCARDI: I could do 9D and up.
JASON LENGSTORF: Yeah. Here, that's just bread. (Laughter).
CHRIS BISCARDI: Well...when does it become toast?
JASON LENGSTORF: This is the line. It's got to be more toasted than this, otherwise it's just bread.
Thank you so much for the sub, Eco.
I've been doing a lot of NPM.
CHRIS BISCARDI: Let's do NPX.
JASON LENGSTORF: Let's go "Toast site," how about that?
CHRIS BISCARDI: Whatever you want, man. It's your computer. (Laughter).
JASON LENGSTORF: This is running the Create Toast package, which is here. It is then creating a new project in the folder called "Toast Site." Let's open this and take a look at it. We've got what appears to be a pretty straightforward site here. So, we've got, um, a postinstall. Okay. We can talk about what that means. We're bringing in Breadbox and Toast.
CHRIS BISCARDI: Breadbox originally, we used Snowpack for singular purpose, basically. I mentioned, before, that Toast is ES Modules only. But what it means is that we write our Node code and our clientside code in real, true ESM. So, Breadbox handles transferring them from the CommonJS world into the ESM world. This is going to go away in favor of ES Install. It is a separate package that we can now dig in and use and it'll be cleaner and it'll be in the Toast package.
JASON LENGSTORF: This is kind of a stepping stone. All right. So, that's exciting. So, that means, then, that so, we've got this package. Brittany had a good question.
CHRIS BISCARDI: You can get rid of the yarn lock, it's in the Git Repo.
JASON LENGSTORF: That's just the create
CHRIS BISCARDI: Even if you didn't remove it, NPM would create it.
JASON LENGSTORF: It would just yell and be like, "what did I do?"
CHRIS BISCARDI: You have to use 13 or higher. 14 introduced ESM into Node. It will just work in Node. You can just run it. 14.13 allows us to import named exports from CommonJS models. There's a little interoperability that was introduced. Technically, you don't need it.
JASON LENGSTORF: If you've never seen this before, this is one of my favorite tools for getting things quickly, I'm using MVM. I was able to install 14.13 and it installs Node. I do this echo and Node, in parenthesis, to this. It creates an MVM that shows which version of Node we're working on. They can do "MVM Use" and install the right version. This is a handy thing if you're sharing tools or have to switch environments.
CHRIS BISCARDI: I think you can do "node/v" and then a caret.
JASON LENGSTORF: Can you? Tada! There's your pro tip, put it into NVM RC and I do want to delete test, I don't need that anymore. So, then we've got this index.js and this looks very familiar to me. This is a React component. We've got props, we've got some JSX and we are exporting a page. We've got Toast.js. We saw the package JSON, that's as far as we're going to go. (Laughter). This is very little code. What I'm going to do, then, is I'm going to look at my package JSON and we're going to do an NPM run build. What didn't you like? "Toast command not found?" I never installed again. (Laughter). Here we go. Here we go. (Laughter). So, now yeah, here goes everything and we can see it's running Breadbox for us.
CHRIS BISCARDI: That is because it's called the postinstall. So, if you install stuff in this repo repo. In this package, it'll run this after it installs stuff.
CHRIS BISCARDI: It's in the index.html.
JASON LENGSTORF: If I do the NPM build again, we run our build. This is one page, so this was extraordinarily past.
CHRIS BISCARDI: These progress bars are, like, helpful hints. They're not absolute counters.
JASON LENGSTORF: So that generates a "public," and we get an "index.html." And for the most part so, we're using regular, old imports. That's ES models.
CHRIS BISCARDI: The HTML you get from this includes an inline script that is sort of, quote/unquote, the code. You get a page wrapper, if you want one. You get a component, if you want one. And you get JSON data, if you want one or "some." It fetches those all, using Dynamic Imports because those work in the browser now and uses them to render the page. This is our rehydration step, if you want to think of it like that.
JASON LENGSTORF: That's really cool.
CHRIS BISCARDI: We got the HTML and this is the client side.
JASON LENGSTORF: Look at how cool this is? We can do this import on a path and await for all those imports to finish and we get out this data. And, like, we didn't need Webpack for that. We don't need any config. This is just how browsers work. This, to me, I think, is the, like, most exciting part. I'm not getting syntax highlighting because I didn't initialize this as a directory. It's because so, I have my I have my dot files and my whole home directory on GitHub so I have a Git Ignore that ignores everything else. So, then what we can do is we can Git Ignore here. I'm going to ignore modules. I'm going to ignore that ".temp."
CHRIS BISCARDI: We can take a look at those, too, if you want to.
JASON LENGSTORF: These ones?
CHRIS BISCARDI: "Public" and ".temp" are probably interesting. You might want to save it. I don't know (Away from mic).
JASON LENGSTORF: We're going to configure this to use (Indiscernible).
CHRIS BISCARDI: So, this is just like your JSX compiled to whatever it compiles to. Nothing else have to change. The files in "public" are run in the browser.
JASON LENGSTORF: Okay. Cool. This is a public or, like, the web version, so we load (Indiscernible) from web modules. We've got our web modules here, with the compiled web version of (Indiscernible), which is not going to be particularly interesting to look at so I'm going to close it. And then we've got this index file, which is dynamically loading all of this, which is really, really nice.
So, this is really only going to grow by the scale of the components that we use, right? Like, we're not going to see more boilerplate get added. Now it's code we write?
CHRIS BISCARDI: This additional code, you're looking at right here, will not change. It will not grow.
JASON LENGSTORF: Excellent. That is exciting.
CHRIS BISCARDI: If you add more components, it runs more code when you download your component.
JASON LENGSTORF: Nice. If I want to serve this, this is one thing that is maybe a little different about Toast is Toast doesn't have a dev server, right?
CHRIS BISCARDI: Yeah, it doesn't have a dev server. It's not, like, a philosophical thing. It's just a thing. We will eventually have one.
JASON LENGSTORF: What do you recommend for if we want to do that? Like, should I NPX Serve?
CHRIS BISCARDI: I do "NPX Serve."
JASON LENGSTORF: Let's do that, just for what am I trying to do? I'm trying to open my console. We're going to NPM install "dev serve."
CHRIS BISCARDI: The focus of Toast originally was on getting the incremental compilation working in the core and things like that, and getting the builds to work. So, now that all of that is working, we will work on a dev server that will serve, like make the DX a little better. But all of this like, all of the fundamentals are here and they work.
JASON LENGSTORF: Nice. So, if we want to serve, I can do a "serve public." And now, if I NPMrun "serve," this opens up local host 5000, which I can open over here. And that is our basic Toast site. So, um, what should I do next? Like, what do you want to build next here?
CHRIS BISCARDI: Um...we can pull in Tailwind.
JASON LENGSTORF: Okay.
CHRIS BISCARDI: We could either do Tailwind or MDX. What do you want to do?
JASON LENGSTORF: Maybe we can start with MDX and then we can style it all with Tailwind?
CHRIS BISCARDI: Sure.
JASON LENGSTORF: Cool.
CHRIS BISCARDI: So you're going to install "toast.dev."
JASON LENGSTORF: Anything else?
CHRIS BISCARDI: No.
JASON LENGSTORF: All right. And so, this is going to get pulled in and then as it gets pulled in, we should see that postinstall run. Did it need to?
CHRIS BISCARDI: It doesn't need to actually, it does need to but we'll get to that.
JASON LENGSTORF: Okay. All right. So, I've got my MDX installed.
CHRIS BISCARDI: Um, so, have you you went to toast.dev MDX repo, right? That's where the docs live right now. Go into "packages." Go into "MDX."
JASON LENGSTORF: Got it. Okay. So, we did this part.
CHRIS BISCARDI: And then you can choose one of the two options. Only use the first one, just because, like, it's easier. Then we don't have to set up MDX. The bottom one lets you if you want to run MDX yourself, you can do the bottom one.
JASON LENGSTORF: Gotcha. So, this is going to we have all right. So, let me actually just pull this to the side and then let's pull this to the side. I'm going to open "toast.dev." And in here, we are using the source data and "set data for slug" here. I'm going to await "source MDX" and pass in set data for slug.
CHRIS BISCARDI: You're passing this function through and, like, plugins and other ecosystems, take control. So, plugins in Gatsby, it's like, "hey, what do you want to run? I'm going to walk over here and do them." Gatsby has control over how they run, when they run, if they run. Plugins, quote/unquote, in Toast, take the opposite approach. They just let you call whatever functions you want to call and in this case, it's just a function that compiles MDX and calls the data for slug.
JASON LENGSTORF: Nice. Okay. Cool. Very cool. So, here, what we're saying then is if I write an MDX file in content, so that would be "content." Is it at the top or does it have to go in "source?"
CHRIS BISCARDI: It's at the top.
JASON LENGSTORF: Okay. We'll call it, like, "my first blog.mdx" and then we'll write one headline. Then, if I save this, what we should see, I assume, is a new page get created?
CHRIS BISCARDI: Yes. So, you have to run a build.
JASON LENGSTORF: Okay. NPM Run Build.
CHRIS BISCARDI: Such a small, tiny terminal.
JASON LENGSTORF: I think it's because the
CHRIS BISCARDI: Your Node version, inside of your integrated terminal, was not set to Node 14, for whatever reason.
JASON LENGSTORF: Actually, that makes sense. Do I need to run the postinstall, do you think?
CHRIS BISCARDI: You will, but we're going to talk about that. So, this is the error you get.
JASON LENGSTORF: Oh, wait! This is interesting.
CHRIS BISCARDI: You haven't imported MDX yet. (Laughter).
JASON LENGSTORF: Okay. Well, that's superhelpful.
Okay. So, here's Source MDX. MDX from toast.dev.mdx. Yes. And now, I actually have this, so it should work, let's try. And, it's actually fetching data and our HTML is rendered, look at that go! So, that's cool. Now I can NPMrun "serve." And we'll go back out here and I'm going to try to go to "post my first blog." And, it just works. Okay. So, that's pretty slick.
So, let's take that a step further and, like, learn some MDX stuff. So, I'm going to create components and we'll call it, like, "image.js."
CHRIS BISCARDI: Let's do one thing before we do that. Check the client of the MDX page. Go "inspect element." This is the reason we use Snowpack. I wanted you to run into this issue, so I didn't say anything before. We have to tell Snowpack, we're going to use that MDX/JS. If you go to www.toast.dev repo, it'll show you how to do this.
JASON LENGSTORF: Here's toast.dev.
CHRIS BISCARDI: Scroll down to the Snowpack section.
JASON LENGSTORF: I'll copy it, first, and then we can walk through what it does.
CHRIS BISCARDI: Sure.
JASON LENGSTORF: Here's my package JSON. So, in this section, we're saying to exclude and the exclude, I assume, is because Snowpack is going to try to scan directories?
CHRIS BISCARDI: Snowpack doesn't actually follow your imports. It just kind of, like, scans the whole directory like Gatsby does. If you have a.GraphQL, it'll scan for it?
JASON LENGSTORF: And so, we're ignoring "public" because "public" is generated. We're ignoring Toast, because Toast is Node and it'll never run in the browser. Then, we have this alias because this is a project we're starting from scratch wait, we still do need this, don't we?
CHRIS BISCARDI: We don't need this if we don't include a thirdparty that includes it. When Snowpack touches your thirdparty dependencies. React Helmet is React. There's full compatibility. We have to tell Snowpack, like, hey, we're not going to import React here. We're going to import React.
JASON LENGSTORF: That's to keep the rendered codebase small. We're using (Indiscernible) to keep things as compact as we can.
CHRIS BISCARDI: It's smaller and faster and whatever. Another reason is it ships an ESM build, by default. React does not. You could just use (Indiscernible) in the browser by itself and you don't have to do anything to it.
JASON LENGSTORF: Which is one of the things I really like about it. If you look at their docs, they have like, a browseronly where's their actually "get started"? There's a browseronly version you can just, like, look at. Yeah. You can just drop this into page and that will work because it's pulling in the model version of Preact.
If I understand this correctly, this entire section of config is not because of Toast. It's because we're trying to make other modules compatible with the modern, like, browser standard way of writing modules. Is that correct?
CHRIS BISCARDI: Right. So, basically what we're doing here is taking any thirdparty dependencies to work with the new way. In the future, ideally, enough people write in ESM because that's where everything is going and then we don't need to do this processing anymore and we can take this dependency and throw it away.
JASON LENGSTORF: What I love about this is adopting that idea of disappearing code. Right. What we're building for is what's built into the browser and all the config that's happening here is code that is made to make the rest of the ecosystem compatible with the browser. So, as everybody shifts, as the community starts writing for the browser, by default, this code becomes less important until you drop a huge amount of code from Toast.
CHRIS BISCARDI: We get to drop Snowpack, which will be ESinstalled. You don't have to worry about the fact that people are writing in CommonJS. You want to get rid of the ESM entrypoint.
JASON LENGSTORF: We're currently importing this. Because we're not importing it, because it's being brought in by the this part, here, be Source MDX, Snowpack can't find it and that's why it doesn't automatically postinstall, right?
JASON LENGSTORF: I'm going to run "build" and" serve."
CHRIS BISCARDI: Do the postinstall.
JASON LENGSTORF: That's going to give us the Breadbox. So now we will see, there's our MDX JS and because it uses hooks apparently, we also bring in hooks.
CHRIS BISCARDI: It doesn't use hooks, we just put that in our config. That's why it came in.
JASON LENGSTORF: Oh, oh!
CHRIS BISCARDI: It's a 2kilobyte file. We're going to use hook somewhere.
JASON LENGSTORF: All of React hooks, this is such a cool project. Preact is such a cool I want to get Jason on the show to talk about it.
So, now when I reload, that is gone. If we look at the network tab, we should see, here's Preact. Here's hooks. Um, and I think if I I think that's as high as I can scroll. Yeah, here's so, we can kind of see what's coming in. I just realized I'm preserving the log so this is showing lots and lots of things. So we can actually see what's being brought in. We've transferred 13.9 kilobytes and this is a rehydrated React APIcompatible page, right?
JASON LENGSTORF: Let's do Preact hooks and we can ship a little component. So, we will export I called it a "componer." "Component" was the word I was trying to use. It will use a state, so we'll say "count, set count, equals, use state zero."
CHRIS BISCARDI: This is Jason's future interview. He's excluded from all whiteboardfacing interviews. (Laughter).
JASON LENGSTORF: The true secret of Learn With Jason is making sure I don't have to do whiteboarding again. (Laughter).
CHRIS BISCARDI: I've written counters! Okay, I haven't written binary trees. (Laughter).
JASON LENGSTORF: We can do set count to count+1. Then we'll say "clicked count times." So that is our button. If I want to include this button, can I just like, so I want to be able to use it right here.
CHRIS BISCARDI: You have two options. One of them is the MDX Provider, in which case, you don't need to import anything into MDX. The other one is you can import it.
JASON LENGSTORF: So I can import it, straightup?
CHRIS BISCARDI: You'll import it from "/source.component." We're importing a URL now.
JASON LENGSTORF: 0hhhhh! That's a good point. If I stop and restart
CHRIS BISCARDI: It's time to schedule a Learn With Jason where we do binary trees. Good luck. (Laughter).
JASON LENGSTORF: It says "module not found. Cannot find my counter." Why can't you find my counter? Ummmmm...
CHRIS BISCARDI: It has to be relative.
JASON LENGSTORF: Yeah.
CHRIS BISCARDI: I misled you. I was like, oh, we're doing everything in the browser. It has to run in Node, too.
JASON LENGSTORF: Still says "module not found."
CHRIS BISCARDI: Do the thing you were going to do. I misled you entirely.
JASON LENGSTORF: Oh, Chris.
CHRIS BISCARDI: I was wrong.
JASON LENGSTORF: We now have a counter, right. And this is a React counter and we've transferred 14.6 kilobytes to the browser. That is so sick! Like, I am just absolutely blown away by how much of a difference that makes, versus, you know, if this was just plain React or a Gatsby site. This is a really, really big win for us.
CHRIS BISCARDI: I was like, I don't know, I haven't built a Gatsby site in awhile. (Laughter).
JASON LENGSTORF: The runtime for Gatsby, the runtime for Next, React is big.
CHRIS BISCARDI: React is big. React is bigger than Preact.
JASON LENGSTORF: We're getting this is, like, a big drop. That is really, really nice from a kind of development standpoint.
Um, but, yeah, this is
CHRIS BISCARDI: One of the things I would love to point out here is we're building MDXbased pages now and this page will not affect any other page on your entire site. If you wanted to draw a 3D game on here, you could. That's not going to blow up your bundle. It's not going to blow up the rest of your site and you can keep writing content, if you would like to.
JASON LENGSTORF: Actually, this this, I think, is hugelyimportant because what you just said is one of the things that kind of plagues, I think, a lot of sites. If we look, again, at this network tab, we will see, in here, that somewhere
CHRIS BISCARDI: You have to clear your network the counter's right there, if you're looking at the counter, before you do that.
JASON LENGSTORF: Yeah. Here's our counter. So, we have brought this in. Right? So, if I go to the other one, which I called "another post," I think? And we look for "counter," it didn't get pulled in. We didn't include that code. It's not bundled. If you use MDX on, like, a Gatsby or a Next site, typicallyspeaking, the components guest hoisted up to the MDX. It shows up in the bundle for every post.
CHRIS BISCARDI: That's true for everything, thought just MDX.
JASON LENGSTORF: Yeah. Basically, without doing some stuff, you can't guarantee that your code doesn't just kind of linearly scale.
CHRIS BISCARDI: It gets bundled if you use the MDX provider? You mean in Gatsby and Next? Yes, absolutely.
JASON LENGSTORF: It would be bundled, right?
CHRIS BISCARDI: It's imported and used.
JASON LENGSTORF: Would it be provided to if we put the counter into the MDX Provider, would it be on this page?
CHRIS BISCARDI: It would be on your page wrapper if you were using the MDX Provider. There's this thing where you can, like, choose what page wrapper you want on any given page. We have source/pagewrapper, which maybe we want to use right now, and show off. But, like, if you put it in that page wrapper, it'll be on every page because you're saying that this code is needed for every page. It isn't, like, a technical restriction. That's a decision that you made.
JASON LENGSTORF: So, the choice would be so, as a kind of practical example of this, if you have a blog and on your blog, you have images and, like, asides or callouts that show up very frequently, it would be a pain in the butt to import that for every blog post, you can put that in the Provider. As you scroll down the page, things are flying all over the place and you're bringing in unity, that doesn't make sense you only use that on one page in your site, so it would make sense, in that case, to import it just on the post you're using it in. It's more of, like, an architectural decision. It's tiny, it's not that big of a deal.
CHRIS BISCARDI: There's a third option, too.
JASON LENGSTORF: 0hh, I like third options.
CHRIS BISCARDI: We can dynamically import it.
JASON LENGSTORF: Whaaattt!!
CHRIS BISCARDI: It could be a dynamic import to pull in whatever. You can just stick everything in your MDX provider, if you wanted to, and it could be powered by a dynamic import. This gets into Suspense React Lazy. Suspense, as you know, doesn't have full support for serverside rendering. It would only do this stuff for things you want to pull in on the client conditionally. But if that component doesn't get rendered through MDX, it won't get used. It won't get imported.
JASON LENGSTORF: Interesting. Got it.
CHRIS BISCARDI: You could provide something to every MDX file, in the page wrapper, and theoretically, it could never hit the site.
JASON LENGSTORF: Let's start by showing how to use the page wrapper. If I want to do that, how do I do that?
CHRIS BISCARDI: It's in page.wrapper.js.
JASON LENGSTORF: What I'm doing, with the import "H" is same as import React from React, this is just the Preact way of doing it.
CHRIS BISCARDI: The "create" element.
JASON LENGSTORF: Got it. Got it. Got it. So, am I doing is that right?
CHRIS BISCARDI: Sure.
JASON LENGSTORF: Okay.
CHRIS BISCARDI: It's the default export.
JASON LENGSTORF: Is it children or something else?
CHRIS BISCARDI: Children.
JASON LENGSTORF: Then I can do oh, I can't do a fragment, can I?
CHRIS BISCARDI: If you do a fragment, there's no, like, ID on the fragment so you'll cause yourself some pain. I would do a div, because it's your page wrapper and you're declaring what you're going to wrap the site with, which is probably going to be something. If you're pagewrapping your site with nothing
JASON LENGSTORF: So what I was thinking is just from the standpoint of, like, so semantics, if we've got a header, a main and a footer
CHRIS BISCARDI: Uhhuh?
JASON LENGSTORF: I don't really care about this. Like, that, I can have as a thing and I would put the children in here and this would be, like, home or something?
CHRIS BISCARDI: What you're doing is you're React.rendering a fragment at the root, which is, like, kind of funky.
JASON LENGSTORF: Okay. So maybe don't do that?
CHRIS BISCARDI: I would not do that. You can technically do that, but I would not do that. (Laughter).
JASON LENGSTORF: Okay. Okay. So, uh, yeah. Can you give a fragment with a key? I have no idea. But this is good enough for now, so we've got our header and that's going to give us a little bit of information and then we can, like, do some do some minor accessibility stuff here. We'll do a "rel home" so people know that's to go home.
And then we render the children inside of our "main" and then we've got our footer. So, if I stop and restart, is this automatically going to show up on everything?
CHRIS BISCARDI: Uhhuh.
JASON LENGSTORF: Boom! Look at it go!
CHRIS BISCARDI: Now we have a page wrapper on the whole site.
JASON LENGSTORF: That is really slick that that just works. Cool. So, this is you know, I can kind of see the power of what's going on here, because, like, another thing that we looked at is, we slugprefixed this with posts, but we could we could just, like, not do that. We can just leave that blank and our posts would show up however and our "about" page could be written that way. There's a world where your Toast site is components and MDX pages to write context and import components.
CHRIS BISCARDI: Like John of MDX, writes his entire site in MDX. If you wanted to, you could point MDX at source pages and you would get, like, all of your MDX as the pages and whatever and then the page wrappers
JASON LENGSTORF: Would this, like, respect like, if I do a subfolder.mdx...we would be able to theoretically go "post, sub, folder." No.
CHRIS BISCARDI: So, that would be a bug, I would consider that, in the MDX plugin. So, if you want to look at the actual implementation, we can just explain what it's doing and then we can sort of explain why that doesn't work. Because this is kind of like the 80% use case plugin.
JASON LENGSTORF: Got it. We can leave that out for now, then. So, for now, you would have to, like, set up each folder. And you could like, we can
CHRIS BISCARDI: You can also specify your own slug.
JASON LENGSTORF: Ohhh.
CHRIS BISCARDI: If you want to create that file again or go to a different file.
JASON LENGSTORF: Okay. Let's do a "subfolder.mdx." And then...do it like that.
CHRIS BISCARDI: And then above that, you're going to want to do "export const meta equals object." And in there, you do a slug.
JASON LENGSTORF: So it would be "subfolder"?
CHRIS BISCARDI: Yeah, do "/." Yeah. And it'll render "/sub/folder." This is the MDX plugin doing the page creation.
JASON LENGSTORF: Is it post we prefixed with "post," so it picks up with that slug and drops it on. We have full control over all that, which is really slick.
CHRIS BISCARDI: Prefix it with that's a bug.
JASON LENGSTORF: This is really this is powerful stuff. You could basically do, like Chris said, do Source Pages and only do MDX and, you know
CHRIS BISCARDI: Your Source Pages is in the wrong
CHRIS BISCARDI: (Away from mic).
JASON LENGSTORF: There's the captions. Do a code block.
CHRIS BISCARDI: And we'll do an MDX Provider and have some fun.
JASON LENGSTORF: So, we can do, like, "true." Okay. (Laughter). So then, to start, you know, this is just Markdown. So when we come back out here, this was in my first post. So, my first blog here. And
CHRIS BISCARDI: So, it looks like this. It looks like this because I made a decision, in the plugin, to include a new element. So, to use the Toast MDX plugin, right now, you would want to provide a code block component in the MDX Provider to render this. So, this is giving you the prism syntax highlighted version of your code.
JASON LENGSTORF: Okay.
CHRIS BISCARDI: And it doesn't require you to ship the prism.js. You didn't import Prism. It's giving you, "hey, here's what it would look like, syntax highlighted." If you go to the page wrapper...and you import MDX Provider...
JASON LENGSTORF: And this is, like, this?
CHRIS BISCARDI: Uhhuh.
JASON LENGSTORF: And that's going to come in from this?
CHRIS BISCARDI: Yep no, from mdx.jsx Toast doesn't wrap everything. You're not importing from Toast Plugin MDX, you're just using MDX. Use your MDX Provider. You can replace your lovely div, if you'd like to.
JASON LENGSTORF: Hooray! It's gone!
CHRIS BISCARDI: This is "components equals" and then "object."
JASON LENGSTORF: Code block how?
CHRIS BISCARDI: Type "code block."
JASON LENGSTORF: Like that?
CHRIS BISCARDI: Yeah. And then create a component. And the children are going to be the thing that you see. So, you're going to if you want it to be just the prism syntax highlighted stuff, you can (Indiscernible) put the children in it.
JASON LENGSTORF: Did I do this from memory?
CHRIS BISCARDI: You did.
JASON LENGSTORF: So, let's try that...look how fast that builds.
CHRIS BISCARDI: There you go! So, this is a decision I made because dealing with the the preelement and the code element and figuring out which one is which is overriding the preelement and not overriding the Preelement. This is a thing I put on top of MDX, as, like, a "nice to have."
JASON LENGSTORF: It's really slick. We all have our opinions about how we want code to look and all those things. If I just needed to get something shipped, I can do a background color of black and build this again and there we go. We're done. I can ship that. We're finished, as far as I'm concerned.
CHRIS BISCARDI: Beautiful!
JASON LENGSTORF: If I'm just trying to get something out the door, the last thing I want to do I feel like this is what kills my motivation inside projects is that I want to do something and then I spend so much time yackshaving and adding callout components. I just did this on Jason.jf. I was like, I like this footnote feature in Markdown, but it doesn't really look good when you render it. I ended up writing a remark plugin to deal with my footnote. You end up with such a good such a huge amount of yackshaving. So being able to walk in and say, just do my syntax highlighting, like, I don't care. This is good enough. I would like to be able to ship my code blog today, please. And it's done.
That that, to me, is huge.
Um, so...we have working React hooks. We've got syntax highlighting. We're still at 16 kilobytes for page size, so I'm feeling pretty good. We've got a customizable page wrapper. Um, what if I want to do, like, a custom page wrapper? Like, I want my blog to look a little bit different.
CHRIS BISCARDI: You want a custom page wrapper? You have a custom wrapper? On your page wrapper, you can determine whether you're on the "/post" suffix and change the way you you can do it however you want, really. Probably probably use not use "effect," because it doesn't happen in the server. You would be able to know.
JASON LENGSTORF: Gotcha. That makes sense.
CHRIS BISCARDI: If you want to look at the toast.js file I guess we needed use that for slug yet. What's the best way to look at this? So, actually, you got autocomplete here, didn't you?
JASON LENGSTORF: I think that's just everything that's on the page.
CHRIS BISCARDI: Set data for slug allows us to set data, a component, a page wrapper and the slug that it's applied to. So, if you set a slug, the first argument is the slug. If you want to create a new page at first argument positional, not in the object.
JASON LENGSTORF: Oh, like, positional. I understand.
CHRIS BISCARDI: The only thing that's recalled is the slug. You're setting data for this slug, so, "/about." We can write a component, for sure. JSON stringify the props?
JASON LENGSTORF: And, we'll get in the props. And, this will return prestringify props and we'll prettify them a little bit.
CHRIS BISCARDI: Vinny, if you want to use a custom prism theme today, you would have to use the other approach and use this plugin, which is the plugin that powers everything. And then you could pass in the prism theme there.
JASON LENGSTORF: Timechecking because I want to make sure we get to T. We've got about 25 minutes left, so we should make sure we get to Tailwind, as well.
CHRIS BISCARDI: Cool. We can do that. Let's finish this up. Set the data for slug. We can set the component to so, actually something that's really interesting is you can set this component to a source code string. So, do "component." And "mode source."
JASON LENGSTORF: Ohh! Object, mode, source. Like this?
CHRIS BISCARDI: Uhhuh. And then "value." And then I'm going to ask you to write a React component in here, without anything JSX.
JASON LENGSTORF: Like this? Oh, oh, oh, I see what you mean. "H div null."
CHRIS BISCARDI: It's a whole source file. If you go into "public" and grab the "index.js" script, it's already compiled for you, just to show this off. Grab this.
JASON LENGSTORF: Oh. Oh, I see.
CHRIS BISCARDI: Drop it inside of a string here.
JASON LENGSTORF: Got it. Okay.
CHRIS BISCARDI: And you need to change that import to be from React. And not from web modules, because it'll get processed.
JASON LENGSTORF: Okay.
CHRIS BISCARDI: The component can take raw source, if you want it to.
JASON LENGSTORF: Sure.
CHRIS BISCARDI: Actually, now that I think about it, it can take JSX, I misled you. Sorry. (Laughter).
JASON LENGSTORF: So we could do
CHRIS BISCARDI: You can export default here, instead of the "h," do the "div."
JASON LENGSTORF: So, we'll get our children and then we can return a div with our children and that's it, right?
CHRIS BISCARDI: True, you're not going to get children because this is a page component and not a page wrapper. Take the on line 15, where you have children, write "props." Regular React component. Right? And then JSON to stringify the props here and we'll see the props come in.
JASON LENGSTORF: Got it. I think I have a rogue I do.
CHRIS BISCARDI: Probably. You usually wouldn't do it this way, I'm just trying to skip us through it. Like, you could read in a file and pass it in here, or something like that, which would be much more reasonable.
On the same level of as component, create a key called "data." And pass in any data "Jason is cool."
JASON LENGSTORF: I don't want to lie to people. (Laughter). I've created this. If I go to "about," here's come boops.
CHRIS BISCARDI: Wrapped in the page wrapper, rendering your custom components. So, this is actually the way that the MDX stuff works. The MDX stuff comes in here as source and then gets rendered out.
JASON LENGSTORF: Awesome. Very cool. I'm going to delete that "about.js." This, that's slick! It's really nice we're able to do that.
So, if I want to bring in Tailwind, how would I do such a thing?
CHRIS BISCARDI: So, if you look at (Indiscernible), it will have the Tailwind config in here. So, we have to we have to install sorry, I couldn't find the word. We have to install CSS in postCSS CLI. And I have Tailwind CSS UI in here, as well. But, that's because I pay for it.
JASON LENGSTORF: So we won't be doing that, I assume?
CHRIS BISCARDI: Yeah. I mean, we don't have to do that. We can just do regular Tailwind. But I do have a license and this is my project as I'm walking through it.
JASON LENGSTORF: I'm down for doing whatever, I just don't want to get anybody in trouble.
CHRIS BISCARDI: Grab CSS UI, as well, and we'll take it out before we publish the repo. It'll be easier if I can show off a couple Tailwind components.
JASON LENGSTORF: Fair enough. Now I have installed these
CHRIS BISCARDI: Now we need to set up the config for Tailwind and that's "Tailwind config."
JASON LENGSTORF: Is it not running my postinstall?
CHRIS BISCARDI: You're doing individual package installs, right?
JASON LENGSTORF: I get it. I understand. We'll run the postinstall, again, after we've written some code.
CHRIS BISCARDI: We don't need to, in this case. We're not running anything on the client.
JASON LENGSTORF: For real?
CHRIS BISCARDI: No, Tailwind
JASON LENGSTORF: I'm not going to lie, I don't know Tailwind at all. (Laughter).
CHRIS BISCARDI: It's just a CSS thing. We're just running postCSS CLI. This CSS config is the folder we care about. You'll see a package JSON and a Tailwind.config.js. We can copy these over. The one that I want to talk about a little bit is the package JSON. Because Toast is ESM, we put our postCSS config in a folder and use this to tell Node that everything in here is going to be CommonJS stuff.
JASON LENGSTORF: Got it. PostCSS configure. And then we got to package JSON. It is CommonJS. Okay.
CHRIS BISCARDI: This is not actually creating a new package. This is saying, hey, the files in this folder, treat them as CommonJS.
JASON LENGSTORF: Got it. Is it.config?
CHRIS BISCARDI: Um, yes, I believe so. I think that's just the convention.
JASON LENGSTORF: So that brings in Tailwind CSS. Do I need to have Autoprefixer?
CHRIS BISCARDI: (Away from mic).
JASON LENGSTORF: I guess we may
CHRIS BISCARDI: We'll find out.
JASON LENGSTORF: And then we've got our Tailwind config. Default theme.
CHRIS BISCARDI: A couple of features and stuff. Most of these don't matter. The purge will only run Purge CSS in production. If we actually, like we can choose to use or not use any of these themes because the default theme is just passed in anyway.
JASON LENGSTORF: Okay. So, we could probably leave most of this out. The I'm not going to worry about the font family. Purge yeah, that's fine. Um, cool. So, this all seems good. Anything anything specific that we want to look at here?
CHRIS BISCARDI: Index.css is going to be our file choice.
JASON LENGSTORF: Index.css in the root. In the root of here. Got it.
CHRIS BISCARDI: I mean, we can realistically put this anywhere. I put in the root. That's where I configured it to be. The only other thing is we need a build step for CSS. In the scripts, there's a build:css that runs CLI.
JASON LENGSTORF: Like that? I should probably look at this command. (Laughter).
CHRIS BISCARDI: Yeah. So, it points to the index.css and then it puts it out in public. Like, the the point, here, is that we are just configuring postCSS. This has nothing to do with Toast really. That's one of the things about Toast is that we let you just use things in the ecosystem. So, if there's an easier way, like the Tailwind, you can use that. You can install your custom CSS plugins because you have full control over that.
JASON LENGSTORF: I just built this and should have built out to styles.css. It did. Excellent. Okay. And so, then I don't know what to do next.
CHRIS BISCARDI: If you look at the page wrapper, there's a style.css in React.Helmet. We need to, like, get our style.css in the head somehow. If you look for "helmet," it should be in there.
JASON LENGSTORF: Here we go.
CHRIS BISCARDI: Just that first line it all we need, with that helmet call.
JASON LENGSTORF: That means I need to install React Helmet.
CHRIS BISCARDI: (Away from mic).
JASON LENGSTORF: Do not?
CHRIS BISCARDI: No, I think it's already installed.
JASON LENGSTORF: So then I'm going to go in here. I'm going to import Helmet
CHRIS BISCARDI: (Away from mic) because we're the NFL.
JASON LENGSTORF: From React Helmet. And then...
CHRIS BISCARDI: If I send you a message, in Discord, with some code, will you get it?
JASON LENGSTORF: Yeah, I'll get it. So I think I can just stick this in like this.
CHRIS BISCARDI: Yeah, you can put it anywhere, really.
JASON LENGSTORF: And that should be good. And let's open this. Do you want me to keep this offscreen?
CHRIS BISCARDI: Um, it's fine. It's so much code that nobody would be able to grab it and use it anyway.
JASON LENGSTORF: Okay.
CHRIS BISCARDI: You're going to copy this whole thing.
JASON LENGSTORF: Okay.
CHRIS BISCARDI: Except for that top comment. Put it anywhere, like index.js. I think it's in a wrapper, right? Yeah.
So, um, we just copy and pasted, like, raw HTML.
JASON LENGSTORF: Something broke.
CHRIS BISCARDI: We copy and pasted raw HTML. The things we are going to be looking for are any HTML comments. You can get rid of comments. It works in Preact. We need to get rid of the HTML comments because those don't work. You need to look for if there's an image, HTML doesn't selfclose image tags and JSX does so you'll have to close those. But those are the only changes. You don't have to do the whole class name (Away from mic).
JASON LENGSTORF: Okay. So, I think these are something's not working and I don't know why. Um
CHRIS BISCARDI: Keep looks for comments and image tags. Those are the two things that I saw in there that would be the
JASON LENGSTORF: Image tag. Image tag. Those are fine.
CHRIS BISCARDI: Okay. Look for HTML comments.
JASON LENGSTORF: No HTML comments.
CHRIS BISCARDI: The screamer perspective of a code handler doesn't come in handy. (Laughter).
JASON LENGSTORF: We've got this, here. Redlines near the bottom of the page, is a whole other thing.
CHRIS BISCARDI: You just scroll through it slowly once.
JASON LENGSTORF: What's that about? Oh, wait, here's unclosed BR. So, let's find more of those.
CHRIS BISCARDI: Probably should have sense this through a JSX Converter before I sent it to you.
JASON LENGSTORF: That worked.
CHRIS BISCARDI: Let's build the site. The only Toastspecific thing is we put the style tag in the Helmet call.
JASON LENGSTORF: Yeah. Okay. And, let's go to the index page.
CHRIS BISCARDI: So, it has a bunch of styles in it.
JASON LENGSTORF: Oh, buddy! There's our wrapper. Like, you know, this is the part that I put in and the footer. And then inside is all Tailwind.
CHRIS BISCARDI: Right.
JASON LENGSTORF: So, that's slick. This is part of Tailwind UI. If you pay for a license, they give this to you?
CHRIS BISCARDI: This is one of their Hero components. It comes with navigation and stuff like that. I've really enjoyed using it.
JASON LENGSTORF: That's pretty handy. We will not be including the source code in the repo.
CHRIS BISCARDI: Not the Tailwind UI stuff. We'll rip that out.
JASON LENGSTORF: If we wanted to use regular Tailwind stuff chat, remind me, what would be, like, some Tailwind classes, if we wanted to let's center this div, and give it some border or something.
CHRIS BISCARDI: BGPink400.
Anything else, chat? Tailwind users?
JASON LENGSTORF: Class is okay. I'm still kind of blown away by this, that this just works.
Tech Center. Oh, Eco's got the whole thing. Flex, center.
CHRIS BISCARDI: Justify on the center.
JASON LENGSTORF: So, we're going to do that. Not knowing any Tailwind, that just made sense to me.
CHRIS BISCARDI: There you go.
JASON LENGSTORF: It didn't quite work because we've got it wrapped in a bunch of other stuff.
CHRIS BISCARDI: We didn't put it on the page wrapper so you're not wrapping the page on a pink border or anything.
JASON LENGSTORF: That's pretty cool stuff. I love that this is his is pretty humanreadable. This all makes sense. It seems like we can probably get away with skipping that part. (Laughter).
CHRIS BISCARDI: And so begins the CSS adjustments.
JASON LENGSTORF: You put in numbers.
CHRIS BISCARDI: (Away from mic).
JASON LENGSTORF: That's cool. I got to do a real Tailwind episode.
CHRIS BISCARDI: Yeah, you do. (Laughter).
JASON LENGSTORF: But, yeah, so this is great. This is really powerful stuff. I think we've got some and I think this is, like, really fun. I should talk to Adam. That would actually be great.
CHRIS BISCARDI: What the index.js size is?
JASON LENGSTORF: How big is the index.js? 373 kilobytes.
CHRIS BISCARDI: Index.js is what they were asking about. The whole site. The whole site is 370 kilobytes.
JASON LENGSTORF: Index.js came back as 178 bytes. (Laughter). We've got let's see
CHRIS BISCARDI: I'll also point out that the total page size, right now, for the development (no audio) and we've jumped quite a bit in 373 kilobytes, because the Tailwind development version of the style.css ships 4.5 megabytes.
JASON LENGSTORF: How do we fix that?
You have to do node, underscore and production and then "CSS build." I do the "buildo" typo all the time.
JASON LENGSTORF: That's got to be my number one. Let's try this again. We just did a production build on Tailwind.
CHRIS BISCARDI: Yeah, you probably could have just refreshed. You didn't need to the CSS
JASON LENGSTORF: I don't need to rebuild.
CHRIS BISCARDI: It's one of those habits you get really used to, using other frameworks and tooling. I made "a" change, I need to rebuild everything. You don't, actually.
JASON LENGSTORF: 11.1 kilobytes transferred. That is a Tailwind site using React or Preact and MDX and a whole bunch of stuff. So, this is, like it just feels, to me, like if what we're after is we want to build extremelyinteractive sites, like, that's the argument for using React or Vue. You want to do these really interactive, really responsive, frequentlyupdating sites.
The other argument is when you ship that much stuff to the browser, it hurts the user experience. It's not great on people in markets where a 3G phone. Using ES modules, using Preact, we start working toward a world where both things can be true. You can ship a great user experience that doesn't use a lot of data and also have really interactive, really dynamic and responsive sites.
That's that's supercool. So, what do you think we've got a few minutes left, here. What do you think is next here? Like, what's coming, that's going to take this experience even further?
CHRIS BISCARDI: In the Toast world?
JASON LENGSTORF: Toast is I think our episode I don't know that we're going to get much else done in our episode. What's coming in Toast or in the pipeline?
CHRIS BISCARDI: A couple quality of life things. You were like, "I'm going to go back and rebuild." It takes 250 milliseconds. It's fine doing it by hand, nobody wants to. We'll set up an automatic (Away from mic) and you'll be able to trigger whatever stuff. It's a bunch of quality of life, a bunch of documentation, a bunch of examples, how to use X, how to use Y. Www.Toast.dev.
Yeah, I mean, that's really it. Quality of life stuff, making it more stable. There's a soft limit of, like, 20,000 pages right now or something like that. So, a 10k site page builds in 40 seconds. We have 20,000 pages now because we passed arguments to the CLI to do rerendering. What does it look like to build a 100,000page Toast site? We don't know what that looks like. 10K is 40 seconds if you use regular Preact.
JASON LENGSTORF: 40 seconds, for 10,000 pages with, like, React and Tailwind, that's not nothing.
CHRIS BISCARDI: Well, yeah. (Laughter). Sorry, I'm looking at it like like, what do I need to look at, next, and that sometimes is, like oh, like, what we have is really nice, as well. (Laughter).
JASON LENGSTORF: Yeah. Um, well, mean, this is I really, really love the idea here. I think is superexciting. I'm in the Jason.af is a Toast site. The overlays you're looking at, on the show, are a Toast site. There are a lot of really interesting applications for Toast. Is there anywhere we should oh, you triggered the stampede. I was wondering if you were going to get there, chat.
Is there anywhere you want people to go to keep up with you, keep up with Toast?
CHRIS BISCARDI: There's a Discord, a Twitter account and the Git Repo.
JASON LENGSTORF: Here's the Discord link, up at the top. Let me drop that straight into the chat. I'll bring back the sound eventually. It was getting so chaotic in here, that I cut back on some of the noise.
The overlay is will be on GitHub, it's not right now. I'm working on a whole thing called Socket Studio
I think I need adult supervision here.
JASON LENGSTORF: I do need adult supervision.
CHRIS BISCARDI: I thought that was the random person in the Zoom call. (Laughter).
JASON LENGSTORF: Socket Studio will be coming out. It's a set of tools for streamers. It's not on the top of my priority list. We'll get there. We'll get there eventually.
With that, I think, let's do one more shout to the sponsors. Thank you, again, to White Coat Captioning, for providing the live captioning today. That's always available. That is made possible through the contributions of Netlify, Fauna, Sanity and Auth0, who kicked in cash to help pay for the captioning. Make sure you go check out their services.
Also, make sure you go and take a look at what's coming on the show. We've got some really fun stuff coming on. Thursday, I am overthemoon. Lynn Fisher will be on. I cannot wait. We're going to make it a little bit spooky. I'm hoping I'm going to wear a costume. I hope that when you're watching, in the chat, you'll wear a costume.
So much fun stuff. We're going to learn Next. We're going to do an accessible audio player. It's going to be all over the place fun.
Come hang out with us in the Party Corgi Discord, which is at partycorgi
CHRIS BISCARDI: (Away from mic).
JASON LENGSTORF: I don't know. Partycorgi.com. Come hang out with us. Chris and I are in there all the time. A lot of people, in the chat, are regulars in that Discord.
Anything else? What else, Chris?
CHRIS BISCARDI: What else? I don't know. Buy any cool onesie's lately?
JASON LENGSTORF: I have not.
Chris, thanks so much.
Staytuned, chat. We're going to raid.
And, we'll see you next time.