<?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: Ibrahim Cesar</title>
    <description>The latest articles on Forem by Ibrahim Cesar (@ibrahimcesar).</description>
    <link>https://forem.com/ibrahimcesar</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%2F189167%2F17a70416-1a55-4b86-b63d-77e0fc53f5c0.jpeg</url>
      <title>Forem: Ibrahim Cesar</title>
      <link>https://forem.com/ibrahimcesar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ibrahimcesar"/>
    <language>en</language>
    <item>
      <title>Kafka on the Serverless Shore: Building event-driven applications with Kafka</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Wed, 25 May 2022 14:08:12 +0000</pubDate>
      <link>https://forem.com/aws-builders/kafka-on-the-serverless-shore-building-event-driven-applications-with-kafka-23df</link>
      <guid>https://forem.com/aws-builders/kafka-on-the-serverless-shore-building-event-driven-applications-with-kafka-23df</guid>
      <description>&lt;p&gt;As I awake one morning from uneasy dreams, I found myself asking why I never tried to use Apache Kafka. &lt;/p&gt;

&lt;p&gt;As a &lt;a href="https://ibrahimcesar.cloud/blog/event-driven-architectures/" rel="noopener noreferrer"&gt;event-driven&lt;/a&gt; enthusiast and with the recent announcements of &lt;a href="https://aws.amazon.com/msk/features/msk-serverless/" rel="noopener noreferrer"&gt;Amazon Managed Streaming for Apache Kafka (MSK) Serverless&lt;/a&gt; and the &lt;a href="https://upstash.com/kafka?utm_source=ibrahim_kafka" rel="noopener noreferrer"&gt;Serverless Kafka&lt;/a&gt; offering of &lt;a href="https://upstash.com?utm_source=ibrahim_kafka" rel="noopener noreferrer"&gt;Upstash&lt;/a&gt; I gave another try. &lt;/p&gt;

&lt;p&gt;I played a little on my computer in the past, but only see the work to go to production. I confess was beyond what I was up to do in my free time. So the serverless come to rescue! This is one of best-selling point of “not having to think about servers”, you can just experiment with new technologies.&lt;/p&gt;

&lt;p&gt;Since the AWS offering is in public preview and not General Available, I went with &lt;strong&gt;Upstash's Kafka Serverless&lt;/strong&gt; offering.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Kafka?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I thought that since Kafka was a system optimized for writing, using a writer’s name would make sense. I had taken a lot of lit classes in college and liked Franz Kafka. Plus, the name sounded cool for an open source project.&lt;br&gt;
So basically there is not much of a relationship.&lt;br&gt;
&lt;strong&gt;Jay Kreps&lt;/strong&gt;, &lt;a href="https://qr.ae/pvYJjL" rel="noopener noreferrer"&gt;Apache Kafka’s co-creator on Quora&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kafka is a publish/subscribe messaging system. Other ways to describe it are “distributed commit log” or nowadays, as a “distributing streaming platform”. &lt;/p&gt;

&lt;p&gt;The core entity for Kafka is a &lt;em&gt;message&lt;/em&gt;. For all purposes, Kafka doesn't care about the content of the message. It's just an array of bytes. Messages also can optionally have a &lt;em&gt;key&lt;/em&gt;. Kafka persistently stores the messages in the order. Is possible replay the stream to get to the state of a system at a point in time. A time machine for your transactions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F09kptfycxc9bd13yny5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F09kptfycxc9bd13yny5p.png" alt="Kafka Topology"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Topics&lt;/strong&gt; are a way to categorize the messages in order to allow other applications to have some visibility of what messages they will access.&lt;/p&gt;

&lt;p&gt;And then, the heart of the system: &lt;strong&gt;Producers&lt;/strong&gt; and &lt;strong&gt;Consumers&lt;/strong&gt;. Basically, the first, also called &lt;em&gt;publishers&lt;/em&gt; or &lt;em&gt;writers&lt;/em&gt;, produces messages, usually &lt;em&gt;a lot&lt;/em&gt; of messages, to require Kafka, and other applications act upon those messages. Consumers read messages from a topic and. We can call them &lt;em&gt;subscribers&lt;/em&gt; or &lt;em&gt;readers&lt;/em&gt; too.&lt;/p&gt;

&lt;p&gt;Kafka is a lengthy subject, worth of books, courses and hand-on practice. There are a lot more concepts that I will not cover in this post. Well is even subject for papers, like &lt;a href="https://arxiv.org/abs/2205.09415" rel="noopener noreferrer"&gt;On Efficiently Partitioning a Topic in Apache Kafka&lt;/a&gt;. I highly recommend &lt;a href="https://www.cloudkarafka.com/blog/part1-kafka-for-beginners-what-is-apache-kafka.html" rel="noopener noreferrer"&gt;Apache Kafka for beginners - What is Apache Kafka?&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The benefits of a serverless offering is the overhead in management of brokers, partitions, the Zookepeer and all the other moving parts to allow a fault-tolerant and highly distributed applications is taken care for you. And then, you can focus on write the code you need in your domain, with your tools — this is what I call &lt;strong&gt;the joy of serverless&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  On the shore
&lt;/h2&gt;

