<?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>DEV Community: ayka.code</title>
    <description>The latest articles on DEV Community by ayka.code (@ayka_code).</description>
    <link>https://dev.to/ayka_code</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F681714%2Fcc843730-80c3-4aa5-984b-fb4aaa76bb0f.jpg</url>
      <title>DEV Community: ayka.code</title>
      <link>https://dev.to/ayka_code</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ayka_code"/>
    <language>en</language>
    <item>
      <title>The Complete Developer's Guide to the HTTP Request/Response Lifecycle</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Wed, 05 Aug 2026 17:17:47 +0000</pubDate>
      <link>https://dev.to/ayka_code/the-complete-developers-guide-to-the-http-requestresponse-lifecycle-24na</link>
      <guid>https://dev.to/ayka_code/the-complete-developers-guide-to-the-http-requestresponse-lifecycle-24na</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;From DNS resolution to TCP handshakes and raw headers—here is exactly what happens when your client sends a GET request.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;The HTTP Request/Response Lifecycle is the synchronous network protocol execution loop through which a client establishes a connection, negotiates a security context, and exchanges structured headers and payloads with a remote server over TCP/IP.&lt;/p&gt;

&lt;p&gt;In today's landscape of abstract, zero-configuration cloud hosts, it's easy to forget that beneath every Next.js route or AI agent API call lies a physical sequence of raw socket writes, DNS recursive traversals, and cryptographic handshakes.&lt;/p&gt;

&lt;p&gt;Understanding these transport-layer mechanics is not academic; it is the boundary between an application that breaks under load and a robust, scalable system that performs gracefully at production scale.&lt;/p&gt;

&lt;p&gt;In this guide, we'll bypass framework-specific abstractions and trace the exact, step-by-step physical journey of an HTTP request.&lt;/p&gt;

&lt;p&gt;We'll dissect raw socket interfaces, analyze packet sequence structures, and write a functional client using low-level Go socket primitives to see the protocol in its purest form.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. Phase 1: Domain Name System (DNS) Recursive Resolution
&lt;/h1&gt;

&lt;p&gt;Before a single socket can be opened, the client must resolve the human-readable domain name into a routable physical IP address.&lt;/p&gt;

&lt;p&gt;The process of translating &lt;code&gt;dev.to&lt;/code&gt; into an IP address is a highly optimized, hierarchical lookup sequence designed to minimize latency and protect root network resources.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Local Resolution Chain
&lt;/h2&gt;

&lt;p&gt;The operating system resolver first attempts to fulfill the query locally to bypass network latency.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Browser Cache&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern browsers maintain their own DNS caches with strict, short Time-to-Live (TTL) expiration frames.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OS Resolver Cache&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The browser executes a system call (typically &lt;code&gt;getaddrinfo()&lt;/code&gt; on Unix-like systems).&lt;/p&gt;

&lt;p&gt;The OS resolver first checks its local static mapping file (&lt;code&gt;/etc/hosts&lt;/code&gt;) before searching its system-level DNS cache.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Local Router / ISP Cache&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the record is missing, the resolver queries the Local DNS Server configured via DHCP (usually your router or ISP resolver).&lt;/p&gt;




&lt;h2&gt;
  
  
  The Recursive Resolution Loop
&lt;/h2&gt;

