<?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: Fredrick Ogutu</title>
    <description>The latest articles on DEV Community by Fredrick Ogutu (@fiveace_merill).</description>
    <link>https://dev.to/fiveace_merill</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%2F3093518%2F4b7b26cf-455c-44b6-9849-5e3c42deb0af.jpg</url>
      <title>DEV Community: Fredrick Ogutu</title>
      <link>https://dev.to/fiveace_merill</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fiveace_merill"/>
    <language>en</language>
    <item>
      <title>A Better Way to build</title>
      <dc:creator>Fredrick Ogutu</dc:creator>
      <pubDate>Fri, 14 Nov 2025 10:40:41 +0000</pubDate>
      <link>https://dev.to/fiveace_merill/a-better-way-to-build-5fec</link>
      <guid>https://dev.to/fiveace_merill/a-better-way-to-build-5fec</guid>
      <description>&lt;p&gt;There was a stage in my development journey when I often dove headfirst into projects without much planning or structure. I’d start coding right away no sketches, no layout drafts, no clear idea of how the final user interface would look.&lt;/p&gt;

&lt;p&gt;I’d usually get a few components built, only to realize later that my design didn’t hold up across different devices. Designing for desktop screens felt familiar and easy, but it often left me stuck in long, tedious sprints of refactoring just to make the project responsive.&lt;/p&gt;

&lt;p&gt;That pattern taught me a valuable lesson: good design starts with intentionality.&lt;/p&gt;

&lt;p&gt;Recently, I’ve made a conscious shift toward &lt;strong&gt;a mobile-first design and development approach&lt;/strong&gt;. Building from smaller screens upward forces me to prioritize what really matters in the user experience. It has made my process more structured, my designs cleaner, and my projects far more enjoyable.&lt;/p&gt;

&lt;p&gt;Pairing this approach with &lt;strong&gt;Tailwind CSS&lt;/strong&gt; utility classes has also been a game-changer development feels faster, smoother, and surprisingly fun.&lt;/p&gt;

&lt;p&gt;Over the past week, I challenged myself to build a &lt;strong&gt;fully responsive static website&lt;/strong&gt; from scratch. It was both a test of my new workflow and a chance to see how quickly I could move from idea to polished result.&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%2F3ap7uuwz8j1hkrwugvko.png" 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%2F3ap7uuwz8j1hkrwugvko.png" alt="screenshot of the desktop layout" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://money-tips-financial-advisor.vercel.app/" rel="noopener noreferrer"&gt;Here is the link to the full project&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Beyond the project itself, I found the experience deeply rewarding. It sparked a curiosity to go further specifically, to build a backend for the site and explore how to enrich the application with &lt;strong&gt;AI agents, MCP, and RAG&lt;/strong&gt; to get the most out of the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Takeaways
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Responsive Design&lt;/strong&gt; isn’t just about resizing elements it’s about adapting experiences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile-First Development&lt;/strong&gt; helps maintain focus, clarity, and scalability from the start.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This shift toward intentional design has not only improved my workflow but also reignited my passion for learning and creating with purpose.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>ui</category>
      <category>design</category>
      <category>webdev</category>
    </item>
    <item>
      <title>⚡ Streaming and Caching for a Better UX in Next.js</title>
      <dc:creator>Fredrick Ogutu</dc:creator>
      <pubDate>Fri, 31 Oct 2025 10:44:07 +0000</pubDate>
      <link>https://dev.to/fiveace_merill/streaming-and-caching-for-a-better-ux-in-nextjs-b0</link>
      <guid>https://dev.to/fiveace_merill/streaming-and-caching-for-a-better-ux-in-nextjs-b0</guid>
      <description>&lt;p&gt;When building data-driven applications in Next.js, one of the most common bottlenecks you’ll face is slow data fetching. Whether you’re pulling data from a remote API or querying your own backend, a delay in just one request can hold back the entire page from rendering.&lt;/p&gt;

&lt;p&gt;As the saying goes, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Your application is only as fast as its slowest data fetch.”  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is especially true for dynamically rendered pages.&lt;/p&gt;

&lt;p&gt;In one of my recent projects, I noticed a significant delay when fetching blog posts from the Dev.to API. While the data itself wasn’t heavy, the delay between fetching and rendering made the page feel sluggish. This experience led me to explore two powerful techniques built into Next.js streaming and caching to make my app feel fast, responsive, and smooth.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌊 Streaming
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Streaming&lt;/strong&gt; allows you to send &lt;strong&gt;parts of a page&lt;/strong&gt; to the client as soon as they’re ready, instead of waiting for all data to load. This means users can start interacting with sections of the UI immediately, even while slower parts are still rendering in the background.&lt;/p&gt;