&lt;p&gt;To start, you just need to login, select Kafka and will create our first &lt;em&gt;cluster&lt;/em&gt;. Kafka works in a distributed way from the get go.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fddizza7iievw2bwn6mm5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fddizza7iievw2bwn6mm5.png" alt="Step 1 Upstash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create the cluster, we'll need a name and select the region. And also, if we need to be in only one availability zone or span of over one. Choose a single-zone for testing/development, multi-zone for production use cases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftpngy642dw5f9ztjuk16.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftpngy642dw5f9ztjuk16.png" alt="Step 2 Upstash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will the create our first topic and choose our desired number of partitions. Partitions are how Kafka provides redundancy and scalability, and each one can live on a different server. This is a very important concern for performance and scaling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fth30wkjcazi5qu3prhxz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fth30wkjcazi5qu3prhxz.png" alt="Step 3 Upstash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the advanced options for topics, there will be several options with sensitive defaults. Some configurations will require an upgrade in your plan. So, plan for the go-live depending on your application needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0hvojqpmbhz2v4c86uj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd0hvojqpmbhz2v4c86uj.png" alt="Step 4 Upstash"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And… &lt;em&gt;that's it&lt;/em&gt;. No need to worry about servers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favi5c83o1vglgol4wb23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favi5c83o1vglgol4wb23.png" alt="Joyce cluster"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this tutorial I will use Node.js on an AWS Lambda. Code is available in this GitHub repository using TypeScript:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ibrahimcesar" rel="noopener noreferrer"&gt;
        ibrahimcesar
      &lt;/a&gt; / &lt;a href="https://github.com/ibrahimcesar/lambda-serverless-kafka" rel="noopener noreferrer"&gt;
        lambda-serverless-kafka
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🐚 Kafka on the Serverless Shore
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🐚 Kafka on the Serverless Shore&lt;/h1&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Experimenting the &lt;a href="https://upstash.com/kafka?utm_source=ibrahim_kafka" rel="nofollow noopener noreferrer"&gt;Upstash's Kafka Serverless&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Read &lt;a href="https://dev.to/aws-builders/kafka-on-the-serverless-shore-building-event-driven-applications-with-kafka-23df" rel="nofollow"&gt;Kafka on the Serverless Shore: Building event-driven applications with Kafka&lt;/a&gt; for context.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Deploying&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;You will need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An AWS account&lt;/li&gt;
&lt;li&gt;CDK v2 installed (&lt;code&gt;npm install -g aws-cdk&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;CDK boostraped in the Account / Region we'll deploy&lt;/li&gt;
&lt;li&gt;A user for the CDK deploy with the right permissions&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;If you need help with all the above, open an Issue to see if there's enough people interested in a tutorial for that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;npm install
cp .env.example .env
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fill &lt;code&gt;.env&lt;/code&gt; with your credentials and names.&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;cdk deploy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Remember if you have multiple AWS profiles in your machine to pass the flag:&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;cdk deploy --profile namedProfile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Bootstraped with my &lt;a href="https://github.com/ibrahimcesar/cdk-simple-lambda-starter" rel="noopener noreferrer"&gt;CDK v2 Simple Lambda HTTP ApiGateway Starter&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ibrahimcesar/lambda-serverless-kafka" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;I'll use the vendor package (&lt;a href="https://www.npmjs.com/package/@upstash/kafka" rel="noopener noreferrer"&gt;@upstash/kafka&lt;/a&gt;) that leverages the REST API. Since we are at the shore, we'll not go open sea and build a ship. Not even a boat. We'll just get our feets wet.&lt;/p&gt;

&lt;p&gt;I'm writing an application that will read something, from some author. And post every line to Kafka. Then, I'll consume after that.&lt;/p&gt;

&lt;p&gt;Basically is just two lambdas, one for each endpoint: a writer and a reader.&lt;/p&gt;

&lt;p&gt;And we'll use my topic &lt;code&gt;ulysses&lt;/code&gt;. I could send all lines with page numbers from the book Ulysses from James Joyce. Or analytics data. Or log data. You get the gist.&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;// This is just a edited. &lt;/span&gt;
&lt;span class="c1"&gt;// View full file at: &lt;/span&gt;
&lt;span class="c1"&gt;// https://github.com/ibrahimcesar/lambda-serverless-kafka/blob/main/src/lambda/producer.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Kafka&lt;/span&gt; &lt;span class="p"&gt;}&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;@upstash/kafka&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;kafka&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Kafka&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// configuration&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;writer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;kafka&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;producer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;try&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;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;writer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;produce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ulysses&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;writing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt; &lt;span class="o"&gt;??&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="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&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;And to consume is simple. Note that I have there two hardcoded values, &lt;code&gt;consumerGroupId&lt;/code&gt; and &lt;code&gt;instanceId&lt;/code&gt;. You, at the time, basically can send whatever you want in the first request and Upstash will provision for you.&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;// Try and catch block. &lt;/span&gt;
&lt;span class="c1"&gt;// View full file at: &lt;/span&gt;
&lt;span class="c1"&gt;// https://github.com/ibrahimcesar/lambda-serverless-kafka/blob/main/src/lambda/consumer.ts&lt;/span&gt;

  &lt;span class="k"&gt;try&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;writing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;consume&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;consumerGroupId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;group_1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;instanceId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;instance_1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;topics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;autoOffsetReset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;autoOffsetReset&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;earliest&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="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;writing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&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;blockquote&gt;
&lt;p&gt;Little TypeScript goodie. I'm using the flag &lt;code&gt;useUnknownInCatchVariables: true&lt;/code&gt; in the &lt;code&gt;tsconfig.json&lt;/code&gt; file, so the catch is of type &lt;code&gt;unknown&lt;/code&gt;. Hat tip for &lt;a href="https://www.typescript-training.com/" rel="noopener noreferrer"&gt;Mike North&lt;/a&gt; to &lt;a href="https://www.typescriptlang.org/tsconfig#useUnknownInCatchVariables" rel="noopener noreferrer"&gt;show the way&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And now we can start writing and reading. To write is just a &lt;code&gt;POST&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1qi9o2up6d0j8t8lkyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1qi9o2up6d0j8t8lkyh.png" alt="POST"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Eventual consistency
&lt;/h2&gt;

&lt;p&gt;To read, we'll use another &lt;code&gt;POST&lt;/code&gt;, but beware: Here comes something important about distributed systems. We have &lt;em&gt;eventual consistency&lt;/em&gt;. Which means, your application cannot rely on the data being immediatly available for you just after the write. If you do, you could get... nothing, like a empty array in this case:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgshqsjjnzz5ik9cfudb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgshqsjjnzz5ik9cfudb.png" alt="No content for you. Not yet."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But, after very little time, you can see all data available in the topic:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7oh7ls97ig7v4pn2ta2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7oh7ls97ig7v4pn2ta2.png" alt="response"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dive Deep
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Checkout &lt;a href="https://docs.upstash.com/kafka?utm_source=ibrahim_kafka" rel="noopener noreferrer"&gt;Upstash's Docs on Kafka&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Be yourself a &lt;em&gt;reader&lt;/em&gt;: &lt;a href="https://amzn.to/3sX6jc2" rel="noopener noreferrer"&gt;Kafka: The Definitive Guide: Real-Time Data and Stream Processing at Scale&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Checkout the &lt;a href="https://www.confluent.io/what-is-apache-kafka/" rel="noopener noreferrer"&gt;Confluent's content on Kafka&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AWS just released &lt;a href="https://aws.amazon.com/msk/features/msk-serverless/" rel="noopener noreferrer"&gt;MKS Serveless&lt;/a&gt;, the Managed Streaming for Apache Kafka (MSK). But please note that, while is a &lt;em&gt;serverless&lt;/em&gt; offering in the sense you'll not need to worry about &lt;em&gt;cluster&lt;/em&gt; servers as they put: "Easily stream data with Amazon MSK &lt;strong&gt;without managing cluster capacity&lt;/strong&gt;". Emphasis mine. You'll need to put a lot more effort than the Upstash's offering as you can see here: &lt;a href="https://docs.aws.amazon.com/msk/latest/developerguide/create-client-machine.html" rel="noopener noreferrer"&gt;Getting Started - Step 2: Create a Client Machine&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;All the code used is open to use in TypeScript, using AWS Cloud Developement Kit (CDK). So you'll have no problem at all in provisioning your infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://unsplash.com/photos/DBw3wqluy64" rel="noopener noreferrer"&gt;Cover image&lt;/a&gt; by &lt;a href="https://unsplash.com/@cartayen" rel="noopener noreferrer"&gt;Alejandro Cartagena&lt;/a&gt; on &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>kafka</category>
      <category>eventdriven</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Certificações AWS — Por quê e de que forma</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Fri, 08 Apr 2022 10:14:20 +0000</pubDate>
      <link>https://forem.com/ibrahimcesar/certificacoes-aws-por-que-e-de-que-forma-3bi6</link>
      <guid>https://forem.com/ibrahimcesar/certificacoes-aws-por-que-e-de-que-forma-3bi6</guid>
      <description>&lt;p&gt;O objetivo desta postagem é responder por quê você deve ter entre seus objetivos uma certificação AWS. Também exploro minhas motivações que me levaram a buscar uma certificação — spoiler: eu não havia nenhum incentivo em minha posição e fiz para validar minha atuação. No final, trago algumas respostas a questões comuns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Por quê você deve tirar uma certificação
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Não existe algoritmo de compressão para experiência. — &lt;em&gt;Andy Jassy&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;É um &lt;em&gt;data-point&lt;/em&gt;. Demonstra, para qualquer pessoa, incluindo você, sua capacidade em um nível mínimo (entre 70% a 75%, dependendo do nível), de reconhecer cenários e associá-los a soluções efetivas, atingindo objetivos propostos, seja escalabilidade, performance, excelência operacional, redução de custos, segurança, entre outros.&lt;/p&gt;

&lt;p&gt;Todos precisamos estudar qualquer problema complexo. Não vai chegar uma demanda e vamos ter opções para escolher. O exame só demonstra que avaliando um conjunto de opções, que no dia a dia você provavelmente levantaria como opções, escolheu a mais apropriada para aquela determinada situação. E isto, demonstra uma agilidade, solidez dos conhecimentos, associação de domínios e conhecimentos.&lt;/p&gt;

&lt;p&gt;No nível &lt;em&gt;Professional&lt;/em&gt;, por exemplo, existem questões em que &lt;strong&gt;todas&lt;/strong&gt; respostas são soluções &lt;em&gt;válidas&lt;/em&gt;. Não há nada que as elimine por detalhes, como ser logicamente impossível, se tratar de uma categoria de armazenamento diferente, etc. Porém, a questão lhe pede, por exemplo, que escolha a que obtenha o &lt;em&gt;menor custo&lt;/em&gt; ou a &lt;em&gt;maior disponibilidade global&lt;/em&gt;, por exemplo.&lt;/p&gt;

&lt;p&gt;E é necessário ter algum conhecimento &lt;em&gt;prático&lt;/em&gt;. Acredito sim que podem existir várias pessoas que estudam sem esse viés e passam com sucesso. Mas eu diria, se concentre em &lt;em&gt;habilidades&lt;/em&gt; e não &lt;em&gt;certificações&lt;/em&gt;. É bem comum ver 4x AWS... 10x AWS... 100x AWS... Mas nesse caso já se torna um jogo de números. Obviamente não tiro o mérito de nenhum, pelo contrário, devem exibir com orgulho, mas para quem está começando, não se concentre nisso. Se concentre em construir habilidades, não apenas o suficiente para passar em um exame. Não existe algoritmo de compressão para experiência.&lt;/p&gt;

&lt;p&gt;Para as empresas, é claro, você vai ser uma pessoa valorizada. No livro &lt;a href="https://amzn.to/3reoXev"&gt;Reaching Cloud Velocity: _ A Leader's Guide to Success in the AWS Cloud_&lt;/a&gt; é citado que com a experiência de diversos clientes — além de estudos como &lt;a href="https://arxiv.org/abs/1102.3931"&gt;Social consensus through the influence of committed minorities&lt;/a&gt;; fica clara a necessidade de atingir uma massa crítica de &lt;em&gt;10%&lt;/em&gt; de pessoas advogando uma plataforma antes dos efeitos de rede tomarem efeito. Ou seja, investir no aprendizado e certificação das pessoas na organização, tem efeitos internos de aceleração, um aumento da qualidade de entregas, torna a empresa mais atrativa e motiva outros da equipe a buscarem suas certificações também.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caso de estudo: Minha própria jornada
&lt;/h3&gt;

&lt;p&gt;Na empresa em que retirei minha primeira certificação e a segunda, eu não tinha nenhum &lt;em&gt;incentivo&lt;/em&gt; para retirar uma certificação. Eu paguei do meu próprio bolso (depois me pediram para avisar nesses casos, mas não me importava). Para mim foi um &lt;em&gt;investimento&lt;/em&gt;. &lt;em&gt;Ah, estava querendo tirar a certificação e trocar de emprego?&lt;/em&gt;. Pelo contrário. Eu estava no que eu chamo de &lt;em&gt;solidão técnica&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Você é a pessoa responsável por uma área, digamos arquitetura. Não tem pares para validar suas decisões, as documentações que está fazendo e muitas vezes, você é a última linha de defesa entre a empresa e o mundo externo, tendo que implementar segurança, a um custo baixo (geralmente solidão técnica existe em empresas de pequeno a médio porte). &lt;/p&gt;

&lt;p&gt;Meu time estava crescendo. Eu não disse a ninguém que estava me preparando. Eu queria dar mais segurança para a gestão da minha organização, para o meu time e, talvez mais ainda, para mim mesmo. &lt;em&gt;Síndrome de impostores&lt;/em&gt; já virou assunto carimbado. É o fantasma percorrendo as entrelinhas de meus textos e códigos. Não tive formação em ciência da computação ou engenharia.&lt;/p&gt;

&lt;p&gt;Comecei com o AWS Certified Cloud Practitioner e então o Architect Associate e agora, recentemente, o Professional. Saí da organização que estava recentemente e ainda que a que eu esteja no momento estimule e &lt;em&gt;pague&lt;/em&gt; por certificações, eu ainda fiz este exame com um voucher que recebi por ser parte do programa AWS Community Builder e fiz, novamente para ancorar meus conhecimentos e habilidades.&lt;/p&gt;

&lt;p&gt;E estudar para os exames me fez descobrir tanta coisa e tantas possibilidades. Eu sou um profissional diferente desde a primeira certificação. É um acelerador pessoal e profissional. Esta é a forma como a certificação me ajudou. &lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Por onde devo começar?
&lt;/h3&gt;

&lt;p&gt;Criando uma conta, fazendo experimentos. Verifique &lt;a href="https://aws.amazon.com/pt/certification/"&gt;o que é esperado em cada exame&lt;/a&gt;. Existem cursos preparatórios da própria AWS. Existem simulados. Há muitos cursos pagos, e outros, inteiramente gratuitos, em plataformas como o YouTube. Não posso fazer uma ampla revisão dos recursos disponíveis pois, obviamente, eu não fiz todos o suficiente para ter uma opinião formada. Mas, tendo realizado cursos no Udemy e um pago, percebi que a relação custo-benefício do curso pago foi muito maior. Inclusive para o trabalho no dia a dia.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DU6B4b96--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2cdt29sye5eopay9qf44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DU6B4b96--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2cdt29sye5eopay9qf44.png" alt="Certificados AWS" width="880" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tem dúvidas, pouca experiência prática com a nuvem? &lt;a href="https://aws.amazon.com/pt/certification/certified-cloud-practitioner/"&gt;AWS Certified Cloud Practitioner&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Qual caminho devo seguir?
&lt;/h3&gt;

&lt;p&gt;Não há nenhuma obrigatoriedade de progressão na AWS. Você não precisa ter um certificado &lt;em&gt;Associate&lt;/em&gt; para fazer a prova &lt;em&gt;Professional&lt;/em&gt;. Se acredita possuir as habilidades e conhecimentos necessários para qualquer certificação, basta escolher. &lt;/p&gt;

&lt;p&gt;Por isso, existem muitos caminhos necessários. Sou AWS Community Builder e vou compartilhar o caminho que vejo ser bem comum: realizar dois ou todos os &lt;em&gt;Associate&lt;/em&gt; antes do &lt;em&gt;AWS Solutions Architecture Professional&lt;/em&gt;, pois a quantidade de serviços que é necessário o conhecimento é enorme. &lt;/p&gt;

&lt;p&gt;Embora o &lt;em&gt;AWS DevOps Engineer Professional&lt;/em&gt; seja igualmente uma tarefa de esforço, ele é limitado a um domínio, o que para os especializados, se torna mais confortável lidar com a carga cognitiva de dezenas, realisticamente, centenas de serviços e recursos que serão exigidos seu conhecimento, ainda que com menos profundidade, mas entendendo seus trade-offs frente a determinadas necessidades. &lt;/p&gt;

&lt;p&gt;Não foi o caminho que tomei como escrevi acima. Avalie seu momento e contexto.&lt;/p&gt;

&lt;h3&gt;
  
  
  É muito caro! Não poderia ser mais barato?
&lt;/h3&gt;

&lt;p&gt;Sim. Para a imensa maioria dos brasileiros o custo de uma certificação é proibitivo. Ainda que determinadas posições sejam associadas com maior poder aquisitivo, mesmo uma certificação de entrada custa &lt;strong&gt;100&lt;/strong&gt; doláres. &lt;/p&gt;

&lt;p&gt;E sim, acredito que poderia existir uma forma de &lt;a href="https://www.investopedia.com/updates/purchasing-power-parity-ppp/"&gt;Purchasing power parity (PPP)&lt;/a&gt;, ou paridade de poder de compra. Somente foi através de PPP que pude adquirir alguns cursos importantes.&lt;/p&gt;

&lt;p&gt;Deveria ser gratuito? Regularmente, a AWS e outras clouds realizam programas para certificação e oferecem algumas de forma totalmente gratuita. Não existem dados oficiais, mas a taxa de uso efetivo desses descontos &lt;em&gt;parece ser baixa&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Certificações expiram. Não se trata de mais uma forma dessas empresas ganharem dinheiro?
&lt;/h3&gt;

&lt;p&gt;Em 2020, o &lt;a href="https://aws.amazon.com/pt/blogs/aws/amazon-s3-update-strong-read-after-write-consistency/"&gt;AWS Simple Storage Service (S3) passou a ter consistência forte na leitura após escrita&lt;/a&gt;, sendo que era até aquele momento, &lt;em&gt;eventual&lt;/em&gt;. O que é uma consideração muito importante e crítica, dependendo do seu tipo de uso. &lt;/p&gt;

&lt;p&gt;As tecnologias mudam. Alguém certificado em 2015 encontra hoje um contexto de tecnologias extremamente diferente. Uma certificação não se foca em fornecer meta-habilidades ou grandes teorias que poderá aplicar a diferentes tecnologias e recursos como uma formação acadêmica ou curso, por exemplo. Ela foca em demonstrar capacidade de reconhecer as melhores soluções baseadas em casos particulares de uso com determinados objetivos a partir das tecnologias existentes. É um &lt;em&gt;exame prático&lt;/em&gt;. Assim como direção, exige uma constante qualificação.&lt;/p&gt;

&lt;h3&gt;
  
  
  Preciso saber inglês?
&lt;/h3&gt;

&lt;p&gt;Sim e não. No momento, a maioria das certificações &lt;em&gt;Associate&lt;/em&gt; além da &lt;em&gt;Fundamental&lt;/em&gt; oferecem versões em português brasileiro. No nível &lt;em&gt;Professional&lt;/em&gt; apenas em inglês. Mas eu recomendo, fortemente, se possível que &lt;em&gt;você faça em inglês&lt;/em&gt;. Nossa atuação seja utilizando com SDKs, CLIs ou mesmo lendo documentações de arquitetura passarão pelo contato com os termos em inglês.&lt;/p&gt;

&lt;p&gt;Os primitivos da nuvem são como os primitivos das linguagens, de sua sintaxe. E estes são em inglês, &lt;em&gt;if&lt;/em&gt;, &lt;em&gt;else&lt;/em&gt;, &lt;em&gt;then&lt;/em&gt;, entre outros. Já fiz alguns cursos disponíveis no &lt;a href="https://explore.skillbuilder.aws/"&gt;AWS Skill Builder&lt;/a&gt; e &lt;em&gt;falhei&lt;/em&gt; em identificar as opções corretas em perguntas que acreditei que acertaria, pois o termo em português não me pareceu satisfatório para a solução. Existem falsos cognatos, entre outros fatores.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;E sim, menos de 5% da população brasileira sabe inglês em qualquer nível. Eu mesmo, tive uma curva de aprendizado bem íngreme. Tenho, em 2022, &lt;em&gt;36 anos&lt;/em&gt;, sempre estudei em escola pública, onde o inglês, &lt;em&gt;quando ensinado&lt;/em&gt;, parecia um eterno &lt;em&gt;loop&lt;/em&gt; do verbo &lt;em&gt;to be&lt;/em&gt;, ao menos em minha época de estudante. Mesmo o acesso a computadores é &lt;em&gt;limitado&lt;/em&gt;. Eu &lt;em&gt;usei&lt;/em&gt; um computador aos 18 anos. A "sala dos computadores" era um local mítico e sagrado em nossa escola, que ninguém entrava. Lembro de irmos uma vez e em trios, sentarmos na frente do computador e sermos &lt;a href="https://en.wikipedia.org/wiki/Office_Assistant"&gt;apresentados ao Clippy, do Windows&lt;/a&gt;. E eu não estou fazendo piada.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Se você deve saber inglês, &lt;em&gt;minha&lt;/em&gt; resposta é &lt;strong&gt;sim, deveria&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  O que acontece se eu não passar no exame?
&lt;/h3&gt;

&lt;p&gt;Você precisa esperar 14 dias para poder agendar outro exame. Para agendar este novo exame, você deverá &lt;strong&gt;adquirir&lt;/strong&gt; novamente. &lt;/p&gt;

&lt;p&gt;Dúvidas? Ponderações? Deixe nos comentários e podemos debater!&lt;/p&gt;

&lt;p&gt;As &lt;em&gt;badges&lt;/em&gt; acabaram de serem repaginadas, então, aproveitem para estudar e já receber uma badge bem mais bonita como esta 😀:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.credly.com/badges/d01a5f09-39af-4848-91e4-fd93c379429b/public_url"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4e1cEubn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/omg116dmr1twkif2k0mt.png" alt="AWS Badge Professional" width="300" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Revisão: Rafael B. Pires&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;Imagem de destaque por &lt;a href="https://unsplash.com/@thisisengineering?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;ThisisEngineering RAEng&lt;/a&gt; em &lt;a href="https://unsplash.com/s/photos/coding?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>portuguese</category>
      <category>certifications</category>
      <category>career</category>
    </item>
    <item>
      <title>Top 5 technology books I read in 2021</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Thu, 30 Dec 2021 21:06:15 +0000</pubDate>
      <link>https://forem.com/ibrahimcesar/top-5-technology-books-i-read-in-2021-4b3l</link>
      <guid>https://forem.com/ibrahimcesar/top-5-technology-books-i-read-in-2021-4b3l</guid>
      <description>&lt;p&gt;My top five picks on technological / technical books I read in 2021 and some honorable mentions. I also read some fiction and non-fiction, in fact I finished a great science fiction series, &lt;em&gt;Remembrance of Earth’s Past&lt;/em&gt; made up of three books: &lt;em&gt;The Three-Body Problem&lt;/em&gt;, &lt;em&gt;The Dark Forest&lt;/em&gt; and &lt;em&gt;Death’s End&lt;/em&gt; by the Chinese author Liu Cixin, which is one of greatest science fiction series I ever read (I’m a big fan of Russian literature and science fiction). But for this list I picked the top tech-related ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Your Computer Is On Fire
&lt;/h2&gt;

&lt;p&gt;Edited by Thomas S. Mullaney, Benjamin Peters, Mar Hicks and Kavita Philip&lt;/p&gt;

&lt;p&gt;This book is a collection of powerful essays from a great number of authors: Janet Abbate, Ben Allen, Paul N. Edwards, Nathan Ensmenger, Mar Hicks, Halcyon M. Lawrence, Thomas S. Mullaney, Safiya Umoja Noble, Benjamin Peters, Kavita Philip, Sarah T. Roberts, Sreela Sarkar, Corinna Schlombs, Andrea Stanton, Mitali Thakor, and Noah Wardrip-Fruin. Technology doesn’t happen in a vacuum. Much is talk about how "tech will change the world", "create experiences". Well, this &lt;strong&gt;is&lt;/strong&gt; intrinsically political. Is about we live, share, trade and connect. Nothing more political than that.&lt;/p&gt;

&lt;p&gt;I would never say judge an essay by its titles, but only take a glance at the titles could give a hint and take your attention. And yes, the essays here are great and direct to the point as the titles make clear. And if you work with technology, I urge you to give this book a chance.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Part I: Nothing Is Virtual

&lt;ul&gt;
&lt;li&gt;The Cloud Is A Factory&lt;/li&gt;
&lt;li&gt;Your AI Is A Human&lt;/li&gt;
&lt;li&gt;A Network Is Not A Network&lt;/li&gt;
&lt;li&gt;The Internet Will Be Decolonized&lt;/li&gt;
&lt;li&gt;Capture Is Pleasure&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Part II: This Is An Emergency

&lt;ul&gt;
&lt;li&gt;Sexism Is A Feature, Not A Bug&lt;/li&gt;
&lt;li&gt;Gender Is A Corporate Tool&lt;/li&gt;
&lt;li&gt;Siri Disciplines&lt;/li&gt;
&lt;li&gt;Your Robot Isn't Neutral&lt;/li&gt;
&lt;li&gt;Broken Is Word&lt;/li&gt;
&lt;li&gt;You Can't Make Games About Much&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Part III: Where Will The Fire Spread?

&lt;ul&gt;
&lt;li&gt;Code Is Not Empowerment&lt;/li&gt;
&lt;li&gt;Source Code Isn't&lt;/li&gt;
&lt;li&gt;Skills Will Not Set You Free&lt;/li&gt;
&lt;li&gt;Platforms Are Infrastructures On Fire&lt;/li&gt;
&lt;li&gt;Typing Is Dead&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;In times like theses in which tech is under (the much needed) public scrutiny, is important to broader our view of technology as "technical-only" and understand the tangled web of political, social and power dynamics in place.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Sooner Safer Happier
&lt;/h2&gt;

&lt;p&gt;One review title on Amazon says &lt;strong&gt;Most honest book I have read in last 4 years&lt;/strong&gt;. I agree. Because it speaks against the so-called &lt;a href="https://martinfowler.com/articles/agile-aus-2018.html" rel="noopener noreferrer"&gt;&lt;em&gt;Agile Industrial Complex&lt;/em&gt;&lt;/a&gt; that broke agile, or well, Agile™. I already &lt;a href="https://ibrahimcesar.cloud/blog/sooner-safer-happier-antipatterns-and-patterns-for-business-by-jonathan-smart/" rel="noopener noreferrer"&gt;wrote about this book earlier this year&lt;/a&gt; and even made a whole talk around it, which I called &lt;a href="https://dev.toblog/peopleops-integracao-continua-do-time-entrega-continua-de-valor/"&gt;PeopleOps&lt;/a&gt; (content in pt-br) and made a mix with another great book, &lt;strong&gt;Team Topologies&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Is a much needed look at Agile landscape that spoke a lot with me and how I see the landscape.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Cloud Native Patterns
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://amzn.to/349UqG9" rel="noopener noreferrer"&gt;&lt;strong&gt;Cloud Native Patterns&lt;/strong&gt;: Designing change-tolerant software&lt;/a&gt; by Cornelia Davis is a brilliant book. The historical perspective the author gives us helps build our mental models and see the patterns that we are so deep that we even realize are constructions. Like the "request/response" model that permeates much of our development and the move to more reactive systems like the &lt;a href="https://ibrahimcesar.cloud/blog/event-driven-architectures/" rel="noopener noreferrer"&gt;Event Driven Architectures&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is a &lt;strong&gt;must read&lt;/strong&gt; for everyone in the Cloud field. The patterns covered are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event-driven microservices&lt;/li&gt;
&lt;li&gt;App redundancy&lt;/li&gt;
&lt;li&gt;Application configuration&lt;/li&gt;
&lt;li&gt;The application lifecycle&lt;/li&gt;
&lt;li&gt;Accessing apps&lt;/li&gt;
&lt;li&gt;Interaction redundancy&lt;/li&gt;
&lt;li&gt;Fronting services&lt;/li&gt;
&lt;li&gt;Troubleshooting&lt;/li&gt;
&lt;li&gt;Cloud-native data&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. The CDK Book
&lt;/h2&gt;

&lt;p&gt;In the 2021 I developed &lt;strong&gt;a lot&lt;/strong&gt; with AWS CDK. In fact, I started nothing on AWS without using it. Is a powerful tool.&lt;/p&gt;

&lt;p&gt;I made talks about CDK at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ibrahimcesar/devops-extreme" rel="noopener noreferrer"&gt;DevOps Extreme&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ibrahimcesar.cloud/talks/2021-10-21-BrazilJSConf-2021/" rel="noopener noreferrer"&gt;BrazilJS&lt;/a&gt;, &lt;em&gt;the self proclaimed biggest JavaScript conference in the World&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=9Gk_7qTkNgs" rel="noopener noreferrer"&gt;AWS Community Day — Brazil&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;And another session on &lt;a href="https://ibrahimcesar.cloud/talks/2021-11-30-TDC-Future/" rel="noopener noreferrer"&gt;TDC Future&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And 2021 was an exceptional year for CDK with a &lt;a href="https://www.youtube.com/watch?v=mwp51yqxmtU" rel="noopener noreferrer"&gt;great spotlight in the work by Matt Coulter&lt;/a&gt; and off course, the launch of CDK v2, which comes with some significant improvements. No more problems with versioning and a model better to understand. The CDK Book &lt;strong&gt;is&lt;/strong&gt; &lt;a href="https://www.dynamodbbook.com/" rel="noopener noreferrer"&gt;The DynamoDB Book&lt;/a&gt; this developer tool deserved.&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://twitter.com/mattbonig" rel="noopener noreferrer"&gt;Matthew Bonig&lt;/a&gt;, &lt;a href="https://twitter.com/hoegertn" rel="noopener noreferrer"&gt;Thorsten Höger&lt;/a&gt;, &lt;a href="https://twitter.com/sathyabhat" rel="noopener noreferrer"&gt;Sathyajith Bhat&lt;/a&gt; and &lt;a href="https://twitter.com/nideveloper" rel="noopener noreferrer"&gt;Matt Coulter&lt;/a&gt;, &lt;a href="https://thecdkbook.com/" rel="noopener noreferrer"&gt;The CDK Book&lt;/a&gt; is a comprehensive guide that will give you access to provision and handle the plethora of AWS services.&lt;/p&gt;

&lt;p&gt;Written by &lt;a href="https://twitter.com/mattbonig" rel="noopener noreferrer"&gt;Matthew Bonig&lt;/a&gt;, &lt;a href="https://twitter.com/hoegertn" rel="noopener noreferrer"&gt;Thorsten Höger&lt;/a&gt;, &lt;a href="https://twitter.com/sathyabhat" rel="noopener noreferrer"&gt;Sathyajitha Bhat&lt;/a&gt; and &lt;a href="https://twitter.com/nideveloper" rel="noopener noreferrer"&gt;Matt Coulter&lt;/a&gt;, &lt;a href="https://thecdkbook.com/" rel="noopener noreferrer"&gt;The CDK Book&lt;/a&gt; is an comprehensive guide that will give you access to provision and handle the plethora of AWS services.&lt;/p&gt;

&lt;p&gt;This year I even contributed with code for CDK!&lt;/p&gt;

&lt;h3&gt;
  
  
  Honorable mentions 📚
&lt;/h3&gt;

&lt;p&gt;This was a year I had a deep dive in DDD — Domain Driven Design, so my honorable mentions is all about DDD:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://amzn.to/3mM5r74" rel="noopener noreferrer"&gt;Domain-Driven Design:Tackling Complexity in the Heart of Software&lt;/a&gt;, the "blue book" by Eric Evans, who "started thee fire". I also read before, but now after some years working with architecture in mind I come with fresh eyes and a much broader understanding than before.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://amzn.to/3eDa4f8" rel="noopener noreferrer"&gt;Learning Domain-Driven Design: Aligning Software Architecture and Business Strategy&lt;/a&gt;, this book didn’t make the cut on my top 5 because I didn’t finish yet. I’m in about the middle and loving it. I think the author, Vlad Khononov, makes a great work of "organize" the content around DDD and gives new insights.&lt;/li&gt;
&lt;li&gt;
&lt;a href=""&gt;Implementing Domain-Driven Design&lt;/a&gt;,also by Vaughn Vernon takes you far beyond "DDD-lite" approaches that embrace DDD solely as a technical toolset, and shows you how to fully leverage DDD’s "strategic design patterns" using Bounded Context, Context Maps, and the Ubiquitous Language. Is not as solid as Khononov’s book, but the breakdown could help a lot make more sense of the mind map DDD gives us to tackle complexity.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://amzn.to/33ZPOlK" rel="noopener noreferrer"&gt;Domain-Driven Design Distilled&lt;/a&gt; by Vaughn Vernon aims to be a concise, readable, and actionable book on DDD. "Distilled" is a term used even in Evan’s book and sometimes this book looks like a "DDD-lite" guide, but I think it serves as a good introduction&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://no-bs-ts.myshopify.com/" rel="noopener noreferrer"&gt;No BS TS&lt;/a&gt; book covers every single video in the popular &lt;a href="https://www.youtube.com/playlist?list=PLNqp92_EXZBJYFrpEzdO2EapvU0GOJ09n" rel="noopener noreferrer"&gt;No BS TS video series&lt;/a&gt; by Jack Herrington. Everything from basic types to generics, using Typescript with React and into Design Patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9dl2euo8ppmi5npv37w1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9dl2euo8ppmi5npv37w1.png" alt="Crafting Interpreters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Crafting Interpreters
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Ever wanted to make your own programming language or wondered how they are designed and built?&lt;br&gt;
If so, this book is for you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://craftinginterpreters.com/" rel="noopener noreferrer"&gt;Crafting Interpreters&lt;/a&gt; by &lt;a href="https://twitter.com/munificentbob" rel="noopener noreferrer"&gt;Robert Nystrom&lt;/a&gt; will be one of my favorite technical books. It gives the same sense of wonder and craft that I felt reading &lt;a href="https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-1.html" rel="noopener noreferrer"&gt;Structure and Interpretation of Computer Programs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As we move in creating the &lt;a href="https://github.com/topics/lox-language" rel="noopener noreferrer"&gt;Lox language&lt;/a&gt; the author gives some historical background, trade-offs and every meaningful step. Even if you are interested in creating your own language, you will learn a ton by reading this book. You will be a better developer.&lt;/p&gt;

&lt;p&gt;The author is kind enough to let everyone &lt;a href="https://craftinginterpreters.com/contents.html" rel="noopener noreferrer"&gt;read for free the web version&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>books</category>
      <category>programming</category>
      <category>architecture</category>
      <category>discuss</category>
    </item>
    <item>
      <title>SAFe™ Considered Harmful</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Sun, 17 Oct 2021 13:50:44 +0000</pubDate>
      <link>https://forem.com/ibrahimcesar/safe-considered-harmful-214</link>
      <guid>https://forem.com/ibrahimcesar/safe-considered-harmful-214</guid>
      <description>&lt;p&gt;Is safe to say, the framework SAFe™ embodies everything wrong with the so-called &lt;em&gt;Agile Industrial Complex&lt;/em&gt;. Is so bloated and focus on the wrong things that are not even remotely &lt;em&gt;agile&lt;/em&gt; in the sense of the original manifesto. I’ll argue how SAFe™ do more harm to the community than generates value and is devoid of any &lt;em&gt;agility&lt;/em&gt;. Pay for your training, get your certificate, some taps on the back and... &lt;em&gt;whatever&lt;/em&gt;. SAFe™ is so bad that makes the case for &lt;em&gt;Waterfall looks like a good idea&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--92LPkkCO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrbdd2feuf38mkjmwlpc.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--92LPkkCO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jrbdd2feuf38mkjmwlpc.jpeg" alt="Meme" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don’t know who needs to hear this, but is safe to say: &lt;em&gt;SAFe™ is not agile&lt;/em&gt;. &lt;a href="https://jeffgothelf.com/blog/safe-is-not-agile/"&gt;Jeff Gothelf made a post&lt;/a&gt; with exactly this title in May 2021. Since they shove up Lean UX in version 4.5 of the framework, people keep asking Gothelf about how both work together. But the “adoption” of Lean UX was more of “let’s add a couple &lt;em&gt;buzzwords more&lt;/em&gt;” with no regard to principles, methodologies or alignments. Gothelf is the author of &lt;a href="https://amzn.to/3rzz1O1"&gt;Lean UX&lt;/a&gt;, and about how works within SAFe™ this is his position:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The slightly longer answer is that all the principles we’ve built into Lean UX don’t seem to exist in SAFe.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--JA0S7LtI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/786484791365468164/9l5BKx0F_normal.jpg" alt="Ewan Leith profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Ewan Leith
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/ewantoo"&gt;@ewantoo&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      There's quite a lot of anti-Agile sentiment in software development circles at the moment. I think we've reached the point where a critical mass of developers have never experienced how terrible "Waterfall" was as a planning methodology, and think it sounds like a good plan🤦‍♂️
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      08:00 AM - 18 Jun 2021
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1405797522652729345" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1405797522652729345" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1405797522652729345" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;Is less “anti-Agile sentiment” and more “anti-Agile Practices™️”. SAFe™ is this Cthulhuian Azathoth-like cosmic horror framework that is driven the bad rep and the harm is doing to the development environment. This isn’t some kind of ‘homebrew’ agile we see selling — SAFe™ is straightforward a &lt;em&gt;vapor agile framework to sell certifications&lt;/em&gt;. ToughtWorks place in their &lt;strong&gt;hold&lt;/strong&gt; category, the &lt;em&gt;Proceed with caution&lt;/em&gt;, which is a polite way to say &lt;em&gt;Run&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Our positioning regarding "being agile before doing agile" and our opinions around this topic shouldn't come as a surprise; but since &lt;a href="http://www.scaledagileframework.com/"&gt;SAFe™&lt;/a&gt; (Scaled Agile Framework®), per Gartner’s May 2019 &lt;a href="http://go.scaledagile.com/Gartner-a.html"&gt;report&lt;/a&gt;, is the most considered and most used enterprise agile framework, and since we're seeing more and more enterprises going through organizational changes, we thought it was time to raise awareness on this topic again. We've come across organizations struggling with SAFe's over-standardized, phase-gated processes. Those processes create friction in the organizational structure and its operating model. It can also promote silos in the organization, preventing platforms from becoming real business capabilities enablers. The top-down control generates waste in the value stream and discourages engineering talent creativity, while limiting autonomy and experimentation in the teams. Rather than measuring effort and focusing on standardized ceremonies, we recommend a leaner, value-driven approach and governance to help eliminate organizational friction such as &lt;a href="https://www.thoughtworks.com/books/edge"&gt;EDGE&lt;/a&gt;, as well as a &lt;a href="https://www.thoughtworks.com/radar/techniques/team-cognitive-load"&gt;team cognitive load&lt;/a&gt; assessment to identify types of teams and determine how they should better interact with each other.&lt;br&gt;
&lt;a href="https://www.thoughtworks.com/radar/techniques?blipid=793"&gt;ToughtWorks Radar 24 Hold technique: SAFe™&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Agily McAgileface
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p1AWTUk4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ef4d5uwp7rwsetvxeqz0.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p1AWTUk4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ef4d5uwp7rwsetvxeqz0.jpeg" alt="Slide" width="880" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This could be a map for SAFe™ but no, is just a slide that was actually used in a briefing to the commanding general of U.S. forces in Afghanistan, Stanley McChrystal.  It purported to explain U.S. counterinsurgency strategy in Afghanistan, all on one slide.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first time I saw this as “agile” on Twitter I laugh. I thought it was just satire. This is &lt;em&gt;actual&lt;/em&gt; SAFe™ map. Find the errors:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TmXa4Rgg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qusid4twiwsvqpa3i24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TmXa4Rgg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8qusid4twiwsvqpa3i24.png" alt="SAFe Map" width="880" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is called "SAFe 5 for Lean Enterprises".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Other ways SAFe™ harmful? It violates the &lt;a href="https://agilemanifesto.org/"&gt;very first agile value&lt;/a&gt;: “Individuals and interactions over processes and tools”, being an upside-down version of it and is a truly industry (“used by 1,000,000 people in 20,000 organizations around the globe”! So much suffering in the world... gives me a &lt;em&gt;broken heart&lt;/em&gt;) of a bloated framework that makes not only Waterfall looks like a good idea but is bad for the lean, agile and DevOps thinking and practices.&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--d-BAHF_O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1042085119505227777/l3Xhlcse_normal.jpg" alt="Allen Holub profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        Allen Holub
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        @allenholub
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Just curios, but has anybody seen an article endorsing SAFe written by someone who (1) actually understands and has worked in an agile environment (so no non-programmer journalists), and (2) doesn’t profit by selling SAFe training, consulting, books, &amp;amp;c.?
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      19:27 PM - 21 Jul 2021
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1417929178540769282" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1417929178540769282" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1417929178540769282" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;





&lt;p&gt;Scaled Agile Framework® and SAFe™ are trademarks of Scaled Agile, Inc. When I just copied the title of their map, just "SAFe 5 for Lean Enterprises", of course they inject some text on my clipboard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;© Scaled Agile, Inc.
Include this copyright notice with the copied content.

Read the FAQs on how to use SAFe content and trademarks here:
https://www.scaledagile.com/about/about-us/permissions-faq/
Explore Training at:
https://www.scaledagile.com/training/calendar/"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Further reading:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tPzxRMjD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f03463252coxtip21fn1.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tPzxRMjD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f03463252coxtip21fn1.jpeg" alt="Scale" width="600" height="788"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>agile</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Event-Driven Architectures on AWS</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Sun, 12 Sep 2021 01:27:05 +0000</pubDate>
      <link>https://forem.com/aws-builders/event-driven-architectures-on-aws-4463</link>
      <guid>https://forem.com/aws-builders/event-driven-architectures-on-aws-4463</guid>
      <description>&lt;p&gt;In September 2021, Corey Quinn, Chief Cloud Economist at The Duckbill Group published &lt;a href="https://www.lastweekinaws.com/blog/the-key-to-unlock-the-aws-billing-puzzle-is-architecture/"&gt;The Key to Unlock the AWS Billing Puzzle is Architecture&lt;/a&gt; and I identified myself a lot with some of his remarks. One, sometimes downplayed is the notion &lt;strong&gt;cost is architecture&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For example, if you didn’t use SQS when building your application because it couldn’t handle your throughput needs or it was too expensive, &lt;a href="https://twitter.com/zackkanter/status/1399698492981981187"&gt;that changed a couple of weeks ago&lt;/a&gt;. SQS is to the point where it’s now effectively unlimited throughput at a cost that’s just 3.6% of what it was at launch.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the 3.6% was because of a typo by Zack Kanter. In fact, the price drop is 99.4% from 2006. Which makes it cost only 0.6% of what was. You will pay less than 1% it was years ago!&lt;/p&gt;

&lt;h2&gt;
  
  
  Loosing our couplings
&lt;/h2&gt;

&lt;p&gt;There’s general advice that is very well known in modern software architecture, at leat in the web or distribute space that advocates for &lt;a href="https://en.wikipedia.org/wiki/Loose_coupling"&gt;&lt;strong&gt;loose coupling&lt;/strong&gt;&lt;/a&gt;. And sure, is a noble goal but there are several kinds of coupling such as &lt;strong&gt;Temporal coupling&lt;/strong&gt; when we deal wit time-based dependencies such as collaborating system components, sequential operations or operations that needs another to complete such a request or another operation. We have &lt;strong&gt;Spatial coupling&lt;/strong&gt; such as not having to know where your collaborating applications are in the network and providing fail-over mechanisms such as Load Balancers, pub/subs, and other. And of course, this comes a lot even more on the serverless space than any other in the Cloud: &lt;strong&gt;Platform coupling&lt;/strong&gt;. Have proprietary protocols and components from a vendor or platform.&lt;/p&gt;

&lt;p&gt;But as pointed, coupling is a function of multiple dimensions, not just binary options like “tight” or “loose”. We are always. &lt;em&gt;Always&lt;/em&gt; working with trade-offs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The event-driven architecture style is a popular distributed asynchronous architecture style used to produce highly scalable and high-performance applications. It is also highly adaptable and can be used for small applications and as well as large, complex ones. Event-driven architecture is made up of decoupled event processing components that asynchronously receive and process events. It can be used as a standalone architecture style or embedded within other architecture styles (such as an event-driven microservices architecture).”&lt;br&gt;
&lt;a href="https://amzn.to/3hqkSPp"&gt;Fundamentals of Software Architecture&lt;/a&gt;, &lt;em&gt;Mark Richards and Neal Ford&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Following the inspiration from &lt;a href="https://www.amazon.com.br/Domain-Driven-Design-Tackling-Complexity-Software-ebook/dp/B00794TAUG?__mk_pt_BR=%C3%85M%C3%85%C5%BD%C3%95%C3%91&amp;amp;crid=HP4DWEA18R3U&amp;amp;dchild=1&amp;amp;keywords=domain+driven+design&amp;amp;qid=1631406769&amp;amp;sprefix=domain+d%2Caps%2C282&amp;amp;sr=8-2&amp;amp;ufe=app_do%3Aamzn1.fos.25548f35-0de7-44b3-b28e-0f56f3f96147&amp;amp;linkCode=sl1&amp;amp;tag=ibrahimcesar-20&amp;amp;linkId=8f2436253039b1df488c9443273ba4de&amp;amp;language=pt_BR&amp;amp;ref_=as_li_ss_tl"&gt;Domain-Driven Design: Tackling Complexity in the Heart of Software&lt;/a&gt; by Eric Evans and later, &lt;a href="https://amzn.to/3l9pIBO"&gt;Domain-Driven Design Distilled&lt;/a&gt; and &lt;a href="https://amzn.to/2XgM8ZY"&gt;Implementing Domain-Driven Design&lt;/a&gt; by Vaughn Vernon one of way to model and work with software involves deal with bounded contexts we can map and create services, applications and systems to better tackle our problems. And to integrate all of this, one pattern is &lt;strong&gt;Domain Events&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Event becomes the primary mechanism for sharing information across bounded context integrations about change in state. Domains events are immutable, self-describing. Events give the data they carry meaning by supplying business context. Not data transfer objects or change data captures. These are state / state change representations that are not reflective of a system's behaviour.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An event is a &lt;em&gt;quanta&lt;/em&gt;, a unit that describes something in the system. Could be a simple JSON as that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eventId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;61452&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OrderPlaced"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2021-10-07"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, with this event, different domains could decide to act or not in the event. Maybe we have an Inventory domain, a Package domain, a service that will email the user about the order and each one will handle the event as seem fit, and we could add and apply as many services and applications needed. We will publish all these events to “Bus”, which in the AWS is via &lt;a href="https://aws.amazon.com/eventbridge/"&gt;Amazon EventBridge&lt;/a&gt;. As a CDK enthusiast, even to create your Infrastructure as Code &lt;a href="https://docs.aws.amazon.com/cdk/api/latest/docs/aws-events-readme.html"&gt;in a couple of lines of TypeScript&lt;/a&gt;.&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-cdk/core&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;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;stack&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;bus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;EventBus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bus&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="na"&gt;eventBusName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyCustomEventBus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;bus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;archive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyArchive&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="na"&gt;archiveName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyCustomEventBusArchive&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyCustomerEventBus Archive&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;eventPattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;account&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;retention&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;days&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;365&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;With the code above you could provision a custom event bus &lt;em&gt;and&lt;/em&gt; create an 365 archives of all events, that if needed, could be used to auditing or event &lt;em&gt;replay event as needed&lt;/em&gt;. And even in my example, let’s say the user wants to cancel the order, we will not delete the previous event. Different domains will need to process the new events in order to undo actions or make an analysis about how and why and so on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"eventId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;61456&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"event"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"OrderCancelled"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2021-10-07"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe another email will be sent, to confirm the cancel, Inventory Package will have to adjust their line of work and so on. And now maybe a CRM system you be fed to understand why the customer canceled after the conversion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coupling will always exist&lt;/strong&gt;. But we can orchestrate with such services and create highly responsive, available and robust architectures. And you can combine EventBridge with &lt;a href="https://aws.amazon.com/lambda/"&gt;Lambda&lt;/a&gt;, &lt;a href="https://aws.amazon.com/sns/"&gt;SNS&lt;/a&gt;, &lt;a href="https://aws.amazon.com/sqs/"&gt;SQS&lt;/a&gt;, &lt;a href="https://aws.amazon.com/step-functions/"&gt;Step Functions&lt;/a&gt; and soon you are dealing with systems that can scale up and down easily and if done correctly, try to optimize a lot your costs because some services and applications we have today sitting at some servers 24/7 sometimes &lt;strong&gt;just need to be active when a specific event happens&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Right now I’m in the middle of an event-driven creation and I really like the mental model and the developer experience as the organization experience and soon we used the “Ubiquitous Language” from DDD. And for this set of tools, none other Cloud seems so fit and solid as AWS does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Books to read
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://amzn.to/3AgY100"&gt;Building Event-Driven Microservices: Leveraging Organizational Data at Scale&lt;/a&gt; by Adam Bellemare. Brings much value with both architectural and application patterns to event-driven architecture.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://amzn.to/3EbrsmT"&gt;Architecture Patterns with Python: Enabling Test-Driven Development, Domain-Driven Design, and Event-Driven Microservices&lt;/a&gt; by Harry Percival and Bob Gregory. Python is not my primary language at work or even my preference, but I get so much from this book. Because is aiming at &lt;em&gt;patterns&lt;/em&gt; if you do not work with Python don’t let the title fool you. There’s a lot from here in this book!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Heroes to follow
&lt;/h2&gt;

&lt;p&gt;Yeah, they are actually &lt;em&gt;heroes&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ben Ellerby
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://twitter.com/EllerbyBen"&gt;@EllerbyBen&lt;/a&gt;&lt;br&gt;
For me one of his post, helped me a lot in my work and opened so many possibilities: &lt;a href="https://medium.com/serverless-transformation/eventbridge-storming-how-to-build-state-of-the-art-event-driven-serverless-architectures-e07270d4dee"&gt;EventBridge Storming — How to build state-of-the-art Event-Driven Serverless Architectures&lt;/a&gt;. &lt;a href="https://medium.com/@bene_37069"&gt;Blogs a lot about the concept of Serverless Transformation&lt;/a&gt;, a term I adopted too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sheen Brisals
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://twitter.com/sheenbrisals"&gt;@sheenbrisals&lt;/a&gt;&lt;br&gt;
Blog often at &lt;a href="https://sbrisals.medium.com/"&gt;Medium&lt;/a&gt;. Last post was &lt;a href="https://medium.com/lego-engineering/how-to-build-better-orchestrations-with-aws-step-functions-task-tokens-and-amazon-eventbridge-19a68eeda461"&gt;How To Build Better Orchestrations With AWS Step Functions, Task Tokens, And Amazon EventBridge!&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  AWS Event-Driven Tools
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/eventbridge/"&gt;Amazon EventBridge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/step-functions/"&gt;AWS Step Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/sns/"&gt;Amazon Simple Notification Service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/pt/event-driven-architecture/"&gt;AWS Event-Driven Primer: What is an Event-Driven Architecture?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>architecture</category>
      <category>eventdriven</category>
      <category>cdk</category>
    </item>
    <item>
      <title>The hidden bias in Core Web Vitals</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Thu, 02 Sep 2021 00:56:36 +0000</pubDate>
      <link>https://forem.com/ibrahimcesar/the-hidden-bias-in-core-web-vitals-2k64</link>
      <guid>https://forem.com/ibrahimcesar/the-hidden-bias-in-core-web-vitals-2k64</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Google's &lt;strong&gt;Core Web Vitals&lt;/strong&gt; has arrived. And as Google prides itself, has an &lt;a href="https://web.dev/vitals-business-impact/" rel="noopener noreferrer"&gt;huge business impact&lt;/a&gt;. The data is very well known that even small increases in performance, with a faster website your conversion rates grows. But the set, based on the top performers, has hidden bias embedded in it I want to talk about.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First, more context: the Core Web Vitals are a set of three metrics.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://web.dev/lcp/" rel="noopener noreferrer"&gt;Largest Contentful Paint (LCP)&lt;/a&gt;: measures loading performance. To provide a good user experience, LCP should occur within 2.5 seconds of when the page first starts loading.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://web.dev/lcp/" rel="noopener noreferrer"&gt;First Input Delay (FID)&lt;/a&gt;: measures interactivity. To provide a good user experience, pages should have a FID of 100 milliseconds or less.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://web.dev/cls/" rel="noopener noreferrer"&gt;Cumulative Layout Shift (CLS)&lt;/a&gt;: measures visual stability. To provide a good user experience, pages should maintain a CLS of 0.1. or less.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google does a great deal to &lt;a href="https://developers.google.com/speed/docs/insights/v5/about" rel="noopener noreferrer"&gt;share a lot of information&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvxa8ouv58nq800docv3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvxa8ouv58nq800docv3.png" alt="The Three Core Web Vitals"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Three Core Web Vitals&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this post I will not argue &lt;em&gt;against&lt;/em&gt; Web Core Vitals. I think is past due the time we take our user metrics, real user metrics (sometimes called by its acronym, RUM) in the center of everything we do. The "rise of user centric" metrics such as CLS (Cumulative Layout Shift) and other are remarkable feats and much needed. But I have some thoughts in the complexity that arise from it. I was lucky enough to attend in person the &lt;a href="https://www.youtube.com/watch?v=F1UP7wRCPH8" rel="noopener noreferrer"&gt;2019 Google Chrome Developer Summit&lt;/a&gt;&lt;sup id="fnref1"&gt;1&lt;/sup&gt;. It was the first time I saw presentations calling out developers to not only pay attention to their top devices — several of the talks the subject and reality of low end devices. It was amazing to see that. But I was thinking... "I'm working in Brazil for at least 10 years and all my references came from here, &lt;em&gt;this place&lt;/em&gt;, and now, &lt;strong&gt;2019&lt;/strong&gt;, they are talking about the most common scenario I face &lt;em&gt;everyday&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F54k4quku9ch6j49sbqhs.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F54k4quku9ch6j49sbqhs.jpeg" alt="Osmani"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1186647094221824001-302" src="https://platform.twitter.com/embed/Tweet.html?id=1186647094221824001"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1186647094221824001-302');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1186647094221824001&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;There’s a material side of web and computing in general&lt;sup id="fnref2"&gt;2&lt;/sup&gt;, that sometimes we think little about. Most of the time, we only take the bits and bytes as part of things. We literally wired together our continents with cables, physical cables, transporting data from one place to another. Even communicating with the computer in the other room takes times. There’s no such thing as instant communication, &lt;a href="https://arstechnica.com/tech-policy/2020/06/fcc-has-serious-doubts-that-spacex-can-deliver-latencies-under-100ms/" rel="noopener noreferrer"&gt;laws of physics continues to apply&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://web.dev/defining-core-web-vitals-thresholds/" rel="noopener noreferrer"&gt;Defining the Core Web Vitals metrics thresholds&lt;/a&gt; that aims to explore the research and methodology behind Core Web Vitals thresholds. Is stated:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Specifically, we aim to identify a threshold that is consistently achievable at the &lt;strong&gt;75th percentile for top performing sites&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;According to Ookla, a company specializing in internet speed testing, reported that the global average download speed on fixed broadband is 85.73 Mbps as of September 2020. The average mobile download speed is 35.96. As technology becomes more advanced and networks are improved, these numbers are expected to continue to grow.&lt;/p&gt;

&lt;p&gt;Based on data from Ookla, Singapore is the nation with the fastest broadband download speeds of 226.60 Mbps. Hong Kong follows this with 210.73 Mbps and Romania with 193.47 Mbps. The United States has the 10th-fastest internet download speeds of 161.14 Mbps.&lt;/p&gt;

&lt;p&gt;The countries with the fastest mobile internet speeds are different. The fastest mobile download speeds can be found in South Korea at 121.00 Mbps. China follows with 113.35 Mbps and the United Arab Emirates with 109.43 Mbps.&lt;/p&gt;

 &lt;a href="https://worldpopulationreview.com/country-rankings/internet-speeds-by-country" title="Internet Speeds By Country 2021" rel="noopener noreferrer"&gt;Internet Speeds By Country 2021&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;The top performing web sites I assume are against the global pool of sites. Mobile speed is not an issue with code itself, but there’s a &lt;strong&gt;material issue&lt;/strong&gt; with this "fair measurement". Because in the Global South we have historically less speed and very low end devices with a minority using top end devices. A site with 1MB payload will load much faster in a 5G connection and in a high end device than in a 3G connection (or sometimes worst as we have here in Brazil and I think I could apply to all great Global South) and low end devices that our audiences use. Using the same data, Brazil has an average of 67.86 in broadband speed and 28.36 in mobile speed. Orders of magnitude lesser than the top velocities. Low end devices also means that we cannot always use the latest improvement in browsers and web apis. We need to use polyfills and other tactics that can hurt even more our overall performance. When Douglas Crockford said that the browser was the most hostile development environment he was talking from some office in Silicon Valley, I wonder what he would say about developing for the wider range of low end devices we have around here.&lt;/p&gt;

&lt;p&gt;I asked a representative of Google on the subject. And asked if the realities in connection and devices would be take in account, the answer and I quote, since in the spirit of the &lt;a href="https://publishersonair.withgoogle.com/events/google-latam-search-webinar-portugues-espanol/watch?talk=google-latam-search-webinar-english" rel="noopener noreferrer"&gt;Honest Results Policy employed by Google in search, was in an open session&lt;/a&gt;, and you can check it out, around 1:05:00 was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm not aware of anything planned in that direction. Regarding on the website and what your audience makes it a bit easier or harder, but essentiality we want this Core Web Vital be as global as possible. In practice, if your users are in very slow connections then you must make sure your site is extra fast for them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F39wstzufip7adx0m5x7o.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F39wstzufip7adx0m5x7o.jpeg" alt="Red Queen"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Not only run, but run at least twice as fast! "Now, here, you see, it takes all the running you can do, to keep in the same place. If you want to get somewhere else, you must run at least twice as fast as that!" — Red Queen from Lewis Carroll's &lt;strong&gt;Through the Looking-Glass&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[...] We have three areas in Core Web Vital metrics ... one is poor, another needs improvement and good. As soon you reach that middle area with the Core Web Vitals fields data, you will see improvements ...So as long you are in that middle range, you are in a good area.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So... is &lt;em&gt;good&lt;/em&gt; not being &lt;strong&gt;good&lt;/strong&gt;?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[...] The good thing about Core Web Vitals you are competing with sites that are in the same situation as you. If you have the same users you are kinda competing against them is not that you are measuring your site against the fastest of the fastest other sites out there. For the individual queries we see websites that have good web vitals and sites that don’t have good web vitals [...] And, &lt;strong&gt;if none of the sites can reach good Core Web Vitals for specific queries that don’t cause any problems because everyone is on the same level again&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When thinking about the question this was the first thing that I thought because of this I put bold in the sentence. Is reasonable and at surface level looks like resolves the “material question” for good. But not so fast.&lt;/p&gt;

&lt;p&gt;But this is a sort of “Invisible Hand” argument. The sites competing for the queries are not born the same. Some have niche audiences (maybe with better connection speeds because is a niche of user with more money and inequality only goes up in South America), some are ultra bare bones blogs created to spread misinformation and “fake news” and therefore will score higher than an outlet that has subscribers, has more content to show, produces graphics and all the things provide better and more contextualized news but has to pay the “tax” to try a broad audience in a reality of several low end devices and poor connections. Is an optimistic and “best-case scenario” answer. Is something that everybody on the internet knows on some level: you are not competing with “your peers”, you are competing with everyone else for individual queries and there’s a whole sort of plurality in the actors.&lt;/p&gt;

&lt;p&gt;I think since they operate with a closer look on the top performers they are not paying enough attention on how these "fair" set of metrics are biased, one-sided and might have several side-effects since it has such an impact on business.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://amzn.to/3DHfp04" rel="noopener noreferrer"&gt;Algorithms of Oppression: How Search Engines Reinforce Racism&lt;/a&gt;,  Safiya Umoja Noble challenges the idea that search engines like Google offer an equal playing field for all forms of ideas, identities, and activities. Data discrimination is a real social problem; Noble argues that the combination of private interests in promoting certain sites, along with the monopoly status of a relatively small number of Internet search engines, leads to a biased set of search algorithms that privilege whiteness and discriminate against people of color, specifically women of color. &lt;/p&gt;

&lt;p&gt;Big Tech always use algorithm as a shield, in order to avoid further scrutiny, and as a means to excuse bad outcomes or deny agency. But as the researcher does, the politics and assumptions about the world are embedded in the tools and even in "fair" metrics that cannot accurately describe and measure with the promised “fairness” from math and algorithm — which besides codes, in the end mean “our choices”.&lt;/p&gt;

&lt;p&gt;Google wants to &lt;strong&gt;"No site gets preferential treatment"&lt;/strong&gt;. And I believe in them. I do. I don't think there's any Evil Room where some "White Guy 10x Developer" is making the decisions, but as all escalations must use public channels, I'm here, trying to push and shine some light in these particular specifics since the structural biases are by definition invisible because they are part of society and world views, and I and hope to open a more diverse conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Read more
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://web.dev/learn-web-vitals/" rel="noopener noreferrer"&gt;Web Vitals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/netzwelt/" rel="noopener noreferrer"&gt;How committing to Core Web Vitals increased Netzwelt's advertising revenues by 18%&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/telegraph/" rel="noopener noreferrer"&gt;Improving Cumulative Layout Shift at Telegraph Media Group&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.smashingmagazine.com/2021/04/complete-guide-measure-core-web-vitals/" rel="noopener noreferrer"&gt;An In-Depth Guide To Measuring Core Web Vitals&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;It was my first time in the United States, I was motivated to &lt;a href="https://github.com/ibrahimcesar/react-lite-youtube-embed" rel="noopener noreferrer"&gt;write my first open source component&lt;/a&gt; and even got engaged! ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;For a great paper on the subject, I highly recommed &lt;a href="https://muse.jhu.edu/article/712112/pdf" rel="noopener noreferrer"&gt;The Environmental History of Computing&lt;/a&gt; by Nathan Ensmenger. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>webdev</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Next.js TypeScript SSR and ISR serverless deploy with AWS CDK</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Thu, 19 Aug 2021 11:32:25 +0000</pubDate>
      <link>https://forem.com/aws-builders/next-js-typescript-serverless-deploy-with-ssr-and-isr-with-aws-cdk-5c7e</link>
      <guid>https://forem.com/aws-builders/next-js-typescript-serverless-deploy-with-ssr-and-isr-with-aws-cdk-5c7e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Incremental Static Regeneration is the Next.js &lt;b&gt;superpower&lt;/b&gt;. We’ll deploy a Next.js webapp in AWS using Lambda@Edge and CloudFront with support for SSR and ISG. Both our Next.js webapp and our Infrastructure as Code (IaC) will use TypeScript, using the Cloud Development Kit (CDK).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When you have a highly dynamic webapp with a lot of content, your number of pages will grow and grow. Static generation is great, but more pages, more time to build. Server Side Rendering is great to solve some of these problems but takes its cut on Time To First Byte (TTFB). Also, long builds with unnecessary computation might also incur additional expenses. Ideally, your application is intelligent enough to understand which products changed and incrementally update those pages with no full rebuild. And Incremental Static Regeneration just do that in Next.js. Until now I was just able to deploy functional webapps with ISR in AWS using containers (ECS or Fargate), but now, thanks to new releases for CDK Construct we can make full serverless deployment of rich webapps on AWS with CDK.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need to know
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Level &lt;strong&gt;200&lt;/strong&gt;: &lt;strong&gt;Intermediate&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Have &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node&lt;/a&gt; installed;&lt;/li&gt;
&lt;li&gt;You should have an &lt;a href="https://aws.amazon.com/cli/" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html" rel="noopener noreferrer"&gt;setting your credentials&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;You should have &lt;a href="https://docs.aws.amazon.com/cdk/latest/guide/cli.html" rel="noopener noreferrer"&gt;CDK&lt;/a&gt; installed and &lt;a href="https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html" rel="noopener noreferrer"&gt;bootstrapped in your account&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Some &lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt; knowledge needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Basic architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fowbmobygftxnfka6sm6n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fowbmobygftxnfka6sm6n.png" alt="Serverless Architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://serverless-nextjs.com/docs/architecture" rel="noopener noreferrer"&gt;From docs&lt;/a&gt;. Missing in this picture is an extra lambda function to handle images, for optimization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotta Fetch’Em All!
&lt;/h2&gt;

&lt;p&gt;Our application will fetch data from the &lt;a href="https://pokeapi.co/" rel="noopener noreferrer"&gt;PokéAPI&lt;/a&gt; — will be not much fancy, just a regular page that fetches some data and render a page server-side, and in a specific route, we’ll make a “starter build” with the first 25 Pokémons, and then regenerate on the go new Pokémons as requested.&lt;/p&gt;

&lt;p&gt;I generated all the types, &lt;code&gt;Pokedex.ts&lt;/code&gt; and &lt;code&gt;Pokemon.ts&lt;/code&gt; from &lt;a href="https://quicktype.io/typescript" rel="noopener noreferrer"&gt;quicktype&lt;/a&gt;. Even their examples are from PokéAPI! I used their VS Code &lt;a href="https://marketplace.visualstudio.com/items?itemName=quicktype.quicktype" rel="noopener noreferrer"&gt;Paste JSON as Code extension&lt;/a&gt;. It takes the API JSON output and returns interfaces and types to better deal with our logic. The autocomplete for the nested attributes on the JSON tree of an object makes the developer experience great, this is what TypeScript was born for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next.js
&lt;/h2&gt;

&lt;p&gt;This tutorial assumes you already know how to setup your environment and take your first steps with Next.js (install, running, create some pages). And knows what is TypeScript, which, has an excellent support on Next.js. To generate a brand new project just run your weapon of choice &lt;code&gt;npm&lt;/code&gt; or &lt;code&gt;yarn&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app &lt;span class="nt"&gt;--ts&lt;/span&gt;
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn create next-app &lt;span class="nt"&gt;--typescript&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or read the great &lt;a href="https://nextjs.org/docs/basic-features/typescript" rel="noopener noreferrer"&gt;official documentation from Next.js team on TypeScript integration&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We’ll use the pattern to create an &lt;code&gt;/src&lt;/code&gt; folder and place our &lt;code&gt;pages&lt;/code&gt; and &lt;code&gt;components&lt;/code&gt; folder there. I like to create at root level a &lt;code&gt;lib&lt;/code&gt; and &lt;code&gt;types&lt;/code&gt; folder &lt;em&gt;and&lt;/em&gt;  a &lt;code&gt;build&lt;/code&gt; folder with the code to deploy our stack. After install all dependencies, dev dependencies and deploy it to AWS, your root folder for this project will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
 public/
 lib/
 src/
 node_modules/
 build/
 types/
 cdk.out/
 cdk.json
 bin.ts
 stack.ts
 next-env.d.ts
 next.config.js
 package-lock.json
 package.json
 tsconfig.json
 README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we don’t need &lt;code&gt;build&lt;/code&gt; or &lt;code&gt;cdk.out&lt;/code&gt; to be on version control, remember to place both on your &lt;code&gt;.gitignore&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  TSConfig
&lt;/h2&gt;

&lt;p&gt;Our &lt;code&gt;tsconfig.json&lt;/code&gt; will work both for our CDK and our Next.js. How cool is that?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"alwaysStrict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"downlevelIteration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"forceConsistentCasingInFileNames"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"inlineSourceMap"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"es2020"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"DOM"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noEmitOnError"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noFallthroughCasesInSwitch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noImplicitAny"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noImplicitThis"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noImplicitReturns"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noUncheckedIndexedAccess"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noUnusedLocals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noUnusedParameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resolveJsonModule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strictBindCallApply"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strictFunctionTypes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strictNullChecks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strictPropertyInitialization"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stripInternal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES2020"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"typeRoots"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"node_modules/@types"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"useDefineForClassFields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allowJs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"skipLibCheck"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noEmit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"commonjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"isolatedModules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"preserve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"baseUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"paths"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@/components/*"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"./src/components/*"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@/lib/*"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"./lib/*"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@/pages/*"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"./src/pages/*"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"@/types/*"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"./types/*"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exclude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"node_modules"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"include"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"next-env.d.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"**/*.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"**/*.tsx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"lib"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some notes about it: &lt;code&gt;compilerOptions.lib&lt;/code&gt; must have &lt;code&gt;[‘es2020’, ‘DOM’]&lt;/code&gt; at least. Our application will have a life in the lambda functions in Node.js and in the browser as a JavaScript webapp. I always use absolute paths &lt;code&gt;compilerOptions.paths[‘@/components/*’]&lt;/code&gt; per example. It makes so clean the imports and is more clear the domains. For this app we’ll follow the &lt;code&gt;strict&lt;/code&gt; path.&lt;/p&gt;

&lt;h3&gt;
  
  
  CDK dependencies and configurations
&lt;/h3&gt;

&lt;p&gt;All CDK dependencies are development dependencies. I will show examples in &lt;code&gt;npm&lt;/code&gt; from now on, but feel free to use &lt;code&gt;yarn&lt;/code&gt; or whatever please you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; aws-cdk @aws-cdk/core @sls-next/cdk-construct @sls-next/lambda-at-edge @aws-cdk/aws-lambda ts-node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As highlight, aside from &lt;a href="https://docs.aws.amazon.com/cdk/api/latest/docs/aws-construct-library.html" rel="noopener noreferrer"&gt;CDK and its construct libraries&lt;/a&gt;, &lt;a href="https://github.com/TypeStrong/ts-node" rel="noopener noreferrer"&gt;&lt;code&gt;ts-node&lt;/code&gt; is a TypeScript execution engine and REPL for Node.js&lt;/a&gt;. It JIT transforms TypeScript into JavaScript, enabling you to directly execute TypeScript on Node.js without pre-compiling. This is accomplished by hooking node’s module loading APIs, enabling it to be used seamlessly alongside other Node.js tools and libraries.&lt;/p&gt;

&lt;p&gt;And we’ll need some types for our webapp:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; @types/gtag.js @types/node @types/react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, we create &lt;code&gt;cdk.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run deploy"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That will instruct CDK to run a specific script we need to add to the &lt;code&gt;scripts&lt;/code&gt; section of the &lt;code&gt;package.json&lt;/code&gt; along side Next.js ones:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"cdk"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cdk"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ts-node bin.ts"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, the &lt;code&gt;deploy&lt;/code&gt; command will run the file &lt;code&gt;bin.ts&lt;/code&gt;:&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&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;@aws-cdk/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Builder&lt;/span&gt; &lt;span class="p"&gt;}&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;@sls-next/lambda-at-edge&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextStack&lt;/span&gt; &lt;span class="p"&gt;}&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;./stack&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;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&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;./build&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="na"&gt;args&lt;/span&gt;&lt;span class="p"&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;build&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]});&lt;/span&gt;

&lt;span class="nx"&gt;builder&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NextStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NextJsPokeStack&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="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;us-east-1&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="na"&gt;analyticsReporting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Testing deploying NextJS Serverless Construct&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="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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;That is importing the &lt;code&gt;stack.ts&lt;/code&gt; file, with our infra declaration for the &lt;code&gt;NextJSLambdaEdge&lt;/code&gt;:&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&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;@aws-cdk/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Duration&lt;/span&gt; &lt;span class="p"&gt;}&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;@aws-cdk/core&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextJSLambdaEdge&lt;/span&gt; &lt;span class="p"&gt;}&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;@sls-next/cdk-construct&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Runtime&lt;/span&gt; &lt;span class="p"&gt;}&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;@aws-cdk/aws-lambda&lt;/span&gt;&lt;span class="dl"&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;class&lt;/span&gt; &lt;span class="nc"&gt;NextStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&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="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NextJSLambdaEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;NextJsApp&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="na"&gt;serverlessBuildOutDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODEJS_12_X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;withLogging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;apiLambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Api`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;defaultLambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Fn&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;imageLambda&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;Image`&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="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;Checkout the docs for more &lt;a href="https://serverless-nextjs.com/docs/cdkconstruct/#available-props" rel="noopener noreferrer"&gt;available props&lt;/a&gt;. I recommend the use of naming each one of three lambda functions created: &lt;code&gt;apiLambda&lt;/code&gt;, &lt;code&gt;defaultLambda&lt;/code&gt; and &lt;code&gt;imageLambda&lt;/code&gt;. Because otherwise will create with a specific name and if you happen to deploy another stack in the same account you will get an error about the a function with that name already exists. So, rename your stacks or even better, add some randomness to names.&lt;/p&gt;

