<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: JulesWritesCode</title>
    <description>The latest articles on Forem by JulesWritesCode (@juleswritescode).</description>
    <link>https://forem.com/juleswritescode</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1945399%2F571b05a1-52dc-4533-8c05-99ac9405da30.jpeg</url>
      <title>Forem: JulesWritesCode</title>
      <link>https://forem.com/juleswritescode</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/juleswritescode"/>
    <language>en</language>
    <item>
      <title>The Second Iteration: Your Key to Finally Writing Excellent Code</title>
      <dc:creator>JulesWritesCode</dc:creator>
      <pubDate>Tue, 03 Sep 2024 09:00:00 +0000</pubDate>
      <link>https://forem.com/juleswritescode/the-second-iteration-your-key-to-finally-writing-excellent-code-2b9j</link>
      <guid>https://forem.com/juleswritescode/the-second-iteration-your-key-to-finally-writing-excellent-code-2b9j</guid>
      <description>&lt;p&gt;Your first version of a piece of code is mediocre at best.&lt;/p&gt;

&lt;p&gt;When you start developing a feature, the beginning feels great. You know where the code needs to sit and how to implement it. But halfway through, you bump into an unforeseen problem, and you find yourself copy-pasting if-statements or meddling with data structures. Towards the end, your work feels rough and unfinished, but you’ve already invested hours and just want to finish it.&lt;/p&gt;

&lt;p&gt;If you had discovered the problems and quirks beforehand, it would’ve been easy to handle them properly and to write simple code from the outset. You couldn’t discover them, however, since you first had to write the damn thing. &lt;/p&gt;

&lt;p&gt;But there’s a simple trick to accelerate making those discoveries and getting a complete picture.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Always throw away the first iteration.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once I started doing this, my PRs had fewer requested changes, my code produced fewer bugs, and it became easier to integrate subsequent features. &lt;/p&gt;

&lt;p&gt;Here’s why.&lt;/p&gt;

&lt;h3&gt;
  
  
  You’ll arrive at a working version &lt;em&gt;rapidly&lt;/em&gt;.
&lt;/h3&gt;

&lt;p&gt;If you throw away everything regardless, you’ll spend less time on making it work.&lt;/p&gt;

&lt;p&gt;During the first iteration, I often don’t even implement functions. Instead, I jot down the signature, return mock data or an error, and continue with the important stuff. Since I know &lt;em&gt;that&lt;/em&gt; and &lt;em&gt;how&lt;/em&gt; the function will work (you must be sure of those two things), I don’t have to spend time on it.&lt;/p&gt;

&lt;p&gt;By only spending time on parts I haven’t fully grasped, I’m significantly reducing the time it takes to finish the first iteration.&lt;/p&gt;

&lt;h3&gt;
  
  
  You’ll get a complete overview before you do the real work.
&lt;/h3&gt;

&lt;p&gt;To understand what your feature requires, you must first make it work.&lt;/p&gt;

&lt;p&gt;The rapidly completed first iteration gives you an overview of requirements, quirks, and issues. You can then identify the spots where you could solve problems or make features work elegantly. This will help you a lot once you start the next iteration.&lt;/p&gt;

&lt;p&gt;Then, designing an elegant implementation becomes straightforward.&lt;/p&gt;

&lt;h3&gt;
  
  
  You won’t waste time on unnecessary details.
&lt;/h3&gt;

&lt;p&gt;As devs, we love to worry about variable names or think about performance optimization.&lt;/p&gt;

&lt;p&gt;But the temptation of optimizing a lower-level function or rewriting code for readability can suck you in for hours. Worse, after finishing a feature, you might realize you never needed the now-optimized function in the first place. Your time would’ve been better spent elsewhere.&lt;/p&gt;

&lt;p&gt;If you consider your first iteration a throwaway, that compulsion to optimize will be easier to resist. &lt;/p&gt;

&lt;h3&gt;
  
  
  Cleaning up will now be a breeze.
&lt;/h3&gt;

&lt;p&gt;Once you start with the second iteration, starting from scratch won’t feel as bad.&lt;/p&gt;