&lt;p&gt;It’s like serving snacks while the main course is still cooking, your users can start interacting with something right away, reducing perceived load time.&lt;/p&gt;

&lt;p&gt;Next.js supports streaming at two levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Page-level streaming&lt;/strong&gt; using &lt;code&gt;loading.tsx&lt;/code&gt; files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Component-level streaming&lt;/strong&gt; using React’s &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Streaming a Whole Page
&lt;/h3&gt;

&lt;p&gt;At the page level, you can use a &lt;strong&gt;&lt;code&gt;loading.tsx&lt;/code&gt;&lt;/strong&gt; file to display fallback UI while your data is being fetched. This helps avoid the “white screen” problem, where nothing is visible to users while they wait.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/blog/loading.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="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;Loading&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"min-h-screen px-4 py-6"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Header skeleton */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mx-auto max-w-5xl mb-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex items-center gap-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* avatar */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
            &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-10 w-10 rounded-full bg-md-background animate-pulse"&lt;/span&gt;
            &lt;span class="na"&gt;aria-hidden&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* site title placeholder */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex-1"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-6 w-64 rounded-md bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mt-3 flex gap-3"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* tag placeholders */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-6 w-20 rounded-full bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-6 w-24 rounded-full bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-6 w-16 rounded-full bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;header&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Cards grid skeleton */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mx-auto max-w-5xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"grid grid-cols-1 md:grid-cols-2 gap-8"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&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;_&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;
              &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"rounded-2xl bg-white shadow-[0_10px_35px_rgba(99,102,241,0.12)] p-6"&lt;/span&gt;
              &lt;span class="na"&gt;aria-hidden&lt;/span&gt;
            &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* image */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-40 md:h-48 w-full rounded-lg bg-md-background animate-pulse mb-4"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

              &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* title + date row */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mb-3"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-5 w-3/4 rounded-md bg-md-background animate-pulse mb-2"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-3 w-1/4 rounded-md bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

              &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* excerpt */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"space-y-2 mb-4"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-3 w-full rounded-md bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-3 w-11/12 rounded-md bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-3 w-8/12 rounded-md bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

              &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* tags */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex flex-wrap gap-2 mb-6"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-8 w-20 rounded-full bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-8 w-24 rounded-full bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-8 w-16 rounded-full bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

              &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* read more button */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-36 h-10 rounded-full bg-md-background animate-pulse"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;article&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&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;With this file in place, Next.js automatically serves it as a temporary placeholder whenever the &lt;code&gt;/blog&lt;/code&gt; route is loading. Users can still navigate around without waiting for the full page to render.&lt;/p&gt;

&lt;p&gt;This design mimics my actual blog cards image at the top, followed by the title, date, tags, and a “Read more” button.&lt;br&gt;
Even though the data hasn’t loaded yet, users can clearly see what to expect.&lt;/p&gt;
&lt;h3&gt;
  
  
  Streaming at the Component Level
&lt;/h3&gt;

&lt;p&gt;While page-level streaming is useful, sometimes you want even finer control. That’s where React’s &lt;a href="https://react.dev/reference/react/Suspense" rel="noopener noreferrer"&gt;suspense&lt;/a&gt; component comes in.&lt;/p&gt;

&lt;p&gt;It lets you defer rendering specific components until their data is ready, ideal for dynamic sections of your app.&lt;/p&gt;

&lt;p&gt;Here’s how I wrapped my &lt;code&gt;Blogs&lt;/code&gt; component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/blog/page.tsx&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;Suspense&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;import&lt;/span&gt; &lt;span class="nx"&gt;Blogs&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;../ui/blog/Blogs&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;BlogSkeleton&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;../ui/blog/skeletons&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;Blog&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"relative pt-2 px-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BlogSkeleton&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Blogs&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;
&lt;span class="c1"&gt;// app/ui/blog/skeletons.tsx&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;BlogSkeleton&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"h-full w-full bg-inherit flex flex-col justify-center items-center gap-6 md:flex-row md:gap-12"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&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;_&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex flex-col items-center w-11/12 px-2 py-3"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mt-3 w-11/12 h-2/6 bg-md-background"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"mt-3 w-full bg-md-background"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bg-md-background"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-4/6 mx-auto"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;section&lt;/span&gt;&lt;span class="p"&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;With this setup, the static parts of the page render immediately, while the &lt;code&gt;&amp;lt;Blogs /&amp;gt;&lt;/code&gt; component streams in once its data has finished loading. If the fetch takes longer, users see the &lt;code&gt;BlogSkeleton&lt;/code&gt; instead of a blank space a small detail that greatly improves perceived responsiveness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caching
&lt;/h2&gt;

