Intermediate React, v6

Server-Side Generation from Scratch

Intermediate React, v6

Lesson Description

The "Server-Side Generation from Scratch" Lesson is part of the full, Intermediate React, v6 course featured in this preview video. Here's what you'd learn in this lesson:

Brian demonstrates building a static site generator with React from scratch. He renders a React component to static HTML using `renderToStaticMarkup` and injects it into an index.html file. While this approach is useful for basic static sites, he recommends frameworks like Astro or Next.js for more complex projects.

Preview
Close

Transcript from the "Server-Side Generation from Scratch" Lesson

[00:00:00]
>> Brian Holt: We're gonna create an App.js file, and again, just really, really simple here I'm gonna say, import, Create Element as H. You can leave this as Create Element. I just 1h was like a really standard thing to do back in the day when people used to not use JSX.

[00:00:19]
So I just kinda stuck with it, but it's just to make it really easy to create React components. It's an alias we'll call function app, and we're going to return H. So this is normally we'd write JSX. We're just gonna do it with vanilla JavaScript for a minute.

[00:00:39]
Div Null and then we'll put another component in here. It's gonna be an H1 has nothing there. And we're gonna say Hello frontend masters. And another H "p", null, and this is SSG.
>> Brian Holt: And then export default App.
>> Brian Holt: So again, if you took complete intro to react, the first part of this course is writing react without JSX.

[00:01:26]
This is essentially what we did here. Later if you wanna come back and reimplement this using Babel and vite and all that kind of stuff, by all means, go ahead. But now we don't have to set up a whole build process, which I think everyone here is like one less webpack step in their life is a good day.

[00:01:43]
Again, this isn't particularly interesting code, so feel free to just copy it out of the docs as well. I'm super okay with that. But I wanna make a file called build.js now, and this is gonna be a little noddy, but you'll kinda get the gist of like what Next and Astro and all these frameworks really do for you.

[00:02:03]
And you're gonna be, it's actually really not that much. Or sometimes if you don't need the full power of Astro behind you, sometimes this can be useful. I just need to get some content templated and generated and I wanna use React to do that. This will work just fine.

[00:02:20]
So we're gonna do import render. I can spell, render to static markup from reactdom/server.
>> Brian Holt: Okay, we're gonna import again our H, create element as h from react. And then we need a bunch of just dumb file stuff from, no Js so bear with me for here just a second.

[00:02:52]
Realfilesync, writefilesync, existssync, makedirsync, readdirsync, and unlinksync. Now, why all the syncs? Again, I was just trying to keep this code simple, not asynchronous. These are async by default and I'm just gonna make the build process wait for every step to happen. If you had a massive app, you'd wanna make this more in parallel, right?

[00:03:24]
And this is just gonna come from, you can put from FS, I imagine most of you are probably used to just writing FS like that, file system. The new way of doing that is actually node colon FS, so you're explicitly coming from the node standard library. That's totally up to you, they both work.

[00:03:41]
I'm just trying to make myself get in the habit of writing node colon coz I don't know someone the one of the node card members told me to do it that way, and I just didn't ask many questions, if we're being really honest, of what happened, okay.
>> Brian Holt: We're gonna import file URL to path from node colon, URL like that we're going to import.

[00:04:09]
Why do I have path in there twice? I don't know, but we're gonna follow the notes and dirname from node colon path, and then we're finally gonna import our app from App./app.js or something like that. Sometimes it gets finicky about the extensions. One of the things, if you've worked much in no JS, you frequently refer to dirname.

[00:04:39]
Like this with this like double underscore coz it allows you to refer to where the app is currently running. It's basically like the president working directly of where you are, if you're familiar with the Linux kinda terminology. I'm just gonna say that I find this incredibly annoying that they didn't anticipate that this was going to be also a practice with es modules.

[00:05:03]
So you have to redefine what dirname is in es modules and I can never remember how to do it. So if you wanna know about, one of the things I use AI for all the time is define dirname for es modules or something like that. And I'll just have it generate this little snippet of code.

[00:05:24]
For me, it generates the same thing for me every single time. Yeah, it looks exactly like this. So it generates file name and which is, you can also use as well and dirname, I think that's literally in my notes there as well, is it looks just like this.

[00:05:37]
But this is like one of the things I use AI for all the time it's like, I know this code out there exists. I don't remember exactly how to do it off top my head. I know you have to use file you are at a path, and then this will actually give you what in common JS will always be defined.

[00:05:52]
But for es modules, you have to redefine it every single time, okay? And then we need to make a distpath, const distpath = path.join_dirname, "dist". So this is actually where we wanted to export the finished files to, right? Okay, const shell =, we're gonna read our index.html, so read filesync, and then we're gonna say path.join_dirname, index.html.

[00:06:34]
>> Brian Holt: And it's a UTF-8 file, which is the encoding, not that you really need to need to care at all.
>> Brian Holt: Okay, so now this is going to be just a string of what's in this index.html file, which is the shell of our app so to speak. Const app is going to be renderToStaticMarkup.

[00:06:58]
And then we have to give it h, coz we have to instantiate the R app, and so App like that. So now this is a string, right? Coz renderToStaticMarkup will give you back a string of whatever this rendered with. So now I have my shell, right? Which is the index.html file and I have whatever is an app rendered out to like a final string.

[00:07:26]
At this point, you can probably guess what's gonna happen, right? So we're gonna say const html equals shell.replace. And we're gonna do that same string. I can type, there we go, root, and we're gonna replace it with app. And now this will be a string of our completed app.