&lt;p&gt;If you invest too much into the first iteration, if you spend too many hours fixing bugs, writing tests, rewriting functions, and optimizing or commenting code, you won’t feel motivated to start over — and understandably so. You don’t want to throw away your work. But if you are less diligent during the first iteration, you are less invested, so it won’t feel like you’re throwing away anything important. &lt;/p&gt;

&lt;p&gt;Instead, you’ll feel motivated to start building it &lt;em&gt;right&lt;/em&gt;.&lt;/p&gt;




&lt;p&gt;The con argument is that this approach takes longer.&lt;/p&gt;

&lt;p&gt;But is that the case? How much time do you spend rewriting code once you’ve stumbled upon your first hurdles? Wouldn’t starting from scratch be easier than cleaning up the mess?&lt;/p&gt;

&lt;p&gt;Give it a try and see if you like it.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>career</category>
      <category>learning</category>
    </item>
    <item>
      <title>From Bass Player To Startup Engineer in &lt;9 months. Here Are Four Things You Can Learn From My Journey</title>
      <dc:creator>JulesWritesCode</dc:creator>
      <pubDate>Tue, 27 Aug 2024 17:26:44 +0000</pubDate>
      <link>https://forem.com/juleswritescode/from-bass-player-to-startup-engineer-in-9-months-here-are-four-things-you-can-learn-from-my-journey-40fk</link>
      <guid>https://forem.com/juleswritescode/from-bass-player-to-startup-engineer-in-9-months-here-are-four-things-you-can-learn-from-my-journey-40fk</guid>
      <description>&lt;p&gt;I started to code when I was 27.&lt;/p&gt;

&lt;p&gt;Before, I was a professional musician. I studied pop music, specializing in bass guitar, and made a living playing concerts and recording songs for German artists. In 2020, the pandemic rendered every musician I knew workless, and I had to learn something new.&lt;/p&gt;

&lt;p&gt;So, in March 2020, I installed VSCode and got to work.&lt;/p&gt;

&lt;p&gt;Nine months later, I got my first self-employed gig as a software engineer. Another three months later, I was hired at Parqet, a fintech company I still work for. &lt;/p&gt;

&lt;p&gt;I got lucky for sure, but some decisions greatly impacted my journey. &lt;/p&gt;

&lt;p&gt;I want to share those with you.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Musician to Startup Engineer
&lt;/h2&gt;

&lt;p&gt;My idea to pick up coding didn't come out of thin air.&lt;/p&gt;

&lt;p&gt;When Covid hit, I had already thought about it for a while, primarily because I thought Mr. Robot was a fantastic series and I would have loved to hack just like Elliot, and secondarily because a drummer friend had proven it to be a good idea by first learning Splunk and then starting to work at a data-analytics company.&lt;/p&gt;

&lt;p&gt;So, when I realized in March 2020 that I would get months, maybe even years of free time, I purchased a couple of Udemy courses and marched down the rabbit hole.&lt;/p&gt;

&lt;p&gt;I created portfolio websites and designed pages using flexbox, wrote Express applications, completed CodeWars katas, and devised simple SQL queries. It was fun. However, Germany's job center, typically unsatisfied with anything that doesn't involve an official licensing paper,  kept calling to ask about my career plans and how I intended to make money. &lt;/p&gt;

&lt;p&gt;So, in September 2020, in an attempt to soothe the bureaucrats, I started a web development bootcamp. &lt;/p&gt;

&lt;p&gt;At that point, I had already learned the basics, so most of the course's topics came effortlessly. The questions I &lt;em&gt;did&lt;/em&gt; have were more advanced than those of the other students. Some instructors struggled to answer, but one, Joe, was excited to be challenged. He quickly took me under his wing and became my private mentor.&lt;/p&gt;

&lt;p&gt;After I finished the course, Joe asked for help with his startup.&lt;/p&gt;