&lt;p&gt;Streaming improves how data loads. Caching improves how often data needs to load.&lt;/p&gt;

&lt;p&gt;Caching stores the results of expensive operations (like API requests) so that subsequent requests for the same data are served faster. This is especially powerful in server components, where you can use React’s built-in &lt;code&gt;cache()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Here’s how I applied caching to my blog data fetch:&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;// app/lib/fetchBlogs.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Blog&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../types/index&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchBlogs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;(&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;fetchBlogs&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;blogs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Blog&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="nl"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="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="s2"&gt;https://dev.to/api/articles?username=fiveace_merill&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="na"&gt;blogs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Blog&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;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;simplifiedBlogs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;blogs&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;id&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="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;published_at&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="nx"&gt;cover_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tag_list&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;id&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="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;published_at&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="nx"&gt;cover_image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;tag_list&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;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;simplifiedBlogs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Articles fetched successfully&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Total blogs: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;count&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;blogs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;simplifiedBlogs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error fetching articles: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;blogs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="na"&gt;count&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="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 fetch logic inside &lt;code&gt;cache()&lt;/code&gt;, repeated requests for the same data are served instantly from memory rather than refetching from the API. This significantly reduces latency and helps avoid hitting external API rate limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enabling Cache Components
&lt;/h2&gt;

&lt;p&gt;Next.js also lets you enable caching at the component level using &lt;strong&gt;Cache Components&lt;/strong&gt; a newer optimization that preserves state during navigation.&lt;/p&gt;

&lt;p&gt;To enable it, update your Next.js config:&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;// next.config.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NextConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;cacheComponents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Once enabled, Next.js uses React’s Activity mode to keep component state intact during client-side navigation.&lt;br&gt;&lt;br&gt;
This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Form inputs and expanded sections remain preserved when moving between routes.
&lt;/li&gt;
&lt;li&gt;Navigation feels faster and more fluid.
&lt;/li&gt;
&lt;li&gt;Effects are cleaned up and restored only when needed.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, caching complements streaming by making transitions and repeated renders smoother without unnecessary data fetching.&lt;/p&gt;

&lt;p&gt;To cache a component add &lt;a href="https://nextjs.org/docs/app/api-reference/directives/use-cache" rel="noopener noreferrer"&gt;&lt;code&gt;use chache&lt;/code&gt;&lt;/a&gt; to any server component to make it cached and included in the prerendered shell or mark utility functions as &lt;code&gt;use cache&lt;/code&gt; and call them from within the server component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchProjects&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;use cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&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;sql&lt;/span&gt;&lt;span class="s2"&gt;`SELECT * FROM projects LIMIT 3`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Data fetch completed after seconds.&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Database Error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Failed to fetch projects data.&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You can not use runtime APIs like &lt;a href="https://nextjs.org/docs/app/api-reference/functions/cookies" rel="noopener noreferrer"&gt;cookies&lt;/a&gt; and &lt;a href="https://nextjs.org/docs/app/api-reference/functions/headers" rel="noopener noreferrer"&gt;headers&lt;/a&gt; from inside a cached component.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Optimizing user experience isn’t just about making things faster it’s about making them feel faster.&lt;/p&gt;

&lt;p&gt;By combining Streaming and Caching in Next.js, I was able to transform a slow, blocking data fetch into an experience where content appears progressively, interactions remain fluid, and returning users benefit from cached data.&lt;/p&gt;

&lt;p&gt;It’s these small technical adjustments that often have the biggest impact on how users perceive your app. Next time you’re faced with sluggish data fetching, consider streaming your components and caching your results your users will thank you.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ux</category>
      <category>nextjs</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Reflections on Learning, Mentorship, and Growth</title>
      <dc:creator>Fredrick Ogutu</dc:creator>
      <pubDate>Mon, 13 Oct 2025 11:19:57 +0000</pubDate>
      <link>https://dev.to/fiveace_merill/reflections-on-learning-mentorship-and-growth-9hj</link>
      <guid>https://dev.to/fiveace_merill/reflections-on-learning-mentorship-and-growth-9hj</guid>
      <description>&lt;p&gt;Learning has never been a straight path for me; it’s been shaped by curiosity, the people I’ve met, and the fears I’ve learned (and still learn) to face. From discovering computers for the first time to watching others pursue mastery before me, this is my reflection on how discomfort, mentorship, and persistence all play their part in growth.&lt;/p&gt;