&lt;p&gt;We will create two different renders, &lt;code&gt;[ditto].tsx&lt;/code&gt; for Server Side Rendering (SSR), that is basically the same of static props, but in server side and because of it, dynamic by nature.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GetServerSideProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Head&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;next/head&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getPokemonData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PokemonForm&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/pokemon&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pokemon&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/types/Pokemon&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PokemonApi&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Pokemon&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;Ditto&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="nx"&gt;PokemonApi&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&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;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&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;pokeName&lt;/span&gt; &lt;span class="o"&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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;species&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;species&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &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;section&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;title&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;pokeName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;PokéServeless&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="nx"&gt;Serverless&lt;/span&gt; &lt;span class="nx"&gt;Lambda&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Edge&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/title&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pokeName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | PokéServeless - AWS Serverless Lambda@Edge`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Head&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;PokéServerless&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt; &lt;span class="nx"&gt;Side&lt;/span&gt; &lt;span class="nx"&gt;Rendering&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PokemonForm&lt;/span&gt; &lt;span class="nx"&gt;poke&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/section&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&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;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetServerSideProps&lt;/span&gt; &lt;span class="o"&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;context&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;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ditto&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;context&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;ditto&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&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="nx"&gt;data&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;getPokemonData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ditto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Ditto&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;[porygon].tsx&lt;/code&gt;, to do Incremental Static Regeneration (ISR). This is an overview of the flow of ISR:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6pjjwkeq2c4blnhi1ib.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6pjjwkeq2c4blnhi1ib.png" alt="ISR flow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Its from Lee Robinson’s &lt;a href="https://www.smashingmagazine.com/2021/04/incremental-static-regeneration-nextjs/" rel="noopener noreferrer"&gt;“A Complete Guide To Incremental Static Regeneration (ISR) With Next.js”&lt;/a&gt; pots and its a very fair title.&lt;/p&gt;

&lt;p&gt;This is my code:&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;// Example of ISG&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GetStaticPaths&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GetStaticProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Head&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;next/head&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getPokemons&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPokemonData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PokemonForm&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/pokemon&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pokemon&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/types/Pokemon&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pokedex&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/types/Pokedex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PokemonApi&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;date&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Porygon&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="nx"&gt;PokemonApi&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&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;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&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;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRouter&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isFallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&lt;/span&gt;&lt;span class="p"&gt;......&lt;/span&gt;&lt;span class="nx"&gt;I&lt;/span&gt; &lt;span class="nx"&gt;had&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="nx"&gt;incrementally&lt;/span&gt;&lt;span class="o"&gt;!!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&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;pokeName&lt;/span&gt; &lt;span class="o"&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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;species&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;species&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;title&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;pokeName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;PokéServerless&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="nx"&gt;Serverless&lt;/span&gt; &lt;span class="nx"&gt;Lambda&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Edge&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/title&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;og:title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pokeName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; | PokéSSR - AWS Serverless Lambda@Edge`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Head&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;PokéServerless&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;Incremental&lt;/span&gt; &lt;span class="nx"&gt;Static&lt;/span&gt; &lt;span class="nx"&gt;Regeneration&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PokemonForm&lt;/span&gt; &lt;span class="nx"&gt;poke&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="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/section&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;poke-center&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;`Generated at &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&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;date&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&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;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&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="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;getStaticProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetStaticProps&lt;/span&gt; &lt;span class="o"&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;context&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;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nx"&gt;data&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;getPokemonData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;porygon&lt;/span&gt; &lt;span class="k"&gt;as&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
  &lt;span class="p"&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;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetStaticPaths&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;porygon&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="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;pokemons&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;getPokemons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Pokedex&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pokemons&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;pokemon&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;porygon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;paths&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Porygon&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To leverage all the power of components we’ll use the same component for each strategy, which we’ll call... &lt;code&gt;pokemon.ts&lt;/code&gt;:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Image&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/image&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next/link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Spacer&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/spacer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pokemon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/types/Pokemon&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PokemonInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Pokemon&lt;/span&gt;
  &lt;span class="p"&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;PokemonForm&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="nx"&gt;PokemonInfo&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;pokeImage&lt;/span&gt; &lt;span class="o"&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;poke&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;sprites&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;other&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;official-artwork&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]?.&lt;/span&gt;&lt;span class="nx"&gt;front_default&lt;/span&gt; &lt;span class="o"&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;poke&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;sprites&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;front_default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&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;poke&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;order&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;isPositive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&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;pokeNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isPositive&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Max version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

 &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;article&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ditto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Image&lt;/span&gt;
          &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pokeImage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;240&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;240&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`Pokémon &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;poke&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;poke-name&lt;/span&gt;&lt;span class="dl"&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;props&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;name&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;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Spacer&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;20px&lt;/span&gt;&lt;span class="dl"&gt;'&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pokeNumber&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;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;Type&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;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;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="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;poke-list&lt;/span&gt;&lt;span class="dl"&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;props&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;poke&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;types&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="na"&gt;info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;index&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;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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="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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Spacer&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;12&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="err"&gt;’&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/article&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;poke-footer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;poke-options&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/ssr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Server Side Rendering&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Image&lt;/span&gt;
                    &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://raw.githubusercontent.com/ibrahimcesar/nextjs-ssr-cdk-aws/main/public/ditto.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;125&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;112&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                  &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Server&lt;/span&gt; &lt;span class="nx"&gt;Side&lt;/span&gt; &lt;span class="nx"&gt;Rendering&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&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;SSR&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;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/isr&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Incremental Static Regeneration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Image&lt;/span&gt;
                    &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://raw.githubusercontent.com/ibrahimcesar/nextjs-ssr-cdk-aws/main/public/porygon.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;125&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                    &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;112&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
                  &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
                  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Incremental&lt;/span&gt; &lt;span class="nx"&gt;Static&lt;/span&gt; &lt;span class="nx"&gt;Regeneration&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;br&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;ISR&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;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/a&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;              &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&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="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;PokemonForm&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It has do some checks, if the number is equal or bigger than one (because Dynamax and Gigamax versions doesn’t return numbers) and which image to use, and we render with the &lt;a href="https://nextjs.org/docs/api-reference/next/image" rel="noopener noreferrer"&gt;Image component from Next.js&lt;/a&gt; for optimization.&lt;/p&gt;

&lt;p&gt;I also made two different “home pages” for each strategy, SSR and ISR, and you could checkout the bare-bones and ugly site for demonstration purposes only™.&lt;/p&gt;

&lt;p&gt;Then, to deploy you just run in your root folder cdk and you should see and approve the changes and wait for ir to finish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cdk deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are like me and have several profiles in your AWS credentials file, as a “advice”, I would argue to always explicit use &lt;code&gt;cdk deploy --profile personal&lt;/code&gt; or whatever you named to not mix environments, resources, stacks and accounts!&lt;/p&gt;

&lt;p&gt;After done you’ll get a ✅  with the name of your stack, mine being &lt;code&gt;NextJsPokeStack&lt;/code&gt; and you can search the address in the CloudFront distribution, or configure a domain in the props or output yourself this value from the process if you needed.&lt;/p&gt;

&lt;p&gt;And... done ✅ You successfully deployed Next.js serverless in AWS with the help of AWS CDK. This is the final infra created, made by the &lt;a href="https://github.com/pistazie/cdk-dia" rel="noopener noreferrer"&gt;awesome tool cdk-dia&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fioy3v5dmoyrwxia69099.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fioy3v5dmoyrwxia69099.png" alt="CDK Diagram"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://ibrahimcesar.s3.amazonaws.com/images/diagram.png" rel="noopener noreferrer"&gt;Click here for a full version&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Earlier this year AWS launched the Amplify SSR support for Next.js but... is stuck at version 9 at the time — you can’t use the Image component and the ISR at the time. And we just made a isomorphic deployment of code AND infra with TypeScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/ibrahimcesar/nextjs-ssr-isr-cdk-aws" rel="noopener noreferrer"&gt;Repo for this project&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://d3k4okkgstczau.cloudfront.net" rel="noopener noreferrer"&gt;Project Demo Home Page&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://d3k4okkgstczau.cloudfront.net/ssr" rel="noopener noreferrer"&gt;SSR Home&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://d3k4okkgstczau.cloudfront.net/isr" rel="noopener noreferrer"&gt;ISR Home&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A SSR route example &lt;code&gt;/ssr&lt;/code&gt;: &lt;a href="https://d3k4okkgstczau.cloudfront.net/scizor" rel="noopener noreferrer"&gt;Scizor&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An ISR route example &lt;code&gt;/isr&lt;/code&gt;: &lt;a href="https://d3k4okkgstczau.cloudfront.net/pokemons/lickitung" rel="noopener noreferrer"&gt;Lickitung&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>serverless</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>NextJS Developer Extensions Pack: Install the best VSCode extensions with one click</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Wed, 21 Jul 2021 01:04:47 +0000</pubDate>
      <link>https://forem.com/ibrahimcesar/nextjs-developer-extensions-pack-install-the-best-vscode-extensions-with-one-click-32jf</link>
      <guid>https://forem.com/ibrahimcesar/nextjs-developer-extensions-pack-install-the-best-vscode-extensions-with-one-click-32jf</guid>
      <description>&lt;p&gt;It looks that we'll never run out of VS Code best extensions posts and lists, right? As an daily user of VS Code I think I can related with the feeling of share with other people how amazing some tools are and help boost our productivity in some many forms and ways that we wouldn't guess.&lt;/p&gt;

&lt;p&gt;As a web developer and mostly focused on NextJS working with style-components and TypeScript, my arsenal of tools may not be everyone's cup of tea but more and more helping others and teaching, I decided to create an extension pack to better share my weapons of choice. After that you can just uninstall that you don't use it or even needed. After all, there's no size fits all, even more with such personal as is the development space in which we program.&lt;/p&gt;

&lt;p&gt;This is all the extensions on my greatest hist lists, I'm sure most are very well known, others are more niche but super helpfull.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-close-tag"&gt;&lt;strong&gt;Auto Close Tag&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Automatically add HTML/XML close tag, same as Visual Studio IDE or Sublime Text&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag"&gt;&lt;strong&gt;Auto Rename Tag&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Auto rename paired HTML/XML tag&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=deque-systems.vscode-axe-linter"&gt;&lt;strong&gt;axe Accessibility Linter&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Coding for accessibility made easy.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments"&gt;&lt;strong&gt;Better Comments&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;The Better Comments extension will help you create more human-friendly comments in your code&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=leodevbro.blockman"&gt;&lt;strong&gt;Blockman - Highlight Nested Code Blocks&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Mark/Highlight code blocks&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=alefragnani.Bookmarks"&gt;&lt;strong&gt;Bookmarks&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;It helps you to navigate in your code, moving between important positions easily and quickly.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker"&gt;&lt;strong&gt;Code Spell Checker&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Spelling checker for source code&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=naumovs.color-highlight"&gt;&lt;strong&gt;Color Highlight&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Highlight web colors in your editor&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=mikestead.dotenv"&gt;&lt;strong&gt;DotENV&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Support for dotenv file syntax&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph"&gt;&lt;strong&gt;Git Graph&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;View a Git Graph of your repository, and perform Git actions from the graph.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens"&gt;&lt;strong&gt;GitLens — Git supercharged&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Supercharge the Git capabilities built into Visual Studio Code — Visualize code authorship at a glance via Git blame annotations and code lens, seamlessly navigate and explore Git repositories, gain valuable insights via powerful comparison commands, and so much more&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint"&gt;&lt;strong&gt;ESLint&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Integrates ESLint JavaScript into VS Code.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=sleistner.vscode-fileutils"&gt;&lt;strong&gt;File Utils&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;A convenient way of creating, duplicating, moving, renaming and deleting files and directories.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow"&gt;&lt;strong&gt;indent-rainbow&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Makes indentation easier to read&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=Orta.vscode-jest"&gt;&lt;strong&gt;Jest&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Use Facebook's Jest With Pleasure.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=MariusAlchimavicius.json-to-ts"&gt;&lt;strong&gt;JSON to TS&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Convert JSON object to typescript interfaces&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=shd101wyy.markdown-preview-enhanced"&gt;&lt;strong&gt;Markdown Preview Enhanced&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Markdown Preview Enhanced ported to vscode&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint"&gt;&lt;strong&gt;markdownlint&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Markdown linting and style checking for Visual Studio Code&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme"&gt;&lt;strong&gt;Material Icon Theme&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Material Design Icons for Visual Studio Code&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=pulkitgangwar.nextjs-snippets"&gt;&lt;strong&gt;Next.js snippets&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;snippets for nextjs&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=quicktype.quicktype"&gt;&lt;strong&gt;Paste JSON as Code&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Copy JSON, paste as Go, TypeScript, C#, C++ and more.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense"&gt;&lt;strong&gt;Path Intellisense&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Visual Studio Code plugin that autocompletes filenames.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode"&gt;&lt;strong&gt;Prettier - Code formatter&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Code formatter using prettier&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=2gua.rainbow-brackets"&gt;&lt;strong&gt;Rainbow Brackets&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Provide rainbow colors for the round brackets, the square brackets and the squiggly brackets. This is particularly useful for Lisp or Clojure programmers, and of course, JavaScript, and other programmers.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=richie5um2.vscode-sort-json"&gt;&lt;strong&gt;Sort JSON objects&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Sorts the keys within JSON objects&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=meganrogge.template-string-converter"&gt;&lt;strong&gt;Template String Converter&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Converts quotes to backticks when a &lt;code&gt;$&lt;/code&gt; and &lt;code&gt;{&lt;/code&gt; are entered within quotes in JavaScript and TypeScript files&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=rangav.vscode-thunder-client"&gt;&lt;strong&gt;Thunder Client&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Rest API Client for VS Code, GUI based Http Client&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree"&gt;&lt;strong&gt;Todo Tree&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Show TODO, FIXME, etc. comment tags in a tree view&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=BriteSnow.vscode-toggle-quotes"&gt;&lt;strong&gt;Toggle Quotes&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;&lt;code&gt;cmd '&lt;/code&gt; (&lt;code&gt;ctrl '&lt;/code&gt; on win/linux) will cycle the first quote pair found&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=shardulm94.trailing-spaces"&gt;&lt;strong&gt;Trailing Spaces&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Highlight trailing spaces and delete them in a flash!&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-tslint-plugin"&gt;&lt;strong&gt;TSLint&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;TSLint support for Visual Studio Code&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=VisualStudioExptTeam.vscodeintellicode"&gt;Visual Studio IntelliCode&lt;/a&gt;: &lt;em&gt;AI-assisted development&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=jpoissonnier.vscode-styled-components"&gt;&lt;strong&gt;vscode-styled-components&lt;/strong&gt;&lt;/a&gt;: &lt;em&gt;Syntax highlighting for styled-components&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To install, just go to the &lt;strong&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=IbrahimCesar.ibrahimcesar-nextjs-developer-pack"&gt;Visual Studio Marketplace&lt;/a&gt;&lt;/strong&gt; and smash the Install button.&lt;/p&gt;

&lt;p&gt;Happy coding everyone 😃&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>webdev</category>
      <category>vscode</category>
      <category>productivity</category>
    </item>
    <item>
      <title>A Trillion Dollar Paradox that never was: the largest bank in Latin America will move half of its infra to AWS Cloud</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Sat, 05 Jun 2021 21:40:23 +0000</pubDate>
      <link>https://forem.com/aws-builders/a-trillion-dollar-paradox-that-never-was-the-largest-bank-in-latin-america-will-move-half-of-its-infra-to-aws-cloud-4ba2</link>
      <guid>https://forem.com/aws-builders/a-trillion-dollar-paradox-that-never-was-the-largest-bank-in-latin-america-will-move-half-of-its-infra-to-aws-cloud-4ba2</guid>
      <description>&lt;p&gt;&lt;a href="https://a16z.com/2021/05/27/cost-of-cloud-paradox-market-cap-cloud-lifecycle-scale-growth-repatriation-optimization/" rel="noopener noreferrer"&gt;The Cost of Cloud, a Trillion Dollar Paradox&lt;/a&gt; by Sarah Wang and Martin Casado makes two main arguments:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Cloud is the “perfect platform to optimize for innovation, agility, and growth, but it comes at a cost; there’s a ‘flexibility tax’ for the nimbleness the cloud provides.” Therefore, it’s critical to make cloud spend a first-class KPI metric, and empower engineering to optimize from day one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As a company grows, the pressure that cloud puts on its margins “can start to outweigh the benefits.” Therefore, Wang and Casado present the idea of “repatriating” cloud workloads — bringing all or most out of the cloud.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;The short version is: You’re crazy if you don’t start in the cloud, but you’re crazy if you stay on it.&lt;br&gt;
&lt;a href="https://www.jeremydaly.com/" rel="noopener noreferrer"&gt;Jeremy Daly&lt;/a&gt; on &lt;a href="https://offbynone.io/issues/144/" rel="noopener noreferrer"&gt;off-by-none #144&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But I think it paints a picture biased with a series de logical jumps and do so ignoring other and probably bigger trends in motion. I would like to bring the case of a Brazilian banking that is &lt;em&gt;repatriating&lt;/em&gt;. But, nothing coming back, but seeking &lt;em&gt;Cloud citizenship&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/List_of_largest_banks_in_Latin_America" rel="noopener noreferrer"&gt;Itaú Unibanco&lt;/a&gt; is the largest bank in Latin America with 407.37 US$ Billions in Assets. Milton Maluhy Filho, CEO of Itaú, highlighted growth as the main driver and technology as a way to do so, in an event in June, 2 called &lt;a href="https://www.youtube.com/watch?v=_zoo457b8qQ" rel="noopener noreferrer"&gt;Itaú Day&lt;/a&gt; (&lt;em&gt;this links is an official English dubbed version of it&lt;/em&gt;). At some point he says that they have 24M MAU in their app (again, a banking app).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy77f64z27wpw2cmvfqg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy77f64z27wpw2cmvfqg0.png" alt="AWS contract"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Contract with AWS ([sic]AmazonWeb Services) &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://youtu.be/oqgN9RVG_ms" rel="noopener noreferrer"&gt;Ricardo Guerra, the banks's CTO&lt;/a&gt; made public a milestone:  they want to move half of its capabilities to the public Cloud until the end of 2022, with a ten-year deal with AWS. &lt;a href="https://press.aboutamazon.com/news-releases/news-release-details/itau-unibanco-selects-aws-its-long-term-strategic-cloud-provider/" rel="noopener noreferrer"&gt;Last year it was made public the contract&lt;/a&gt; only hinting that "a great cut" of its infra would go to the Cloud. Now the number has revealed to be 50%.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvsvp6o54tw2kojh4qsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvsvp6o54tw2kojh4qsi.png" alt="50% of the bank in the Cloud"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;50% of the bank in the Cloud until 2022&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It was mentioned analytics, machine learning, serverless, containers, managed databases, computing, storage and security – the whole deal. And they also publicly announced they are moving from &lt;em&gt;monoliths&lt;/em&gt; to &lt;em&gt;microsservices&lt;/em&gt;. The infrastructure for &lt;a href="https://www.paymentsjournal.com/why-pix-is-the-revolution-of-consumer-experience-in-brazil/" rel="noopener noreferrer"&gt;Pix&lt;/a&gt;, a new and more cheap payment released by Brazil's Central Bank is already in a microservices architecture, and the Credit Card operation as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foj9bmsl8wnu9e50ttzcc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foj9bmsl8wnu9e50ttzcc.png" alt="Microsservices"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Microservices &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Last year, profits of Itaú because of COVID-19 and Brazilian market, felt strongly 35%. They made only 18.91 BRL Billions &lt;em&gt;in profit&lt;/em&gt;. "In times of crises, some people cry — other people sell handkerchiefs", there's a saying. I would add, "...and then there are the &lt;em&gt;banks&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;For this they already hired 4 thousand new professionals. Until 5 years ago, the plan was invest in its own infra: the bank own that in 2015 received 3.3 BRL Billions, which if you take the inflation, would around 1 US$ Billion.&lt;/p&gt;

&lt;p&gt;We are &lt;a href="https://www.baguete.com.br/noticias/04/06/2021/metade-do-itau-na-nuvem-ate-2022" rel="noopener noreferrer"&gt;talking about&lt;/a&gt; call-centers, bank web and mobile apps and banking platforms.&lt;/p&gt;

&lt;p&gt;Nubank, a Brazilian Unicorn, is also the &lt;a href="https://techcrunch.com/2020/03/03/valued-at-10b-nubank-launches-its-nu-credit-card-in-mexico/" rel="noopener noreferrer"&gt;largest independent digital bank in the world&lt;/a&gt;. It started with a credit card offering and now is turning itself in a complete bank, without one single physical agency. And &lt;a href="https://aws.amazon.com/solutions/case-studies/nubank/?nc1=h_ls" rel="noopener noreferrer"&gt;runs on AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I bring attention to these two prominent examples that are close to home to me and from one of the hardest markets in the world: &lt;em&gt;banking&lt;/em&gt;. The focus on SaaS also leaves a lot of workloads of a far great Universe of companies using the public Cloud.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To frame the discussion: We estimate the recaptured savings in the extreme case of full repatriation, and use public data to pencil out the impact on share price. We show (using relatively conservative assumptions!) that across 50 of the top public software companies currently utilizing cloud infrastructure, an estimated $100B of market value is being lost among them due to cloud impact on margins — relative to running the infrastructure themselves. And while we focus on software companies in our analysis, the impact of the cloud is by no means limited to software. Extending this analysis to the broader universe of scale public companies that stands to benefit from related savings, we estimate that the total impact is potentially greater than $500B.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can say I'm just a person random on the Internet, but these numbers are completely made-up. Right after state that the "&lt;em&gt;point of this post isn’t to argue for repatriation&lt;/em&gt;", and then drops a bomb that leads to the trillion dollar paradox of the title. The only paradox in this case, I would say is that it was never existed first place. &lt;/p&gt;

&lt;p&gt;I also recommend &lt;a href="https://twitter.com/zackkanter" rel="noopener noreferrer"&gt;Zack Kanter&lt;/a&gt; Stedi's Founder and CEO analysis of the piece: &lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1399013516107948037-705" src="https://platform.twitter.com/embed/Tweet.html?id=1399013516107948037"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1399013516107948037-705');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1399013516107948037&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;So, again, I think nothing better than analyses actual use cases to get a better picture of what's going on or even the myths and narratives some people created based on their own limited dataset. The biggest bank in Latin America is moving on-premises to be 50% Cloud at AWS until 2022 and they invested a huge money and they had plan to expand but their strategy changed to embrace Cloud, and one of Brazil's Unicorn, also from Banking industry is Cloud Native since day one. If I was a VC, I would bet my money on &lt;em&gt;Cloud citizenship&lt;/em&gt; and not otherwise.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>finops</category>
      <category>microservices</category>
    </item>
    <item>
      <title>We need to talk more about equality in tech</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Sun, 23 May 2021 21:02:38 +0000</pubDate>
      <link>https://forem.com/ibrahimcesar/we-need-to-talk-more-about-equality-in-tech-4g2k</link>
      <guid>https://forem.com/ibrahimcesar/we-need-to-talk-more-about-equality-in-tech-4g2k</guid>
      <description>&lt;p&gt;This post is an invitation by &lt;a href="https://twitter.com/whitep4nth3r" rel="noopener noreferrer"&gt;Salma&lt;/a&gt; from &lt;a href="https://unbreak.tech/" rel="noopener noreferrer"&gt;Unbreak.tech&lt;/a&gt; that aims to be “a platform for MEN to educate other MEN about the need for change and equality in tech”. &lt;em&gt;Politics&lt;/em&gt; is a taboo in tech circles. I’m out of my base here, but in &lt;a href="https://www.theverge.com/2021/5/3/22418208/basecamp-all-hands-meeting-employee-resignations-buyouts-implosion" rel="noopener noreferrer"&gt;some camps politics led to a meltdown&lt;/a&gt; after &lt;a href="https://world.hey.com/jason/changes-at-basecamp-7f32afc5" rel="noopener noreferrer"&gt;some gems&lt;/a&gt; of privileged men in power. But &lt;em&gt;we are social animals&lt;/em&gt;. Politics is everywhere because is about everything we do. As simple as a &lt;a href="https://en.wikipedia.org/wiki/Politics" rel="noopener noreferrer"&gt;Wikipedia definition&lt;/a&gt; can be, politics “is the set of activities that are associated with deciding in groups, or other forms of power relations between individuals, such as the distribution of resources or status". And I will talk direct with you, my fellow men.&lt;/p&gt;

&lt;p&gt;Even if you cannot see there’s a context, a structural web of power relations codified in the public speech, gender norms, cultural products and in the market itself that are a byproduct of several instances of decision making that made the world what it is. Sexist. Racist. Abusive. And I know, is difficult to see, exactly because of that. It embedded us in it. Because, my friends, this is water.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/8CrOL-ydFMI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;This video, from the late writer David Foster Wallace, starts with a humorous parable:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are two young fish swimming along who meet an older fish. The older fish nods at them and says:&lt;/p&gt;

&lt;p&gt;‘Morning boys, how’s the water?’&lt;/p&gt;

&lt;p&gt;The two young fish swim on for a bit and then eventually one of them looks over at the other and asks:&lt;/p&gt;

&lt;p&gt;‘What the hell is water?’&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is easy to not see the environment structures, we are immersed and shaped every aspect of our existence. Structural racism, gender norms. We come out to this world and this doesn’t look like the “natural way of this”. This is water.&lt;/p&gt;

&lt;p&gt;We must embrace other perspectives, understand our immersion and bias. We must listen. As David Foster Wallace, understand this has nothing to do with knowledge, that we developers are so proud of, but with “how to think”, and he says: “The alternative is unconsciousness. The gnawing sense of having lost some infinite thing”. Maybe because a highly respected white guy said this, more people can understand and immerse in this call for empathy and think in our context, give gravitas. Do not consider only the lobster. Consider people with disabilities. Consider people of color. Consider people of all genders.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Even prior to the term “computer” being a name given to a machine, it had been the name given to job. Originally, a computer was a person—almost always a young woman—who computed complex equations with the help of pen and paper or a desktop accounting machine. A common misperception is that women got into computing during World War II simply because men were at the front, but the gendering of computing work existed before the war, and before computers were electronic. The feminization of this work continued through and after the war, with women returning to the civilian workforce to perform computing work with electromechanical and later electronic systems—everything from programming and operation, to systems analysis, to hardware assembly.”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mitpress.mit.edu/books/your-computer-fire" rel="noopener noreferrer"&gt;“Your Computer Is on Fire”&lt;/a&gt;, “Sexism Is a Feature, Not a Bug” by &lt;a href="https://marhicks.com/" rel="noopener noreferrer"&gt;Mar Hicks&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And if you are a man, you don’t feel personally responsible for any of that. Right? You did nothing wrong. We mean, well, except maybe &lt;em&gt;that&lt;/em&gt; time or &lt;em&gt;that&lt;/em&gt; time. Was a grey area wasn’t? But this is water.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If you are white in a white supremacist society, you are racist. If you are male in a patriarchy, you are sexist.” — Ijeoma Oluo, &lt;a href="https://amzn.to/3fJ62BW" rel="noopener noreferrer"&gt;So You Want to Talk About Race&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since we are existing in this planet if you is identified with a specific set of characteristics you are, signed or not for this, benefiting from this. What to do?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/monteiro" rel="noopener noreferrer"&gt;Mike Monteiro&lt;/a&gt; wrote &lt;a href="https://amzn.to/3ffmZ7W" rel="noopener noreferrer"&gt;Ruined by Design: How Designers Destroyed the World, and What We Can Do to Fix It&lt;/a&gt;. This book talks about our roles in creating – or ruined - the world. Monteiro calls the responsibility in the hands of the designers of digital products, meaning everyone involved in the process to plan, mock, code, ship and support digital products. In one moment of the book &lt;a href="https://monteiro.medium.com/d-r-e-a-m-74935dacfaf5" rel="noopener noreferrer"&gt;he recalls a grim conversation&lt;/a&gt; he had in Copenhagen:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[…] the topic of “being good allies” came up. To which my new Danish friend shouted that men our age had committed too many sins and done too many things wrong to ever be good allies in &lt;em&gt;any&lt;/em&gt; sense of the world. And the best thing we could to for the planet was to die. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I still think a lot on it. As Monteiro points out: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As uncomfortable as it is to admit, I am both those things. And if you are reading this and you look like me, you are too. Regardless of how well you’ve lived your life, regardless of how good your intentions were, you benefited from a stacked deck. And yet, even with the deck stacked in our favor, we couldn’t do the job. So yes, the best thing we can do for the planet is to die.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I think a lot about this. But I don’t know if suggest you to die would be useful. All human beings are entitled to live. You are entitled to pursue your happiness, but we should be aware of the water.&lt;/p&gt;

&lt;p&gt;I’m a male cisgender Brazilian. I doubt that any American or person in Europe would call me “White”—I think this should be a common issue with Latinxs in their homelands. And we even talked about intersectionality. If you are a person of color, the accents (if I was talking to you right now, maybe you would be biased by my way of talk since English is my second language). But my skin falls in the spectrum of whiteness here in Brazil and I have many of the benefits of it. Even having a lot of miscegenation on my family. I rise from a poor family to be a technology director at a small, but innovative, company in São Paulo, our biggest city. I could be the poster child of “meritocracy”. But this is bullshit. Meritocracy appeared first as a parody. There is no such thing as meritocracy. &lt;/p&gt;

&lt;p&gt;It was not entirely but design, but at certain time, I was the only &lt;a href="https://aws.amazon.com/blogs/startups/news-startup-nexo-runs-a-lean-tech-team-by-leveraging-aws-and-amplify/" rel="noopener noreferrer"&gt;male developer on my team&lt;/a&gt;. Which is rare in a market in which woman occupy 25% of the roles, and this research included support and QA, areas that we like or not are considered “less” than others. Brillant engineers I have the  opportunity to look and simply didn’t get a change in the workplace.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1393201902762954752-253" src="https://platform.twitter.com/embed/Tweet.html?id=1393201902762954752"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1393201902762954752-253');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1393201902762954752&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Worst yet if you to be a founder. To automate the work of Paul Graham as VC we would not even need Machine Learning. A few &lt;em&gt;if&lt;/em&gt; and &lt;em&gt;else&lt;/em&gt;’s would do the job. White. &lt;em&gt;Male&lt;/em&gt;. Dropout, but of an Ivy League College. Looks like Mark Zuckerberg.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“As our technological systems become increasingly destructive to our professed social and political ideals, we can no longer afford to collectively fail to understand the layers and decades of intentional decisions that have led to these supposedly unforeseen consequences. The current situation shows us clearly how, as large computing and telecommunications systems have scaled, the power imbalances they foster have altered all of our social institutions, including our political process”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mitpress.mit.edu/books/your-computer-fire" rel="noopener noreferrer"&gt;“Your Computer Is on Fire”&lt;/a&gt;, “Sexism Is a Feature, Not a Bug” by &lt;a href="https://marhicks.com/" rel="noopener noreferrer"&gt;Mar Hicks&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Still, what to do? So many things in so many areas.&lt;/p&gt;

&lt;p&gt;Hire women. Promote women. If you see a woman being interrupted, ask for her input right after the interruption. If someone makes a “joke”, ask why that person thinks that is funny. See something weird, ask her if she feels safe. Raise your voice to speak &lt;em&gt;with&lt;/em&gt; her if needed. Do not be complacent. Instead of trying to be “10x Developer”, why not first try to be at least 1x human? Do something. Act. Because only posts will not do much. Only actions will mean a thing for the person you helped. Use &lt;em&gt;your power&lt;/em&gt;. Yes, you have. You born with this, asking or not for it. With great power comes great responsibility. Is up to us. Do not just reproduce structural sexism. What are you, an android? Are you just programmed? Chances are you are. We are born this way. We must fight it every minute. Keep afloat. Do not get drowned in the abyss of the deep water. The alternative is unconsciousness. The gnawing sense of having lost some infinite thing.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Cover image, detail of &lt;a href="https://www.pexels.com/pt-br/foto/html-borrao-mancha-nevoa-5473950/" rel="noopener noreferrer"&gt;photo by cottonbro on Pexels&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>equality</category>
      <category>diversity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>How to host a Next.js web apps with server-side rendering (SSR) in AWS Amplify</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Tue, 18 May 2021 23:31:45 +0000</pubDate>
      <link>https://forem.com/aws-builders/how-to-host-a-next-js-web-apps-with-server-side-rendering-ssr-in-aws-amplify-3n3h</link>
      <guid>https://forem.com/aws-builders/how-to-host-a-next-js-web-apps-with-server-side-rendering-ssr-in-aws-amplify-3n3h</guid>
      <description>&lt;p&gt;No more waiting! It’s finally here, &lt;a href="https://aws.amazon.com/about-aws/whats-new/2021/05/aws-amplify-hosting-announces-server-side-rendering-support-for-next-js-web-apps/" rel="noopener noreferrer"&gt;AWS Amplify hosting for Next.js server-side rendering (SSR)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this is great&lt;/strong&gt;: It’s no joke, I wait for this feature for &lt;em&gt;more than a year&lt;/em&gt;. And is finally here and is fast!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not so great&lt;/strong&gt;: Next 10.x.x was a huge leap forward. All things I wanted to try, right off the bat, and backed in my applications...But this will be on hold, as the time of writing, this launch only his support is for Next.js 9.x.x version. Considering version 10.x is from October 2020 I think the pace is a little slow to catchup.&lt;/p&gt;

&lt;p&gt;To evaluate what type of rendering your application need, I recommend the post &lt;a href="https://vercel.com/blog/nextjs-server-side-rendering-vs-static-generation" rel="noopener noreferrer"&gt;Next.js: Server-side Rendering vs. Static Generation&lt;/a&gt; by &lt;a href="https://twitter.com/leeerob" rel="noopener noreferrer"&gt;Lee Robinson&lt;/a&gt;—and in the &lt;em&gt;real world&lt;/em&gt; sometimes you’ll need both.&lt;/p&gt;

&lt;h2&gt;
  
  
  The webapp
&lt;/h2&gt;

&lt;p&gt;For all purposes, you could do with your app or create a boilerplate new &lt;a href="https://nextjs.org/docs/basic-features/pages#server-side-rendering" rel="noopener noreferrer"&gt;NextJS with SSR&lt;/a&gt;. I created this barebones site that renders some info from the &lt;a href="https://pokeapi.co/" rel="noopener noreferrer"&gt;PokéAPI&lt;/a&gt;. This is the repository on GitHub:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ibrahimcesar" rel="noopener noreferrer"&gt;
        ibrahimcesar
      &lt;/a&gt; / &lt;a href="https://github.com/ibrahimcesar/nextjs-ssr-amplify-aws" rel="noopener noreferrer"&gt;
        nextjs-ssr-amplify-aws
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      👾 ‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎Repository to test NextJS Server Side Rendering with AWS Amplify
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
  &lt;a href="https://amplify.aws/community" rel="nofollow noopener noreferrer"&gt;
    &lt;img alt="Amplify" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Faws-amplify%2Flearn%2Fraw%2Fmain%2Fsrc%2Fassets%2Fimages%2Flogo-dark.png" width="60"&gt;
  &lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;
  👾 AWS Amplify NextJS SSR
&lt;/h1&gt;
&lt;/div&gt;
&lt;blockquote&gt;Example of NextJS SSR example to deploy with AWS Amplify SSR Hosting using the PokéAPI&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/ellerbrock/typescript-badges/" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/722fbbb8b605651efe6834f674a02f275b4352d1f39ac64fb7a7dd30592b69cc/68747470733a2f2f6261646765732e66726170736f66742e636f6d2f747970657363726970742f636f64652f747970657363726970742e7376673f763d313031" alt="TypeScript"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Developed in 🇧🇷 &lt;span&gt;Brazil&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://updown.io/akzp" rel="nofollow noopener noreferrer"&gt;PokéAPI Status Page&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Deploying&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;If you never used Amplify&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;You’ll need to have the amplify &lt;a href="https://docs.amplify.aws/cli/start/install" rel="nofollow noopener noreferrer"&gt;installed and configured&lt;/a&gt;. Just follow the docs and you’ll be ready to go. Or make sure you have the latest version.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Amplify Init&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;❯ amplify init
Note: It is recommended to run this &lt;span class="pl-c1"&gt;command&lt;/span&gt; from the root of your app directory

&lt;span class="pl-k"&gt;?&lt;/span&gt; Enter a name &lt;span class="pl-k"&gt;for&lt;/span&gt; the project pokessr

The following configuration will be applied:

Project information

&lt;span class="pl-k"&gt;|&lt;/span&gt; Name: pokessr

&lt;span class="pl-k"&gt;|&lt;/span&gt; Environment: dev

&lt;span class="pl-k"&gt;|&lt;/span&gt; Default editor: Visual Studio Code

&lt;span class="pl-k"&gt;|&lt;/span&gt; App type: javascript

&lt;span class="pl-k"&gt;|&lt;/span&gt; Javascript framework: react

&lt;span class="pl-k"&gt;|&lt;/span&gt; Source Directory Path: src

&lt;span class="pl-k"&gt;|&lt;/span&gt; Distribution Directory Path: build

&lt;span class="pl-k"&gt;|&lt;/span&gt; Build Command: npm run-script build

&lt;span class="pl-k"&gt;|&lt;/span&gt; Start Command: npm run-script start

&lt;span class="pl-k"&gt;?&lt;/span&gt; Initialize the project with the above configuration&lt;span class="pl-k"&gt;?&lt;/span&gt; Yes

Using&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ibrahimcesar/nextjs-ssr-amplify-aws" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;You can leave all build options as it is, because Amplify will automatically pick up as SSR and deploy it. For this to happen you also don’t need (or have to) choose a different export folder. If you clone my repo, you could check that I’m indeed using NextJS &lt;code&gt;10.0.0&lt;/code&gt; but, I cannot use any additional feature like the new &lt;code&gt;Image&lt;/code&gt; component.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deploying
&lt;/h2&gt;

&lt;h3&gt;
  
  
  If you never used Amplify
&lt;/h3&gt;

&lt;p&gt;You’ll need to have the amplify &lt;a href="https://docs.amplify.aws/cli/start/install" rel="noopener noreferrer"&gt;installed and configured&lt;/a&gt;. Just follow the docs and you’ll be ready to go. Or make sure you have the latest version.&lt;/p&gt;

&lt;h3&gt;
  
  
  Amplify Init
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ amplify init
Note: It is recommended to run this &lt;span class="nb"&gt;command &lt;/span&gt;from the root of your app directory
? Enter a name &lt;span class="k"&gt;for &lt;/span&gt;the project pokessr
The following configuration will be applied:
Project information
| Name: pokessr
| Environment: dev
| Default editor: Visual Studio Code
| App &lt;span class="nb"&gt;type&lt;/span&gt;: javascript
| Javascript framework: react
| Source Directory Path: src
| Distribution Directory Path: build
| Build Command: npm run-script build
| Start Command: npm run-script start

? Initialize the project with the above configuration? Yes
Using default provider  awscloudformation
? Select the authentication method you want to use: AWS profile
For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html

? Please choose the profile you want to use amplify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Besides the name, &lt;code&gt;pokessr&lt;/code&gt;, I only choose my profile to deploy, called &lt;code&gt;amplify&lt;/code&gt; but you can deploy in whatever profile you configured. I accepted all defaults. Then amplify will create your environment:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Adding backend environment dev to AWS Amplify Console app: d31r520fbr96mj

⠙ Initializing project in the cloud...

CREATE_IN_PROGRESS amplify-pokessr-dev-185133 AWS::CloudFormation::Stack Tue May 18 2021 18:51:41 GMT-0300 (Horário Padrão de Brasília) User Initiated
CREATE_IN_PROGRESS UnauthRole                 AWS::IAM::Role             Tue May 18 2021 18:51:45 GMT-0300 (Horário Padrão de Brasília)
CREATE_IN_PROGRESS AuthRole                   AWS::IAM::Role             Tue May 18 2021 18:51:45 GMT-0300 (Horário Padrão de Brasília)
CREATE_IN_PROGRESS DeploymentBucket           AWS::S3::Bucket            Tue May 18 2021 18:51:46 GMT-0300 (Horário Padrão de Brasília)
CREATE_IN_PROGRESS UnauthRole                 AWS::IAM::Role             Tue May 18 2021 18:51:46 GMT-0300 (Horário Padrão de Brasília) Resource creation Initiated
CREATE_IN_PROGRESS AuthRole                   AWS::IAM::Role             Tue May 18 2021 18:51:46 GMT-0300 (Horário Padrão de Brasília) Resource creation Initiated

⠇ Initializing project in the cloud...

CREATE_IN_PROGRESS DeploymentBucket AWS::S3::Bucket Tue May 18 2021 18:51:46 GMT-0300 (Horário Padrão de Brasília) Resource creation Initiated

⠸ Initializing project in the cloud...

CREATE_COMPLETE AuthRole   AWS::IAM::Role Tue May 18 2021 18:51:59 GMT-0300 (Horário Padrão de Brasília)
CREATE_COMPLETE UnauthRole AWS::IAM::Role Tue May 18 2021 18:51:59 GMT-0300 (Horário Padrão de Brasília)

⠹ Initializing project in the cloud...

CREATE_COMPLETE DeploymentBucket           AWS::S3::Bucket            Tue May 18 2021 18:52:08 GMT-0300 (Horário Padrão de Brasília)
CREATE_COMPLETE amplify-pokessr-dev-185133 AWS::CloudFormation::Stack Tue May 18 2021 18:52:10 GMT-0300 (Horário Padrão de Brasília)

✔ Successfully created initial AWS cloud resources for deployments.
✔ Initialized provider successfully.

Initialized your environment successfully.

Your project has been successfully initialized and connected to the cloud!

Some next steps:

“amplify status” will show you what you’ve added already and if it’s locally configured or deployed
“amplify add &amp;lt;category&amp;gt;“ will allow you to add features like user login or a backend API
“amplify push” will build all your local backend resources and provision it in the cloud
“amplify console” to open the Amplify Console and view your project status
“amplify publish” will build all your local backend and frontend resources (if you have hosting category added) and provision it in the cloud

Pro tip:
Try “amplify add api” to create a backend API and then “amplify publish” to deploy everything
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;What we are going to use is &lt;code&gt;hosting&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And by zero configuration, you just need to connect your repository and the building settings will be set. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnplnbf5sqsoy4mkvrb8k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnplnbf5sqsoy4mkvrb8k.png" alt="Build settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And you can always have a look at how the build is going accessing the logs in the AWS Amplify console. For our purposes, see a &lt;code&gt;Starting SSR Build&lt;/code&gt; in your logs:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;2021-05-18T22:35:49.379Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: info  - Creating an optimized production build...
2021-05-18T22:35:58.592Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: info  - Compiled successfully
                                 info  - Collecting page data...
2021-05-18T22:35:59.098Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: info  - Generating static pages &lt;span class="o"&gt;(&lt;/span&gt;0/28&lt;span class="o"&gt;)&lt;/span&gt;
2021-05-18T22:35:59.480Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: info  - Generating static pages &lt;span class="o"&gt;(&lt;/span&gt;7/28&lt;span class="o"&gt;)&lt;/span&gt;
2021-05-18T22:35:59.600Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: info  - Generating static pages &lt;span class="o"&gt;(&lt;/span&gt;14/28&lt;span class="o"&gt;)&lt;/span&gt;
2021-05-18T22:35:59.706Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: info  - Generating static pages &lt;span class="o"&gt;(&lt;/span&gt;21/28&lt;span class="o"&gt;)&lt;/span&gt;
2021-05-18T22:35:59.797Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: info  - Generating static pages &lt;span class="o"&gt;(&lt;/span&gt;28/28&lt;span class="o"&gt;)&lt;/span&gt;
2021-05-18T22:35:59.797Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: info  - Finalizing page optimization...
2021-05-18T22:35:59.814Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: 
2021-05-18T22:35:59.860Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: Page                              Size     First Load JS
                                 ┌ λ /                             1.32 kB        68.7 kB
                                 ├   /_app                         0 B            64.2 kB
                                 ├ λ /[ditto]                      1.39 kB        68.7 kB
                                 ├ ○ /404                          2.76 kB        66.9 kB
                                 ├ ● /pokemons/[name]              1.53 kB        68.9 kB
                                 ├   ├ /pokemons/bulbasaur

                                 ├   ├ /pokemons/ivysaur

                                 ├   ├ /pokemons/venusaur

                                 ├   └ &lt;span class="o"&gt;[&lt;/span&gt;+22 more paths]

                                 └ λ /random                       1.39 kB        68.7 kB
                                 + First Load JS shared by all     64.2 kB
                                 ├ chunks/commons.b2f5db.js      13.5 kB
                                 ├ chunks/framework.149f13.js    42 kB
                                 ├ chunks/main.e0d560.js         6.8 kB
                                 ├ chunks/pages/_app.9245f7.js   865 B
                                 ├ chunks/webpack.f82c36.js      950 B
                                 └ css/b8e1ed54af27c57535f7.css  897 B

2021-05-18T22:35:59.861Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: λ  &lt;span class="o"&gt;(&lt;/span&gt;Server&lt;span class="o"&gt;)&lt;/span&gt;  server-side renders at runtime &lt;span class="o"&gt;(&lt;/span&gt;uses getInitialProps or getServerSideProps&lt;span class="o"&gt;)&lt;/span&gt;
                                 ○  &lt;span class="o"&gt;(&lt;/span&gt;Static&lt;span class="o"&gt;)&lt;/span&gt;  automatically rendered as static HTML &lt;span class="o"&gt;(&lt;/span&gt;uses no initial props&lt;span class="o"&gt;)&lt;/span&gt;
                                 ●  &lt;span class="o"&gt;(&lt;/span&gt;SSG&lt;span class="o"&gt;)&lt;/span&gt;     automatically generated as static HTML + JSON &lt;span class="o"&gt;(&lt;/span&gt;uses getStaticProps&lt;span class="o"&gt;)&lt;/span&gt;
                                 &lt;span class="o"&gt;(&lt;/span&gt;ISR&lt;span class="o"&gt;)&lt;/span&gt;     incremental static regeneration &lt;span class="o"&gt;(&lt;/span&gt;uses revalidate &lt;span class="k"&gt;in &lt;/span&gt;getStaticProps&lt;span class="o"&gt;)&lt;/span&gt;

2021-05-18T22:35:59.993Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: Starting SSR Build...
2021-05-18T22:37:10.138Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: SSR Build Complete.
2021-05-18T22:37:11.159Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: &lt;span class="c"&gt;# Completed phase: build&lt;/span&gt;
2021-05-18T22:37:11.159Z &lt;span class="o"&gt;[&lt;/span&gt;INFO]: &lt;span class="c"&gt;## Build completed successfully&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then you gave to wait a couple of minutes and your application you be on your custom domain or in the generate domain of Amplify. For this demonstration my web apps is &lt;a href="https://main.d31r520fbr96mj.amplifyapp.com/" rel="noopener noreferrer"&gt;available here&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Pages
&lt;/h3&gt;

&lt;p&gt;The front page is itself server side generated:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetServerSideProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;data&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;getPokemons&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;data&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It will query in the PokéAPI and return all Pokémons until reaching the number or the maximum today. I placed &lt;code&gt;3000&lt;/code&gt; but as you can check, the actual number today is &lt;code&gt;1118&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When you click in a Pokémon, I use a dynamic route in the file &lt;code&gt;ditto&lt;/code&gt; to generate the Pokémon by the name. Pokémon fans will get the reference. And &lt;code&gt;[ditto].tsx&lt;/code&gt; is also SSR.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetServerSideProps&lt;/span&gt; &lt;span class="o"&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;context&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;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ditto&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;ditto&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="err"&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;data&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;getPokemonData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ditto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;But for fun I created a &lt;code&gt;random&lt;/code&gt; page... that renders a random Pokémons to test even better the SSR. It get all the possible Pokémons and returns one at random using &lt;code&gt;Math.random()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getServerSideProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetServerSideProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;random&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;getPokemons&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Pokedex&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ditto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;random&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="nx"&gt;random&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="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;ditto&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="err"&gt;‘&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="err"&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;data&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;getPokemonData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ditto&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;data&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And to test ISG (Incremental Static Generation) I created a folder called &lt;code&gt;pokemons&lt;/code&gt;. &lt;a href="https://nextjs.org/blog/next-9-5#stable-incremental-static-regeneration" rel="noopener noreferrer"&gt;Stable static generation was added to Next 9.3&lt;/a&gt; but my test doesn’t show that works right now with the Amplify SSR hosting, it defaults to the SSR. ISG is a mechanism to update existing pages, by re-rendering them in the background as traffic comes in using the property &lt;code&gt;revalidate&lt;/code&gt;. Also, another great use is, per example, you have a specific dataset of pages to generate at build time but you’ll need on dynamic routes to be generated new pages as soon you publish another in your headless CMS or database. &lt;a href="https://github.com/serverless-nextjs/serverless-next.js/issues/804" rel="noopener noreferrer"&gt;ISG generated even a bounty as feature in another project&lt;/a&gt; and unlocks a lot of interesting use cases.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getStaticProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetStaticProps&lt;/span&gt; &lt;span class="o"&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;context&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;let&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;data&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;getPokemonData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="k"&gt;as&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
  &lt;span class="p"&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;getStaticPaths&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GetStaticPaths&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&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="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;pokemons&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;getPokemons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Pokedex&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pokemons&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;pokemon&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pokemon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;paths&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For my example, I generate at build time the first 25 Pokémons. See that my props are changing, I’m passing a dynamic date. But my first 25 Pokémons, starting with &lt;a href="https://main.d31r520fbr96mj.amplifyapp.com/pokemons/bulbasaur" rel="noopener noreferrer"&gt;Bulbasaur&lt;/a&gt; and going up to &lt;a href="https://main.d31r520fbr96mj.amplifyapp.com/pokemons/pikachu" rel="noopener noreferrer"&gt;Pikachu&lt;/a&gt;. They have a text &lt;code&gt;Generated at&lt;/code&gt; that will not revalidate at all (right now configured to re-validate at each 5 minutes &lt;code&gt;revalidate: 60 * 5&lt;/code&gt; in which it should change this date. But if you access any other Pokémon than the first 25, like the number 26, &lt;a href="https://main.d31r520fbr96mj.amplifyapp.com/pokemons/raichu" rel="noopener noreferrer"&gt;Raichu&lt;/a&gt; or the 186, &lt;a href="https://main.d31r520fbr96mj.amplifyapp.com/pokemons/scizor" rel="noopener noreferrer"&gt;Scizor&lt;/a&gt; will be server-side generated at the time and you’ll see the date of any time you accessing again, so no ISG. This feature was not advertised but since it was stable at 9.3+ and I did not found work and it happens you are after this, you’ll need to wait or surprise me show-me what I’m getting wrong here because I would love to have ISG already 😀&lt;/p&gt;



&lt;p&gt;I also created a private first component for YouTube embeds if you plan to use something like this in your Next app, check it out:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/ibrahimcesar" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F189167%2F17a70416-1a55-4b86-b63d-77e0fc53f5c0.jpeg" alt="ibrahimcesar"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/ibrahimcesar/why-i-made-my-open-source-react-component-private-by-default-an-open-source-story-1jja" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Why I made my open source React component private by default: an Open Source story&lt;/h2&gt;
      &lt;h3&gt;Ibrahim Cesar ・ May 18 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#opensource&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#typescript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#privacy&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;Please leave your thoughts, takes and insights in the comments! Or problems if you have one or the solution to ISG!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>amplify</category>
      <category>nextjs</category>
      <category>react</category>
    </item>
    <item>
      <title>Why I made my open source React component private by default: an Open Source story</title>
      <dc:creator>Ibrahim Cesar</dc:creator>
      <pubDate>Tue, 18 May 2021 12:22:44 +0000</pubDate>
      <link>https://forem.com/ibrahimcesar/why-i-made-my-open-source-react-component-private-by-default-an-open-source-story-1jja</link>
      <guid>https://forem.com/ibrahimcesar/why-i-made-my-open-source-react-component-private-by-default-an-open-source-story-1jja</guid>
      <description>&lt;p&gt;I’m a big fan of open source. Because, well, we all owe to this vast collection of code, libraries, frameworks and knowledge. Just like with arts and science, we stand on the shoulders of Giants. Inspired and iterations upon previous works, adding one more chain, keeping us together. And not just in the &lt;em&gt;figurative&lt;/em&gt; sense, but &lt;em&gt;literally&lt;/em&gt;, as xkcd pointed in the “It’s funny cause is truth”, &lt;a href="https://xkcd.com/2347/" rel="noopener noreferrer"&gt;Dependency&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefwtn5lt8k8krxhcaz02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefwtn5lt8k8krxhcaz02.png" alt="Dependency"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ibrahimcesar.cloud/blog/10-livros-de-2020/" rel="noopener noreferrer"&gt;Last year, one of books&lt;/a&gt; I loved was &lt;a href="https://amzn.to/2JY2S1s" rel="noopener noreferrer"&gt;Working in Public&lt;/a&gt; from &lt;a href="https://twitter.com/nayafia" rel="noopener noreferrer"&gt;Nadia Eghbal&lt;/a&gt; whose subtitle, “The Making and Maintenance of Open Source Software” makes clear about the themes in the book: the para-social relationship between maintainers and community, the different kinds of projects in a very helpful framework and the economics of produce and maintain high quality work &lt;em&gt;for free&lt;/em&gt; for almost all projects. If you scan for reviews quickly, you’ll see someone “complaining” is not technical or doesn’t help as a maintainer... I think they just misread the book and its purposes: explore a vast topic, where each actor has its own interest, that much of our infrastructure at production today depended on, and ... &lt;em&gt;works&lt;/em&gt;. These &lt;a href="https://squidarth.com/books/2020/08/18/working-in-public.html" rel="noopener noreferrer"&gt;notes from Sid Shanker helps to summarize it&lt;/a&gt; or a more &lt;a href="https://www.techbookofthemonth.com/books/oct20" rel="noopener noreferrer"&gt;in-depth guide here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9r6mnu31usfw39occof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9r6mnu31usfw39occof.png" alt="Ehgbal’s framework"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nadia Ehgbal’s framework has four classifications: &lt;em&gt;Federations&lt;/em&gt;, &lt;em&gt;Clubs&lt;/em&gt;, &lt;em&gt;Stadiums&lt;/em&gt; and &lt;em&gt;Toys&lt;/em&gt;. My story comes from the ranks of the &lt;em&gt;toys&lt;/em&gt; – another world from those in the big categories, like the &lt;a href="https://babeljs.io/blog/2021/05/10/funding-update" rel="noopener noreferrer"&gt;post from the the Babel project, used by millions but running out of funds&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;I was fortunate enough to take part of the &lt;a href="https://www.youtube.com/playlist?list=PLNYkxOF6rcIDA1uGhqy45bqlul0VcvKMr" rel="noopener noreferrer"&gt;Chrome Developer Summit 2019&lt;/a&gt; in San Francisco (on a personal note, I propose to my wife there, in the Cupid’s Span). At the time I was finishing a project in the works in the last 6 months: a complete rewrite of our frontend. We used a Bootstrap 3.0 in a backed-in framework on our CMS, that we had basically to “shadow” properties we don’t wanted in the JSPs. It was madness. With the new offering of a headless CMS we rewrote everything in React SSR. I work at a digital only news site in Brazil. I was doing what I called “Lighthouse-Driven Development” to achieve better performance.&lt;/p&gt;

&lt;p&gt;I notice two things right away: YouTube iframe looked to load not so fast like the rest. And we don’t run ads in our sites. Of any kind. But as soon as our iframe load with our videos, every ad-blocker would point that there was an ad in the page, and traced back to the YouTube embed. Also, our embeds sometimes loaded with several little “recommendations” that don’t matched our themes exactly. But who I was to blame YouTube embed?&lt;/p&gt;

&lt;p&gt;But in one of the talks, &lt;a href="https://twitter.com/paul_irish" rel="noopener noreferrer"&gt;Paul Irish&lt;/a&gt; presented &lt;a href="https://github.com/paulirish/lite-youtube-embed" rel="noopener noreferrer"&gt;Lite YouTube Embed&lt;/a&gt;, a custom element renders just like the real thing but approximately &lt;a href="https://paulirish.github.io/lite-youtube-embed/" rel="noopener noreferrer"&gt;224× faster&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fetw31n0xk5cet7gzmhx0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fetw31n0xk5cet7gzmhx0.png" alt="Ads network"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And there, in the code, I found that I was loading at least two sources of ad for one iframe. But I was more interested in the “224x”. The project at work could not “wait”. for me work on this. But I used my free time and weekends and built &lt;a href="https://github.com/ibrahimcesar/react-lite-youtube-embed" rel="noopener noreferrer"&gt;📺 React Lite YouTube Embed&lt;/a&gt; that later became part of my project. My benchmarks never got close, but I could do a faster and cleaner way of loading iframes for our project since we would wait for user interaction, applying &lt;a href="https://www.youtube.com/watch?v=puUPpVrIRkc" rel="noopener noreferrer"&gt;Adaptive Loading&lt;/a&gt; as presented by &lt;a href="https://twitter.com/addyosmani" rel="noopener noreferrer"&gt;Addy Osmani&lt;/a&gt;—which, many of the ideas were a lot about my &lt;em&gt;every day work&lt;/em&gt; since I was dealing with very poor performance mobiles and low-quality networks that we have here in Brazil and not exception. My motivation was part solve a problem for me and part apply those ideas of respect users’s hardware and network.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1zqig24h3zhu3k5prgs.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1zqig24h3zhu3k5prgs.jpeg" alt="Addy presenting the adaptive loading"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It’s alive!
&lt;/h2&gt;

&lt;p&gt;The first release I was so afraid. Of criticism. Of put my code out there. I had to do some tweaks because when integrating with my own work I faced problems. I receive feedback, &lt;em&gt;pull requests&lt;/em&gt; and then, on the &lt;a href="https://github.com/ibrahimcesar/react-lite-youtube-embed/pull/6" rel="noopener noreferrer"&gt;6th PR&lt;/a&gt; a collaborator, &lt;a href="https://github.com/elbotho" rel="noopener noreferrer"&gt;Botho&lt;/a&gt; added a nice option &lt;code&gt;noCookie&lt;/code&gt;, when &lt;code&gt;true&lt;/code&gt;, connected to YouTube via the Privacy-Enhanced Mode using &lt;code&gt;https://www.youtube-nocookie.com&lt;/code&gt;. I already had in place &lt;code&gt;adNetwork&lt;/code&gt; to preconnect or not to the ad networks and it delighted me to get this kind of not only validation for these kind of concerns but active ideas and work towards the goal. But these privacy enhancements were all by opt-in.&lt;/p&gt;

&lt;p&gt;I was getting feedback that the component was not playing nice with &lt;code&gt;Next.JS&lt;/code&gt;. I was making a hard-coded import of the css and this would make the app not render at all. Since I was taking more and a more close look to Next.JS—and loving it! I did not want to my first open sourced my little project doesn’t give access to this framework and potentially others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Privacy by default
&lt;/h2&gt;

&lt;p&gt;At the same time in Brazil we got a new law, our own home-baked GDPR, called LGPD (Lei Geral de Proteção de dados or General Law of Data Protection) and all concerns with the massive misuse of our data. I made a course in the area to better prepare our systems (since we deal with billing for subscriptions and other kind of PII). And I was a “TypeScript newborn”, a recent converted and got the challenge to rewrite from the zero (well, is a small lib, it was not a tremendous feat!). And got me thinking about privacy, how sensitive defaults could become the norm in an invisible, but fundamental way and, I as designer of this component, decided I would make a private by default component. I would make the developer responsible for the choices or even better, be possible to give to the user these choices.&lt;/p&gt;

&lt;p&gt;How will evolve our society trusting on advertising corporations to be neutral purveyors of information when their profit depends on manipulating that information misunderstands our capitalist marketplace and the value and nature of unbiased information? I as a developer in a news media outlet was thinking on things like that and I know everyone has an approach to this, even if is “I don’t care”. So, I choose privacy by default.&lt;/p&gt;

&lt;p&gt;And this will be my choice from now on. And that PR, of a person I never meet or spoke, but that we collaborate in the same piece of code, gave me confidence in my choices.&lt;/p&gt;




&lt;p&gt;And this is my first open source project, on &lt;code&gt;2.0&lt;/code&gt; since the TypeScript migration.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ibrahimcesar" rel="noopener noreferrer"&gt;
        ibrahimcesar
      &lt;/a&gt; / &lt;a href="https://github.com/ibrahimcesar/react-lite-youtube-embed" rel="noopener noreferrer"&gt;
        react-lite-youtube-embed
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      📺 ‏‏‎ ‎‏‏‎ ‎‏‏‎ ‎&amp;lt; A private by default, faster and cleaner YouTube embed component for React applications /&amp;gt;
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt; &lt;div&gt;
  &lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;📺  React Lite YouTube Embed&lt;/h1&gt;
&lt;/div&gt;
  &lt;blockquote&gt;A private by default, faster and cleaner YouTube embed component for React applications&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://www.typescriptlang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/722fbbb8b605651efe6834f674a02f275b4352d1f39ac64fb7a7dd30592b69cc/68747470733a2f2f6261646765732e66726170736f66742e636f6d2f747970657363726970742f636f64652f747970657363726970742e7376673f763d313031" alt="TypeScript"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/react-lite-youtube-embed" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/65252d89fd8800a2f434d80e316e5ff37b3bfbb829391f1cf5dee919116ab5b9/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f72656163742d6c6974652d796f75747562652d656d6265643f6c6162656c3d6c617465737425323076657273696f6e" alt="Version"&gt;&lt;/a&gt;      &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/2c6a66a875496d589118ea964627b0939d3d342903c08ecdb9ae06dae739db3e/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f64742f72656163742d6c6974652d796f75747562652d656d6265643f636f6c6f723d253233464630303030266c6f676f3d6e706d"&gt;&lt;img src="https://camo.githubusercontent.com/2c6a66a875496d589118ea964627b0939d3d342903c08ecdb9ae06dae739db3e/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f64742f72656163742d6c6974652d796f75747562652d656d6265643f636f6c6f723d253233464630303030266c6f676f3d6e706d" alt="Total Downloads"&gt;&lt;/a&gt;      &lt;a href="https://github.com/ibrahimcesar/react-lite-youtube-embed./LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b8ca6bd7227df380243d8e8ad6627bc7c5e337b34085e71a864c1099074331a0/68747470733a2f2f62616467656e2e6e65742f6769746875622f6c6963656e73652f6962726168696d63657361722f72656163742d6c6974652d796f75747562652d656d626564" alt="License"&gt;&lt;/a&gt;      &lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/139c63dbd550bb04221a87e208cb5afd6e391147d3ba9381243741a2b33d6ef5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6962726168696d63657361722f72656163742d6c6974652d796f75747562652d656d6265642f627567"&gt;&lt;img src="https://camo.githubusercontent.com/139c63dbd550bb04221a87e208cb5afd6e391147d3ba9381243741a2b33d6ef5/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732f6962726168696d63657361722f72656163742d6c6974652d796f75747562652d656d6265642f627567" alt="GitHub issues by-label"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Developed in 🇧🇷 &lt;span&gt;Brazil&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Port of Paul Irish's &lt;a href="https://github.com/paulirish/lite-youtube-embed" rel="noopener noreferrer"&gt;Lite YouTube Embed&lt;/a&gt; to a React Component. Provide videos with a supercharged focus on visual performance. The gain is not the same as the web component of the original implementation but saves some requests and gives you more control of the embed visual. An &lt;a href="https://www.youtube.com/watch?v=puUPpVrIRkc" rel="nofollow noopener noreferrer"&gt;"Adaptive Loading"&lt;/a&gt; way to handle iframes for YouTube.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://main.d1vubvlhfep0xm.amplifyapp.com/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fibrahimcesar%2Freact-lite-youtube-embed_example_lite.gif" alt="iFrame example"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&lt;a href="https://main.d1vubvlhfep0xm.amplifyapp.com/" rel="nofollow noopener noreferrer"&gt;View Demo&lt;/a&gt;&lt;/h2&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🔒 Up 2.0.0 Privacy by Default&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The biggest change is, from 2.0.0 this component is private by default. Meaning that will not preconnect with the ad network from Google and connect to YouTube via the Privacy-Enhanced Mode using &lt;a href="https://www.youtube-nocookie.com" rel="nofollow noopener noreferrer"&gt;https://www.youtube-nocookie.com&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Install&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Use your favorite package manager:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;yarn add react-lite-youtube-embed&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm install react-lite-youtube-embed -S&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🕹️ Basic Usage&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-js notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-v"&gt;React&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;"react"&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-kos"&gt;{&lt;/span&gt; &lt;span class="pl-s1"&gt;render&lt;/span&gt; &lt;span class="pl-kos"&gt;}&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;"react-dom"&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-k"&gt;import&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ibrahimcesar/react-lite-youtube-embed" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Please leave your thoughts, takes and insights in the comments!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@christianw?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Christian Wiediger&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/youtube?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>opensource</category>
      <category>typescript</category>
      <category>privacy</category>
    </item>
  </channel>
</rss>