&lt;p&gt;He had built a fintech application and wanted me to add a multi-language mode. I did my best, which was terrible then, but he was happy about the result. Joe didn't have any more work afterward, but he recommended me to another founder in the fintech space.&lt;/p&gt;

&lt;p&gt;That founder's name was Sumit, and I started working with him at Parqet.&lt;/p&gt;

&lt;p&gt;When I started, we were two engineers on the backend: junior me and senior Kevin (an incredibly talented guy and by now a friend; he currently works at Supabase). &lt;/p&gt;

&lt;p&gt;This equaled private mentoring, so I learned &lt;em&gt;a ton&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We've since evolved into a team of five developers and Parqet continues to grow steadily. Considering the pay, remote work hours, and the responsibility and freedom I have (and anything else, really), it's a dream job.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would do again
&lt;/h2&gt;

&lt;p&gt;I love practicing. During music university, I regularly locked myself in the basement for four hours or more to work on bass lines, scales, technique, and timing. To this day, I love such a strict regimen.&lt;/p&gt;

&lt;p&gt;So, in bootcamp, I was more of a hard-liner than my peers, trying to squeeze out the maximum learning experience.&lt;/p&gt;

&lt;p&gt;While some things were needlessly stressful, here are four things I'd definitely repeat.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. I'd try to master the basics
&lt;/h3&gt;

&lt;p&gt;There are a gazillion frameworks and libraries in web development.&lt;/p&gt;

&lt;p&gt;But regardless of what you'll end up using or what project you'll work on, you'll always deal with the basics. You'll write for-loops and filters to manipulate data with JavaScript. You'll choose the correct HTML tags for your cards and navigation menus. You'll write CSS to make your content readable and your UI easy to navigate.&lt;/p&gt;

&lt;p&gt;The better you understand those basics, the more productive you'll be. &lt;/p&gt;

&lt;p&gt;Plus, a firm grasp of the basics is a requirement for getting hired. &lt;/p&gt;

&lt;p&gt;A team of senior developers will enjoy and benefit from teaching you advanced concepts, but if they must teach you how CSS and JS work, they're wasting precious time explaining something you could quickly learn on your own. Not knowing the basis means slowing down your team. &lt;/p&gt;

&lt;p&gt;So don't waste time learning all the shiny new tech. Instead, master your HTML, CSS, and JS.&lt;/p&gt;

&lt;p&gt;Here's an incomplete list of concepts you should know inside out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JS: Closure, event-loop, Array &amp;amp; Object methods, prototypes, "this" keyword, async-await&lt;/li&gt;
&lt;li&gt;CSS: Specificity rules, flex &amp;amp; grid, inheritance, positioning, etc.&lt;/li&gt;
&lt;li&gt;HTML: the most common tags, inline- vs. block elements, accessibility, inputs, buttons, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. I'd purchase multiple sources of information
&lt;/h3&gt;

&lt;p&gt;I didn't only buy one course or book on JavaScript – I bought many.&lt;/p&gt;

&lt;p&gt;Any learning material, say, an online video course, will try to explain mental models of its core topics. You won't understand some of them, but the issue isn't that you are stupid (though many junior devs regrettably think that about themselves). Instead, it could be the mental model is vague, the course assumes a more knowledgeable viewer, or the teaching style doesn't resonate with you.&lt;/p&gt;

&lt;p&gt;What helped me overcome these issues was having multiple sources of information.&lt;/p&gt;

&lt;p&gt;For example, I struggled with async-await. My course didn't explain how the event loop worked, so I didn't understand how JavaScript could wait for a task to finish &lt;em&gt;and&lt;/em&gt; simultaneously do other tasks. My mental model was incomplete. I had no chance of understanding it.&lt;/p&gt;

&lt;p&gt;Thankfully, the second course and another book I had purchased brought relief. The additional info bridged knowledge gaps, and I finally could comprehend the topic.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. I'd try to force myself out of my comfort zone
&lt;/h3&gt;

&lt;p&gt;Learning to code is like learning to speak a language.&lt;/p&gt;