[00:07:57]
>> Brian Holt: And then the bottom part here is just making sure if the directory exists, create it. If it's full of stuff, delete the stuff in there. And then at the end you just write all of your files out and then you were done. So we're gonna say if existsSync distpath.

[00:08:21]
>> Brian Holt: Mkdirsync distpath.
>> Brian Holt: Okay, else const files equals readersync
>> Brian Holt: Dist path, and then we're just gonna go and delete everything, which is called unlinking. So you're gonna say for const file of files.
>> Brian Holt: And then you're gonna go through here and say, unlink sync path.join distpath and file.

[00:09:06]
Okay, does that make sense? What this does directory exists. If it doesn't exist, create it if it does exist, delete everything in it and then write filesync path.join distpath index.html and you're gonna write out your HTML.
>> Brian Holt: No, this is it, right? We should run this, right? Coz it's gonna be amazing and it's gonna blow your mind.

[00:09:38]
You're gonna be like, My God, I have created fire, right? Like you just banged two rocks together. This obviously only works on one file right now with one app with no props and put it, but I'm hoping that you can look at this and like, yeah, I can very much understand here how to create multiple pages, right?

[00:09:56]
With multiple different props and multiple different permutations, right? This here is the beginnings of a framework that you're building for static site generation. This is essentially what Astro does for you underneath the hood, right? It renders your app, it just outputs it to raw files and that's what you get.

[00:10:16]
So we should be able to just run node build. Okay, so now we have this disk directory. You can look in your index at HTML, and you can see, hello, frontend masters, this is SSG, right? No mention of React. You never would even have to know that this was generated by react, right?

[00:10:33]
And like I said, this is really what Astro does for you underneath the hood. It's a more sophisticated build.js file, but yeah, I'm sure you can imagine here we could define, like a routes.js file. You would define this file corresponds to this component, and generate them in this order, with these props, have these permutations.

[00:10:55]
You could actually have little mini React js Apps that would instantiate on every page. You actually could add some interactivity. This is what I'm talking about where we can kinda shove some of these things together. Just because you're doing static site generation doesn't mean that you can't have React on top of it.

[00:11:12]
This is just another way of accomplishing some of these things. You could definitely bring in something like React router or ten stack router and put that on top of that and now you have a spa, right? So, the world is your oyster is really what I'm trying to say.

[00:11:31]
>> Brian Holt: Okay, any questions about the code that we went through here?
>> Brian Holt: Make sense?
>> Brian Holt: Yeah, I mean, it's one of those things that you probably went through this as wow, I assumed this did more. And that's why I love doing these kind of first principles apps together, is you realize it doesn't really do that much for you.

[00:11:55]
The complexity that's underneath the hood really isn't that complex.
>> Brian Holt: So going back here to static site generation is like, okay, but just use Astro. [LAUGH] right, I've now shown you everything of how you could do this yourself, but now that you understand the tool and what next and Gatsby and Astro were all doing for you.

[00:12:17]
Just use them, right? And now you understand when stuff breaks, you can understand where some of these things are falling apart. And you can also probably understand how you can improve and make them more performant and better and all these kind of things, right? But Astro is an amazing piece of software, I like it quite a bit.

[00:12:34]
If I was gonna recreate something today, I probably would just use Astro, I quite like it.
>> Brian Holt: So yeah, like I said, this app is built on top of Next.js. It's just obviously what I know the best, but Astro is awesome as well. The previous versions of this, course, were built on Gatsby.

[00:12:53]
That's a fun fact, but now that they got acquired by Netlify, they don't seem to be as maintained as they were. So I would say these two Astro, Next are really the state of the art at the moment. Again, this site you're looking at yourself is a more complicated static site.

[00:13:10]
So just to kinda walk you through that, this is the markdown that generated this page that you're looking at. I mean, that's the really nice part about all this, is I get to author everything in Markdown, which I love. You can see here, has all the keywords and description.

[00:13:29]
This is the stuff I was telling you that was generated by chat GPT. So, it makes experience. And then you can see down here to the next config I have the export part. That's the part that makes it so it's static site. You can see that actually ends up being this HTML doc, right, which is great.

[00:13:52]
It's exactly what I want. So you can see this entire site is just one. Just straight up HTML, right?
>> Brian Holt: It makes it super easy to do things to help the front of masters team with the editing of this, it generates a CSV file of all the various different lessons, it makes all the SEO stuff very easy.

[00:14:18]
But that's all thanks to static site generation, it's perfect for that use kinda use case. So any questions about SSG?
>> Speaker 2: Do you ever use markdown instead of React components or somehow mix and match?
>> Brian Holt: I see them as different tools for different jobs. If I was gonna write this course in React, it would be very painful for no reason, right?

[00:14:47]
I don't understand why you would just directly author JSX for static sites, unless you were building some large layer of interactivity on top of it. But even then, would use I forgot what it's called, but there's some markdown flavor that allows you to embed React components in it.

[00:15:03]
I'm sure someone here knows what it is. I would use something like that, right? I wouldn't actually still author it directly in markdown. So markdown is great for just like I got h1s, h2s, paragraphs, block quotes, all that kind of stuff. And then I will render that to HTML, and then I will put that into a page, right?

[00:15:23]
So it's one layer of abstraction higher than a React component.
>> Speaker 2: Chad is shouting, MDX
>> Brian Holt: Yeah, you got it, MDX, thank you, Chad.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now