&lt;p&gt;If the record remains unresolved, the recursive DNS resolver initiates a multi-step query loop across the global DNS hierarchy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ OS Resolver ] --(1. Query: dev.to)--&amp;gt; [ Recursive Resolver ]
                                               |
        +--------------------------------------+--------------------------------------+
        | (2. Query .)                         | (4. Query .to)                       | (6. Query dev.to)
        v                                      v                                      v
  [ Root Name Server ]                  [ TLD Name Server ]                  [ Authoritative Name Server ]
  (Returns .to NS)                      (Returns dev.to NS)                  (Returns A/AAAA IP Record)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Root Nameservers (&lt;code&gt;.&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;The recursive resolver queries one of the 13 logical root nameservers.&lt;/p&gt;

&lt;p&gt;The root server does not know the IP address of &lt;code&gt;dev.to&lt;/code&gt;, but it returns the name servers responsible for the requested top-level domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  TLD Nameservers (&lt;code&gt;.to&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;The resolver queries the &lt;code&gt;.to&lt;/code&gt; TLD nameserver.&lt;/p&gt;

&lt;p&gt;It responds with the authoritative name servers responsible for &lt;code&gt;dev.to&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authoritative Nameservers
&lt;/h3&gt;

&lt;p&gt;Finally, the resolver contacts the authoritative DNS server.&lt;/p&gt;

&lt;p&gt;This server returns either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an &lt;strong&gt;A Record (IPv4)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an &lt;strong&gt;AAAA Record (IPv6)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The IP address is then cached locally and returned to the browser.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. Phase 2: Transport Layer Connectivity — TCP &amp;amp; TLS 1.3
&lt;/h1&gt;

&lt;p&gt;Once the destination IP is acquired, the client initiates transport layer connectivity.&lt;/p&gt;

&lt;p&gt;Since HTTP relies on TCP for reliable, ordered delivery of data streams, a TCP connection must first be established.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Port &lt;strong&gt;80&lt;/strong&gt; → HTTP&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Port &lt;strong&gt;443&lt;/strong&gt; → HTTPS&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The TCP Three-Way Handshake
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client                                                  Server
  |                                                       |
  | -------- SYN (Seq = X) -----------------------------&amp;gt; |
  |                                                       |
  | &amp;lt;------- SYN-ACK (Seq = Y, Ack = X + 1) ------------ |
  |                                                       |
  | -------- ACK (Ack = Y + 1) -------------------------&amp;gt; |
  V                                                       V
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. SYN
&lt;/h3&gt;

&lt;p&gt;The client transmits a TCP segment with the SYN flag set.&lt;/p&gt;

&lt;p&gt;A random Initial Sequence Number (ISN) is generated.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. SYN-ACK
&lt;/h3&gt;

&lt;p&gt;The server allocates TCP buffers, generates its own sequence number, and acknowledges the client's sequence.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. ACK
&lt;/h3&gt;

&lt;p&gt;The client acknowledges the server.&lt;/p&gt;

&lt;p&gt;The TCP connection is now established.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Cryptographic Dance: TLS 1.3
&lt;/h2&gt;

&lt;p&gt;TLS 1.3 reduces connection setup from two round trips (TLS 1.2) to a single round trip.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Client Hello
&lt;/h3&gt;

&lt;p&gt;The client sends:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supported TLS versions&lt;/li&gt;
&lt;li&gt;Supported cipher suites&lt;/li&gt;
&lt;li&gt;ECDHE public key&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2 — Server Hello
&lt;/h3&gt;

&lt;p&gt;The server returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selected cipher suite&lt;/li&gt;
&lt;li&gt;Server certificate&lt;/li&gt;
&lt;li&gt;Server public key&lt;/li&gt;
&lt;li&gt;Handshake signature&lt;/li&gt;
&lt;li&gt;Finished message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both parties independently compute the same symmetric session key.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — Client Finished
&lt;/h3&gt;

&lt;p&gt;The client verifies the certificate, validates the signature, computes the shared secret, and sends an encrypted Finished message.&lt;/p&gt;

&lt;p&gt;From this point onward, every byte written to the TCP socket is encrypted.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. Phase 3: Inside the Raw HTTP Request
&lt;/h1&gt;

&lt;p&gt;With TLS established, the browser constructs the actual HTTP request.&lt;/p&gt;

&lt;p&gt;Instead of using &lt;code&gt;net/http&lt;/code&gt;, we'll manually build and transmit an HTTP request over a raw socket.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"crypto/tls"&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"io"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"dev.to"&lt;/span&gt;
    &lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"443"&lt;/span&gt;
    &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JoinHostPort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Step 1: Establish low-level TCP Connection&lt;/span&gt;
    &lt;span class="n"&gt;tcpConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to establish TCP connection: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&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;defer&lt;/span&gt; &lt;span class="n"&gt;tcpConn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[+] Established TCP Connection to %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Step 2: Wrap TCP connection in TLS&lt;/span&gt;
    &lt;span class="n"&gt;tlsConfig&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;tls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ServerName&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;MinVersion&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VersionTLS13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;tlsConn&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tcpConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tlsConfig&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tlsConn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Handshake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TLS Handshake failed: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"[+] Established TLS 1.3 Session. Cipher Suite: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;tls&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CipherSuiteName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;tlsConn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CipherSuite&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="c"&gt;// Step 3: Construct raw HTTP request&lt;/span&gt;
    &lt;span class="n"&gt;httpRequest&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt;
        &lt;span class="s"&gt;"GET / HTTP/1.1&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"Host: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"User-Agent: RawGoSocketClient/1.0&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"Accept: text/html,application/xhtml+xml&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"Connection: close&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;

    &lt;span class="c"&gt;// Step 4: Send request&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tlsConn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;httpRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Failed to write HTTP request: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[+] Sent Raw HTTP GET Request:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;httpRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// Step 5: Read response&lt;/span&gt;
    &lt;span class="n"&gt;responseBuffer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;([]&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tlsConn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseBuffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EOF&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatalf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error reading response bytes: %v"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[+] Received Raw Response Bytes:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseBuffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Deconstructing the HTTP Request Structure
&lt;/h2&gt;

&lt;p&gt;A raw HTTP request consists of three logical sections.&lt;/p&gt;

&lt;h3&gt;
  
  
  Request Line
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET&lt;/code&gt; → HTTP Method&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/&lt;/code&gt; → Requested resource&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HTTP/1.1&lt;/code&gt; → Protocol version&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Headers
&lt;/h3&gt;

&lt;p&gt;Headers provide metadata about the request.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Host: dev.to
User-Agent: RawGoSocketClient/1.0
Accept: text/html
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Host&lt;/code&gt; header is mandatory in HTTP/1.1 because servers often host multiple websites on the same IP.&lt;/p&gt;




&lt;h3&gt;
  
  
  Blank Line
&lt;/h3&gt;

&lt;p&gt;A mandatory &lt;code&gt;\r\n\r\n&lt;/code&gt; separates the headers from the body.&lt;/p&gt;

&lt;p&gt;If this were a POST request, the JSON payload would begin immediately afterward.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. Phase 4: Server Processing and the Raw HTTP Response
&lt;/h1&gt;

&lt;p&gt;When encrypted bytes arrive at the server's Network Interface Card (NIC), the operating system passes them to the listening web server.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NGINX&lt;/li&gt;
&lt;li&gt;HAProxy&lt;/li&gt;
&lt;li&gt;Apache&lt;/li&gt;
&lt;li&gt;Go binaries&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Server Processing Loop
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;TLS Decryption&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Parse the HTTP stream&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Route the request&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Authentication / Authorization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Database queries&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Construct the response&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send the response back through the encrypted TLS socket&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Raw HTTP Response
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;text/html; charset=utf-8&lt;/span&gt;
&lt;span class="na"&gt;Content-Length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1042&lt;/span&gt;
&lt;span class="na"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;close&lt;/span&gt;
&lt;span class="na"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Wed, 05 Aug 2026 11:56:15 GMT&lt;/span&gt;
&lt;span class="na"&gt;Cache-Control&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;public, max-age=3600&lt;/span&gt;
&lt;span class="na"&gt;ETag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"9b4d186f-52fe"&lt;/span&gt;

&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;DEV Community&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Welcome to DEV!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Response Structure
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Status Line
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;200&lt;/span&gt; &lt;span class="ne"&gt;OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Protocol&lt;/li&gt;
&lt;li&gt;Status code&lt;/li&gt;
&lt;li&gt;Status text&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Headers
&lt;/h3&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Content-Type&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Content-Length&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Cache-Control&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ETag&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Blank Line
&lt;/h3&gt;

&lt;p&gt;Separates headers from the response body.&lt;/p&gt;




&lt;h3&gt;
  
  
  Body
&lt;/h3&gt;

&lt;p&gt;The actual resource:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTML&lt;/li&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  5. Phase 5: Performance Optimization &amp;amp; Caching Boundaries
&lt;/h1&gt;

&lt;p&gt;To protect origin servers and reduce latency, modern applications rely heavily on caching.&lt;/p&gt;




&lt;h2&gt;
  
  
  Browser Cache
&lt;/h2&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Cache-Control: max-age=31536000, immutable
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This instructs the browser to reuse the resource without contacting the server for up to one year.&lt;/p&gt;




&lt;h2&gt;
  
  
  ETags and Conditional Requests
&lt;/h2&gt;

&lt;p&gt;Suppose the cached asset expires.&lt;/p&gt;

&lt;p&gt;Instead of downloading the file again, the browser sends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;If-None-Match: "9b4d186f-52fe"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the file has not changed, the server responds with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;304 Not Modified
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No body is transmitted, saving bandwidth.&lt;/p&gt;




&lt;h2&gt;
  
  
  CDN Edge Caching
&lt;/h2&gt;

&lt;p&gt;Content Delivery Networks (CDNs) cache static assets at servers geographically close to users.&lt;/p&gt;

&lt;p&gt;Instead of reaching the origin server, clients receive content from nearby edge locations.&lt;/p&gt;

&lt;p&gt;Benefits include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lower latency&lt;/li&gt;
&lt;li&gt;Faster page loads&lt;/li&gt;
&lt;li&gt;Reduced origin server load&lt;/li&gt;
&lt;li&gt;Improved Largest Contentful Paint (LCP)&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;The HTTP request/response lifecycle is a highly choreographed protocol sequence executed millions of times per second.&lt;/p&gt;

&lt;p&gt;Behind the elegant abstractions of modern frameworks lies a transport layer governed by strict rules of synchronization, validation, and encryption.&lt;/p&gt;

&lt;p&gt;By understanding the complete journey your data takes—from DNS resolution to TCP connectivity, TLS encryption, HTTP message construction, server processing, and caching—you gain the systems-level knowledge needed to build faster, more resilient, and production-ready applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aymenkani.gumroad.com/" rel="noopener noreferrer"&gt;Follow me&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>networking</category>
      <category>go</category>
      <category>performance</category>
    </item>
    <item>
      <title>📐👷🏻‍♂️🏛️ | A quick architecture challenge for you - Rate-limiting</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Tue, 28 Jul 2026 10:38:30 +0000</pubDate>
      <link>https://dev.to/ayka_code/-a-quick-architecture-challenge-for-you-rate-limiting-55pp</link>
      <guid>https://dev.to/ayka_code/-a-quick-architecture-challenge-for-you-rate-limiting-55pp</guid>
      <description>&lt;p&gt;Hi there,&lt;/p&gt;

&lt;p&gt;I just shared a new visual lesson on X, and I thought you'd enjoy it.&lt;/p&gt;

&lt;p&gt;It's a simple architecture challenge:&lt;/p&gt;

&lt;p&gt;You're building an LLM generation API.&lt;/p&gt;

&lt;p&gt;Which rate-limiting algorithm would you choose?&lt;/p&gt;

&lt;p&gt;Token Bucket?&lt;/p&gt;

&lt;p&gt;Sliding Window Counter?&lt;/p&gt;

&lt;p&gt;The first image presents a real-world scenario and lets you think through the problem on your own. The second image walks through the reasoning, explains how both algorithms work, and shows when each one is the better choice in production.&lt;/p&gt;

&lt;p&gt;If you enjoy learning through visual diagrams instead of long articles, I think you'll like this one.&lt;/p&gt;

&lt;p&gt;Check out the post here 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/elKaniAymen/status/2079513865809776879" rel="noopener noreferrer"&gt;📐👷🏻‍♂️🏛️ | A quick architecture challenge for you - Rate-limiting&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you're not following me on X yet, consider following me there. I regularly share practical backend architecture, system design, Node.js, DevOps, security, and distributed systems content that doesn't always make it into my courses or emails.&lt;/p&gt;

&lt;p&gt;Thanks for being part of this community, and I'd love to know which algorithm you picked before seeing the answer.&lt;/p&gt;

</description>
      <category>api</category>
      <category>ratelimiting</category>
      <category>ai</category>
      <category>llm</category>
    </item>
    <item>
      <title>Build a Serverless RAG Engine for with Gemini chatbot and deploy it for $0</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Fri, 13 Feb 2026 12:30:01 +0000</pubDate>
      <link>https://dev.to/ayka_code/build-a-serverless-rag-engine-for-0-3jop</link>
      <guid>https://dev.to/ayka_code/build-a-serverless-rag-engine-for-0-3jop</guid>
      <description>&lt;h3&gt;
  
  
  Master modern AI architecture with Node.js, Gemini 2.5, and Cloudflare R2
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://aymenkani.gumroad.com/l/nodejs-enterprise-launchpad/UDEMY-VIP?price=4&amp;amp;option=2nCmfCVPlr707OzzOD7UGA%3D%3D&amp;amp;_gl=1*1kk0qxj*_ga*NTYyNDU1Mjc4LjE3NjA5NzUzNDg.*_ga_6LJN6D94N6*czE3NzA5ODQ2NzkkbzQ4MyRnMSR0MTc3MDk4NDY5OCRqNDEkbDAkaDA." rel="noopener noreferrer"&gt;Get the Source Code &amp;amp; Template Here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://aymenkani.github.io/nodeJs-multimodal-rag-starter/rag-pipeline/" rel="noopener noreferrer"&gt;Read the full tutorial here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction: The Problem with "Toy" RAG Apps
&lt;/h2&gt;

&lt;p&gt;Most RAG tutorials skip the hard parts that actually matter in production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No security model:&lt;/strong&gt; Users can access each other's private data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Naive file handling:&lt;/strong&gt; Large uploads crash your Node.js server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expensive infra:&lt;/strong&gt; AWS egress fees and managed vector DBs drain your wallet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blocking operations:&lt;/strong&gt; Processing files freezes your entire API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are going to solve all of these using a production-proven architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  The $0 Tech Stack
&lt;/h3&gt;

&lt;p&gt;Every piece of this stack has a generous free tier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare R2:&lt;/strong&gt; S3-compatible storage with &lt;strong&gt;zero egress fees&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini 2.5 Flash:&lt;/strong&gt; High-performance LLM with a free tier of 15 requests/minute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL + pgvector:&lt;/strong&gt; Battle-tested database with native vector support.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BullMQ:&lt;/strong&gt; Redis-backed job queue to handle heavy processing in the background.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Understanding the Architecture
&lt;/h2&gt;

&lt;p&gt;We follow a 4-phase workflow designed for scale:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Direct-to-Cloud Uploads:&lt;/strong&gt; Browser uploads files directly to R2 using presigned URLs. Your server never touches the raw bytes, preventing memory crashes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous Ingestion:&lt;/strong&gt; A BullMQ worker handles the "heavy lifting"—downloading, chunking, and embedding—without blocking your API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid Retrieval:&lt;/strong&gt; We use PostgreSQL row-level security so users only search their own data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contextual Generation:&lt;/strong&gt; Gemini generates answers with &lt;strong&gt;smart citations&lt;/strong&gt; (temporary links to the source files).&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Step 2: Zero-Cost Storage with Cloudflare R2
&lt;/h2&gt;

&lt;p&gt;Traditional uploads stream data through your server. If 10 users upload 50MB files simultaneously, your server spikes by 500MB and likely crashes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution: The Reservation Pattern&lt;/strong&gt;&lt;br&gt;
We issue a time-limited &lt;strong&gt;Presigned URL&lt;/strong&gt;. The browser sends the file directly to Cloudflare.&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;// Backend: Generate the permission&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;signedUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileId&lt;/span&gt; &lt;span class="p"&gt;}&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;uploadService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateSignedUrl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;fileType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;fileSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;isPublic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; 
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;signedUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fileId&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Contextual Query Rewriting
&lt;/h2&gt;

&lt;p&gt;If a user asks "Who is the CEO of Tesla?" followed by "What about SpaceX?", a naive vector search for "What about SpaceX?" will fail because it lacks context.&lt;/p&gt;

&lt;p&gt;We use &lt;strong&gt;Gemma 3-12B&lt;/strong&gt; to rewrite queries in ~200ms:&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;// User: "What about SpaceX?"&lt;/span&gt;
&lt;span class="c1"&gt;// Gemma Rewrites: "Who is the CEO of SpaceX?"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This ensures your vector search actually finds the right documents.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Hybrid Search with Row-Level Security
&lt;/h2&gt;

&lt;p&gt;Multi-tenancy is the biggest hurdle in RAG. You can't let User A see User B's documents. Instead of filtering in JavaScript (which is slow and buggy), we do it in &lt;strong&gt;SQL&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"originalName"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;vectorQuery&lt;/span&gt;&lt;span class="p"&gt;}::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="nv"&gt;"Document"&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="nv"&gt;"File"&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"fileId"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"userId"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"isPublic"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;distance&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This enforces security at the database layer. No accidental data leaks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Visual RAG - Understanding Images
&lt;/h2&gt;

&lt;p&gt;Traditional RAG is text-only. If you upload a receipt, most systems fail. We use &lt;strong&gt;Gemini Vision&lt;/strong&gt; to describe the image in detail, then embed that description.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input&lt;/th&gt;
&lt;th&gt;Gemini Vision Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Photo of coffee receipt&lt;/td&gt;
&lt;td&gt;"Starbucks receipt, Jan 15, 2026. Grande Latte $5.45. Paid with Visa..."&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now, when you search "How much did I spend at Starbucks?", the system finds the &lt;strong&gt;image&lt;/strong&gt; because of its semantic description.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion: Build vs Buy
&lt;/h2&gt;

&lt;p&gt;Commercial RAG solutions can cost &lt;strong&gt;$1,900+/year&lt;/strong&gt;. By building this architecture, you save that money while gaining skills in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Distributed systems (BullMQ)&lt;/li&gt;
&lt;li&gt;Vector Database optimization (pgvector)&lt;/li&gt;
&lt;li&gt;Cloud Security (Presigned URLs)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🚀 Want the Full Source Code?
&lt;/h3&gt;

&lt;p&gt;If you want to save 40+ hours of setup, I’ve packaged this entire production-ready architecture into the &lt;strong&gt;Node.js Enterprise Launchpad&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standard Price:&lt;/strong&gt; $20&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Launch Special:&lt;/strong&gt; &lt;strong&gt;$4 (80% OFF)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It includes the RAG pipeline, Auth, RBAC, Socket.io, and Docker configurations.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://aymenkani.gumroad.com/l/nodejs-enterprise-launchpad/UDEMY-VIP?price=4&amp;amp;option=2nCmfCVPlr707OzzOD7UGA%3D%3D&amp;amp;_gl=1*1kk0qxj*_ga*NTYyNDU1Mjc4LjE3NjA5NzUzNDg.*_ga_6LJN6D94N6*czE3NzA5ODQ2NzkkbzQ4MyRnMSR0MTc3MDk4NDY5OCRqNDEkbDAkaDA." rel="noopener noreferrer"&gt;Get the Source Code &amp;amp; Template Here&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>prisma</category>
      <category>rag</category>
      <category>ai</category>
    </item>
    <item>
      <title>Build Your First REST API with Node.js and Express (in 15 Minutes)</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Tue, 10 Jun 2025 09:58:58 +0000</pubDate>
      <link>https://dev.to/ayka_code/build-your-first-rest-api-with-nodejs-and-express-in-15-minutes-5hb7</link>
      <guid>https://dev.to/ayka_code/build-your-first-rest-api-with-nodejs-and-express-in-15-minutes-5hb7</guid>
      <description>&lt;p&gt;Learning backend development might seem overwhelming at first — databases, APIs, routing, deployment — where do you even start?&lt;/p&gt;

&lt;p&gt;Well, here's some good news: You can build your first backend API using Node.js and Express in just 15 minutes. And by the end of this post, you'll have your own working API ready to go!&lt;/p&gt;

&lt;p&gt;Let’s jump right in 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 What We're Building
&lt;/h2&gt;

&lt;p&gt;A simple Books API with 3 routes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /books&lt;/code&gt; — List all books&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /books&lt;/code&gt; — Add a new book&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /books/:id&lt;/code&gt; — Get a book by ID&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🛠️ Step 1: Setup Your Project
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir books-api
cd books-api
npm init -y
npm install express

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

&lt;/div&gt;



&lt;p&gt;Create a file named index.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Step 2: Create a Simple Express Server
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
const app = express();
const port = 3000;

app.use(express.json()); // for parsing JSON

app.listen(port, () =&amp;gt; {
  console.log(`Server is running on http://localhost:${port}`);
});

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

&lt;/div&gt;



&lt;p&gt;Run the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node index.js

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  📚 Step 3: Add Book Routes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let books = [
  { id: 1, title: 'Clean Code' },
  { id: 2, title: 'The Pragmatic Programmer' },
];

// GET all books
app.get('/books', (req, res) =&amp;gt; {
  res.json(books);
});

// GET a book by ID
app.get('/books/:id', (req, res) =&amp;gt; {
  const book = books.find(b =&amp;gt; b.id === parseInt(req.params.id));
  if (!book) return res.status(404).send('Book not found');
  res.json(book);
});

// POST a new book
app.post('/books', (req, res) =&amp;gt; {
  const book = {
    id: books.length + 1,
    title: req.body.title,
  };
  books.push(book);
  res.status(201).json(book);
});

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

&lt;/div&gt;



&lt;p&gt;Now you can:&lt;/p&gt;

&lt;p&gt;Use Postman or Insomnia to send GET, POST requests&lt;/p&gt;

&lt;p&gt;Try it out at &lt;code&gt;http://localhost:3000/books&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🌱 What You Just Learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How to set up an Express server&lt;/li&gt;
&lt;li&gt;Basic routing in Node.js&lt;/li&gt;
&lt;li&gt;Handling JSON input&lt;/li&gt;
&lt;li&gt;Working with dynamic route parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the &lt;strong&gt;first step&lt;/strong&gt; toward building real-world backend applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎓 Want to Go Deeper?
&lt;/h2&gt;

&lt;p&gt;This was just a glimpse into what you can build with Node.js. If you enjoyed this, I've created a full all-in-one backend development course that covers:&lt;/p&gt;

&lt;p&gt;✅ Node.js, Express, TypeScript&lt;br&gt;
✅ MongoDB, PostgreSQL, Mongoose&lt;br&gt;
✅ REST &amp;amp; GraphQL APIs&lt;br&gt;
✅ Authentication, Stripe, Docker&lt;br&gt;
✅ GitHub Actions, CI/CD, and more&lt;/p&gt;

&lt;h2&gt;
  
  
  🎁 Grab the course with two options:
&lt;/h2&gt;

&lt;p&gt;💸 Support the course (only $9.99):&lt;br&gt;
&lt;a href="https://www.udemy.com/course/express-typescript-nodejs-mongodb-more-the-real-path/?couponCode=93AC6D647A1F2AD85580" rel="noopener noreferrer"&gt;https://www.udemy.com/course/express-typescript-nodejs-mongodb-more-the-real-path/?couponCode=93AC6D647A1F2AD85580&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🙌 Get it free (for early learners):&lt;br&gt;
&lt;a href="https://www.udemy.com/course/express-typescript-nodejs-mongodb-more-the-real-path/?couponCode=FA39975BFDE32309993C" rel="noopener noreferrer"&gt;https://www.udemy.com/course/express-typescript-nodejs-mongodb-more-the-real-path/?couponCode=FA39975BFDE32309993C&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Learn Node.js Before React.js: Mastering Node.js as Your First Step Towards Full-Stack Domination</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Sun, 02 Jul 2023 12:27:02 +0000</pubDate>
      <link>https://dev.to/ayka_code/why-choose-nodejs-over-reactjs-mastering-nodejs-as-your-first-step-towards-full-stack-domination-111m</link>
      <guid>https://dev.to/ayka_code/why-choose-nodejs-over-reactjs-mastering-nodejs-as-your-first-step-towards-full-stack-domination-111m</guid>
      <description>&lt;p&gt;Are you an aspiring JavaScript developer looking to expand your skills and embark on a journey towards becoming a full-stack developer? It's time to make a smart choice that sets a solid foundation for your programming career. In this blog post, we'll explore why starting with Node.js is the best way to kickstart your full-stack development journey. By the end, you'll understand the immense potential Node.js holds and why investing in my comprehensive Node.js course on Udemy is the perfect next step for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Node.js before React?
&lt;/h2&gt;

&lt;p&gt;While React is undoubtedly a powerful front-end library, mastering Node.js first opens up a world of opportunities that will enhance your overall development prowess. Here are three compelling reasons to prioritize Node.js before diving into React:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Full-Stack Synchronization&lt;/strong&gt;: Node.js enables you to build both the server-side and client-side components of your application using a single language, JavaScript. This synchronicity results in smoother collaboration between the front-end and back-end teams, facilitating faster development cycles and efficient code sharing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Unleashing JavaScript Everywhere&lt;/strong&gt;: By focusing on Node.js, you solidify your understanding of JavaScript and unlock its full potential on the server-side. This empowers you to build scalable and high-performance web applications, handle real-time communication with ease, and even dive into areas like machine learning and Internet of Things (IoT).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Broader Career Opportunities&lt;/strong&gt;: Node.js has seen a rapid rise in popularity, with numerous enterprises and startups adopting it as their go-to backend solution. Mastering Node.js not only equips you with in-demand skills but also broadens your job prospects and increases your earning potential as a full-stack developer.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Introducing&lt;/em&gt;: &lt;a href="https://www.udemy.com/course/express-typescript-nodejs-mongodb-more-the-real-path/?couponCode=3187F3E03D7BF90E6664" rel="noopener noreferrer"&gt;Nodejs, Express, Typescript, MongoDb &amp;amp; more: The real path Course&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%2Flmt0qxlgij6jx5nlwj73.jpg" 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%2Flmt0qxlgij6jx5nlwj73.jpg" alt="course,Nodejs, Express, Typescript, MongoDb &amp;amp; more: The real path"&gt;&lt;/a&gt;&lt;br&gt;
Ready to take the leap and become a proficient Node.js developer? My course, "&lt;a href="https://www.udemy.com/course/express-typescript-nodejs-mongodb-more-the-real-path/?couponCode=3187F3E03D7BF90E6664" rel="noopener noreferrer"&gt;Nodejs, Express, Typescript, MongoDb &amp;amp; more: The real path&lt;/a&gt;," on Udemy is designed with your learning journey in mind. Here's what you can expect:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Comprehensive Curriculum:&lt;/strong&gt; Learn the ins and outs of Node.js, including advanced concepts and best practices. Dive into TypeScript, a statically typed superset of JavaScript, to enhance your code quality and development experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Building a Shopping API:&lt;/strong&gt; Construct a robust shopping API from scratch, incorporating essential features like user authentication, product listing, cart management, and seamless payment integration using Stripe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Real-World Projects:&lt;/strong&gt; Develop practical skills by working on hands-on projects that mimic real-life scenarios. Gain confidence in building scalable APIs and deploying them to production environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Engaging Learning Experience:&lt;/strong&gt; Benefit from clear explanations, code samples, and quizzes to solidify your understanding of Node.js and TypeScript concepts. The course also provides ongoing support and a vibrant community to assist you along your learning journey.&lt;/p&gt;

&lt;p&gt;Choosing the right path for your full-stack development career is crucial. By starting with Node.js, you'll acquire a versatile skill set that empowers you to create powerful applications across the entire tech stack. Take the next step today by &lt;a href="https://www.udemy.com/course/express-typescript-nodejs-mongodb-more-the-real-path/?couponCode=3187F3E03D7BF90E6664" rel="noopener noreferrer"&gt;enrolling&lt;/a&gt; in my "&lt;em&gt;Nodejs, Express, Typescript, MongoDb &amp;amp; more: The real path&lt;/em&gt;" course on Udemy. Unleash your potential, become a sought-after developer, and embark on an exciting journey towards full-stack domination.&lt;/p&gt;

&lt;p&gt;Don't wait—invest in your future now!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
    <item>
      <title>The Ultimate GraphQL and Apollo Server Course with Express and TypeScript</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Sun, 23 Apr 2023 07:39:04 +0000</pubDate>
      <link>https://dev.to/ayka_code/the-ultimate-graphql-and-apollo-server-course-with-express-and-typescript-3e46</link>
      <guid>https://dev.to/ayka_code/the-ultimate-graphql-and-apollo-server-course-with-express-and-typescript-3e46</guid>
      <description>&lt;p&gt;Are you ready to take your API development skills to the next level? Look no further than *&lt;em&gt;&lt;a href="https://www.udemy.com/course/graphql-with-apollo-and-express-a-hands-on-approach/?couponCode=0C20D4C1B119BFE95197"&gt;The Ultimate GraphQL and Apollo Server Course with Express and TypeScript! (9.99$ for limited time!)&lt;/a&gt;&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
In this comprehensive course, we'll start with the basics of GraphQL and Apollo Server and gradually move on to more advanced topics. You'll learn how to use GraphQL with Apollo and advanced tools and technologies to build powerful APIs.&lt;/p&gt;

&lt;p&gt;We'll cover key concepts like queries, mutations, and schemas, as well as advanced topics like &lt;strong&gt;SocketIo, JWT,&lt;/strong&gt; and &lt;strong&gt;database migration&lt;/strong&gt; with &lt;strong&gt;TypeORM&lt;/strong&gt;. You'll also learn how to work with TypeORM and use Postgres with &lt;strong&gt;Docker&lt;/strong&gt;, giving you the tools you need to build scalable and efficient APIs.&lt;/p&gt;

&lt;p&gt;The teaching is clear and the content is comprehensive, making this course the ultimate resource for developers looking to master &lt;strong&gt;GraphQL&lt;/strong&gt; and &lt;strong&gt;Apollo Server&lt;/strong&gt; with &lt;strong&gt;TypeScript&lt;/strong&gt; and &lt;strong&gt;Express&lt;/strong&gt;. The skills you'll learn are in high demand in the job market, making this course a valuable investment in your career.&lt;/p&gt;

&lt;p&gt;By the end of the course, you'll have the skills and knowledge to build your own GraphQL API using Apollo Server and Express with TypeScript, as well as advanced features like SocketIo and database migration with TypeORM. You'll also be able to confidently work with GraphQL and Apollo Server in your own projects.&lt;/p&gt;

&lt;p&gt;Enroll now in The &lt;a href="https://www.udemy.com/course/graphql-with-apollo-and-express-a-hands-on-approach/?couponCode=0C20D4C1B119BFE95197"&gt;Ultimate GraphQL and Apollo Server Course with Express and TypeScript&lt;/a&gt; and take your API development skills to the next level!&lt;/p&gt;

</description>
      <category>graphql</category>
      <category>typescript</category>
      <category>express</category>
      <category>apollo</category>
    </item>
    <item>
      <title>Do You Really Need to Learn Every Git Command to be a Senior or Mid-Senior Web Developer?</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Sat, 14 Jan 2023 19:20:10 +0000</pubDate>
      <link>https://dev.to/ayka_code/do-you-really-need-to-learn-every-git-command-to-be-a-senior-or-mid-senior-web-developer-5a8b</link>
      <guid>https://dev.to/ayka_code/do-you-really-need-to-learn-every-git-command-to-be-a-senior-or-mid-senior-web-developer-5a8b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Read on my personal blog: &lt;a href="https://bracketorbits.vercel.app/post/do-you-really-need-to-learn-every-git-command-to-be-a-senior-or-mid-senior-web-developer" rel="noopener noreferrer"&gt;bracketOrbits&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a web developer, it's important to have a solid understanding of version control and Git is one of the most widely used tools for this purpose. But the question is, do you really need to know every single Git command to be a senior or mid-senior web developer? The short answer is no.&lt;/p&gt;

&lt;p&gt;While it's certainly beneficial to have a deep understanding of all the different commands and options that Git offers, it's not a requirement for being a successful web developer. In fact, many experienced developers only use a small subset of the available commands on a regular basis.&lt;/p&gt;

&lt;p&gt;One of the great things about the field of web development is that it is constantly evolving and changing. This means that as you progress in your career and take on new projects and challenges, you will naturally learn the Git commands that are most relevant to your work. For example, if you work on a large project with many contributors, you will likely need to know how to resolve merge conflicts. On the other hand, if you work on a smaller project with fewer collaborators, you may not need to use this command as often.&lt;/p&gt;

&lt;p&gt;The most important thing is to have a good understanding of the basic Git workflow: how to commit, push, pull, and branch. Once you have a solid grasp of these concepts, you can start to explore more advanced features like merging and rebasing.&lt;/p&gt;

&lt;p&gt;Here are some of the most commonly used Git commands that are important for each developer to know:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git init&lt;/code&gt;: Initializes a new Git repository.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone&lt;/code&gt;: Creates a copy of a remote repository on your local machine.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git add&lt;/code&gt;: Adds changes to the staging area, preparing them to be committed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git commit&lt;/code&gt;: Records changes to the repository with a commit message.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git status&lt;/code&gt;: Shows the status of the current repository, including changes that have been made but not yet committed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git log&lt;/code&gt;: Shows a history of all commits made in the repository.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git diff&lt;/code&gt;: Shows the differences between the working tree and the last committed version.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git branch&lt;/code&gt;: Shows a list of all branches in the repository, with the current branch indicated by an asterisk.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git checkout&lt;/code&gt;: Allows you to switch between branches or restore specific file versions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git merge&lt;/code&gt;: Merges changes from one branch into another.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git pull&lt;/code&gt;: Fetches the latest changes from a remote repository and merges them with the local branch.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git push&lt;/code&gt;: Pushes the local changes to a remote repository.&lt;/p&gt;

&lt;p&gt;Another important aspect of Git is understanding how to use it in conjunction with other tools, such as Github or Gitlab. These platforms provide a convenient way to collaborate with other developers and track issues and pull requests. Knowing how to navigate these platforms and use their features is a valuable skill for any web developer.&lt;/p&gt;

&lt;p&gt;In summary, while it's great to have a deep understanding of all the different Git commands, it's not a requirement for being a senior or mid-senior web developer. The most important thing is to have a good understanding of the basic Git workflow and how to use it in conjunction with other tools. And as you progress in your career and take on new projects, you will naturally learn the Git commands that are most relevant to your work.&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>Maximizing the Power of Child Processes in Node.js: Real-world Examples</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Fri, 13 Jan 2023 15:12:44 +0000</pubDate>
      <link>https://dev.to/ayka_code/maximizing-the-power-of-child-processes-in-nodejs-real-world-examples-1954</link>
      <guid>https://dev.to/ayka_code/maximizing-the-power-of-child-processes-in-nodejs-real-world-examples-1954</guid>
      <description>&lt;p&gt;Node.js is a popular open-source JavaScript runtime that allows developers to build scalable and high-performance web applications. One of the most powerful features of Node.js is its ability to handle child processes. Child processes allow you to spawn new processes, run shell commands, execute scripts, or even fork multiple processes to handle a heavy workload. In this blog post, we will discuss how to use child processes in Node.js and provide real-world examples of how they can be used to improve the performance and scalability of your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the Child Process module
&lt;/h2&gt;

&lt;p&gt;The built-in &lt;code&gt;'child_process'&lt;/code&gt; module in Node.js provides several methods for spawning and managing child processes. The most commonly used methods are 'exec', 'spawn', and 'fork'.&lt;/p&gt;

&lt;p&gt;'exec' method: This method allows you to...Read more:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://bracketorbits.vercel.app/post/maximizing-power-child-processes-nodejs-real-world-examples" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fbracketorbits.vercel.app%2Fapi%2Fog%3Ftitle%3DMaximizing%2520the%2520Power%2520of%2520Child%2520Processes%2520in%2520Node.js%3A%2520Real-world%2520Examples%26mainTopics%3DNode.js%2CChild%2520Processes" height="630" class="m-0" width="1200"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://bracketorbits.vercel.app/post/maximizing-power-child-processes-nodejs-real-world-examples" rel="noopener noreferrer" class="c-link"&gt;
          Maximizing the Power of Child Processes in Node.js: Real-world Examples| BracketOrbits [👨‍💻]
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Learn about the power of child processes in Node.js and how they can be used to improve performance and scalability. Discover real-world exam....
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.graphassets.com%2FFGbWEgRLCV41IMjwWgpw" width="500" height="500"&gt;
        bracketorbits.vercel.app
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>javascript</category>
      <category>programming</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Mastering React in One Month: A Step-by-Step Guide</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Wed, 11 Jan 2023 11:23:41 +0000</pubDate>
      <link>https://dev.to/ayka_code/mastering-react-in-one-month-a-step-by-step-guide-29j2</link>
      <guid>https://dev.to/ayka_code/mastering-react-in-one-month-a-step-by-step-guide-29j2</guid>
      <description>&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
      &lt;div class="c-embed__cover"&gt;
        &lt;a href="https://bracketorbits.vercel.app/post/mastering-react-in-one-month" class="c-link s:max-w-50 align-middle" rel="noopener noreferrer"&gt;
          &lt;img alt="" src="https://res.cloudinary.com/practicaldev/image/fetch/s--vtHFu6re--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bracketorbits.vercel.app/api/og%3Ftitle%3DMastering%2520React%2520in%2520One%2520Month:%2520A%2520Step-by-Step%2520Guide%26mainTopics%3DReact%2Cjavascript" height="462" class="m-0" width="880"&gt;
        &lt;/a&gt;
      &lt;/div&gt;
    &lt;div class="c-embed__body"&gt;
      &lt;h2 class="fs-xl lh-tight"&gt;
        &lt;a href="https://bracketorbits.vercel.app/post/mastering-react-in-one-month" rel="noopener noreferrer" class="c-link"&gt;
          Mastering React in One Month: A Step-by-Step Guide| BracketOrbits [👨‍💻]
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;p class="truncate-at-3"&gt;
          Learn how to master React in just one month with this step-by-step guide. Dedicate 6 hours a day to studying and practicing, and follow our schedule and r....
        &lt;/p&gt;
      &lt;div class="color-secondary fs-s flex items-center"&gt;
          &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://res.cloudinary.com/practicaldev/image/fetch/s--z8Oa6oXZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://media.graphassets.com/FGbWEgRLCV41IMjwWgpw" width="500" height="500"&gt;
        bracketorbits.vercel.app
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Scaling Node.js Applications: Strategies and Techniques</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Sun, 08 Jan 2023 22:41:34 +0000</pubDate>
      <link>https://dev.to/ayka_code/scaling-nodejs-applications-strategies-and-techniques-3ofp</link>
      <guid>https://dev.to/ayka_code/scaling-nodejs-applications-strategies-and-techniques-3ofp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Check on my personal blog: &lt;a href="https://devtomars.vercel.app/post/scaling-nodejs-applications-strategies-and-techniques" rel="noopener noreferrer"&gt;BraketOrbits&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As web applications grow and the number of users increases, it becomes important to ensure that the application can scale effectively to handle the increased load. If an application is unable to scale, it can lead to slow response times and a poor user experience.&lt;/p&gt;

&lt;p&gt;One popular backend technology that is often used to build scalable web applications is Node.js. Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine that allows developers to build scalable network applications quickly and efficiently.&lt;/p&gt;

&lt;p&gt;There are several strategies and techniques that can be used to scale Node.js applications. Some of the most effective strategies include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vertical scaling&lt;/strong&gt;: This involves increasing the resources available to a single server, such as adding more CPU or memory. This can be an effective way to scale an application, but it can become expensive as the application grows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Horizontal scaling&lt;/strong&gt;: This involves adding more servers to the application, allowing it to handle more traffic and users. This can be an effective way to scale an application, but it requires careful planning to ensure that the application is able to distribute traffic and data effectively across multiple servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caching&lt;/strong&gt;: Caching involves storing frequently accessed data in a cache so that it can be quickly retrieved when needed. This can help to reduce the load on the database and improve the performance of the application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Load balancing&lt;/strong&gt;: This involves distributing traffic across multiple servers to ensure that no single server is overwhelmed. This can be achieved through the use of a load balancer, which routes traffic to the appropriate server based on factors such as server availability and workload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asynchronous programming&lt;/strong&gt;: Node.js uses an event-driven, non-blocking I/O model, which makes it well-suited for scalable applications. By writing code that makes use of asynchronous programming techniques, it is possible to build highly scalable applications that can handle a large number of concurrent requests.&lt;/p&gt;

&lt;p&gt;By implementing these strategies and techniques, it is possible to build scalable Node.js applications that can handle a large number of users and a high volume of traffic. This can help to ensure that your application delivers a fast and reliable experience to your users.&lt;/p&gt;

</description>
      <category>gratitude</category>
    </item>
    <item>
      <title>Creating Auto Dynamic OG Images for Your Next.js Application with Serverless Functions</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Fri, 06 Jan 2023 21:41:04 +0000</pubDate>
      <link>https://dev.to/ayka_code/creating-auto-dynamic-og-images-for-your-nextjs-application-with-serverless-functions-35cf</link>
      <guid>https://dev.to/ayka_code/creating-auto-dynamic-og-images-for-your-nextjs-application-with-serverless-functions-35cf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;For clear an better UI you can read this blog post on my personal blog: &lt;a href="https://devtomars.vercel.app/post/creating-dynamic-og-images-for-your-next-js-application-with-serverless-functions" rel="noopener noreferrer"&gt;Creating Auto Dynamic OG Images for Your Next.js Application with Serverless Functions&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you have a blog or website, you may want to create open graph (OG) images to use when sharing your content on social media platforms. OG images are displayed when someone shares your content on social media, and they help to give context to the shared content and make it more visually appealing.&lt;/p&gt;

&lt;p&gt;In this tutorial, we'll look at how to create dynamic OG images in a Next.js application using a &lt;code&gt;serverless&lt;/code&gt; function. We'll use the &lt;code&gt;@vercel/og&lt;/code&gt; package to create the OG image within the &lt;code&gt;serverless&lt;/code&gt;function.&lt;/p&gt;

&lt;p&gt;Before we get started, you'll need to have a Next.js application set up. If you don't already have one, you can create a new Next.js project by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install the &lt;code&gt;@vercel/og&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @vercel/og
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have the necessary packages installed, we can create the &lt;code&gt;serverless&lt;/code&gt; function that will generate the OG image. To do this, create a &lt;code&gt;og.js&lt;/code&gt; in the api folder of your Next.js project and  import &lt;code&gt;ImageResponse&lt;/code&gt; class at the top of the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ImageResponse&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;@vercel/og&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we'll set the runtime for the serverless function to "edge" in the config object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;edge&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will ensure that the function is executed on the edge network, which is required for creating &lt;code&gt;OG&lt;/code&gt; images.&lt;br&gt;
Now, let's define the main handler function for the &lt;code&gt;serverless&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;searchParams&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// code for generating the OG image goes here&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Failed to generate the image`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&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;This function takes a request object as an argument and returns an &lt;strong&gt;OG&lt;/strong&gt; image response. If an error occurs while generating the image, it returns a response with a status of 500 and an error message.&lt;/p&gt;

&lt;p&gt;Now let's start adding the code for generating the &lt;strong&gt;OG&lt;/strong&gt; image. First, we'll parse the search parameters from the request URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { searchParams } = new URL(req.url);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, we'll check if the title search parameter is present in the query string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the &lt;code&gt;title&lt;/code&gt; parameter is present, we slice it to a maximum of 100 characters and assign it to the title variable, If the &lt;code&gt;title&lt;/code&gt; parameter is not present, we set the title variable to the default value of "DevToMars":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hasTitle&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&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;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&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;DevToMars&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Next, we retrieve the &lt;code&gt;mainTopics&lt;/code&gt; search parameter from the query string and split it into an array using the split method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mainTopics&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mainTopics&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;split&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows us to pass multiple main topics as a comma-separated list in the query string.&lt;/p&gt;

&lt;p&gt;Now that we have the title and &lt;code&gt;mainTopics&lt;/code&gt; variables, we can use them to render the OG image. To do this, we use the &lt;code&gt;ImageResponse&lt;/code&gt; class from the &lt;code&gt;@vercel/og&lt;/code&gt; package, which allows us to create an &lt;strong&gt;OG&lt;/strong&gt; image from a React component.&lt;/p&gt;

&lt;p&gt;We pass a simple div element with some inline styles applied to it to the &lt;code&gt;ImageResponse&lt;/code&gt; class as the React component . The styles specify the layout and appearance of the &lt;strong&gt;OG&lt;/strong&gt; image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ImageResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;backgroundSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;150px 150px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;column&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;flexWrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nowrap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;65px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;}}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* The Body of the Image */&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;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we are displaying the div as a flex because Next.js requires this for every element with more than one child. You can use &lt;code&gt;Tailwindcss&lt;/code&gt; for styling, but I don't recommend it because it is not stable and it is not fully supported for generating images with Next.js. &lt;/p&gt;