&lt;h2&gt;
  
  
  Early Encounters &amp;amp; Missed Turns
&lt;/h2&gt;

&lt;p&gt;Growing up, I was lucky enough to be exposed to computers a Windows Vista, to be exact. My dad introduced me to Microsoft Word, and that small exposure felt magical. I spent hours poking at menus, typing, and undoing mistakes. It didn’t feel like a career path yet just a toy, a curiosity.&lt;/p&gt;

&lt;p&gt;When high school arrived, the notion of &lt;em&gt;computer studies&lt;/em&gt; was there, but I opted out. Part of me excuses it as fate; part of me knows I just didn’t believe I belonged. My brother once remarked that computer classes seemed tedious, not “worth it.” At the time, I accepted that remark without question. I also watched classmates who cared deeply about tech still drift into other careers; teachers, doctors, as if the spark had been dimmed somewhere along the way.&lt;/p&gt;

&lt;p&gt;But one friend stood apart. He was an early adopter, experimenting with code, pushing boundaries even when the rest of us were content with textbooks.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Gap Year &amp;amp; What I Learned from Him
&lt;/h2&gt;

&lt;p&gt;We spent a lot of that gap year before college together. By then, he was already part of the &lt;strong&gt;Andela Community&lt;/strong&gt;, tinkering with side projects, reading documentation, and engaging with dev circles. I watched him jump into frameworks and tools I’d barely heard of.&lt;/p&gt;

&lt;p&gt;Watching him in his element was something else: flying through terminal windows, dropping terms like &lt;em&gt;Docker&lt;/em&gt;, &lt;em&gt;Kubernetes&lt;/em&gt;, and &lt;em&gt;Kotlin&lt;/em&gt; like they were a second language. He didn’t just know computers; he understood their potential, their language, their logic.  &lt;/p&gt;

&lt;p&gt;But more than that, he showed me a path of devouring uncertainty rather than avoiding it. He seemed comfortable failing fast, exploring boldly, admitting “I don’t know,” then going to figure it out. He made learning look alive.&lt;/p&gt;

&lt;p&gt;That contrast between those who drifted away and him who leaned in quietly rewired how I saw possibility. He didn’t hand me answers. He embodied a posture. And that posture nudged me: I wanted fluency too, not just surface comfort.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Mentorship, Noise, and the Challenge of Learning&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If inspiration is a spark, mentorship is the fuel that keeps it burning. In tech, where everything changes, stacks evolve, and “best practices” expire, having someone with just a bit more visibility helps you cut through the noise.&lt;/p&gt;

&lt;p&gt;Looking back, I realize that learning often begins as a deep, intentional desire to be better, but it’s also shaped by the people around us. I realize now that my first mentor wasn’t official; there were no check-ins, but he was my friend. Watching him work taught me more than I could have learned from any syllabus. I observed his habits, his curiosity, and his willingness to fail fast and recover even faster. Without ever intending to, he modeled what active learning looked like.&lt;/p&gt;

&lt;p&gt;Over time, I realized mentorship isn’t always about direct instruction. Sometimes it’s quiet, the kind that happens through observation. It’s not just advice; it’s &lt;em&gt;example&lt;/em&gt;. It’s the implicit permission to be curious, to fail, to explore tangents, and to ask “dumb” questions without shame. That form of mentorship shaped me long before I recognized it for what it was.&lt;/p&gt;

&lt;p&gt;That realization became critical later, when anxiety and self-doubt crept in. Especially in software, the fear of not knowing enough, of falling behind, or of failing publicly it’s ever-present.&lt;/p&gt;

&lt;p&gt;Then I came across an article that reframed my thinking: &lt;strong&gt;“Unnecessary Anxiety in Software Development”&lt;/strong&gt; by &lt;em&gt;SimpleThread&lt;/em&gt;. It argued that anxiety, rather than being an obstacle, can serve as a &lt;em&gt;signal&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The author used a vivid metaphor: imagine walking across a narrow plank between two buildings. The task is the same as walking on flat ground, but the stakes or perceived danger make it terrifying. In development, we often work without safety nets: no tests, no staging, no guardrails. Naturally, anxiety rises because the environment amplifies the risk.&lt;/p&gt;