&lt;p&gt;When learning Spanish, you can't expect to get better by only repeating what your audio-book instructor says. You need to &lt;em&gt;speak&lt;/em&gt;. You need to express your own thoughts using vocabulary and grammar you're unfamiliar with.&lt;/p&gt;

&lt;p&gt;But most coding newbies don't do that.&lt;/p&gt;

&lt;p&gt;Instead, they go through tutorials step-by-step and mindlessly follow instructions.&lt;/p&gt;

&lt;p&gt;Doing so won't teach you anything. To improve, force yourself to think and work like a programmer: Equip yourself with knowledge, pick a problem, devise a plan to tackle it, and debug and research and fumble your way to the solution. &lt;/p&gt;

&lt;p&gt;In short, step outside your comfort zone.&lt;/p&gt;

&lt;p&gt;You can achieve such a learning experience with books and courses, provided you use them right. Instead of reading a paragraph and immediately executing the instructions, read the entire chapter. Take notes on objectives and upcoming stumbling blocks, then close the book. Try to complete the tasks using only your memory and notes, and reopen the book only if you've been stuck for at least twenty minutes. &lt;/p&gt;

&lt;p&gt;Doing this, you'll be outside your comfort zone. But there's no reason you won't finish the project; due to your initial read, you have sufficient knowledge to not be overwhelmed.&lt;/p&gt;

&lt;p&gt;You'll internalize more lessons than by only going through the motions.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. I'd spend time to meet people and maybe find a mentor
&lt;/h3&gt;

&lt;p&gt;A single friend with contacts can save you from writing 100 applications.&lt;/p&gt;

&lt;p&gt;I knew this from my days in the music industry, and meeting Joe, who later introduced me to Sumit, further confirmed it. But meeting people can, amidst coding tutorials and writing applications, and since the results of meetups are not directly measurable, become an afterthought.&lt;/p&gt;

&lt;p&gt;It shouldn't. &lt;/p&gt;

&lt;p&gt;Instead, you should treat meeting people as an obligation, a higher priority on your to-do list (without becoming a sociopath, of course). &lt;/p&gt;

&lt;p&gt;Spend two hours researching which developers who share the same tech stack or interests live in your town, which meetups happen regularly, and whether there are any large events like web development summits within driving distance. And then, visit them! I've been, for instance, to indie-hackers and Supabase meetups and had several coffee chats.&lt;/p&gt;

&lt;p&gt;You might even find a mentor.&lt;/p&gt;

&lt;p&gt;Receiving feedback from an experienced developer is the best way to accelerate your learning journey. I was lucky to work with Kevin during my first years at Parqet. While I sometimes felt frustrated when I revised my code according to his critique for the umpteenth time, the result was always better. Years later, I still draw on his lessons.&lt;/p&gt;

&lt;p&gt;If you're willing to learn, finding someone who takes you under their wing is easy.&lt;/p&gt;

&lt;p&gt;People enjoy helping others, especially those they like.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parting Words
&lt;/h2&gt;

&lt;p&gt;You might spend extra cash or time following my advice, but I'm confident it works.&lt;/p&gt;

&lt;p&gt;Following those tips won't &lt;em&gt;guarantee&lt;/em&gt; that you will get a great job quickly. Still, I believe they will significantly increase your chances. They certainly increased mine.&lt;/p&gt;

&lt;p&gt;I wish you all the best on your journey. Please share any other tips or success stories you have.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>career</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>The Junior Developer's Complete Guide to SSR, SSG and SPA</title>
      <dc:creator>JulesWritesCode</dc:creator>
      <pubDate>Tue, 20 Aug 2024 08:02:59 +0000</pubDate>
      <link>https://forem.com/juleswritescode/the-junior-developers-complete-guide-to-ssr-ssg-and-spa-288n</link>
      <guid>https://forem.com/juleswritescode/the-junior-developers-complete-guide-to-ssr-ssg-and-spa-288n</guid>
      <description>&lt;p&gt;Every dev tools company and -team seems to assume that Junior Devs are familiar with these terms.&lt;/p&gt;