&lt;p&gt;Our image will contain a &lt;code&gt;title&lt;/code&gt; that fills up &lt;code&gt;75%&lt;/code&gt; of the image width with some padding and a &lt;code&gt;margin-top&lt;/code&gt; of &lt;code&gt;30px&lt;/code&gt;, a logo with a brand name, and a list of main topic tags. :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&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;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;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;fontStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;normal&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;letterSpacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-0.025em&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&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="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0 100px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;lineHeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;whiteSpace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pre-wrap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;75%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;700&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;textTransform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;capitalize&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="p"&gt;}}&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;w-10 capitalize&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;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/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;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;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;70px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;70px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&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://media.graphassets.com/gncWvSEqRFaBSUPZGoTP&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="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;70&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;70&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devtomars blog&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;/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;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;backgroundClip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;transparent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;backgroundImage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;linear-gradient(to right, #ec4899, #8b5cf6)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;700&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="na"&gt;fontSize&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="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;DevToMars&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="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;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;flexDirection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;row&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex-end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;justifyItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;75%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nx"&gt;mainTopics&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;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&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;div&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;i&lt;/span&gt;&lt;span class="p"&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;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;5px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;topic&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;/div&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="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="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we pass an option object to create an &lt;strong&gt;OG&lt;/strong&gt; image with a width of 1200 pixels and a height of 630 pixels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ImageResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="c1"&gt;// JSX element here&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;630&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 that's it! You now have a &lt;code&gt;serverless&lt;/code&gt; function that can generate dynamic &lt;strong&gt;OG&lt;/strong&gt; images for your Next.js application. To use the function, simply make a request to the function's URL with the desired title and &lt;code&gt;mainTopics&lt;/code&gt; query parameters. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://your-next-app.vercel.app/api/og?title=My Blog Post&amp;amp;mainTopics=nodejs,javascript,react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will generate an OG image with the title "My Blog Post" and the main topics "nodejs", "javascript", and "react".&lt;br&gt;
You can then use the generated OG image in your social media sharing tags, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:image"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"https://your-next-app.vercel.app/api/og?title=My Blog Post&amp;amp;mainTopics=nodejs,javascript,react"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! You now know how to create dynamic OG images for your Next.js application using a serverless function. I hope this tutorial was helpful!&lt;/p&gt;

</description>
      <category>jokes</category>
    </item>
    <item>
      <title>Create a Post Editor Similar to Twitter with a Responsive Images Grid with tailwindcss</title>
      <dc:creator>ayka.code</dc:creator>
      <pubDate>Thu, 05 Jan 2023 21:02:17 +0000</pubDate>
      <link>https://dev.to/ayka_code/create-a-post-editor-similar-to-twitter-with-a-responsive-images-grid-with-tailwindcss-j7a</link>
      <guid>https://dev.to/ayka_code/create-a-post-editor-similar-to-twitter-with-a-responsive-images-grid-with-tailwindcss-j7a</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Check my original blog post for better UI: &lt;a href="https://devtomars.vercel.app/post/create-post-editor-similar-to-twitter-with-responsive-images-grid" rel="noopener noreferrer"&gt;Create a Post Editor Similar to Twitter with a Responsive Images Grid with tailwindcss&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this tutorial, we will create a React component for a social media post editor that allows the user to write posts and display a grid of selected images while preserving their aspect ratio. The component also allows the user to remove images from the grid.&lt;/p&gt;

&lt;p&gt;We're going to use Tailwindcss and nextjs in this tutorial so make sure to install and configure  your project following &lt;a href="https://tailwindcss.com/docs/guides/nextjs" rel="noopener noreferrer"&gt;Tailwind css with Nextjs guide&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;To get started, let's import the necessary dependencies and create a functional component called PostEditorImages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&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;react&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;PostEditorImages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;removeImage&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="c1"&gt;// component code goes here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our component will accept two props:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;images&lt;/code&gt;: an array of images of type File, representing the images to be displayed in the grid.&lt;br&gt;
&lt;code&gt;removeImage&lt;/code&gt;: a function that removes an image from the images array and updates the state of the parent component.&lt;/p&gt;

&lt;p&gt;Next, let's set up some state variables that we will use to control the layout of the image grid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;imagesContainerGrid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setImagesContainerGrid&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid-cols-2 grid-rows-2&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aspectRatios&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAspectRatios&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;imagesContainerGrid&lt;/code&gt; state variable will hold a string of CSS class names that define a grid template columns of 2 and rows of 2. The &lt;code&gt;aspectRatios&lt;/code&gt; state variable will hold an object that maps the index of each image to its aspect ratio.&lt;/p&gt;

&lt;p&gt;Now, let's write a &lt;code&gt;useEffect&lt;/code&gt; hook that updates the &lt;code&gt;imagesContainerGrid&lt;/code&gt; state variable based on the number of images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&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="nf"&gt;setImagesContainerGrid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;images&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;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid-cols-2 grid-rows-2 h-[300px]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;images&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;&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grid-cols-2&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;grid-cols-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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This &lt;code&gt;useEffect&lt;/code&gt; hook will run every time the images prop changes. If there are three or more images, it will set the &lt;code&gt;imagesContainerGrid&lt;/code&gt; state variable to a string that specifies a grid with two columns and two rows, with a fixed height of &lt;code&gt;300px&lt;/code&gt;. If there are two or more images, it will set the &lt;code&gt;imagesContainerGrid&lt;/code&gt; state variable to a string that specifies a grid with two columns. If there is only one image, it will set the &lt;code&gt;imagesContainerGrid&lt;/code&gt; state variable to a string that specifies a grid with one column.&lt;/p&gt;

&lt;p&gt;Now, let's write a &lt;code&gt;useEffect&lt;/code&gt; hook that calculates the aspect ratio of each image and updates the &lt;code&gt;aspectRatios&lt;/code&gt; state variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&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;images&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;image&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reader&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;FileReader&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;img&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;Image&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&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;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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;gcd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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;b&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;a&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;gcd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;b&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;numerator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;img&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="nf"&gt;gcd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&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;denominator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;img&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="nf"&gt;gcd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nf"&gt;setAspectRatios&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ratios&lt;/span&gt; &lt;span class="o"&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="nx"&gt;ratios&lt;/span&gt;&lt;span class="p"&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;numerator&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;denominator&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;span class="p"&gt;};&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;readAsDataURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This code iterates over an array of images and calculates the aspect ratio of each image. It does this by:&lt;/p&gt;

&lt;p&gt;Creating a &lt;code&gt;FileReader&lt;/code&gt; object for each image, which allows the code to read the contents of the file as a data URL.&lt;br&gt;
Setting an &lt;code&gt;onload&lt;/code&gt; event handler for the &lt;code&gt;FileReader&lt;/code&gt; object, which is called when the file has been successfully read. The event handler creates a new image object, sets its &lt;code&gt;src&lt;/code&gt; property to the data URL, and sets an &lt;code&gt;onload&lt;/code&gt; event handler for the image object.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;onload&lt;/code&gt; event handler for the image object calculates the aspect ratio of the image by dividing the width by the greatest common divisor of the width and height, and dividing the height by the greatest common divisor. It then updates the &lt;code&gt;aspectRatios&lt;/code&gt; state variable by creating a new object that spreads the existing aspect ratios and adds a new key-value pair for the current image's index and aspect ratio.&lt;/p&gt;

&lt;p&gt;Finally, the code calls the &lt;code&gt;readAsDataURL&lt;/code&gt; method on the &lt;code&gt;FileReader&lt;/code&gt; object, passing in the image file as an argument. This starts the process of reading the file as a data URL.&lt;/p&gt;

&lt;p&gt;Finally, let's render the image grid in the component's JSX:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;` [grid-area:images] grid gap-1 &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;imagesContainerGrid&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;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* display the selected images */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;images&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;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;images&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;image&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;image&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="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`relative rounded-md`&lt;/span&gt;&lt;span class="p"&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;backgroundImage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`url(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;image&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;backgroundSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cover&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;backgroundPosition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;backgroundRepeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-repeat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;aspectRatio&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;aspectRatios&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="p"&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;button&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;absolute flex items-center justify-center top-0 text-sm right-0 p-2 text-white rounded-full w-7 h-7 shadow-md bg-black bg-opacity-60 hover:bg-opacity-100&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
            &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;removeImage&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;X&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&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;/button&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="p"&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;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This JSX creates a div of &lt;code&gt;grid-area:images&lt;/code&gt; that will be defined in the parent component , with the grid class and the &lt;code&gt;imagesContainerGrid&lt;/code&gt; class, which defines the layout of the image grid. Inside the div, it maps over the images array and renders a div for each image. &lt;br&gt;
Each image div has a background image set to the image file, and the &lt;code&gt;aspectRatio&lt;/code&gt; style property set to the aspect ratio of the image. The div also has a remove button that calls the &lt;code&gt;removeImage&lt;/code&gt; function and passes in the index of the image to be removed.&lt;/p&gt;

&lt;p&gt;That's it! With these simple steps, we have created a React component that displays a grid of images selected by the user, and allows the user to remove images from the grid.&lt;/p&gt;

&lt;p&gt;To use the component, we need to create the &lt;code&gt;SocialMediaTextEditor&lt;/code&gt; component which represents the text editor for the the social media app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SocialMediaTextEditor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;// state to store the text;&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;images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setImages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt; &lt;span class="c1"&gt;// state to store the images&lt;/span&gt;


  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;imageContainerRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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;handleTextChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;handleImageChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="c1"&gt;// update the images state by concatenating the selected files with the existing ones&lt;/span&gt;
    &lt;span class="nf"&gt;setImages&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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;removeImage&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="c1"&gt;// create a new array with the selected image removed&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newImages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="nx"&gt;newImages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setImages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newImages&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we have the &lt;code&gt;handleTextChange&lt;/code&gt;  to save the latest value of the text field, the &lt;code&gt;handleImageChange&lt;/code&gt; and &lt;code&gt;removeImage&lt;/code&gt; functions are responsible for adding and removing images from the images list.&lt;/p&gt;

&lt;p&gt;Now lets define and style the post editor component using grid template areas with &lt;code&gt;tailwindcss&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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;div&lt;/span&gt;
  &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;` rounded-lg p-4
    grid gap-y-1
    grid-cols-[40px_5px_1fr]
    grid-rows-[40px_1fr_minmax(0,_max-content)_40px]
    [grid-template-areas:'profile_p1_post'_'empty2_p3_post'_'empty3_p3_images'_'empty4_p4_postActions']`&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="cm"&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;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;SocialMediaTextEditor&lt;/code&gt; component contains a profile area where you can add a profile image. The post area represents the text field where the user can write their post. The &lt;code&gt;p1, p3,&lt;/code&gt; and &lt;code&gt;p4&lt;/code&gt; represent a &lt;code&gt;5px&lt;/code&gt; gap that is defined in the &lt;code&gt;grid-cols-[40px_5px_1fr]&lt;/code&gt; layout. The &lt;code&gt;postActions&lt;/code&gt; area holds the upload images button and the post button. The &lt;code&gt;emptyX&lt;/code&gt; fills in the profile area in all grid rows except the first row, giving the component a similar style to the Twitter post editor. &lt;/p&gt;

&lt;p&gt;Now, let's define the JSX code for the profile, text field, and displayed images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="err"&gt;⁠&lt;/span&gt;   &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* profile area */&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;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;[grid-area:profile] rounded-full bg-red-500&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="cm"&gt;/* post area */&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;textarea&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;w-full [resize:none] [grid-area:post] h-fit p-2 rounded-lg text-gray-500  focus:outline-none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Write your post here...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleChange&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* display selected images */&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;PostEditorImages&lt;/span&gt; &lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;removeImage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;removeImage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
⁠&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now add the jsx code that will allow us to select images from the local system :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* display selected images */&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;PostEditorImages&lt;/span&gt; &lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;images&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;removeImage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;removeImage&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;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;[grid-area:postActions] flex flex-row justify-between&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="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;justify-self-start flex flex-row gap-2&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="cm"&gt;/* add the input element to select images */&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;label&lt;/span&gt; &lt;span class="nx"&gt;htmlFor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image-upload&lt;/span&gt;&lt;span class="dl"&gt;"&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;cursor-pointer&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;FaImage&lt;/span&gt; &lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rgb(31 41 55)&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;/label&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;input&lt;/span&gt;
        &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image-upload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;file&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="nx"&gt;multiple&lt;/span&gt;
        &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleImageChange&lt;/span&gt;&lt;span class="p"&gt;}&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;hidden&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;/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;button&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;bg-red-500 justify-self-end hover:bg-red-700 text-white font-bold py-2 px-4 rounded-full&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Post&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&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="p"&gt;...&lt;/span&gt;


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

&lt;/div&gt;



&lt;p&gt;You can import the &lt;code&gt;FaImage&lt;/code&gt; component from &lt;code&gt;react-icons&lt;/code&gt; package.&lt;/p&gt;

&lt;p&gt;That's it! You now have a fully functional social media post editor component with a responsive display images grid and a style similar to the Twitter post editor. Of course, you still need to create the logic for uploading the images to the server.&lt;/p&gt;

&lt;p&gt;I hope this tutorial was helpful in showing you how to display and manage a grid of images in a React app. Happy coding!&lt;/p&gt;

</description>
      <category>emptystring</category>
    </item>
  </channel>
</rss>