&lt;p&gt;One insight stood out:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;When working on anxiety, do the thing that feels bad and avoid the thing that feels good.&lt;/em&gt;&lt;br&gt;&lt;br&gt;
In other words, approach discomfort instead of retreating from it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That line stayed with me because it echoed something I’d already seen in my friend’s behavior and something I still try, often imperfectly, to practice myself.&lt;/p&gt;

&lt;p&gt;In hindsight, what I called friendship was also mentorship in disguise, a reminder that guidance doesn’t always arrive with a title. Sometimes it’s simply someone showing you, by example, that the uncomfortable path forward is still worth taking.&lt;/p&gt;

&lt;p&gt;One insight stood out:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;When working on anxiety, do the thing that feels bad and avoid the thing that feels good.&lt;/em&gt;&lt;br&gt;&lt;br&gt;
In other words, approach discomfort instead of retreating from it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That line stayed with me because it echoed something I’d already seen in my friend’s behavior and something I still try, often imperfectly, to practice myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ongoing Conflict: Learning vs. Bills
&lt;/h2&gt;

&lt;p&gt;Here’s a truth I don’t pretend to have solved: I still oscillate between wanting to learn and needing to earn. There are days when I’m turned toward a new framework, excited to build something just for fun. And there are days when I worry if those hours will ever pay the rent.&lt;/p&gt;

&lt;p&gt;Learning feels risky. Investing time in something may or may not yield fruit. Meanwhile, bills and responsibilities demand immediate returns. That tension is real. But I try to remember: learning with intention, even if it’s slow, compounds. I don’t have to master everything, but I can commit to leaning in where curiosity and need intersect.&lt;/p&gt;

&lt;p&gt;I also lean on small guardrails: naming what I want to learn, framing small experiments, pairing with others, and asking naive questions. These act like my safety nets. They reduce my internal cost of failure.&lt;/p&gt;




&lt;h2&gt;
  
  
  From Fear to Signal, From Anxiety to Action
&lt;/h2&gt;

&lt;p&gt;The article argues anxiety isn’t always a foe; it can be a signal. Instead of ignoring it, I try to listen: &lt;em&gt;What’s behind this worry? What do I fear missing? What’s the next small step I can take that moves me forward, not paralyzed?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This flip from avoidance to approach is hard. It doesn’t just require willpower; it requires strategy. Often, I remind myself: &lt;em&gt;the blinders of fear are opaque.&lt;/em&gt; They hide solutions that are right in front of you.&lt;/p&gt;

&lt;p&gt;Sometimes the move is structural: add tests, staging, peer review, guardrails in your workflow so that the stakes feel safer and you can experiment. Sometimes it’s personal: reach out to a mentor, share where you’re stuck, break a problem down, try something new, even if you expect failure.&lt;/p&gt;

&lt;p&gt;Anxiety doesn’t disappear. But it becomes less of a tyrant, more of a map.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts &amp;amp; a Question for You
&lt;/h2&gt;

&lt;p&gt;I don’t pretend to have mastered my path. I’m still juggling curiosity, fear, bills, and ambition. But I see how small, intentional choices seeking connection, leaning into discomfort, and naming my fears make the journey more meaningful.&lt;/p&gt;

&lt;p&gt;Every time I ask myself whether I’ll pick the secure path or the learning path, I try to remember: &lt;strong&gt;growth happens where stability and risk overlap&lt;/strong&gt; not at extremes, but in the tension.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do you approach learning in the midst of your work, and how do you balance it with what life expects of you?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;Inspired by &lt;a href="https://www.simplethread.com/unnecessary-anxiety-in-software-development/" rel="noopener noreferrer"&gt;Unnecessary Anxiety in Software Development&lt;/a&gt; by SimpleThread.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>learning</category>
      <category>mentalhealth</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>From CSV to SQL: Importing CSV Real World Data into PostgreSQL.</title>
      <dc:creator>Fredrick Ogutu</dc:creator>
      <pubDate>Sat, 03 May 2025 15:24:09 +0000</pubDate>
      <link>https://dev.to/fiveace_merill/from-csv-to-sql-importing-csv-real-world-data-into-postgresql-1n5j</link>
      <guid>https://dev.to/fiveace_merill/from-csv-to-sql-importing-csv-real-world-data-into-postgresql-1n5j</guid>
      <description>&lt;p&gt;Like many other data projects, I found myself staring at a Kaggle dataset, which in this case was centered around &lt;a href="https://www.kaggle.com/datasets/hopesb/student-depression-dataset" rel="noopener noreferrer"&gt;&lt;em&gt;student depression&lt;/em&gt;&lt;/a&gt;. However, this time equipped with a new skill, SQL, I couldn't help but wonder what insights I could obtain about the complex and sensitive topic of mental health. Out of curiosity, I set out to go from CSV to SQL in PostgreSQL.&lt;br&gt;
