Video Summary and Transcription
The Talk covers the speaker's personal journey into server-side rendering (SSR) and the evolution of web development frameworks. It explores the use of jQuery for animations in SSR, the challenges faced in integrating React with Umbraco, and the creation of a custom SSR framework. The Talk also discusses the benefits of Next.js and the use of serverless artifacts for deployment. Finally, it highlights the features of Astro, including its function per route capability.
1. Introduction to SSR and Personal Journey
Today I'm going to talk to you about SSR and my personal journey into SSR. First, let's dive into it! My name is Emanuele Stoppo, I'm Italian, I live in Ireland. I'm a core contributor of the Biome project and I belong to the team platform of the Aster project. We're going to start our journey talking about this coding framework, which is essentially my first experience with SSR. And we're going to arrive and end our journey with Astro. Now, what is server-side rendering? It's when a server gives you HTML and you render a page on your server. Let's start with my first experience in 2010 as a PHP developer working with Codingigniter, a framework based on MVC.
Hi everyone! Today I'm going to talk to you about SSR and my personal journey into SSR. Let's dive into it! First, well, presentations in order. My name is Emanuele Stoppo, I'm Italian, as you might understand from my accent, I live in Ireland. I'm a core contributor of the Biome project and I belong to the team platform of the Aster project. And I'm also an avid console gamer.
So, by the time that this video will come out, probably I will be playing Final Fantasy 7. Now, we're going to start our journey talking about this coding framework, which is essentially my first experience with SSR. And we're going to arrive and end our journey with Astro. And that's where things will get interesting. And we'll see why.
Now, first of all, what is server-side rendering? The thing is, it's changed over the years. When I actually started, server-side rendering was how you make websites. It's how you make them. But then Node.js came along, new patterns, new possibilities, new tools, blah, blah, blah. And things got different, new patterns, and so on. Essentially, it's when a server gives you HTML and you give it to your client. So, you render a page on your server and that's it. So, that's really, really basic. So, now we understand what is SSR.
Let's start with my first experience. It was 2010. I came out of university. It was one year after. And PHP was my first experience. I was a PHP developer. And I got to work with Codingigniter, which is a framework based on MVC, which stands for Model-View-Controller. Just to give you a rundown of what's this pattern. Essentially, you have your own class, which is the controller that has all the business logic of your page. Then, you have the model. Model is usually that entity that takes care of everything around your data.
2. CRUD Operations, Templating Languages, and jQuery
So, the CRUD operations. Validations and whatnot. It connects with the database and talks with the database. Then, you have the view. You can have multiple views or reuse all the views. The view is usually a templating language. jQuery came along as a revolution. It's how I learned JavaScript. Here's an example of how I used it with SSR. We had requirements for animations without leaving the user page. So, we created a new endpoint with a controller model view and outputted only the desired HTML.
So, the CRUD operations. Validations and whatnot. So, it connects with the database and talks with the database. And then you have the view. So, the view is usually, you call it inside your controller. You can also have multiple views or reuse all the views. And the view, it's usually a templating language. So, this is an example of a templating language. If you use, for example, Vue and Svelte, you already know what's a templated language. And that's how I used to do it back in the day. So, it hasn't changed that much. Like with Vue and Svelte, they have a different syntax. But, I mean, the concept. It's the same. We interpolate the templated language with the variables. We spit out HTML and we give it to the browser. That's my first. That's how I started.
And then jQuery came along. So, jQuery was a revolution at that time. It's how I learned JavaScript. And here's an example of how I used it with SSR. So, I had my jQuery. And there was another MVC framework which is called Grails. Grails is based on this language called Groovy. It compiles in JVM. As I said, it's still an MVC. And what I did was essentially we had some requirements where we wanted to have some animations without going out from the user page. So, what you usually do at that time was you create a new endpoint with a controller model view. Specifically, for these needs, you spit out only the HTML that you want to have.
3. jQuery, Central Touch, and React
With jQuery, you could replace an HTML with another using animations. Client-side rendering was really interesting. I was in charge of the controllers and views. Then we have Central Touch, an all-in-one mobile framework for web apps. It didn't generate much interest. React came along with refreshing features. I wanted to use it, but there was a but. My manager said, let's use it.
And then with jQuery, you just do a get. You get your HTML and then you do animations and so on. So, with jQuery, you could replace an HTML with another using animations. And that's how client-side rendering was back in the day. It was a really... Yeah, I mean, at the end, you could do all your strategies and things like that. But that's how I was able to play with this kind of thing. It was really, really interesting. And I was in charge also of the controllers and the views. So, I could just go there in the framework, create a new controller, do parameters, and it was really fun at that time.
Then we have Central Touch. I'm not gonna bother you about Central Touch. It's essentially an all-in-one mobile framework to build essentially web apps. You have your stores, you have your components, views, models, and everything. But it didn't take it so much interest. It was like a few years before React came along. It was really boring. Not that... I mean, I got to learn a lot of stuff, but you were essentially caged into the framework. And now that's where we start getting interesting stuff. Yes. React came along, and it had really nice features. And some of these features were really refreshing. And I wanted to use them. Right? So, yeah. But, no. There's always a but. So, I had this project. I wanted to use React a lot. And my manager said, let's use it.
4. Using React with Umbraco
In an enterprise world with restrictions, the website was powered by Umbraco, similar to WordPress. But I wanted to use React. So, I wrote my SSL framework and followed three principles. Go Blast state manager and Redux were used. Node.js was the runtime.
But still, we are in an enterprise world, so things aren't perfect. In this project, there were some restrictions. So, the website was pumped by a Microsoft.NET framework. Specifically, a CMS called Umbraco. And it seemed like a WordPress. You have your back office. You can customize it. But also, the website is provided. The actual website is rendered by WordPress. Same thing with Umbraco. So... But I wanted to use React. So... How did I do that? Well... Yes, I wrote my SSL framework. And, yeah. As you... Yes, it's a meme. But, I mean, that's true. But the thing is, at that time, there were no frameworks to do that. Neither in .NET. I mean, I was writing unsounded grounds at that time. So, I had to come up with something. Well, the thing is, writing your own SSL framework is not that difficult. It's actually easier than you think. There are just, like, three principles that you have to follow. So, you must have a Go Blast state manager. At that time, Redux was the place to go. You need to have a runtime. So, at that time, Node.js was the way to go.
5. Creating an SSL Framework
You couldn't glop it everywhere. Once you have these three things, you can have your SSL framework. I had a .NET framework with a template engine. A library allowed passing a React framework to get the actual HTML at runtime. The foundations of creating your own SSL framework involve connecting these foundations using available libraries.
You couldn't glop it everywhere. You just run it, and it gives you what you need using a script. And then, either hit the page.
So, once you have these three things, you can have your SSL framework. So, let's look briefly at what I did at that time. So, I had a .NET framework. So, there was a template engine, as we saw before. So, usually you go to a page, and you have your own Redux global state. That's a global object. And, essentially, for each page, you inject the initial global state of your page. All right?
Then, you must have this runtime. So, fortunately, at that time, there was this library that allowed you to pass a React framework. And it was able to give you the actual HTML. It was, like, at runtime inside the template engine. It was really fast. There was no overhead whatsoever, even because, like, the pages, usually, that contain React components were, like, really small. So, we didn't need to render, like, the whole page. All right? So, we had pages where we had, like, a React component here or React component there. So, it was a mix of static HTML and React components. So, once you have this HTML, you have it in your template engine. And at the end, we go back to our page. We need to actually fetch the ID of where the React component was rendered and iterate it. So, as you can see, it's not that difficult. So, these are the foundations of essentially creating your own SSL framework. And then you just need to connect these foundations using the libraries that you have. And the job is done. Like, there's no rocket science. And I was actually really proud of that work. And I went to check it. This webpack still uses the same logic.
6. Introduction to Next.js and Enterprise Constraints
That was a really good choice. Next.js is a great framework that made life easier with GetStaticProps. However, enterprise constraints posed challenges as our backend only used lambdas. The initial version of the website was negatively penalized for SEO.
So, I mean, that was a really good choice. Sure, things have changed. But it still works. Okay.
Now we go with a more modern approach. And that's where Next.js comes into play. So, yeah. I got to work with Next.js as well. It's a really great framework. And with GetStaticProps, life was way, way easier. Like, GetStaticProps eliminated a bunch of the network that I explained, because that's what Next.js at that time did. So, it creates your own global state and whatnot. But Next.js also has more, like progressive client-side routing and other stuff. It's a really good framework. Actually, it is. But, you know, enterprise is different, yes. So, at that time, we had really weird constraints.
So, our backend didn't have any servers at all. But we just, we could use only lambdas. Like, the backend was using lambdas. And for them, it was great. But for us, that was quite challenging. The initial version of the website was SPAS. So, we had an HTML page. We studied JavaScript. And so, no. No. CreateRectApp. So, it was a fork of CreateRectApp. But the SEO was actually, of the website, was negatively penalized."
7. Exporting Pages as Serverless Artifacts
Next.js introduced the option to export each page as a serverless artifact. I built my own deployment layer, a meta framework, which hooked into the Next.js serverless build. This allowed us to create lambdas for each page, deploy them, and have client-side navigation. The compact layer translated the event passed from the lambda to the artifact page.
So, we had to do something. At that time, Next.js introduced a new option called output serverless, or something like that. And it would allow to export each page as a serverless artifact. Not a lambda, a serverless artifact. And it was great for us. It was great.
So, what did they do? Well. Guess what? I built my own deployment layer. So, it's like I built my meta framework. Exactly so. And it was actually really, really fun.
Now, let's see what did I do. All right. So, Next.js, as I said before, creates this artifact for each page. All right. Then, my meta framework essentially hooks the Next.js serverless build. So, programmatically, we run the build. This build gives me all the information needed to actually create a lambda for each page. So, at the end of the build, we had all these lambdas that we were able to deploy in the different environments, execute them at each request, and get just the page that we asked for, and have client-side navigation from there. And that's how Next.js used to work at that time.
So, this lambda, actually, is not just a lambda. So, I was more. Okay. So, there's actually the real lambda built dynamically. We then had the compact layer. So, a compact layer that takes the event passed from the lambda and create a response request. And these response requests were passed to the artifact page. Because the artifact was not, as I said before, AWS lambda friendly. It just takes, like, an incoming request Node.js-like. So, we needed a compact layer to translate this on information.
8. The Compact Layer, Terraform, and Astro
We needed a compact layer to translate the information. I open-sourced everything, but it's now archived. Eventually, we came to Astro, where SSG is SSR with an extra step. Astro has a generic way to export pages and adapters can manipulate artifacts for different requirements. Additionally, I created niche features in Astro, such as function per route.
So, we needed a compact layer to translate this on information. And then we had the Terraform sources. So, the beta framework created dynamically all the Terraform files that then eventually were called at the end of the build.
So, eventually, what did I do? I open-sourced everything. So, I took all the logic that I built for the company. I just added a CLI in front with a few options. And, yeah, I mean, I thought I did something great. I mean, sure, it's a really niche case what I have. But maybe someone else is facing the same issue. So, I open-sourced it. But now it's actually archived because Next.js removed the serverless option.
And eventually, we came to Astro. So, I work at Astro and I build actually some nice stuff that I'm going to show you. But before going to that, I'm going to unveil some secrets about Astro. So, you know about SSG, static site generation, or static websites. But you know that actually SSG in Astro is SSR with an extra step? Yes, because when we actually build it, we actually run SSR.
We create all these pages, like right artifacts, files. We import them, we execute them, and then they were like requested response when we get their response, the HTML, and we render it. And we put them in an HTML file. So, it's SSR all over the place, you know? But then, what's SSR in Astro? Well, it's actually SSR with a different build step. So, we just have a different configuration and we emit these artifacts with a different thing, like in a generic way. So, adapters can actually consume them and build them, actually, as they prefer. So, we have a generic way to export and also an interface to export the pages of the routes, let's call them.
And then the adapters, such as Node.js, Deno, Vercel, Cloudflare, Netlify, and so on, which have different requirements, can take these artifacts, manipulate them if they need, and create their own configurations based on their needs. So, it's like what I did before, like with the meta framework. Essentially, that's what Astro does. But there's more. Like, recently, I got to create a couple of niche features, really nice, in Astro, using SSR and a bunch of other tools. One is function per route.
9. Astro's Function per Route
Astro's function per route allows for multiple entry points and is useful for heavy pages with lots of code.
One is function per route. So, what does it mean? So, by default, this is how SSR looks like in Astro. So, we have just one single file that handles all your routes. So, when we hit and when the server, actually the client, requests one route, what we do, we actually dynamically import the artifact that belongs to that page and return its response. Instead, with function per route, we have multiple entry points. So, it's actually a niche case. Nobody needs something like this. But if you have really heavy pages with a lot of code, a lot of JavaScript, sometimes this use case might help you, because essentially it's like code splitting on the serverless platform.
Comments