&lt;p&gt;When I started to code, I saw them everywhere: Nuxt is an SSR framework, you can use Gatsby for SSG, and you can enable SPA mode if you set this or that flag in your &lt;code&gt;next.config.js&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;What the hell?&lt;/p&gt;

&lt;p&gt;As a first step, here's a glossary – though it won't help you to understand the details:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSR = Client-Side Rendering&lt;/li&gt;
&lt;li&gt;SPA = Single Page Application&lt;/li&gt;
&lt;li&gt;SSR = Server-Side Rendering&lt;/li&gt;
&lt;li&gt;SSG = Static Site Generation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, let's shed some light into the dark.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static Web Servers
&lt;/h2&gt;

&lt;p&gt;Initially, a website was an HTML file you requested from a server.&lt;/p&gt;

&lt;p&gt;Your browser would ask the server, "Hey, can you hand me that /about page?" and the server would respond with an &lt;code&gt;about.html&lt;/code&gt; file. Your browser knew how to parse said file and rendered a beautiful website &lt;a href="https://motherfuckingwebsite.com/" rel="noopener noreferrer"&gt;such as this one&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We call such a server a &lt;em&gt;static web server&lt;/em&gt;. A developer wrote HTML and CSS (and maybe a bit of JS) by hand, saved it as a file, placed it into a folder, and the server delivered it upon request. There was no user-specific content, only general, static (unchanging) content accessible to everybody.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/about&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./about.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Interactive Web Apps &amp;amp; Request-Specific Content
&lt;/h2&gt;

&lt;p&gt;Static websites are, however, boring. &lt;/p&gt;

&lt;p&gt;It's much more fun for a user if she can &lt;em&gt;interact&lt;/em&gt; with the website. So developers made it possible: With a touch of JS, she could click on buttons, expand navigation bars, or filter her search results. The web became interactive.&lt;/p&gt;

&lt;p&gt;This also meant that the &lt;code&gt;/search-results.html&lt;/code&gt; page would contain different elements depending on what the user sent as search parameters.&lt;/p&gt;

&lt;p&gt;So, the user would type into the search bar, hit Enter, and send a request with his search parameters to the server. Next, the server would grab the search results from a database, convert them into valid HTML, and create a complete &lt;code&gt;/search-results.html&lt;/code&gt; file. The user received the resulting file as a response.&lt;/p&gt;