This article documents the steps I took to load the dataset into a PostgreSQL database: cleaning the data, designing a table schema, and loading the data using PostgreSQL's built-in tools.  &lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Inspecting and Cleaning the dataset&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The dataset seemed relatively intuitive to use. The cleaning process involved the following steps.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Renaming the table and column names using &lt;a href="https://wiki.postgresql.org/wiki/Don't_Do_This#:~:text=Don%27t%20use%20upper%20case%20table,or%20column%20names" rel="noopener noreferrer"&gt;lowercase snakecase&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Removing special character "?" from the Financial Stress column.&lt;/li&gt;
&lt;li&gt;Validation of data types, e.g, ascertaining that numeric columns are numeric.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Defining a PostgreSQL Schema&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With the dataset cleaned, I found the schema below to best represent the data in the file.&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;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;student_depression&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;gender&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;profession&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;academic_pressure&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;work_pressure&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;cgpa&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;study_satisfaction&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;job_satisfaction&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;sleep_duration&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;dietary_habits&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;degree&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;suicidal_thoughts&lt;/span&gt; &lt;span class="nb"&gt;BOOLEAN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;work_study_hours&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;financial_stress&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;family_history&lt;/span&gt; &lt;span class="nb"&gt;BOOLEAN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;depression&lt;/span&gt; &lt;span class="nb"&gt;BOOLEAN&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Importing the CSV file into PostgreSQL&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Depending on your tools and environment, there are several options for importing data, from using a graphical tool like &lt;a href="https://www.pgadmin.org/" rel="noopener noreferrer"&gt;pgAdmin&lt;/a&gt; to a direct SQL query.&lt;br&gt;
For my case, I was using a locally hosted PostgreSQL, and found the command line to be convenient.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;psql &lt;span class="nt"&gt;-U&lt;/span&gt; your_username &lt;span class="nt"&gt;-d&lt;/span&gt; student_depression &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\C&lt;/span&gt;&lt;span class="s2"&gt;OPY student_depression FROM 'path/to/student_depression_dataset.csv' DELIMITER ',' CSV HEADER;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The \copy command reads the file from your computer and sends it to the database, and is easier to use when there is no direct &lt;a href="https://www.postgresql.org/docs/current/sql-copy.html#:~:text=Do%20not%20confuse%20,copy%60%20is%20used" rel="noopener noreferrer"&gt;file access on the server&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Requirement to successfully load a CSV file with psql&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The table should already exist with a matching schema.&lt;/li&gt;
&lt;li&gt;Problematic columns and values should either be renamed or removed during the cleaning process.&lt;/li&gt;
&lt;li&gt;Only then can you use the \ COPY command embedded within the bash script.&lt;/li&gt;
&lt;li&gt;In the event of an error message, like mismatched columns or conflicting data types. Adjustment of the file was required.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Running Sample SQL Queries&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With the data loaded, you can test and explore your dataset with SQL. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Counting total records&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&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="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&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;total_students&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;student_depression&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Grouping by gender&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&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;gender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;student_depression&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Average cgpa by depression status&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&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;depression&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cgpa&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;avg_cgpa&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;student_depression&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;depression&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;Top five cities by number of students&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&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;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&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;num_students&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;student_depression&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;city&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;num_students&lt;/span&gt; &lt;span class="k"&gt;DESC&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;h2&gt;
  
  
  &lt;strong&gt;Conclusion and next steps&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This project turned out to be a rewarding venture into structuring data into a queryable SQL format. Even though I loaded the dataset into a single flat table, it was a great opportunity to explore and reinforce fundamental concepts of SQL. I now appreciate the importance of a proper schema design.&lt;/p&gt;

&lt;p&gt;However, the limitations of the singular table approach quickly became apparent. Analyzing CGPA trends across cities and other measures was difficult to perform effectively. Concepts like common Table Expressions, subqueries, correlated subqueries, and window functions are much more suitable when used with a relational setup.&lt;/p&gt;

&lt;p&gt;Moving forward, using primary and foreign keys, the dataset should be normalized and refactored into multiple linked tables to unlock more analytical power.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>learning</category>
      <category>database</category>
      <category>postgres</category>
    </item>
  </channel>
</rss>