&lt;p&gt;(To simplify creating request-specific HTML, developers invented HTML templating languages, such as Handlebars.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/search-results&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;searchParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;htmlList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;htmlList&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/li&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;htmlList&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./search-results.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fullPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;embedIntoTemplate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;htmlList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fullPage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A short detour about "rendering"
&lt;/h2&gt;

&lt;p&gt;For the longest time, I found the term &lt;em&gt;rendering&lt;/em&gt; highly confusing.&lt;/p&gt;

&lt;p&gt;In its original meaning, &lt;em&gt;rendering&lt;/em&gt; describes the computer creating a human-processable image. In video games, for example, &lt;em&gt;rendering&lt;/em&gt; refers to the process of creating, say, 60 images per second, which the user could consume as an engaging 3D-experience. I wondered, already having heard about &lt;em&gt;Server Side Rendering&lt;/em&gt;, how that could work — how could the &lt;em&gt;server&lt;/em&gt; render images for the user to see?&lt;/p&gt;

&lt;p&gt;But it turned out, and I realized this a bit too late, that "rendering" in the context of Server- or Client-Side Rendering means a different thing.&lt;/p&gt;

&lt;p&gt;In the context of the browser, "rendering" keeps its original meaning. The browser &lt;em&gt;does&lt;/em&gt; render an image for the user to see (the website). To do so, it needs a blueprint of what the final result should look like. This blueprint comes in the form of HTML and CSS files. The browser will interpret those files and derive from it a model representation, the Document Object Model (DOM), which it can then render and manipulate. &lt;/p&gt;

&lt;p&gt;Let's map this to buildings and architecture so we can understand it a bit better: There's a blueprint of a house (HTML &amp;amp; CSS), the architect turns it into a small-scale physical model on his desk (the DOM) so that he can manipulate it, and when everybody agrees on the result, construction workers look at the model and "render" it into an actual building (the image the user sees).&lt;/p&gt;

&lt;p&gt;When we talk about "rendering" in the context of the Server, however, we talk about &lt;em&gt;creating&lt;/em&gt;, as opposed to parsing, HTML and CSS files. This is done first so the browser can receive the files to interpret.&lt;/p&gt;

&lt;p&gt;Moving on to Client-Side Rendering, when we talk about "rendering", we mean manipulating the DOM (the model that the browser creates by interpreting the HTML &amp;amp; CSS files). The browser then converts the DOM into a human-visible image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Client-Side Rendering &amp;amp; Single Page Applications (SPAs)
&lt;/h2&gt;

&lt;p&gt;With the rise of platforms like Facebook, developers needed more and faster interactivity.&lt;/p&gt;

&lt;p&gt;Processing a button-click in an interactive web app took time — the HTML file had to be created, it had to be sent over the network, and the user's browser had to render it. &lt;/p&gt;

&lt;p&gt;All that hassle while the browser could already manipulate the website without requesting anything from the server. It just needed the proper instructions — in the form of JavaScript. &lt;/p&gt;

&lt;p&gt;So that's where devs placed their chips.&lt;/p&gt;

&lt;p&gt;Large JavaScript files were written and sent to the users. If the user clicked on a button, the browser would insert an HTML component; if the user clicked a "show more" button below a post, the text would be expanded — without fetching anything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Document&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
      &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DOMContentLoaded&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
            &amp;lt;h1&amp;gt;Home&amp;lt;/h1&amp;gt;
            &amp;lt;button&amp;gt;About&amp;lt;/button&amp;gt;
        `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;btn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
            &amp;lt;h1&amp;gt;About&amp;lt;/h1&amp;gt;
        `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Though the code snippet suggests the opposite, developers didn't write vanilla JavaScript.&lt;/p&gt;

&lt;p&gt;Ginormous web apps like Facebook had so much interactivity and duplicate components (such as the infamous Like-button) that writing plain JS became cumbersome. Developers needed tools that made it simpler to deal with all the rendering, so around 2010, frameworks like Ember.js, Backbone.js, and Angular.js were born. &lt;/p&gt;

&lt;p&gt;Of them, Angular.js was the one that brought Single Page Applications (SPAs) into the mainstream. &lt;/p&gt;

&lt;p&gt;An SPA is the same as Client-Side Rendering, but it is taken a step further. The conventional page navigation, where a click on a link would fetch and render another HTML document, was taken over by JavaScript. A click on a link would now fire a JS function that replaced the page's contents with other, already preloaded content.&lt;/p&gt;

&lt;p&gt;For this to work properly, devs needed to bypass existing browser mechanisms.&lt;/p&gt;

&lt;p&gt;For example, if you click on a &lt;code&gt;&amp;lt;button type="submit"&amp;gt;&lt;/code&gt; that's wrapped in a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element, the browser normally sends a POST request to the server and renders the HTML file of the response (an agreed upon standard all browsers conform to). But, since the server had already sent all the instructions, and the browser had now taken control over rendering pages, that behavior needed to be prevented.&lt;/p&gt;

&lt;p&gt;Devs invented all kinds of hacks to bypass this and other mechanisms, but discussing those hacks is outside the scope of this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Side Rendering
&lt;/h2&gt;

&lt;p&gt;So what were the issues with &lt;em&gt;that&lt;/em&gt; approach? &lt;/p&gt;

&lt;p&gt;SEO and Performance.&lt;/p&gt;

&lt;p&gt;First, if you look closely at the above HTML file, you'll barely see any content in the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tags (except for the script). The content was stored in JS and only rendered once the browser executed the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;. Hence, Google's robots had a hard time guessing what the page's content was about — in fact, they couldn't guess anything. &lt;/p&gt;

&lt;p&gt;The site couldn't be indexed and thus wouldn't rank highly on Google. &lt;/p&gt;

&lt;p&gt;Second, since the browser would only send a single request to the server and then continue to render the SPA on its own, all content that could ever be rendered had to be delivered with the initial request. With large web apps, this could easily surpass a couple megabytes, which slowed down the page load significantly. Amazon conducted a &lt;a href="https://www.conductor.com/academy/page-speed-resources/faq/amazon-page-speed-study/" rel="noopener noreferrer"&gt;study&lt;/a&gt; that concluded businesses would lose 1% of revenue with every 100ms in added page load time, so that was a huge no-no for most companies.&lt;/p&gt;

&lt;p&gt;In short, developers needed to create HTML files on the server again.&lt;/p&gt;

&lt;p&gt;But they couldn't circle back to templating-languages and request-specific content — by now, everybody was writing React, and they loved the component-driven approach. Wasn't there a way to write React and render it on the server? Of course! With the advent of Node.js, developers were already writing JS on the backend, and the road to full-stack frameworks such as Next.js or Nuxt was paved. &lt;/p&gt;

&lt;p&gt;Those frameworks render React (or Vue, Svelte...) on the server. Basically, React turned into a templating language such as Handlebars.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// List.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}[]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ListElement&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;))}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ListElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// server.ts&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/search-results&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;searchParams&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;q&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fullPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;renderToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fullPage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note: the only difference to the "Request-Specific Content" approach is that we're now using modern frontend frameworks to write our HTML.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Static Site Generation
&lt;/h2&gt;

&lt;p&gt;Great, so our pages were indexable and fast again.&lt;/p&gt;

&lt;p&gt;However, some sites weren't as fast as they &lt;em&gt;could be&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;If the content didn't change (like the page of a blog post), why should the server newly fetch and build the HTML for every user visiting the page? That seemed wasteful. Wouldn't it be enough to build the HTML once and reuse it whenever somebody requested it?&lt;/p&gt;

&lt;p&gt;That approach is called static site generation. &lt;/p&gt;

&lt;p&gt;In contrast to the original static web server approach, where developers manually wrote and stored HTML files on the server, here, the HTML files were &lt;em&gt;generated&lt;/em&gt;: &lt;/p&gt;

&lt;p&gt;Non-technical people wrote content and uploaded images in a CMS (Content Management System, such as WordPress or Sanity). Developers wrote React components, used the CMS's API, and executed a &lt;em&gt;build script&lt;/em&gt; that fetched the data for every page and built the HTML file according to the outlined blueprint. The finished file was then stored on the server, ready to be delivered upon a user's request. &lt;/p&gt;

&lt;p&gt;Developers could then re-trigger the build script to create new files when new content became available.&lt;/p&gt;

&lt;h2&gt;
  
  
  The new kid on the block: Server Components
&lt;/h2&gt;

&lt;p&gt;As of August 2024, React Server Components (RSCs) – though still marked as experimental – are all the rage.&lt;/p&gt;

&lt;p&gt;The basic idea is this: Before RSCs, a React Component first had to be delivered to the client. There, it would render and, if it needed to fetch data, send another request to the server; it had to wait for the response and re-render. This is wasteful. RSCs make it possible to both fetch the data and render the component on the server. Only the finished, isolated HTML component is sent to the client, and there merged with the existing HTML – the rest of the page is left as is. &lt;/p&gt;

&lt;p&gt;The result is a much better performance: less back-and-forth between the server, fewer kilobytes over the network, and less re-rendering.&lt;/p&gt;

&lt;p&gt;Plus, you can &lt;code&gt;await&lt;/code&gt; your data right in your React Code, making it much simpler to write.&lt;/p&gt;

&lt;p&gt;But, as usual when new features are added to existing frameworks, RSCs make React much more complex. You must constantly consider whether you need a component on the server or the client; caching layers are involved; interactivity is impossible with RSCs – tl;dr, the waters are still muddy.&lt;/p&gt;

&lt;p&gt;As a counter-movement, developers who are fed up with the front-end complexity have started to write and favor simple frameworks, such as HTMX. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
