<?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: topeogunleye</title>
    <description>The latest articles on DEV Community by topeogunleye (@topeogunleye).</description>
    <link>https://dev.to/topeogunleye</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%2F394545%2F07069708-4142-401b-9c7a-94f62bac39b9.jpg</url>
      <title>DEV Community: topeogunleye</title>
      <link>https://dev.to/topeogunleye</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/topeogunleye"/>
    <language>en</language>
    <item>
      <title>Building a Game Review API with Strapi 5.36.1, Rest API and Next.js 16: A Step-by-Step Guide.</title>
      <dc:creator>topeogunleye</dc:creator>
      <pubDate>Sat, 29 Nov 2025 12:42:35 +0000</pubDate>
      <link>https://dev.to/topeogunleye/building-a-game-review-api-with-strapi-a-step-by-step-beginners-guide-98m</link>
      <guid>https://dev.to/topeogunleye/building-a-game-review-api-with-strapi-a-step-by-step-beginners-guide-98m</guid>
      <description>&lt;p&gt;If you’ve ever worked with WordPress or any traditional CMS, you probably noticed that both the frontend and backend are tightly connected.&lt;/p&gt;

&lt;p&gt;That’s great for simple setups — until you want full control over how your frontend looks and behaves. Then it becomes a pain because you have to work around WordPress themes, plugins, and templating systems.&lt;/p&gt;

&lt;p&gt;That’s where a headless CMS comes in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Headless CMS&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A management system for content without a frontend meaning you only get an admin panel or backend and then you’ll decide whatever frontend technology you’ll like to use in displaying your content.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Strapi is a CMS that you can use for your backend content management because when you use strapi, you get an API that you can use on your frontend built with any frontend technology (React, Vanilla JS, Swelt, Vue).&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;/blogs&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Fetch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;all&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;blog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;posts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;/blogs/:id&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Fetch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;single&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;blog&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;post&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;by&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’re going to use the fetch API to make requests for the data in the endpoints above, Strapi works really well with GraphQL.&lt;/p&gt;

&lt;p&gt;While Strapi works beautifully with GraphQL, in this guide, we will use the built-in REST API and Next.js Server Actions to fetch our data efficiently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In order to build this API, you’re going to need the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Knowledge of How GraphQL works.&lt;/li&gt;
&lt;li&gt;Nodejs installed on your system.&lt;/li&gt;
&lt;li&gt;An understanding of React and React Hooks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Part A:  Creating a New Project Using Strapi&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First on all, Create a game-review folder that will contain both your backend and frontend folders.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;mkdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;game-review&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Navigate into your game-review folder, then create a backend folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;game-review&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;mkdir&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;backend&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command into your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;npx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;create-strapi@latest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;&lt;br&gt;
Instead of manually configuring your environment, follow the official &lt;a href="https://docs.strapi.io/cms/quick-start" rel="noopener noreferrer"&gt;Strapi Quick Start Guide&lt;/a&gt; from no 2 under &lt;strong&gt;Step 1: Run the installation script and create a Strapi Cloud account&lt;/strong&gt; to &lt;strong&gt;Step 2: Register the first local administrator user&lt;/strong&gt;. This ensures you are using the most stable version and the latest features (like the automatic Strapi Cloud 30-day trial).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Visit:&lt;/strong&gt; &lt;a href="https://docs.strapi.io/cms/quick-start" rel="noopener noreferrer"&gt;Strapi Quick Start Guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action:&lt;/strong&gt; Follow and run the commands in  &lt;strong&gt;Part A: Create a new project with Strapi&lt;/strong&gt; as directed*&lt;em&gt;.&lt;/em&gt;*&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To use GraphQL with Strapi, you must install the plugin. Run this in your backend folder:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Your backend is live.&lt;/strong&gt; Now that the engine is running, let’s go to &lt;strong&gt;Part B&lt;/strong&gt; and build out our gaming review structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Part B: Build your Content Structure with Content-Type Builder
&lt;/h2&gt;

&lt;p&gt;In Strapi, a &lt;strong&gt;Content-type&lt;/strong&gt; acts as a blueprint. It defines exactly what fields your data should have (e.g., a "Review" needs a title and a rating). You will build a &lt;strong&gt;Collection Type&lt;/strong&gt;, which allows you to create multiple entries of the same kind.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create a "Review" Collection Type
&lt;/h3&gt;

&lt;p&gt;Navigate to your local admin panel at &lt;code&gt;http://localhost:1337/admin&lt;/code&gt;. This is your command center for data management.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Access the Builder:&lt;/strong&gt; Click on &lt;strong&gt;Content-Type Builder&lt;/strong&gt; in the main navigation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initialize:&lt;/strong&gt; Click &lt;strong&gt;Create new collection type&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Naming:&lt;/strong&gt; Enter &lt;code&gt;Review&lt;/code&gt; for the Display name and click &lt;strong&gt;Continue&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Add Fields to Your Blueprint
&lt;/h3&gt;

&lt;p&gt;We need to define what a "Review" looks like. Follow the table below to add the necessary fields:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Field Type&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Name&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Settings&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Text&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;title&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Advanced:&lt;/strong&gt; Set as &lt;em&gt;Required&lt;/em&gt; and &lt;em&gt;Unique&lt;/em&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Number&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rating&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Format:&lt;/strong&gt; &lt;em&gt;Integer&lt;/em&gt;. &lt;strong&gt;Advanced:&lt;/strong&gt; &lt;em&gt;Required&lt;/em&gt;, Min: 1, Max: 10.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rich Text&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;body&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Advanced:&lt;/strong&gt; Set as &lt;em&gt;Required&lt;/em&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Finalize:&lt;/strong&gt; Once all fields are added, click &lt;strong&gt;Finish&lt;/strong&gt;, then click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Note:&lt;/strong&gt; Strapi will automatically restart your server to apply these changes to the database.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part C: Create and Publish Content
&lt;/h2&gt;

&lt;p&gt;Now that the blueprint is ready, let's add some data.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the &lt;strong&gt;Content Manager&lt;/strong&gt; in the left sidebar.&lt;/li&gt;
&lt;li&gt;Select the &lt;strong&gt;Review&lt;/strong&gt; collection type you just created.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create new entry&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fill the data:&lt;/strong&gt; * &lt;strong&gt;Title:&lt;/strong&gt; Mario Golf

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Body:&lt;/strong&gt; [Your Review Text]&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rating:&lt;/strong&gt; 9&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publish:&lt;/strong&gt; Click &lt;strong&gt;Save&lt;/strong&gt;, then click &lt;strong&gt;Publish&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; In Strapi, an entry must be &lt;strong&gt;Published&lt;/strong&gt; to be accessible via the API. If it is only "Saved," it remains a draft and will return a 404 error when you try to fetch it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 3: Set Permissions (Making the API Public)
&lt;/h3&gt;

&lt;p&gt;By default, Strapi protects your data. To allow your frontend to see these reviews, we must grant public access.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Settings&lt;/strong&gt; (⚙️) &amp;gt; &lt;strong&gt;Users &amp;amp; Permissions Plugin&lt;/strong&gt; &amp;gt; &lt;strong&gt;Roles&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Public&lt;/strong&gt; role.&lt;/li&gt;
&lt;li&gt;Scroll to the &lt;strong&gt;Review&lt;/strong&gt; section and expand it.&lt;/li&gt;
&lt;li&gt;Check the &lt;strong&gt;find&lt;/strong&gt; and &lt;strong&gt;findOne&lt;/strong&gt; boxes.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  PART D: Using Our API IN OUR NEXTJS APPLICATION:
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Step 1: &lt;strong&gt;Initialize the Next.js Project:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Instead of manually configuring your environment, follow the official &lt;a href="https://nextjs.org/docs/app/getting-started/installation" rel="noopener noreferrer"&gt;Nextjs Quick Start Guide&lt;/a&gt;. This ensures you are using the most stable version and the latest features.&lt;/p&gt;

&lt;p&gt;Navigate back to your game-review folder to create the frontend, create your Next.js project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;npx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;create-next-app@latest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;frontend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;--use-npm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;--use-yarn&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Let’s create an API route that fetches game reviews from Strapi and makes them available to our Next.js app&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a new file named ./app/api/reviews/route.ts and&lt;/strong&gt; add the following*&lt;em&gt;:&lt;/em&gt;*&lt;/p&gt;






&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Path:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;./app/api/jobs/route.ts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;NextResponse&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next/server"&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;GET()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;res&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fetch(&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:1337/api/reviews"&lt;/span&gt;&lt;span class="err"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;res.json();&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;reviews&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;json.map((review:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;any)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...review&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;review.documentId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;));&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="err"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;NextResponse.json(reviews);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;List Reviews in Next.js Dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Define Typescript Interfaces for Your Game Review App:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Let's define the type structures for the review data we’ll be working with, to give us reliable typing, improved code readability, and helpful autocomplete support.&lt;/p&gt;

&lt;p&gt;Create a file at: &lt;code&gt;./app/types/index.ts,&lt;/code&gt; and add the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;interface&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Review&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;number;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;documentId:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;rating:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;number;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;title:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;body:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Array&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;children:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Array&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string;&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;text:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;createdAt:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;updatedAt:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;publishedAt:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Review interfaces gives structure and clarity to the data used in our frontend app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Review&lt;/code&gt;: Represents a complete game review with its metadata and rich text content. It includes the review's unique identifier (&lt;code&gt;id&lt;/code&gt; and &lt;code&gt;documentId&lt;/code&gt;), the numeric rating score, a title, and a richly-formatted body composed of text blocks and inline elements. It also tracks three important timestamps—&lt;code&gt;createdAt&lt;/code&gt; (when the review was written), &lt;code&gt;updatedAt&lt;/code&gt; (when it was last modified), and &lt;code&gt;publishedAt&lt;/code&gt; (when it became publicly visible).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Set Up the Global Layout &amp;amp; Header:
&lt;/h3&gt;

&lt;p&gt;Next.js uses a special file called &lt;code&gt;layout.tsx&lt;/code&gt; to define the UI shell that wraps around all your pages. This is the perfect place to set up global fonts, SEO metadata, and shared components like your navigation bar.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;./app/layout.tsx&lt;/code&gt; file and replace the default code with this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Metadata&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next"&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Poppins&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next/font/google"&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;SiteHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"../components/SiteHeader"&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./globals.css"&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Optimize&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Google&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Font&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;loading&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;poppins&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Poppins(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;subsets:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"latin"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;weight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"100"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"200"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"300"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"400"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"500"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"600"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"700"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"800"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"900"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;);&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;metadata:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Metadata&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;title:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ninja Reviews"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;description:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A site for ninja reviews"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;RootLayout(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Readonly&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;children:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;React.ReactNode;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;html&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;lang=&lt;/span&gt;&lt;span class="s2"&gt;"en"&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;className=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;poppins.className&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;div&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;className=&lt;/span&gt;&lt;span class="s2"&gt;"App"&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;SiteHeader&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Here is what this code does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Optimized Fonts:&lt;/strong&gt; We import the &lt;code&gt;Poppins&lt;/code&gt; font from &lt;code&gt;next/font/google&lt;/code&gt;. Next.js automatically optimizes this at build time so the browser doesn't have to make an extra network request to Google, speeding up your load times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO Metadata:&lt;/strong&gt; The &lt;code&gt;metadata&lt;/code&gt; object defines the global title and description for your app, which is essential for search engines and social media sharing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global Components:&lt;/strong&gt; We wrap the &lt;code&gt;{children}&lt;/code&gt; (which represents your individual pages) with a &lt;code&gt;&amp;lt;SiteHeader /&amp;gt;&lt;/code&gt; component. This ensures your navigation bar stays consistent across every single page without needing to import it multiple times.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Creating the Site Header Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because we just imported &lt;code&gt;&amp;lt;SiteHeader /&amp;gt;&lt;/code&gt; into our layout, our app will throw an error if that file doesn't exist yet. Let's build it!&lt;/p&gt;

&lt;p&gt;Create a new folder named &lt;code&gt;components&lt;/code&gt; in the root of your project (alongside your &lt;code&gt;app&lt;/code&gt; folder), and inside it, create a file named &lt;code&gt;SiteHeader.tsx&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is happening here?&lt;/strong&gt;&lt;br&gt;
Instead of using a standard HTML &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; tag, we are importing the &lt;code&gt;&amp;lt;Link&amp;gt;&lt;/code&gt; component from Next.js. This enables lightning-fast client-side navigation. When a user clicks your site title to go back to the homepage, Next.js routes them instantly without doing a full page refresh!&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4: &lt;strong&gt;Create Homepage Component&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To display reviews on the Next.js frontend, we’ll update our &lt;code&gt;page&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;This component will fetch the reviews  data from our Strapi backend, and render a card for each review with its key details.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;./app/page.tsx&lt;/code&gt;  file and Add this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'next/link';&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Review&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'../types';&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Extract&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;text&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;rich&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;text&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;body&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;getBodyText(body:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Review&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'body'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;body&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;.flatMap((block)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;block.children.map((child)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;child.text))&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;.join('&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;');&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Homepage()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Server-side&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fetching!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;No&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;need&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;useEffect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;loading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;states.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Next.js&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;handles&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;before&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sending&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTML&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;browser.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;res&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fetch('http://localhost:&lt;/span&gt;&lt;span class="mi"&gt;1337&lt;/span&gt;&lt;span class="err"&gt;/api/reviews'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Optional:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;caching&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;strategies&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;here&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;e.g.&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cache:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'no-store'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;);&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(!res.ok)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Error('Failed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fetch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data');&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;res.json();&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Review&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;response.data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;response;&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;data.map((review)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;div&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;key=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;review.id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;className=&lt;/span&gt;&lt;span class="s2"&gt;"review-card"&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;div&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;className=&lt;/span&gt;&lt;span class="s2"&gt;"rating"&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;review.rating&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;h&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;review.title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/h&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;small&amp;gt;console&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;list&amp;lt;/small&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;getBodyText(review.body).substring(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;...&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;Link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;href=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;`/details/$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;review.id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;Read&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;more&amp;lt;/Link&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;))&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(error)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;p&amp;gt;Error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;loading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;reviews&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;(error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Error).message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;:(&amp;lt;/p&amp;gt;;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

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

&lt;/div&gt;



&lt;p&gt;Here is a breakdown of what the code does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Server-Side Fetching:&lt;/strong&gt; Uses an async Next.js component to fetch game reviews directly, eliminating the need for &lt;code&gt;useEffect&lt;/code&gt; and loading states.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rich Text Parsing:&lt;/strong&gt; Relies on a &lt;code&gt;getBodyText&lt;/code&gt; helper function to extract and stitch together raw text from Strapi's nested array format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review Cards:&lt;/strong&gt; Maps through the fetched data to display the game's title, rating, and a clean 200-character excerpt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling:&lt;/strong&gt; Uses a &lt;code&gt;try...catch&lt;/code&gt; block as a safety net to gracefully display a fallback message if the Strapi API goes down.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 5: Create the Dynamic Details Page
&lt;/h3&gt;

&lt;p&gt;Create this directory structure:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./app/details/[id]/page.tsx&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;[id]&lt;/code&gt; folder is Next.js syntax for dynamic routes—it captures the review ID from the URL and passes it to your component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;Implementation&lt;/code&gt;&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Here's the code for &lt;code&gt;page.tsx:&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Review&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'../../../types';&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Extract&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;text&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;rich&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;text&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;body&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;getBodyText(body:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Review&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'body'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;body&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;.flatMap((block)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;block.children.map((child)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;child.text))&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;.join('&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;');&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;DetailsPageProps&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;params:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Promise&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;export&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;default&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ReviewDetails(&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;params&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;DetailsPageProps)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;resolvedParams&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;params;&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Server-side&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fetching!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;No&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;need&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;useEffect&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;loading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;states.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Next.js&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;handles&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;this&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;on&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;server&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;before&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;sending&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTML&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;browser.&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;console.log(`Fetching&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;review&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;details&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;resolvedParams.id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Debug&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;verify&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;being&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fetched&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;res&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fetch(`http://localhost:&lt;/span&gt;&lt;span class="mi"&gt;1337&lt;/span&gt;&lt;span class="err"&gt;/api/reviews?filters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;id&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="err"&gt;$eq&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;=$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;resolvedParams.id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Optional:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;caching&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;strategies&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;here&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;e.g.&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;cache:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;'no-store'&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;);&lt;/span&gt;&lt;span class="w"&gt;  

    &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(!res.ok)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;throw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Error(`Failed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fetch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;res.status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;res.statusText&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;`);&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;await&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;res.json();&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="err"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Review&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Array.isArray(response.data)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;response.data&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="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;response;&lt;/span&gt;&lt;span class="w"&gt;

  &lt;/span&gt;&lt;span class="err"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;div&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;key=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;data.id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;className=&lt;/span&gt;&lt;span class="s2"&gt;"review-card"&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;h&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;Review&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Details&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ID:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;resolvedParams.id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/h&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;div&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;className=&lt;/span&gt;&lt;span class="s2"&gt;"rating"&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;data.rating&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;h&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;data.title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/h&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;small&amp;gt;console&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;list&amp;lt;/small&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;getBodyText(data.body)&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(error)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;lt;p&amp;gt;Error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;loading&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;review&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;details&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;(error&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Error).message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;:(&amp;lt;/p&amp;gt;;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Here is what the code above does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Route Parameter:&lt;/strong&gt; The [id] in the folder name captures the review ID from the URL (e.g., &lt;code&gt;/details/123&lt;/code&gt; extracts &lt;code&gt;id: '123'&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server-Side Fetching:&lt;/strong&gt; This is an async server component that fetches the review directly from Strapi before rendering—no loading states needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extract the ID:&lt;/strong&gt; The component awaits &lt;code&gt;params&lt;/code&gt;, then uses &lt;code&gt;resolvedParams.id&lt;/code&gt; to query &lt;code&gt;/api/reviews?filters[id][$eq]=${id}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Render the Full Review:&lt;/strong&gt; It displays the complete title, rating, and rich text body using the &lt;code&gt;getBodyText()&lt;/code&gt; helper function to flatten the nested body structure into readable text.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling&lt;/strong&gt;: If the fetch fails, it displays a user-friendly error message.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach ensures that each review has its own permalink (e.g., &lt;code&gt;/details/1&lt;/code&gt;, &lt;code&gt;/details/2&lt;/code&gt;) and delivers the full content on initial page load.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 6: Add Basic Styling&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The classes you’ve sprinkled through the JSX (&lt;code&gt;className="review-card"&lt;/code&gt;, &lt;code&gt;.rating&lt;/code&gt;, etc.) don’t do anything until you give them some style.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;globals.css&lt;/code&gt; and toss in (or merge with) a small snippet that treats each review like a card and makes the score badge stand out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;/*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Note:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;The&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;@import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;url()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Poppins&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;was&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;removed.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;We&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;will&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;handle&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;layout.tsx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;*/&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;margin:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="err"&gt;px;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;background:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#f&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;f&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;f&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;h&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;,h&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;,h&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;,h&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;font-weight:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;.App&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;font-size:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.2&lt;/span&gt;&lt;span class="err"&gt;em;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;margin:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="err"&gt;px&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;auto;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;width:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="err"&gt;%;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;max-width:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="err"&gt;px;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;padding:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="err"&gt;px;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;box-sizing:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;border-box;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;text-decoration:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;none;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;color:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;8e2&lt;/span&gt;&lt;span class="err"&gt;ad&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;border-bottom:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;px&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;dotted;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;.site-header&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;h&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;font-size:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="err"&gt;em;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;color:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;8e2&lt;/span&gt;&lt;span class="err"&gt;ad&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;padding-bottom:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="err"&gt;px;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;border-bottom:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="err"&gt;px&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;solid;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;/*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;review&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;*/&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;.review-card&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;background:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;white;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;margin:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="err"&gt;px&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;auto;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;padding:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;px&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="err"&gt;px&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="err"&gt;px&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="err"&gt;px;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;position:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;relative;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;.review-card&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.rating&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;position:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;absolute;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;top:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-20&lt;/span&gt;&lt;span class="err"&gt;px;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;left:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-20&lt;/span&gt;&lt;span class="err"&gt;px;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;background:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;8e2&lt;/span&gt;&lt;span class="err"&gt;ad&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;font-size:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="err"&gt;em;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;width:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="err"&gt;px;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;height:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="err"&gt;px;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;text-align:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;center;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;color:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;white;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;.review-card&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;h&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;margin-bottom:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;.review-card&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;small&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;margin-right:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="err"&gt;px;&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;color:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;777&lt;/span&gt;&lt;span class="err"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Tip: this is all in globals.css because it applies across the app; feel free to tweak spacing, colors, or add shadows to suit your taste.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With those rules in place the grid of reviews will appear as distinct cards and the rating “badge” will really pop – much nicer than plain text!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Run the Full-Stack Application
&lt;/h2&gt;

&lt;p&gt;To see your project in action, you need to have both the &lt;strong&gt;Strapi Backend&lt;/strong&gt; and the &lt;strong&gt;Next.js Frontend&lt;/strong&gt; running at the same time. You can do this by opening two separate terminal windows or using a process runner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 1: The Manual Way (Two Terminals)
&lt;/h3&gt;

&lt;p&gt;Open two terminal tabs in your root &lt;code&gt;game-review&lt;/code&gt; folder:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Terminal 1 (Backend):&lt;/strong&gt;Bash&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;backend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;npm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;develop&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;em&gt;Admin panel will be at:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;*&lt;/span&gt;http://localhost:1337/admin&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Terminal 2 (Frontend):&lt;/strong&gt;Bash&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;frontend &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run dev
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;em&gt;Your app will be live at: &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;&lt;code&gt;http://localhost:3000&lt;/code&gt;&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=yqbFTy_0DWw" rel="noopener noreferrer"&gt;Getting Started with Next.js 15 and Strapi 5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This video provides a practical walkthrough of setting up a local environment for Next.js and Strapi 5, which perfectly complements the manual steps you've written.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Congratulations! You've built a full-stack Headless CMS application. To take this further, you could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deploy:&lt;/strong&gt; Push your backend to Strapi Cloud and your frontend to Vercel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expand:&lt;/strong&gt; Add a "Category" collection type to filter reviews by console (PS5, Xbox, Switch).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Switch to GraphQL:&lt;/strong&gt; Now that you have the basics, try swapping the &lt;code&gt;fetch&lt;/code&gt; calls for Apollo Client queries.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>api</category>
      <category>strapi</category>
      <category>nextjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Install PostgreSQL 18 on Ubuntu 24.04</title>
      <dc:creator>topeogunleye</dc:creator>
      <pubDate>Wed, 01 Oct 2025 11:30:30 +0000</pubDate>
      <link>https://dev.to/topeogunleye/how-to-install-postgresql-18-on-ubuntu-2404-1doc</link>
      <guid>https://dev.to/topeogunleye/how-to-install-postgresql-18-on-ubuntu-2404-1doc</guid>
      <description>&lt;p&gt;PostgreSQL, often called Postgres, is an advanced object-relational database management system. It is used because it is free, open-source, and known for its reliability, flexibility, and strong adherence to SQL standards. Some of its common uses include transaction processing, data analytics, mobile and web applications, geospatial applications, database and application modernization, generative ai.&lt;/p&gt;

&lt;p&gt;PostgreSQL has remained open-source since its development at Berkeley. Being open-source means that the code is completely available for viewing, modification, and distribution. &lt;/p&gt;

&lt;p&gt;You will install PostgreSQL on Ubuntu 24.04 using this guide.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 24.04 Installed on your local machine or on a server.&lt;/li&gt;
&lt;li&gt;A non-root user with sudo privileges.&lt;/li&gt;
&lt;li&gt;To know how to use the Linux terminal.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Step 1 - Installing PostgreSQL&lt;/strong&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  1. Update Your Package Index
&lt;/h2&gt;

&lt;p&gt;Ubuntu’s default repositories come together with Postgres packages, so you can install these using the apt packaging system.&lt;/p&gt;

&lt;p&gt;If you haven’t updated your system’s packages recently, run the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Add the PGDG repo
&lt;/h2&gt;

&lt;p&gt;Add the PostgreSQL Global Development Group repo to get the latest stable PostgreSQL releases plus older supported versions. This will allow APT to know where to find PostgreSQL versions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;sh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" &amp;gt; /etc/apt/sources.list.d/pgdg.list'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What the Command above does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;$(lsb_release -cs)&lt;/code&gt; → It inserts the Ubuntu codename e.g noble for Ubuntu 24.04.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pgdg&lt;/code&gt; → tells it to use the PostgreSQL repository for that release.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Import the repository signing Keys:
&lt;/h2&gt;

&lt;p&gt;Import the repository signing Keys (so APT knows it can trust packages from that repo)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://www.postgresql.org/media/keys/ACCC4CF8.asc | &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /etc/apt/trusted.gpg.d/postgresql.gpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What the command above does:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;curl -fsSL https://.../ACCC4CF8.asc&lt;/code&gt; → downloads the PostgreSQL repository signing key (a GPG key).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gpg --dearmor&lt;/code&gt; → converts it from ASCII-armored format into binary format that APT can use.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;o /etc/apt/trusted.gpg.d/postgresql.gpg&lt;/code&gt; → saves it in the directory where APT looks for trusted keys.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4 Update Your Package Index again
&lt;/h2&gt;

&lt;p&gt;This is to allow APT to know about the new repositories after:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Install PostgreSQL Version 18:
&lt;/h2&gt;

&lt;p&gt;This command below Installs specifically PostgreSQL Version 18&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="nb"&gt;install &lt;/span&gt;postgresql-18
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2 — Start, Enable, and Check Status
&lt;/h2&gt;

&lt;p&gt;Start the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start postgresql

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

&lt;/div&gt;



&lt;p&gt;Enable the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;postgresql

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

&lt;/div&gt;



&lt;p&gt;Check the current status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status postgresql

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

&lt;/div&gt;



&lt;p&gt;If the service is active, the output will show &lt;strong&gt;active (running)&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Secure the PostgreSQL Database on Ubuntu (Local Machine)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Log in as the PostgreSQL user:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres psql

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Modify the default postgres user with a new strong password:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="n"&gt;postgres&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;ENCRYPTED&lt;/span&gt; &lt;span class="n"&gt;PASSWORD&lt;/span&gt; &lt;span class="s1"&gt;'strong_password'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a new user &lt;code&gt;db_manager&lt;/code&gt; with a new strong password:
You shouldn’t use the default user “db_manager” for daily tasks. You should create a new user (e.g., db_manager) with its own password:
&lt;/li&gt;
&lt;/ol&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;USER&lt;/span&gt; &lt;span class="n"&gt;db_manager&lt;/span&gt; &lt;span class="k"&gt;ENCRYPTED&lt;/span&gt; &lt;span class="n"&gt;PASSWORD&lt;/span&gt; &lt;span class="s1"&gt;'strong_password'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Exit the PostgreSQL console:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Edit the main configuration file to enable password authentication:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'/^local/s/peer/scram-sha-256/'&lt;/span&gt; /etc/postgresql/16/main/pg_hba.conf

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart PostgreSQL to apply changes:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart postgresql

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4 — Creating a New Role
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Switching to the postgres Account
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres psql

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Create a New Role
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Using createuser (interactive):&lt;/strong&gt;&lt;br&gt;
Now, that you have switched to the default postgres account, you can create a new user with the command below.:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;createuser &lt;span class="nt"&gt;--interactive&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Or if you want to create a new role without switching to the postgres account, use this command below and do it directly from your terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres createuser &lt;span class="nt"&gt;--interactive&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With login + password:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To create a basic user that can log in, you can run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;createuser new_username &lt;span class="nt"&gt;--interactive&lt;/span&gt; &lt;span class="nt"&gt;--pwprompt&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This command will interactively ask for the role name, a password, and what privileges to grant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using SQL (createrole):&lt;/strong&gt;&lt;br&gt;
A role without the LOGIN attribute cannot be used to log in. They are typically used as “group roles” to bundle a set of permissions together which can then be used to grant permissions to multiple user roles simplifying permission management&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;ROLE&lt;/span&gt; &lt;span class="n"&gt;new_username&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;LOGIN&lt;/span&gt; &lt;span class="n"&gt;PASSWORD&lt;/span&gt; &lt;span class="s1"&gt;'a_secure_password'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Note: &lt;code&gt;CREATE USER&lt;/code&gt; is an alias for &lt;code&gt;CREATE ROLE ... WITH LOGIN&lt;/code&gt;. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Grant Privileges (Optional)
You can grant specific privileges to a role either during its creation or afterward using the ALTER ROLE command.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From your terminal, switch to a superuser account, for example: a postgres account because only a superuser can grant SUPERUSER status&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Superuser Priviledge:&lt;/strong&gt;
You use the command below to bypass all permission checks for a user:
&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;ALTER&lt;/span&gt; &lt;span class="k"&gt;ROLE&lt;/span&gt; &lt;span class="n"&gt;new_username&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;SUPERUSER&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;Database Creation Privilege:&lt;/strong&gt;
You use the command below to allow the role to create new databases.
&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;ALTER&lt;/span&gt; &lt;span class="k"&gt;ROLE&lt;/span&gt; &lt;span class="n"&gt;new_username&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="k"&gt;CREATEDB&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;Multiple Privileges at Once:&lt;/strong&gt;
Make use of the command below to assign these attributes directly when creating the role.
&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;CREATE&lt;/span&gt; &lt;span class="k"&gt;ROLE&lt;/span&gt; &lt;span class="n"&gt;new_username&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;LOGIN&lt;/span&gt; &lt;span class="n"&gt;PASSWORD&lt;/span&gt; &lt;span class="s1"&gt;'a_secure_password'&lt;/span&gt; &lt;span class="n"&gt;SUPERUSER&lt;/span&gt; &lt;span class="k"&gt;CREATEDB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5 — Creating a New Database
&lt;/h2&gt;

&lt;p&gt;Only a superuser can create a database and assign ownership to another role simultaneously. You must be a superuser or have the special CREATEDB privilege.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Switching to the postgres Account&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you aren’t current on a postgres or superuser account. use this command to do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres psql

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Create a New Database
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Using createdb (Shell Command):&lt;/strong&gt;&lt;br&gt;
This command is a wrapper for the CREATE DATABASE command. Use the -O (uppercase O) flag to specify the new owner. This command should be run from your server's command line, not inside the psql shell.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;createdb &lt;span class="nt"&gt;-O&lt;/span&gt; new_role new_database_name

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Using SQL (inside psql):&lt;/strong&gt;&lt;br&gt;
From within the psql interface, you can use the CREATE DATABASE command with the OWNER clause.&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;DATABASE&lt;/span&gt; &lt;span class="n"&gt;new_database_name&lt;/span&gt; &lt;span class="k"&gt;OWNER&lt;/span&gt; &lt;span class="n"&gt;new_role&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;By default, if you do not specify an owner, the role executing the command becomes the owner of the new database. If you need to change the owner after creation, you can use the ALTER DATABASE command.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6 — Altering Databases
&lt;/h2&gt;

&lt;p&gt;Similarly to the &lt;code&gt;CREATE DATABASE&lt;/code&gt; command, Only a superuser can Alter a database, still in the supperuser account that you just used. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change name of database
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ALTER DATABASE name RENAME TO new_name&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Change the owner i.e the role that owns the database:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ALTER DATABASE name OWNER TO &lt;span class="o"&gt;{&lt;/span&gt; new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Examples:&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;ALTER&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;mydb&lt;/span&gt; &lt;span class="k"&gt;OWNER&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;new_owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;mydb&lt;/span&gt; &lt;span class="k"&gt;OWNER&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="k"&gt;CURRENT_USER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Move the databases file to a different storage
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TABLESPACE&lt;/span&gt; &lt;span class="n"&gt;new_tablespace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&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;ALTER&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;mydb&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;TABLESPACE&lt;/span&gt; &lt;span class="n"&gt;fast_ssd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Refresh collation metadata used by the database to match the system libc locale/collation version.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="n"&gt;REFRESH&lt;/span&gt; &lt;span class="k"&gt;COLLATION&lt;/span&gt; &lt;span class="k"&gt;VERSION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&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;ALTER&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;mydb&lt;/span&gt; &lt;span class="n"&gt;REFRESH&lt;/span&gt; &lt;span class="k"&gt;COLLATION&lt;/span&gt; &lt;span class="k"&gt;VERSION&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7 — Accessing the Postgres Prompt With New Role
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a matching Linux user:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;adduser johndoe

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Switch over and connect:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; johndoe
psql

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; sammy psql

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check connection info:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;conninfo&lt;/span&gt;

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 8 — Creating and Deleting Tables
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Basic syntax:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;column_name1&lt;/span&gt; &lt;span class="n"&gt;col_type&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field_length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;column_constraints&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;column_name2&lt;/span&gt; &lt;span class="n"&gt;col_type&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field_length&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;column_name3&lt;/span&gt; &lt;span class="n"&gt;col_type&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;field_length&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;&lt;strong&gt;Sample table:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;animals&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;perm_id&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;species&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sex&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&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;&lt;strong&gt;Insert sample data:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;perm_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;species&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'401'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Bird'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'m'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'403'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Cattle'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'m'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'404'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Fish'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'f'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Query table:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Delete table:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Alter table:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt; &lt;span class="n"&gt;ALTER_OPTION&lt;/span&gt; &lt;span class="n"&gt;sub_options&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Exit:&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="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;

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

&lt;/div&gt;






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

&lt;p&gt;You have successfully installed PostgreSQL on your Ubuntu 24.04 machine. There is much more to learn about PostgreSQL including and not limited to: querying data on a table, adding and deleting columns from a table, and updating data in a table.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>postgres</category>
      <category>database</category>
    </item>
    <item>
      <title>Optimize React Performance in 2024 — Best Practices</title>
      <dc:creator>topeogunleye</dc:creator>
      <pubDate>Mon, 02 Sep 2024 19:38:27 +0000</pubDate>
      <link>https://dev.to/topeogunleye/optimize-react-performance-in-2024-best-practices-4f99</link>
      <guid>https://dev.to/topeogunleye/optimize-react-performance-in-2024-best-practices-4f99</guid>
      <description>&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%2Fqn69itfwf2uqpqug6prx.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%2Fqn69itfwf2uqpqug6prx.png" alt="Rocket" width="400" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating dynamic user interfaces with React is both exciting and empowering. This feature-rich library has become a favorite in today's development world, offering endless possibilities to developers. But with all that power comes a bit of a catch—it's easy to get carried away and misuse features without fully considering how they might impact performance.&lt;/p&gt;

&lt;p&gt;In this article, we’re going to learn about eight essential tips for optimizing your React applications. These strategies will help you keep your projects running smoothly and efficiently, ensuring that your apps remain robust and responsive, no matter how complex they get.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://www.npmjs.com/package/react-virtualized" rel="noopener noreferrer"&gt;List Virtualization&lt;/a&gt;
&lt;/h3&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%2Fwtmzazlan3fcvtait2a2.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%2Fwtmzazlan3fcvtait2a2.png" alt="List Virtualization Image" width="512" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine you have a huge list of items. Rendering all of them at once? Not cool. It can seriously drag down your app’s performance and hog a ton of memory. But fear not—list virtualization to the rescue!&lt;/p&gt;

&lt;p&gt;With list virtualization, you only render the items that are visible in the viewport, saving precious resources. As the user scrolls, this technique works its magic by dynamically swapping out the rendered items with new ones, keeping everything smooth and efficient. It’s like having a magic scroll that only shows what you need when you need it—perfect for handling massive lists or tables without breaking a sweat.&lt;/p&gt;

&lt;p&gt;In the React world, there are several ways to get this magic going, with the &lt;strong&gt;&lt;a href="https://www.npmjs.com/package/react-virtualized" rel="noopener noreferrer"&gt;react-virtualized&lt;/a&gt;&lt;/strong&gt; library being one of the most popular.&lt;/p&gt;

&lt;p&gt;Now, let’s move on to number two: lazy loading.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading" rel="noopener noreferrer"&gt;Lazy Loading Images&lt;/a&gt;
&lt;/h3&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%2Faq2gc06yrrztxkyge9wr.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%2Faq2gc06yrrztxkyge9wr.png" alt="Lazy Loading Image" width="512" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lazy loading images gives your website a breath of fresh air—it’s all about loading what’s needed when it’s needed, rather than piling everything on at once. Instead of loading every image on a page during the initial load, lazy loading waits until an image is visible to the user before bringing it in. This approach not only enhances performance but also makes your app feel faster and more responsive.&lt;/p&gt;

&lt;p&gt;Here’s how it works: when the page first loads, only a placeholder or a low-res version of the image (like a tiny thumbnail or a loading placeholder as seen above) is shown. Then, as the user scrolls and the image comes into view, the actual image is loaded and replaces the placeholder.&lt;/p&gt;

&lt;p&gt;In React, you have a few options for implementing lazy loading. The &lt;code&gt;react-lazyload&lt;/code&gt; library is a popular choice, offering a straightforward way to delay image loading. But if you’re feeling adventurous, you can roll your solution using the Intersection Observer API. This handy web API detects when an element enters or exits the viewport, and when combined with React’s &lt;code&gt;useEffect&lt;/code&gt; hook, it allows you to craft a custom lazy loading strategy that’s perfectly tailored to your app.&lt;/p&gt;

&lt;p&gt;Now, let's move on to number three: memoization.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://react.dev/reference/react/memo" rel="noopener noreferrer"&gt;Memoization&lt;/a&gt;
&lt;/h3&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%2Fdvkbm91cl0ajh3e6t8q0.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%2Fdvkbm91cl0ajh3e6t8q0.png" alt="Memoization Image" width="512" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Memoization in React is like giving your components a memory boost, allowing them to remember the results of previous computations so they don’t have to do the same work over and over again. This is particularly handy when you're dealing with functions that are heavy on processing or get called frequently with the same inputs. By caching these results, you can skip redundant calculations and keep your app running smoothly.&lt;/p&gt;

&lt;p&gt;There are three key tools in React for memoization: &lt;code&gt;React.memo&lt;/code&gt;, the &lt;code&gt;useMemo&lt;/code&gt; hook, and the &lt;code&gt;useCallback&lt;/code&gt; hook.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://react.dev/reference/react/memo" rel="noopener noreferrer"&gt;React.memo&lt;/a&gt;&lt;/strong&gt;: Imagine you have a component that renders based on its props. Normally, every time the parent component re-renders, the child component will too, even if its props haven’t changed. This can be inefficient, especially if rendering is resource-intensive. With &lt;code&gt;React.memo&lt;/code&gt;, you can wrap the child component, and React will remember the result from the last render. If the props are the same, it reuses that result, saving on unnecessary re-renders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://react.dev/reference/react/useMemo" rel="noopener noreferrer"&gt;useMemo&lt;/a&gt;&lt;/strong&gt;: The &lt;code&gt;useMemo&lt;/code&gt; hook helps you avoid unnecessary recalculations. Let’s say you have a function that crunches some serious numbers—it’s time-consuming. Without memoization, this function would run every time the component re-renders, even if the inputs stay the same. By using &lt;code&gt;useMemo&lt;/code&gt;, you tell React to cache the result of this function and only redo the calculation if the inputs change. This way, the function result is stored and reused, boosting efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://react.dev/reference/react/useCallback" rel="noopener noreferrer"&gt;useCallback&lt;/a&gt;&lt;/strong&gt;: The &lt;code&gt;useCallback&lt;/code&gt; hook is like &lt;code&gt;useMemo&lt;/code&gt; but for functions themselves. In React, every time a component re-renders, any functions inside it are recreated. This can be a problem when these functions are passed as props to child components because React sees them as new functions and triggers re-renders in the child. &lt;code&gt;useCallback&lt;/code&gt; comes to the rescue by memoizing the function, ensuring it stays the same between re-renders as long as its dependencies haven’t changed. This helps avoid unnecessary re-renders in the child component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A powerful combination is using &lt;code&gt;useCallback&lt;/code&gt; with &lt;code&gt;React.memo&lt;/code&gt;. While &lt;code&gt;React.memo&lt;/code&gt; ensures the child component doesn’t re-render if its props haven’t changed, &lt;code&gt;useCallback&lt;/code&gt; keeps the functions passed as props stable, preventing new instances of the function on every re-render. Together, they make your components even more efficient, especially when working with callbacks.&lt;/p&gt;

&lt;p&gt;If you find this concept challenging, feel free to comment below, and I'll create a write-up that explains everything step by step in great detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://medium.com/@shubham3480/debouncing-and-throttling-in-react-e71c711fc6c5" rel="noopener noreferrer"&gt;Throttling and Debouncing Events&lt;/a&gt;
&lt;/h3&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%2Fjqxu6ls8pp6252gle66p.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%2Fjqxu6ls8pp6252gle66p.png" alt="Throttling and Debouncing Events" width="429" height="117"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Throttling and debouncing are the secret weapons in your React toolkit (pun intended) for managing how often functions or event handlers are called, which can make a big difference in your app's performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.freecodecamp.org/news/throttling-in-javascript/" rel="noopener noreferrer"&gt;Throttling&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Throttling is all about setting a limit on how often a function can run within a certain time frame. Imagine you have a function that’s tied to a window resize event. Without throttling, this function might fire off continuously as the user resizes the window, which can be overwhelming for your app. By throttling, you can ensure that the function only runs once every, say, 200 milliseconds, no matter how many times the event is triggered in that interval. This helps prevent your app from getting bogged down by too many function calls in a short period, keeping things running smoothly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://medium.com/@jamischarles/what-is-debouncing-2505c0648ff1" rel="noopener noreferrer"&gt;Debouncing&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Debouncing works a bit differently. Instead of limiting the frequency of function calls, debouncing delays the function until there’s a pause in the activity. Think of a search input field where you want to trigger a search function. If the function fires with every keystroke, you might end up sending a flood of API requests, which is inefficient. With debouncing, the function waits until the user has stopped typing for a certain period—like 300 milliseconds—before it runs. This way, the search function is only called when it’s really needed, cutting down on unnecessary operations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.freecodecamp.org/news/throttling-in-javascript/" rel="noopener noreferrer"&gt;Throttling&lt;/a&gt; makes sure a function isn’t called too often, while debouncing ensures it’s only called after a lull in activity. Both techniques are invaluable for handling events that can happen frequently, like scrolling, resizing, or typing, and they go a long way in keeping your app responsive and performant.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://legacy.reactjs.org/docs/code-splitting.html" rel="noopener noreferrer"&gt;Code-Splitting&lt;/a&gt;
&lt;/h3&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%2Fnfex8vdbsiawtuydpof6.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%2Fnfex8vdbsiawtuydpof6.png" alt="Code-Splitting Image" width="512" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code splitting in React is a powerful technique that enhances performance by breaking down a large JavaScript bundle into smaller, more manageable chunks. Instead of loading the entire application’s code upfront, code splitting ensures that only the necessary code for a specific part of the application is loaded when needed.&lt;/p&gt;

&lt;p&gt;In a typical React application, all JavaScript code, including components, libraries, and other dependencies, is bundled together into a single file. As the application grows, this bundle can become quite large, leading to slower initial load times, which can negatively impact the user experience.&lt;/p&gt;

&lt;p&gt;Code splitting addresses this issue by dividing the large bundle into multiple smaller chunks. These chunks are loaded selectively based on the current needs of the application. For example, when a user visits a specific page or triggers a particular action, only the relevant code for that page or action is fetched and executed, rather than loading the entire bundle at once.&lt;/p&gt;

&lt;p&gt;This technique is especially useful for improving performance in larger React applications with complex and diverse features.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://react.dev/reference/react/Fragment" rel="noopener noreferrer"&gt;React Fragments&lt;/a&gt;
&lt;/h3&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%2Fbmg4c4kc4zjtecqyelva.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%2Fbmg4c4kc4zjtecqyelva.png" alt="React Fragments" width="512" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React Fragments are invisible containers that let you group multiple elements without adding any extra tags to your DOM. This is super handy when you want to keep your markup clean and avoid unnecessary wrapper elements that could clutter up your DOM tree.&lt;/p&gt;

&lt;p&gt;Usually, when you’re rendering a list of items or a bunch of components, you might wrap them in a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; or another container element. But every time you do that, you’re adding an extra node to the DOM, which can make it messier and even slow down rendering, especially in large applications. React Fragments let you avoid this by grouping your elements without adding any extra HTML tags.&lt;/p&gt;

&lt;p&gt;Using Fragments keeps your DOM smaller and more efficient, which is a simple yet effective way to optimize your React components. It’s a small change that can make a big difference, especially when you’re dealing with complex, large-scale applications. So next time you find yourself reaching for a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, consider whether a Fragment might be a cleaner, more efficient option.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers" rel="noopener noreferrer"&gt;Web Workers&lt;/a&gt;
&lt;/h3&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%2Fyoa0p50c03vbv1oq95ne.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%2Fyoa0p50c03vbv1oq95ne.png" alt="Web Workers" width="512" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JavaScript is a single-threaded language, meaning it handles all tasks—such as DOM manipulation, UI interactions, API data processing, and CSS animations—on a single thread. While this design works well for many applications, it can lead to performance bottlenecks, especially when handling computationally intensive tasks that may block the main thread and cause the user interface to become unresponsive.&lt;/p&gt;

&lt;p&gt;Web Workers provide a solution to this problem by allowing you to offload such tasks to a separate thread that runs independently of the main JavaScript thread. By running scripts in the background, Web Workers can perform long-running or resource-heavy operations without affecting the responsiveness of the UI. By offloading resource-intensive tasks to Web Workers, you can run complex calculations or process large datasets without tying up the main thread. This means your app can keep running smoothly, even when a lot is going on behind the scenes.&lt;/p&gt;

&lt;p&gt;For example, consider an image processing application that applies filters to high-resolution images. Without Web Workers, applying a filter could cause the entire UI to freeze until the operation is complete, leading to a poor user experience. By delegating this task to a Web Worker, the main thread remains free to handle user interactions, animations, and rendering updates, resulting in a more responsive application.&lt;/p&gt;

&lt;p&gt;Integrating Web Workers into a React application involves a few key steps. First, create a separate JavaScript file for the Web Worker script, containing the code for the resource-intensive task. Then, instantiate the Web Worker in your React component and set up communication between the main thread and the Web Worker using the &lt;code&gt;postMessage&lt;/code&gt; and &lt;code&gt;onmessage&lt;/code&gt; methods. This allows you to send data to the Web Worker for processing and receive the results asynchronously, without blocking the main thread.&lt;/p&gt;

&lt;p&gt;Here’s a simple example of how to integrate Web Workers into a React application:&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;// myWorker.js (Web Worker script)&lt;/span&gt;
&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// Perform a resource-intensive task&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;processData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Send the result back to the main thread&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// React component (main thread)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;MyComponent&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;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setResult&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;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myWorker.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Send data to the Web Worker&lt;/span&gt;

    &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Receive the result from the Web Worker&lt;/span&gt;
      &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;terminate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Terminate the Web Worker to free resources&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;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;terminate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Clean up the Web Worker when the component unmounts&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="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;Web&lt;/span&gt; &lt;span class="nx"&gt;Worker&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;result&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By incorporating Web Workers into your React application, you can enhance its performance, responsiveness, and scalability, ensuring a smooth and seamless experience for your users.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://react.dev/reference/react/useTransition" rel="noopener noreferrer"&gt;useTransition Hooks&lt;/a&gt;
&lt;/h3&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%2Fgenb88id5w43so6w5tgl.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%2Fgenb88id5w43so6w5tgl.png" alt="useTransition Hooks" width="512" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The useTransition hook is a secret weapon in your React’s toolkit, giving you the power to update state without slowing down the UI. Imagine a scenario where a function inside a component needs to update two states at once. Normally, React bundles these updates together, making sure everything’s done before the component re-renders. This is pretty smart because it means just one render happens after all the changes, instead of two.&lt;br&gt;
But what if one of those updates is a real brain-buster? React still tries to group them, which can lead to delays because the quicker update has to wait for the slower one to finish. And that’s where things can get a bit sluggish.&lt;br&gt;
Enter the useTransition hook—your new best friend! With useTransition, you can tell React to prioritize certain updates by marking others as less urgent. The less critical updates still happen, but React doesn’t hold up the re-render waiting for them. This way, the important stuff gets done right away, keeping your UI snappy, while the other tasks run in the background.&lt;br&gt;
By using useTransition, you can dodge the slowdown caused by heavy operations and keep your app running smoothly—even when things get complex. It’s like having a traffic cop for your state updates, making sure everything flows just right!&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Optimizing React applications involves a combination of strategies and techniques, each targeting specific areas of performance improvement. By applying these eight essential tips—list virtualization, lazy loading images, memoization, throttling and debouncing events, code splitting, using React Fragments, and leveraging Web Workers—you can ensure that your React applications deliver a smooth, responsive, and efficient user experience.&lt;/p&gt;

&lt;p&gt;Remember, performance optimization is an ongoing process that requires continuous monitoring, testing, and refinement. As your React applications grow and evolve, revisit these techniques and explore new ones to keep your applications running at their best.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Turbocharge Your React Apps with These 8 Essential Performance Tips</title>
      <dc:creator>topeogunleye</dc:creator>
      <pubDate>Mon, 02 Sep 2024 19:19:42 +0000</pubDate>
      <link>https://dev.to/topeogunleye/turbocharge-your-react-apps-with-these-8-essential-performance-tips-3k9</link>
      <guid>https://dev.to/topeogunleye/turbocharge-your-react-apps-with-these-8-essential-performance-tips-3k9</guid>
      <description>&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%2Fuq1tb6o5ptk54jero9we.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%2Fuq1tb6o5ptk54jero9we.png" alt="React Rocket" width="400" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating dynamic user interfaces with React is both exciting and empowering. This feature-rich library has become a favorite in today's development world, offering endless possibilities to developers. But with all that power comes a bit of a catch—it’s easy to get carried away and misuse features without fully considering how they might impact performance.&lt;/p&gt;

&lt;p&gt;In this article, we’re going to explore eight essential tips for optimizing your React applications. These strategies will help you keep your projects running smoothly and efficiently, ensuring that your apps remain robust and responsive, no matter how complex they get.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;a href="https://www.npmjs.com/package/react-virtualized" rel="noopener noreferrer"&gt;List Virtualization&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine you have a huge list of items. Rendering all of them at once? Not cool. It can seriously drag down your app’s performance and hog a ton of memory. But fear not—list virtualization to the rescue!&lt;/p&gt;

&lt;p&gt;With list virtualization, you only render the items that are visible in the viewport, saving precious resources. As the user scrolls, this technique dynamically swaps out the rendered items with new ones, keeping everything smooth and efficient. It’s like having a magic scroll that only shows what you need when you need it—perfect for handling massive lists or tables without breaking a sweat.&lt;/p&gt;

&lt;p&gt;In the React world, there are several ways to get this magic going, with the &lt;a href="https://www.npmjs.com/package/react-virtualized" rel="noopener noreferrer"&gt;react-virtualized&lt;/a&gt; library being one of the most popular.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading" rel="noopener noreferrer"&gt;Lazy Loading Images&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Lazy loading images gives your website a breath of fresh air—it’s all about loading what’s needed when it’s needed, rather than piling everything on at once. Instead of loading every image on a page during the initial load, lazy loading waits until an image is visible to the user before bringing it in. This approach not only enhances performance but also makes your app feel faster and more responsive.&lt;/p&gt;

&lt;p&gt;In React, you have a few options for implementing lazy loading. The &lt;code&gt;react-lazyload&lt;/code&gt; library is a popular choice, offering a straightforward way to delay image loading. If you’re feeling adventurous, you can roll your own solution using the Intersection Observer API, combining it with React’s &lt;code&gt;useEffect&lt;/code&gt; hook to craft a custom lazy loading strategy tailored to your app.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;a href="https://react.dev/reference/react/memo" rel="noopener noreferrer"&gt;Memoization&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Memoization in React is like giving your components a memory boost, allowing them to remember the results of previous computations so they don’t have to do the same work over and over again. This is particularly handy when you're dealing with functions that are heavy on processing or get called frequently with the same inputs.&lt;/p&gt;

&lt;p&gt;There are three key tools in React for memoization: &lt;code&gt;React.memo&lt;/code&gt;, &lt;code&gt;useMemo&lt;/code&gt;, and &lt;code&gt;useCallback&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://react.dev/reference/react/memo" rel="noopener noreferrer"&gt;React.memo&lt;/a&gt;&lt;/strong&gt;: Wrap a component with &lt;code&gt;React.memo&lt;/code&gt; to prevent it from re-rendering unless its props change. This is great for optimizing components that don’t need to update often.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://react.dev/reference/react/useMemo" rel="noopener noreferrer"&gt;useMemo&lt;/a&gt;&lt;/strong&gt;: Cache the result of a function to avoid recalculating it on every render. This is useful for expensive calculations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://react.dev/reference/react/useCallback" rel="noopener noreferrer"&gt;useCallback&lt;/a&gt;&lt;/strong&gt;: Memoize a function itself, preventing unnecessary re-renders in child components that receive the function as a prop.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. &lt;a href="https://medium.com/@shubham3480/debouncing-and-throttling-in-react-e71c711fc6c5" rel="noopener noreferrer"&gt;Throttling and Debouncing Events&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Throttling and debouncing are essential tools in your React toolkit for managing how often functions or event handlers are called.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.freecodecamp.org/news/throttling-in-javascript/" rel="noopener noreferrer"&gt;Throttling&lt;/a&gt;&lt;/strong&gt;: Limit how often a function can run within a specific timeframe. For example, throttle a window resize event handler to run every 200 milliseconds, preventing performance issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://medium.com/@jamischarles/what-is-debouncing-2505c0648ff1" rel="noopener noreferrer"&gt;Debouncing&lt;/a&gt;&lt;/strong&gt;: Delay the execution of a function until there’s a pause in activity. This is perfect for optimizing input fields that trigger searches or API calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. &lt;a href="https://legacy.reactjs.org/docs/code-splitting.html" rel="noopener noreferrer"&gt;Code-Splitting&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Code splitting in React is a powerful technique that enhances performance by breaking down a large JavaScript bundle into smaller, more manageable chunks. Instead of loading the entire application’s code upfront, code splitting ensures that only the necessary code for a specific part of the application is loaded when needed.&lt;/p&gt;

&lt;p&gt;This technique is especially useful for improving performance in larger React applications with complex and diverse features.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. &lt;a href="https://react.dev/reference/react/Fragment" rel="noopener noreferrer"&gt;React Fragments&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;React Fragments are invisible containers that let you group multiple elements without adding extra tags to your DOM. This keeps your markup clean and avoids unnecessary wrapper elements that can clutter up your DOM tree.&lt;/p&gt;

&lt;p&gt;Using Fragments keeps your DOM smaller and more efficient—a simple yet effective way to optimize your React components.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers" rel="noopener noreferrer"&gt;Web Workers&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;JavaScript is single-threaded, meaning all tasks—such as DOM manipulation, UI interactions, API data processing, and CSS animations—are handled on one thread. This can lead to performance bottlenecks, especially with computationally intensive tasks.&lt;/p&gt;

&lt;p&gt;Web Workers allow you to offload such tasks to a separate thread that runs independently of the main JavaScript thread. By offloading resource-intensive tasks to Web Workers, you can keep your app running smoothly, even when processing large datasets or complex calculations.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. &lt;a href="https://react.dev/reference/react/useTransition" rel="noopener noreferrer"&gt;useTransition Hooks&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;useTransition&lt;/code&gt; hook is your secret weapon for updating state without slowing down the UI. It allows you to prioritize certain updates by marking others as less urgent, ensuring that your app remains responsive even when performing complex operations.&lt;/p&gt;

&lt;p&gt;By using &lt;code&gt;useTransition&lt;/code&gt;, you can dodge the slowdown caused by heavy operations and keep your app running smoothly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Ready to turbocharge your React apps? These eight performance tips are your secret weapon for making your projects lightning-fast and silky smooth. With strategies like memoization, code-splitting, and the useTransition hook, you'll take your app's performance and scalability to new heights.&lt;/p&gt;

&lt;p&gt;We're not just talking about any optimizations here; we're talking about the essentials for crafting a user interface that's as sleek as it is speedy, all thanks to React's virtual DOM wizardry. By fine-tuning your component structure, cutting down on unnecessary re-renders, and nailing those hooks, you'll take your app's performance and scalability to new heights.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mastering LCP: A Step-by-Step Guide to Optimizing Largest Contentful Paint for Better Web Performance</title>
      <dc:creator>topeogunleye</dc:creator>
      <pubDate>Fri, 30 Aug 2024 18:12:24 +0000</pubDate>
      <link>https://dev.to/topeogunleye/mastering-lcp-a-step-by-step-guide-to-optimizing-largest-contentful-paint-for-better-web-performance-21l7</link>
      <guid>https://dev.to/topeogunleye/mastering-lcp-a-step-by-step-guide-to-optimizing-largest-contentful-paint-for-better-web-performance-21l7</guid>
      <description>&lt;p&gt;&lt;a href="https://web.dev/articles/lcp#what-is-lcp" rel="noopener noreferrer"&gt;Largest Contentful Paint (LCP)&lt;/a&gt; is one of the three Core Web Vitals metrics. Core Web Vitals are essential performance indicators that every website owner should monitor, as they significantly impact the user experience and overall performance of web pages.&lt;br&gt;
Optimizing for these metrics is crucial for the long-term success of any website. Core Web Vitals are integrated across all Google tools, making them indispensable for enhancing web performance. By focusing on these metrics, you ensure a smoother, faster, and more enjoyable experience for your users, which can lead to better engagement and higher search rankings.&lt;br&gt;
Do you want to know more about Core Web Vitals metrics and tips on how to optimize for them? let’s learn&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%2F0fsb6cibkrmyedbf9r3a.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%2F0fsb6cibkrmyedbf9r3a.png" alt="Interaction to Next Paint" width="171" height="150"&gt;&lt;/a&gt;&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%2Frux1yuzkfi93due1dzpf.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%2Frux1yuzkfi93due1dzpf.png" alt="Largest Contentful Shift" width="171" height="150"&gt;&lt;/a&gt;&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%2Fdjtravlj03tdzn60gbyr.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%2Fdjtravlj03tdzn60gbyr.png" alt="Largest Contentful Paint" width="171" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://web.dev/articles/lcp#what-is-lcp" rel="noopener noreferrer"&gt;Largest Contentful Paint (LCP)&lt;/a&gt;: This metric gauges loading performance. To ensure a positive user experience, the LCP should occur within 2.5 seconds from when the page begins to load.&lt;br&gt;
&lt;a href="https://web.dev/articles/inp#what-is-inp" rel="noopener noreferrer"&gt;Interaction to Next Paint (INP)&lt;/a&gt;: INP evaluates the responsiveness of a page to user interactions. For a seamless experience, the INP should be 200 milliseconds or less.&lt;br&gt;
&lt;a href="https://web.dev/articles/cls#what-is-cls" rel="noopener noreferrer"&gt;Cumulative Layout Shift (CLS)&lt;/a&gt;: CLS measures the visual stability of a page by tracking unexpected layout shifts. To maintain a stable visual experience, pages should aim for a CLS score of 0.1 or lower.&lt;/p&gt;

&lt;p&gt;First, let’s break down what LCP, or Largest Contentful Paint, is and why developers must understand its metrics and improve their scores. LCP measures the time it takes from when a user starts loading a web page until the largest image or text block within the viewport finishes rendering.&lt;/p&gt;

&lt;p&gt;Google sets a benchmark for a good user experience by recommending an LCP score of 2.5 seconds or less for at least 75% of page visits. This means that if your page can render the largest image or text block within 2.5 seconds in 75% of user interactions, Google considers it to offer a fast and smooth loading experience. Understanding and optimizing LCP is key to enhancing performance and user satisfaction on your website. &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%2F85y56o337lgge7jehwvv.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%2F85y56o337lgge7jehwvv.png" alt="An example of LCP optimization for slow experiences" width="750" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the chart above, each bar represents a real person’s loading experience when visiting this page. &lt;a href="https://web.dev/articles/optimize-lcp#:~:text=To%20provide%20a%20good%20user%20experience%2C%20sites%20should%20strive%20to%20have%20an%20LCP%20of%202.5%20seconds%20or%20less%20for%20at%20least%2075%25%20of%20page%20visits." rel="noopener noreferrer"&gt;Typically, a site might have thousands or even millions of these data points, but for simplicity, we’re using an example with just 36 page visits. To find the 75th percentile from a sorted list of values like this, you simply need to identify the value that falls at 75%, or ¾, of the way through the list. In this example with 36 data points, the 75th percentile is represented by the 27th value in the list&lt;/a&gt;.&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%2Fgqgfjaawia23ih9xjuso.gif" 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%2Fgqgfjaawia23ih9xjuso.gif" alt="Example LCP distribution across all visits" width="1200" height="675"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, this value is just under 3 seconds, which falls into the "needs improvement" category. &lt;a href="https://web.dev/articles/optimize-lcp#:~:text=To%20provide%20a%20good%20user%20experience%2C%20sites%20should%20strive%20to%20have%20an%20LCP%20of%202.5%20seconds%20or%20less%20for%20at%20least%2075%25%20of%20page%20visits." rel="noopener noreferrer"&gt;For an LCP score to be classified as "good," it must be 2.5 seconds or less. The reason we're focusing on this is to understand the impact of performance optimizations. Imagine we implement an optimization that makes all the already fast LCP experiences even faster. Notice that while the LCP times improved for some users, as shown below&lt;/a&gt;:&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%2Fn6ft1dyewy357dm5puoz.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%2Fn6ft1dyewy357dm5puoz.png" alt="An example of LCP optimization for already fast experiences" width="750" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 75th percentile value remains unchanged. This highlights the importance of targeting optimizations that will benefit the users experiencing slower load times to truly improve overall performance.&lt;/p&gt;

&lt;p&gt;If the site were to slightly improve the poor experiences, making them faster but still below optimal, the 75th percentile would remain unchanged:&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%2Fu2vro2hqe3acoyww67gq.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%2Fu2vro2hqe3acoyww67gq.png" alt="An example of LCP optimization for slow experiences" width="750" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To truly boost your LCP score at the 75th percentile, you need to enhance the experience for a significant portion of users so that at least &lt;a href="https://web.dev/articles/optimize-lcp#:~:text=To%20provide%20a%20good%20user%20experience%2C%20sites%20should%20strive%20to%20have%20an%20LCP%20of%202.5%20seconds%20or%20less%20for%20at%20least%2075%25%20of%20page%20visits." rel="noopener noreferrer"&gt;75% fall within the "good" threshold. The most effective strategy is to implement optimizations that improve the experience across the board, rather than focusing on a specific subset of users&lt;/a&gt;.&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%2Fz7iwybodo8j6uh3m2tfg.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%2Fz7iwybodo8j6uh3m2tfg.png" alt="An example of an ideal situation for the LCP metric" width="750" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the Focus on LCP
&lt;/h2&gt;

&lt;p&gt;Now, you might wonder why I'm zeroing in on LCP today, instead of discussing the other Core Web Vitals metrics. The reason is simple: LCP is the metric that sites struggle with the most, according to data from the Chrome User Experience Report. While 52% of sites meet the good LCP threshold, the numbers are much higher for CLS and FID:&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%2Fn0ctkwy7vjftny76wnrx.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%2Fn0ctkwy7vjftny76wnrx.png" alt="Why the Focus on LCP" width="512" height="290"&gt;&lt;/a&gt;&lt;br&gt;
Moreover, LCP is improving at a slower pace than the other metrics&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%2Fj6zxvlf8z3iltllcrwhr.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%2Fj6zxvlf8z3iltllcrwhr.png" alt="LCP VS CLS" width="512" height="292"&gt;&lt;/a&gt;&lt;br&gt;
suggesting that developers are finding it more challenging to optimize&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes LCP So Hard to Optimize:
&lt;/h2&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%2F51pkk1finqe5pa2gu0df.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%2F51pkk1finqe5pa2gu0df.jpg" alt="What Makes LCP So Hard to Optimize:" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are likely many reasons why LCP is difficult to optimize, but a major factor is the sheer complexity of load performance. Developers often put in a lot of effort to improve LCP, but their attempts don't always yield the desired results. The key challenge is figuring out what specific actions will make a meaningful difference for your site.&lt;/p&gt;

&lt;p&gt;LCP is a complex problem, but like any big challenge, it becomes more manageable when you break it down into smaller, more focused problems. That’s exactly what I propose we do with LCP.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking Down LCP
&lt;/h2&gt;

&lt;p&gt;In the rest of this, I’ll outline a framework for how developers can improve LCP on their sites. Let’s start by looking at a typical waterfall chart from a page load, which includes CSS, JavaScript, and image resources. While all these network requests are important, when it comes to optimizing LCP, you really need to focus on just two: the HTML document and whatever other resource is required to render the LCP element.&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%2Fs5qjkiom72y7794d9gsm.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%2Fs5qjkiom72y7794d9gsm.png" alt="An example of a page resource loading timeline up to LCP" width="512" height="288"&gt;&lt;/a&gt;&lt;br&gt;
While all network requests during a page load are important, when it comes to optimizing LCP, the focus should primarily be on two key resources: the HTML document and whatever additional resource is necessary to render the LCP element. &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%2Fb4zis99oetmow0zt4bmc.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%2Fb4zis99oetmow0zt4bmc.png" alt="Highlight the HTML document and the LCP element" width="512" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, the LCP element is an image, but the same principle applies to a text node that requires a web font before it can render. Once we've pinpointed these two crucial resources, we can use their timing attributes to break down LCP into its most significant subparts. The first subpart is the time from when the user initiates the page load to when the browser receives the first byte of the HTML document response—this is known as the Time to First Byte (TTFB).&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%2Faracx1qzt4aofg742bms.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%2Faracx1qzt4aofg742bms.png" alt="The 4 components of LCP" width="512" height="285"&gt;&lt;/a&gt;&lt;br&gt;
TTFB is critical because it marks the first moment the browser can start identifying additional resources needed to render the page, including those necessary for the LCP element. Understanding and optimizing TTFB is a foundational step in improving your LCP score.&lt;/p&gt;

&lt;p&gt;The second subpart of LCP is the &lt;strong&gt;LCP resource load delay&lt;/strong&gt;—&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%2Fdkxrf16dlkgsjdt7y28o.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%2Fdkxrf16dlkgsjdt7y28o.png" alt="LCP resource load delay" width="512" height="288"&gt;&lt;/a&gt;&lt;br&gt;
the time between TTFB and when the browser starts loading the resource needed for LCP. In some cases, like when the LCP element is a text node using a system font, no additional resources are needed, so the resource load delay is zero. Ideally, you want this delay to be as small as possible.&lt;/p&gt;

&lt;p&gt;The third subpart is the &lt;strong&gt;time it takes to load the LCP resource&lt;/strong&gt;. Again, if your LCP element doesn’t require an external resource, this time will be zero.&lt;/p&gt;

&lt;p&gt;Lastly, the fourth subpart of LCP is the &lt;strong&gt;element render delay&lt;/strong&gt;—the time from when the LCP resource finishes loading to when it’s rendered on the screen.&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%2Foga1wu5rk14trd21awrd.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%2Foga1wu5rk14trd21awrd.png" alt="LCP element render delay" width="512" height="288"&gt;&lt;/a&gt;&lt;br&gt;
Each page’s LCP can be broken down into these four subparts, with no overlap or gaps between them. Together, they add up to the total LCP time. For example, if we reduce the resource load time, the element render delay might extend by the same amount, meaning the overall LCP doesn’t change.&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%2Felqbmypmuinou0oo6nvd.gif" 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%2Felqbmypmuinou0oo6nvd.gif" alt="If we compress the image, in this timeline, LCP does not change" width="750" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This happens because the page might be waiting for JavaScript (those yellow bars at the bottom) to load before adding the LCP element.&lt;/p&gt;

&lt;p&gt;This point is crucial and often a source of frustration for developers. When seeking advice on improving LCP, one of the most common suggestions is to optimize images. However, optimizing images only affects one part of LCP. If this part isn’t your bottleneck, then reducing it won’t improve your score, as seen in this example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices Within Each Subpart of LCP
&lt;/h2&gt;

&lt;p&gt;The key to improving LCP is identifying where your bottlenecks are. To do this, it’s helpful to know the ideal or recommended values for each LCP subpart. At a high level, the advice is straightforward.&lt;/p&gt;

&lt;h2&gt;
  
  
  High-Level Goals: Optimizing LCP Timing
&lt;/h2&gt;

&lt;p&gt;When optimizing for LCP, your main objective is clear: spend most of your time on the network requests necessary to render the LCP element. Anything that delays the start of loading the LCP resource or slows down rendering after the resource is loaded is essentially wasted time.&lt;/p&gt;

&lt;p&gt;In an ideal scenario, here’s how these LCP subparts should break down on a well-optimized page:&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%2Fyotxa6f0yao1opz9i9jm.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%2Fyotxa6f0yao1opz9i9jm.png" alt="Reference values ​​for LCP components" width="512" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The total time on the right is based on the goal of a 2.5-second LCP, with other times proportionally distributed. Notice that around 80% of the time is dedicated to network requests, while only 20% is allocated to everything else. Later, I’ll walk you through a real-world example of a performance optimization, using this 80-20 principle to pinpoint improvement opportunities.&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%2Fy12bej3idujz08njhe90.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%2Fy12bej3idujz08njhe90.png" alt="LCP Broken Down" width="512" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Data Insights
&lt;/h2&gt;

&lt;p&gt;Curious about how time is spent across LCP subparts in real-world sites? While we don’t have real user data for these specific metrics, we do have lab data from the HTTP Archive. This data comes from 5.3 million web page test runs, focusing on pages where the LCP element was an image with a URL source.&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%2Ferdrj9lj9ybez2ooc15e.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%2Ferdrj9lj9ybez2ooc15e.png" alt="LCP Broken Down Analysis" width="512" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s how the data breaks down:&lt;/p&gt;

&lt;p&gt;I sorted all runs by LCP value, from fastest to slowest, and divided them into five buckets. The top bucket represents the fastest 20% of pages, while the bottom represents the slowest 20%. For each bucket, I averaged the LCP subpart times to create stacked bars, where the total length represents the average LCP value in that bucket.&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%2Ff0zfmrjzy1czx2ue8me3.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%2Ff0zfmrjzy1czx2ue8me3.png" alt="LCP components in online web pages, in order of LCP" width="512" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Surprising Discovery
&lt;/h2&gt;

&lt;p&gt;When I first saw this data, I was surprised. I expected the majority of LCP time would be spent loading large, unoptimized images—anticipating those green bars to dominate, especially in the slowest bucket. However, the data suggests that image load times might not be the main bottleneck. Instead, the purple segments, representing resource load delay, appear to be the biggest issue.&lt;/p&gt;

&lt;p&gt;Now, keep in mind that this is lab data, not real-world data. The tests use a single network and device configuration for each run, so it’s not fully representative of the diverse devices and networks used in real life. Additionally, HTTP Archive tests don’t account for repeat visits, meaning the user’s cache state isn’t factored in. While we can’t definitively say this is how LCP breakdowns look in the wild, it’s clear that sites could be doing a better job optimizing LCP resource loads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimism Amid Challenges
&lt;/h2&gt;

&lt;p&gt;Despite these challenges, there’s reason for optimism. The subparts of LCP that are hardest to improve—represented by the blue and green segments—are fewer in number. The purple and yellow segments, representing the parts of LCP that are easiest to improve, show ample opportunity for enhancement. By helping developers identify their bottlenecks, we could see significant improvements in LCP across the board.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recipe for LCP Optimization: A Step-by-Step Approach
&lt;/h2&gt;

&lt;p&gt;There are only four steps to optimize LCP, ordered by ease and impact:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Eliminate Unnecessary Resource Load Delay
&lt;/h3&gt;

&lt;p&gt;The key here is to prioritize the LCP resource so it starts loading immediately after the HTML document is received. To check if your page’s LCP resource is loading early enough, compare its request start time with the start time of the first sub-resource.&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%2Fepko3pcnvu7yhm8dtdy7.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%2Fepko3pcnvu7yhm8dtdy7.png" alt="An example of project time" width="512" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the LCP image starts loading later than, say, a stylesheet starts loading before it, that’s a sign there’s room for improvement. You can fix this by using &lt;code&gt;preload&lt;/code&gt; or adding priority hints to the image tag, prompting the browser to start loading it sooner. Also, ensure the LCP image isn’t lazy-loaded, as that could introduce unwanted delays. Preloading the image should solve this issue.&lt;/p&gt;

&lt;p&gt;Here’s what happens after implementing these changes:&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%2Fuowmn5rdxgjn8yv8ufym.gif" 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%2Fuowmn5rdxgjn8yv8ufym.gif" alt="An example of project time reduction" width="750" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, the image resource starts loading simultaneously with the first stylesheet, exactly as intended. Step one is done. But remember, reducing resource load delay won’t necessarily improve LCP if it’s still blocked by JavaScript, as mentioned earlier.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tips:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Add priority hints or preload&lt;/li&gt;
&lt;li&gt;Minimize network connections&lt;/li&gt;
&lt;li&gt;Use same-origin resources (if possible)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Eliminate Unnecessary Element Render Delay
&lt;/h3&gt;

&lt;p&gt;To optimize LCP, it's crucial to ensure that once the LCP resource finishes loading, nothing else on the page delays its rendering. Any delay here can prevent the LCP element from appearing as quickly as possible.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tips:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Remove or minimize render-blocking stylesheets.&lt;/li&gt;
&lt;li&gt;Defer render-blocking JavaScript.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;font-display: optional&lt;/code&gt; for web fonts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
One way to reduce render times is by optimizing the size of the JavaScript files being loaded. Techniques like minification and tree shaking can reduce script download times, improving overall performance.&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%2Fqq4ehgc92zx6y21b28vn.gif" 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%2Fqq4ehgc92zx6y21b28vn.gif" alt="An example of optimizing resource rendering delay&amp;lt;br&amp;gt;
" width="750" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While this is an improvement, it’s still not ideal. The goal is to eliminate anything that blocks rendering after the LCP resource finishes loading, not just reduce blocking time. For instance, if the JavaScript code is client-side rendering the application, updating the framework to use server-side rendering or pre-rendering pages as static files can prevent JavaScript from blocking the LCP image render.&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%2Fgeegeosx05bz1ljkn67u.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%2Fgeegeosx05bz1ljkn67u.png" alt="An example of optimizing the LCP metric by changing the rendering of the resource" width="512" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this update, the JavaScript code no longer blocks rendering, allowing the LCP image to appear immediately after it’s downloaded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Reduce Resource Loading Time
&lt;/h3&gt;

&lt;p&gt;The third step is to minimize the resource load time as much as possible by following best practices for optimizing images and web fonts. Anything that reduces the file size of the resource will help reduce load times.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tips:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Compress images.&lt;/li&gt;
&lt;li&gt;Use modern image formats like AVIF or WebP.&lt;/li&gt;
&lt;li&gt;Properly sized images.&lt;/li&gt;
&lt;li&gt;Set far-future cache expiry headers.&lt;/li&gt;
&lt;li&gt;Use a CDN to reduce network distance.&lt;/li&gt;
&lt;/ul&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%2Flif3488opd6u2bhta53p.gif" 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%2Flif3488opd6u2bhta53p.gif" alt="An example of reducing LCP resource loading time&amp;lt;br&amp;gt;
" width="750" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
In the example above, optimizing the LCP resource so much that it becomes smaller than the stylesheet can lead to the stylesheet blocking rendering. To prevent this, consider techniques like critical CSS or removing unused styles where possible. Alternatively, you can inline CSS into the document, though this might have negative effects on performance for repeat visitors.&lt;/p&gt;

&lt;p&gt;The best approach is to reduce the size of the stylesheet so it’s smaller than the LCP resource, ensuring it’s not blocking or rarely blocking, which is a good compromise. &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%2F3indp3kj5g3lidn6e5zp.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%2F3indp3kj5g3lidn6e5zp.png" alt="An example of reducing LCP resource loading time" width="512" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, slightly reducing the stylesheet’s size is enough to prevent it from blocking the LCP image’s rendering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Reduce Time to First Byte (TTFB)
&lt;/h3&gt;

&lt;p&gt;The final step, reducing TTFB, is often the hardest for developers to optimize and typically the one with the least control. However, having a good TTFB is critical because it impacts everything that follows.&lt;br&gt;
Here is a Visual Illustration of improving TTFP:&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%2Fg5cfbmxup21d09x7gdzd.gif" 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%2Fg5cfbmxup21d09x7gdzd.gif" alt="An example of TTFB (Time To First Byte) optimization&amp;lt;br&amp;gt;
" width="750" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Tips:
&lt;/h4&gt;

&lt;p&gt;Use a CDN to reduce network distance, getting servers closer to users.&lt;br&gt;
Upgrade server hardware for faster processing.&lt;br&gt;
Ensure the response body can be streamed.&lt;/p&gt;

&lt;p&gt;Improving TTFB will directly enhance every subsequent step, as nothing can happen on the front end until the back end delivers the first byte of the response.&lt;/p&gt;




&lt;h4&gt;
  
  
  Recap:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start Early&lt;/strong&gt;: Ensure the LCP resource starts loading as soon as possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Render Immediately&lt;/strong&gt;: Ensure the LCP element can render immediately after its resource finishes loading.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduce Load Times&lt;/strong&gt;: Minimize the load time of the LCP resource without compromising quality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deliver Fast&lt;/strong&gt;: Deliver the initial HTML document as quickly as possible.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By following these four steps, you can ensure an optimal loading experience for your users, which should be reflected in improved real-world LCP scores.&lt;/p&gt;

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

&lt;p&gt;Optimizing the Largest Contentful Paint (LCP) is like setting the stage for a great first impression on your website. Imagine your visitors arriving at your site, eager to see what you have to offer. The speed at which the main content loads plays a huge role in whether they stick around or leave. By honing in on four key areas—getting the most important content to load early, avoiding any delays in rendering, speeding up resource load times, and cutting down the time it takes to get the first bit of data to the browser—you can make sure your site performs at its best.&lt;/p&gt;

&lt;p&gt;These steps aren’t just about making small tweaks here and there. It’s about creating a smoother, faster experience that all your users will appreciate. When you get these optimizations right, you’re not just improving a single metric; you’re boosting the overall experience, making your site feel faster and more responsive. In the long run, this means happier users, better satisfaction, and stronger LCP scores. By carefully identifying and tackling performance bottlenecks, you can ensure your site remains speedy and robust, even as new challenges arise.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Redis for Beginners (Part 2 of 2)</title>
      <dc:creator>topeogunleye</dc:creator>
      <pubDate>Thu, 25 Jul 2024 14:15:40 +0000</pubDate>
      <link>https://dev.to/topeogunleye/redis-for-beginners-part-2-of-2-32e1</link>
      <guid>https://dev.to/topeogunleye/redis-for-beginners-part-2-of-2-32e1</guid>
      <description>&lt;p&gt;Welcome back to the second part of our Redis for Beginners series. In Part 1, we covered some basic setups of a Redis database and a couple of fundamental commands. In this second part, we will further explore advanced options for commands while deeply focusing on the difference between lists and sets in Redis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Command Options
&lt;/h3&gt;

&lt;p&gt;Not all commands have options, but a few, for example, &lt;code&gt;SET&lt;/code&gt;, have certain added features that can be essential.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;EX seconds&lt;/strong&gt;: Sets an expiration time in seconds (must be a positive integer).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PX milliseconds&lt;/strong&gt;: Sets an expiration time in milliseconds (must be a positive integer).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EXAT timestamp-seconds&lt;/strong&gt;: Sets a specific Unix timestamp for expiration (must be a positive integer).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NX&lt;/strong&gt;: Sets the key only if it does not already exist.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XX&lt;/strong&gt;: Sets the key only if it already exists.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note: You can't use &lt;code&gt;NX&lt;/code&gt; and &lt;code&gt;XX&lt;/code&gt; together because they will conflict with each other. Also, you can use only one option for expiration (&lt;code&gt;EX&lt;/code&gt; or &lt;code&gt;PX&lt;/code&gt;) at a time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To learn more about the &lt;code&gt;SET&lt;/code&gt; command visit &lt;a href="https://redis.io/commands/set/" rel="noopener noreferrer"&gt;here&lt;/a&gt; to check out the Redis documentation page.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example: SET Command Using the EX Option
&lt;/h3&gt;

&lt;p&gt;When executing the following at your workbench, you will define a key with an expiration in Redis:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET key value EX seconds

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

&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the key that contains the string and &lt;code&gt;value&lt;/code&gt; with the new value you would like to store. Replace &lt;code&gt;seconds&lt;/code&gt; with the amount of time, in seconds, after which the key should expire.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt; if you want to set your name value to "Yoshi", and you want it to expire after 7 seconds, run:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET name carint EX 7

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

&lt;/div&gt;



&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/c612980bf72345499b95a4d7f8e1e268"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;This command updates the value of &lt;code&gt;name&lt;/code&gt; to "Yoshi" and sets an expiration of 7 seconds from the time the command is executed.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example: SET Command with NX and XX Options
&lt;/h3&gt;

&lt;p&gt;You can set the key conditionally concerning its existence in Redis by using the options &lt;code&gt;NX&lt;/code&gt;, which stands for Not eXists, and &lt;code&gt;XX&lt;/code&gt;, which stands for eXists, in the &lt;code&gt;SET&lt;/code&gt; command:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using NX (Not eXists) Option:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET key value NX

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

&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the key you want to set and &lt;code&gt;value&lt;/code&gt; with the value you want to store in the key. This command sets the value of &lt;code&gt;key&lt;/code&gt; to &lt;code&gt;value&lt;/code&gt; only if &lt;code&gt;key&lt;/code&gt; does not already exist. If &lt;code&gt;key&lt;/code&gt; already exists, the command will not perform any action.&lt;/p&gt;

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

&lt;p&gt;If you want to set a new key &lt;code&gt;username&lt;/code&gt; to "alice" only if &lt;code&gt;username&lt;/code&gt; does not already exist, you would use:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET username alice NX
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/7a79d49943644e229127156761fd086b"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Using XX (eXists) Option:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET key value XX

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

&lt;/div&gt;


&lt;p&gt;This command sets the value of &lt;code&gt;key&lt;/code&gt; to &lt;code&gt;value&lt;/code&gt; only if &lt;code&gt;key&lt;/code&gt; already exists. If &lt;code&gt;key&lt;/code&gt; does not exist, the command will not perform any action.&lt;/p&gt;

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

&lt;p&gt;If you want to update the value of an existing key &lt;code&gt;username&lt;/code&gt; to "bob" only if &lt;code&gt;username&lt;/code&gt; already exists, you would use:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET username bob XX

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

&lt;/div&gt;





&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/0e6351b64de8439da63862593a79e5be"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;Lists vs. Sets&lt;/p&gt;

&lt;h3&gt;
  
  
  Lists
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An ordered collection of strings.&lt;/li&gt;
&lt;li&gt;Supports operations like adding elements to the head or tail, trimming based on ranges, etc.&lt;/li&gt;
&lt;li&gt;Useful for maintaining ordered data structures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commands&lt;/strong&gt;: &lt;code&gt;RPUSH&lt;/code&gt;, &lt;code&gt;LPUSH&lt;/code&gt;, &lt;code&gt;LRANGE&lt;/code&gt;, &lt;code&gt;LPOP&lt;/code&gt;, &lt;code&gt;RPOP&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sets
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An unordered collection of unique strings.&lt;/li&gt;
&lt;li&gt;Supports operations like adding, removing, and checking membership.&lt;/li&gt;
&lt;li&gt;Useful for storing unique items and performing set operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commands&lt;/strong&gt;: &lt;code&gt;SADD&lt;/code&gt;, &lt;code&gt;SREM&lt;/code&gt;, &lt;code&gt;SMEMBERS&lt;/code&gt;, &lt;code&gt;SISMEMBER&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;When deciding between lists and sets, consider the order requirements and the need for uniqueness in your data.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  RPUSH: Adding Elements to the End of a List
&lt;/h3&gt;

&lt;p&gt;To add one or more elements to the end of a list, use the &lt;code&gt;RPUSH&lt;/code&gt; command. Here’s how to use it in your workbench:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RPUSH key element [element ...]

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

&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the list, and &lt;code&gt;element&lt;/code&gt; with the elements you want to add.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a list named &lt;code&gt;fruits&lt;/code&gt; and add elements to it:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RPUSH fruits apple banana cherry

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

&lt;/div&gt;


&lt;p&gt;This will add "apple", "banana", and "cherry" to the end of the &lt;code&gt;fruits&lt;/code&gt; list.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/700a49550fbc4ec3905a9b5e3a501e4c"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;






&lt;h3&gt;
  
  
  LPUSH: Adding Elements to the Beginning of a List
&lt;/h3&gt;

&lt;p&gt;To add one or more elements to the beginning of a list, use the &lt;code&gt;LPUSH&lt;/code&gt; command. Here’s how to use it in your workbench:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LPUSH key element [element ...]

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

&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the list, and &lt;code&gt;element&lt;/code&gt; with the elements you want to add.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add elements to the beginning of the &lt;code&gt;fruits&lt;/code&gt; list:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LPUSH fruits mango orange

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

&lt;/div&gt;


&lt;p&gt;This will add "mango" and "orange" to the beginning of the &lt;code&gt;fruits&lt;/code&gt; list.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/547b160213c149b5a291708e554aa292"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;






&lt;h3&gt;
  
  
  LRANGE: Retrieving Elements from a List
&lt;/h3&gt;

&lt;p&gt;To retrieve a range of elements from a list, use the &lt;code&gt;LRANGE&lt;/code&gt; command. Here’s how to use it in your workbench:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LRANGE key start stop

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

&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the list, &lt;code&gt;start&lt;/code&gt; with the starting index, and &lt;code&gt;stop&lt;/code&gt; with the ending index.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve elements from the &lt;code&gt;fruits&lt;/code&gt; list:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LRANGE fruits 0 2

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

&lt;/div&gt;


&lt;p&gt;This will return the first three elements: "mango", "orange", and "apple".&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/965633a0fe3b4ece89807b5b4e6e103b"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;






&lt;h3&gt;
  
  
  LPOP: Removing the First Element from a List
&lt;/h3&gt;

&lt;p&gt;To remove and return the first element of a list, use the &lt;code&gt;LPOP&lt;/code&gt; command. Here’s how to use it in your workbench:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LPOP key

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

&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove the first element from the &lt;code&gt;fruits&lt;/code&gt; list:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LPOP fruits

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

&lt;/div&gt;


&lt;p&gt;This will remove and return "orange".&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/202236d1c95a459c83a16a564ce1f55d"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;






&lt;h3&gt;
  
  
  RPOP: Removing the Last Element from a List
&lt;/h3&gt;

&lt;p&gt;To remove and return the last element of a list, use the &lt;code&gt;RPOP&lt;/code&gt; command. Here’s how to use it in your workbench:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RPOP key

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

&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove the last element from the &lt;code&gt;fruits&lt;/code&gt; list:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RPOP fruits

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

&lt;/div&gt;


&lt;p&gt;This will remove and return "cherry".&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/db828db5c9044d289ea111e7f2974dfb"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;






&lt;h3&gt;
  
  
  SADD: Adding Elements to a Set
&lt;/h3&gt;

&lt;p&gt;To add one or more elements to a set, use the &lt;code&gt;SADD&lt;/code&gt; command. Here’s how to use it in your workbench:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SADD key member [member ...]

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

&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the set, and &lt;code&gt;member&lt;/code&gt; with the elements you want to add.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a set named &lt;code&gt;colors&lt;/code&gt; and add elements to it:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SADD colors red green blue

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

&lt;/div&gt;


&lt;p&gt;This will add "red", "green", and "blue" to the &lt;code&gt;colors&lt;/code&gt; set.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/a9d13932de4b4ac3b539900d9ccdc345"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;






&lt;h3&gt;
  
  
  SREM: Removing Elements from a Set
&lt;/h3&gt;

&lt;p&gt;To remove one or more elements from a set, use the &lt;code&gt;SREM&lt;/code&gt; command. Here’s how to use it in your workbench:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SREM key member [member ...]

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

&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the set, and &lt;code&gt;member&lt;/code&gt; with the elements you want to remove.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Remove elements from the &lt;code&gt;colors&lt;/code&gt; set:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SREM colors blue

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

&lt;/div&gt;


&lt;p&gt;This will remove "blue" from the &lt;code&gt;colors&lt;/code&gt; set.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/8fb34980bb994b22b7792309c500d454"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;






&lt;h3&gt;
  
  
  SMEMBERS: Retrieving All Elements from a Set
&lt;/h3&gt;

&lt;p&gt;To retrieve all the elements of a set, use the &lt;code&gt;SMEMBERS&lt;/code&gt; command. Here’s how to use it in your workbench:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SMEMBERS key

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

&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the set.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve all elements from the &lt;code&gt;colors&lt;/code&gt; set:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SMEMBERS colors

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

&lt;/div&gt;


&lt;p&gt;This will return all elements in the &lt;code&gt;colors&lt;/code&gt; set: "red" and “green”.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/03b541e139bb4d15a053fb0b07212e1f"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;






&lt;h3&gt;
  
  
  SISMEMBER: Checking if an Element Exists in a Set
&lt;/h3&gt;

&lt;p&gt;To check if an element is a member of a set, use the &lt;code&gt;SISMEMBER&lt;/code&gt; command. Here’s how to use it in your workbench:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SISMEMBER key member

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

&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the set, and &lt;code&gt;member&lt;/code&gt; with the element you want to check.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check if "red" is in the &lt;code&gt;colors&lt;/code&gt; set:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SISMEMBER colors red

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

&lt;/div&gt;


&lt;p&gt;This will return &lt;code&gt;1&lt;/code&gt; if "red" is a member of the set, and &lt;code&gt;0&lt;/code&gt; otherwise.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/920b9dd3c25c425fa07c94288a0d5741"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;






&lt;h3&gt;
  
  
  Hashes in Redis
&lt;/h3&gt;

&lt;p&gt;In Redis, hashes are maps between string fields and string values. They are ideal for representing objects or entities with multiple attributes. Unlike sets or lists, which hold single values, hashes store key-value pairs where both the field and the value are strings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: Using HSET Command for Hashes
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;HSET&lt;/code&gt; command sets a field in the hash stored at key to a specified value. If the key does not exist, it creates an empty hash.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;HSET key field value

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the hash.&lt;/li&gt;
&lt;li&gt;Replace &lt;code&gt;field&lt;/code&gt; with the attribute to change.&lt;/li&gt;
&lt;li&gt;Replace &lt;code&gt;value&lt;/code&gt; with the new value to assign.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example: Setting Fields in a Hash
&lt;/h3&gt;

&lt;p&gt;Create a hash &lt;code&gt;user:1001&lt;/code&gt; representing a user with attributes:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;HSET user:1001 username alice email alice@example.com

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

&lt;/div&gt;


&lt;p&gt;This command sets &lt;code&gt;username&lt;/code&gt; to "alice" and &lt;code&gt;email&lt;/code&gt; to "&lt;a href="mailto:alice@example.com"&gt;alice@example.com&lt;/a&gt;" in the hash &lt;code&gt;user:1001&lt;/code&gt;.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/700d1cceb1db46eab87162b042ca7012"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Example: Using HGET Command for Hashes
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;HGET&lt;/code&gt; command retrieves the value of a field from the hash stored at key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;HGET key field

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the hash.&lt;/li&gt;
&lt;li&gt;Replace &lt;code&gt;field&lt;/code&gt; with the specific field whose value you want to retrieve.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example: Getting Fields from a Hash
&lt;/h3&gt;

&lt;p&gt;To retrieve the &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;email&lt;/code&gt; fields from the &lt;code&gt;user:1001&lt;/code&gt; hash:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;HGET user:1001 username
HGET user:1001 email

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

&lt;/div&gt;


&lt;p&gt;These commands will return "alice" and "&lt;a href="mailto:alice@example.com"&gt;alice@example.com&lt;/a&gt;" respectively.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/bb8041316af44a068bd1e8296529ef4f"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Example: Using HDEL Command for Hashes
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;HDEL&lt;/code&gt; command deletes one or more fields from the hash at key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;HDEL key field &lt;span class="o"&gt;[&lt;/span&gt;field ...]

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the hash from which fields are removed.&lt;/li&gt;
&lt;li&gt;Replace &lt;code&gt;field&lt;/code&gt; with the field(s) to remove.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example: Removing Fields from a Hash
&lt;/h3&gt;

&lt;p&gt;To remove the &lt;code&gt;email&lt;/code&gt; field from the &lt;code&gt;user:1001&lt;/code&gt; hash:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;HDEL user:1001 email

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

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;email&lt;/code&gt; field will be removed from the &lt;code&gt;user:1001&lt;/code&gt; hash.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/96fea33190a14922a87c9de203f9fc44"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Redis has evolved significantly, positioning itself not just as a caching layer but as a primary database. It offers data persistence, replication for durability and availability, JSON support, and search modules for storing and querying complex data. Redis OM, an Object mapping library, simplifies usage. This series focuses on Redis's core capabilities.&lt;/p&gt;




&lt;p&gt;This format organizes the content into sections with headings, subheadings, and clear examples, suitable for readability and reference in Notion.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Redis for Beginners (Part 1 of 2)</title>
      <dc:creator>topeogunleye</dc:creator>
      <pubDate>Thu, 25 Jul 2024 14:13:17 +0000</pubDate>
      <link>https://dev.to/topeogunleye/redis-for-beginners-part-1-of-2-5cd8</link>
      <guid>https://dev.to/topeogunleye/redis-for-beginners-part-1-of-2-5cd8</guid>
      <description>&lt;p&gt;Redis has come a long way; now, it can be placed as your primary database—not just a cache layer. It features added data persistence and replication for durability and availability. Additional JSON support and search modules make it easier to store and query more complex data. Now, Redis has an Object mapping library, Redis OM, which simplifies things.&lt;/p&gt;

&lt;p&gt;In this two-part series, the focus is on the core of Redis. This is the first part, which will guide you through setting up a Redis database and using some basic commands.&lt;/p&gt;




&lt;h3&gt;
  
  
  Setting Up a Redis Database
&lt;/h3&gt;

&lt;h3&gt;
  
  
  On a Macbook, use Homebrew
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;First&lt;/strong&gt;, make sure you have Homebrew installed. From the terminal, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew --version

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

&lt;/div&gt;


&lt;p&gt;If this command fails, you'll need to follow the Homebrew installation instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From the terminal, run:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;brew install redis

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

&lt;/div&gt;


&lt;p&gt;After running the above command, the following output is usually displayed:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;==&amp;gt; Downloading &amp;lt;https://homebrew.bintray.com/bottles/redis-6.2.6.catalina.bottle.tar.gz&amp;gt;
==&amp;gt; Downloading from &amp;lt;https://d29vzk4ow07wi7.cloudfront.net/xxxxx/redis-6.2.6.catalina.bottle.tar.gz&amp;gt;
######################################################################## 100.0%
==&amp;gt; Pouring redis-6.2.6.catalina.bottle.tar.gz
==&amp;gt; Caveats
To have launchd start redis now and restart at login:
  brew services start redis
Or, if you don't want/need a background service you can just run:
  redis-server /usr/local/etc/redis.conf
==&amp;gt; Summary
🍺  /usr/local/Cellar/redis/6.2.6: 1,204 files, 9.6MB
==&amp;gt; `brew cleanup` has not been run in 30 days, running now...
Removing: /usr/local/Cellar/old_formula/old_version... (xMB)
...
Removing: /Users/username/Library/Caches/Homebrew/old_formula--old_version... (xMB)
...
==&amp;gt; Caveats
==&amp;gt; redis
To have launchd start redis now and restart at login:
  brew services start redis
Or, if you don't want/need a background service you can just run:
  redis-server /usr/local/etc/redis.conf

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

&lt;/div&gt;


&lt;p&gt;This will install Redis on your system.&lt;/p&gt;
&lt;h3&gt;
  
  
  On Windows, use WSL
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Installation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;From Powershell, run:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wsl --install

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

&lt;/div&gt;


&lt;p&gt;After running the above command, the following output is usually displayed:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;==&amp;gt; Starting Installation:
Installing: Virtual Machine Platform Virtual Machine Platform has been installed.
==&amp;gt; WSL Installation:
Installing: Windows Subsystem for Linux
Windows Subsystem for Linux has been installed.
==&amp;gt; Downloading and Installing Linux Distribution:
Downloading: [Distribution Name]
Installing: [Distribution Name]
==&amp;gt; Setting WSL2 as the Default Version:
Setting WSL 2 as the default.
Installation successful.
==&amp;gt; Prompt to Reboot:
The requested operation is successful. Changes will not be effective until the system is rebooted.

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

&lt;/div&gt;


&lt;p&gt;Microsoft provides detailed instructions for installing WSL. Once you're running Ubuntu on Windows, you can follow the steps detailed at &lt;a href="https://redis.io/" rel="noopener noreferrer"&gt;Redis Site Installation Steps&lt;/a&gt; which are the same steps for installing Redis on Linux to install recent stable versions of Redis from the official packages.&lt;/p&gt;
&lt;h3&gt;
  
  
  Using Redis Cloud
&lt;/h3&gt;

&lt;p&gt;The last option for installing Redis is called Redis Cloud, and that's what you’ll be using here. It allows you to set up a Redis database online. It also comes with Redis insights that can be used to test different commands and visualize your stored data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To use the Redis database online, follow the steps below:&lt;/strong&gt;&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/13d90ac8a7ff4aaba6c39c7b48792ba7"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sign Up for a Free Redis Account:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Visit the Redis website (&lt;a href="https://redis.io/" rel="noopener noreferrer"&gt;https://redis.io/&lt;/a&gt;) and sign up for a free account.&lt;/li&gt;
&lt;li&gt;Provide the necessary details and create your account.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a Subscription:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Once logged in, navigate to the “Subscriptions” section (usually found in the left-hand menu).&lt;/li&gt;
&lt;li&gt;Click on “New Database” or a similar option.&lt;/li&gt;
&lt;li&gt;Scroll down and select the free tier, which typically comes with 30MB of storage.&lt;/li&gt;
&lt;li&gt;Click on “Create Database.”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Download the Redis App:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;To work with Redis locally, download the Redis app for your system (Windows, macOS, or Linux).&lt;/li&gt;
&lt;li&gt;Install the app following the instructions provided.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect to Your Database:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;After creating the database, find the “Connect” option and click on it.&lt;/li&gt;
&lt;li&gt;Click on the "Open with RedisInsights" button. This will launch your installed Redis application.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Basic Commands
&lt;/h3&gt;

&lt;p&gt;When using your RedisInsights application, navigate to your workbench. You can access your workbench by clicking on this icon: &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%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Fd82cba5f-2971-455c-8b0f-683c67cd6231%2F410223b3-ab4e-40e5-a2ee-85747d162642%2FUntitled.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%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Fd82cba5f-2971-455c-8b0f-683c67cd6231%2F410223b3-ab4e-40e5-a2ee-85747d162642%2FUntitled.png" alt="Untitled" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  SET: Using the SET Command to Set a Key-Value Pair
&lt;/h3&gt;

&lt;p&gt;To set a key-value pair in Redis, follow these steps:&lt;/p&gt;

&lt;p&gt;In your workbench input section, type the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET key value

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the key you want to set, and &lt;code&gt;value&lt;/code&gt; with the corresponding value you want to assign to that key.&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;CTRL + Enter&lt;/code&gt; to execute the command.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, executing &lt;code&gt;SET name charlie&lt;/code&gt; will set the value "maria" for the key &lt;code&gt;name&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You should receive the message "OK" in the output section below, confirming that the key-value pair was successfully set.&lt;/p&gt;

&lt;p&gt;To verify, go back to the Redis browser, switch to the data view, and refresh the view to see the updated key-value pair.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/46de8fb38b3140799c9b0ca9ab4fd69a"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Error Handling:&lt;/strong&gt;&lt;br&gt;
If you include a space in your data without quotes, you’ll get a syntax error. To include spaces, enclose the data in quotes.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET name "Xhun li"

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

&lt;/div&gt;



&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/b9303908eff842989e535f78f5c49897"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  GET: Retrieving a Value by Key
&lt;/h3&gt;

&lt;p&gt;To retrieve the value of a specific key, use the GET command. In your workbench, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET key

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the key you want to retrieve.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if you have a key named &lt;code&gt;name&lt;/code&gt; with the value "Xhun li", executing &lt;code&gt;GET name&lt;/code&gt; will return "Xhun li". Press &lt;code&gt;CTRL + Enter&lt;/code&gt; to execute the command.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/50d36f4f44074106b59ee1b2bc4870ac"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  SET MULTIPLE: Setting Multiple Key-Value Pairs
&lt;/h3&gt;

&lt;p&gt;To set multiple key-value pairs simultaneously, use the MSET command. In your workbench, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MSET key1 value1 key2 value2 key3 value3

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;key1&lt;/code&gt;, &lt;code&gt;key2&lt;/code&gt;, &lt;code&gt;key3&lt;/code&gt;, etc., with the names of the keys you want to set, and &lt;code&gt;value1&lt;/code&gt;, &lt;code&gt;value2&lt;/code&gt;, &lt;code&gt;value3&lt;/code&gt;, etc., with their respective values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For instance:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MSET name1 maria name2 yoshi color green rating 10

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

&lt;/div&gt;


&lt;p&gt;This command sets the keys &lt;code&gt;name1&lt;/code&gt;, &lt;code&gt;name2&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt;, and &lt;code&gt;rating&lt;/code&gt; with their respective values. Press &lt;code&gt;CTRL + Enter&lt;/code&gt;. Ensure the key comes first, followed by the value.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/3c05f66ad0e448dfa856eb7ef4601a3d"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  DEL: Deleting Keys
&lt;/h3&gt;

&lt;p&gt;To delete one or more keys and their associated values, use the DEL command. In your workbench, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DEL key1 key2 key3 ...

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;key1&lt;/code&gt;, &lt;code&gt;key2&lt;/code&gt;, &lt;code&gt;key3&lt;/code&gt;, etc., with the names of the keys you want to delete.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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;DEL name1 name2

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

&lt;/div&gt;


&lt;p&gt;Executing this command will delete the keys &lt;code&gt;name1&lt;/code&gt; and &lt;code&gt;name2&lt;/code&gt; along with their respective values. The command will return an integer indicating the number of keys deleted. For instance, a response of 2 indicates that two keys were successfully deleted. Press &lt;code&gt;CTRL + Enter&lt;/code&gt; to execute the command.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/e21b735fa3704bed8aff7fdb711b8c13"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  GET MULTIPLE: Retrieving Multiple Values
&lt;/h3&gt;

&lt;p&gt;To retrieve values for multiple keys at once, use the MGET command. In your workbench, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MGET key1 key2 key3

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;key1&lt;/code&gt;, &lt;code&gt;key2&lt;/code&gt;, &lt;code&gt;key3&lt;/code&gt;, etc., with the names of the keys you want to retrieve.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;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;MGET name color rating

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

&lt;/div&gt;


&lt;p&gt;This command will return the values associated with keys &lt;code&gt;name1&lt;/code&gt;, &lt;code&gt;name2&lt;/code&gt;, and &lt;code&gt;rating&lt;/code&gt;. Press &lt;code&gt;CTRL + Enter&lt;/code&gt;. The values "Xhun li", "green", and "10" will be returned in the output section.&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/4bc7740b7538489a870ec6753d7fe599"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  GETRANGE: Retrieving Substrings
&lt;/h3&gt;

&lt;p&gt;To retrieve a substring of a value stored in a key, use the &lt;code&gt;GETRANGE&lt;/code&gt; command. Here’s how to use it in your workbench:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GETRANGE key start end

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Replace &lt;code&gt;key&lt;/code&gt; with the name of the key, &lt;code&gt;start&lt;/code&gt; with the starting index, and &lt;code&gt;end&lt;/code&gt; with the ending index.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Set a key named &lt;code&gt;name&lt;/code&gt; with the value "christopher":&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET name christopher

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

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Retrieve the first five letters of "christopher" with the following command:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GETRANGE name 0 4

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

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This will return the substring "Chris".&lt;/p&gt;


&lt;div&gt;
  &lt;iframe src="https://loom.com/embed/7e83d59b12434be6986a50d6ffda89b1"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;






&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In this first part of our Redis for Beginners series, you learned how to set up a Redis database and run basic commands such as setting, getting, deleting, and retrieving multiple key-value pairs. These are basic skills that anyone working with Redis should be conversant with.&lt;/p&gt;

&lt;p&gt;In the next part of this series, we will explore more advanced commands, and command options, and go into the differences between lists and sets in Redis. Stay tuned!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding CSS Percentage Values</title>
      <dc:creator>topeogunleye</dc:creator>
      <pubDate>Thu, 25 Jul 2024 14:10:25 +0000</pubDate>
      <link>https://dev.to/topeogunleye/understanding-css-percentage-values-ain</link>
      <guid>https://dev.to/topeogunleye/understanding-css-percentage-values-ain</guid>
      <description>&lt;p&gt;Have you ever wondered why a percentage value isn’t working as expected in your CSS? Let’s explore some common scenarios where percentage values can be tricky.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;A brief overview of CSS percentage values:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;CSS percentage values are relative units that allow you to specify sizes and positions as a proportion of the containing element.&lt;/li&gt;
&lt;li&gt;They are commonly used to create flexible, responsive designs for layout purposes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When using percentages in CSS, the reference point must be identified. Often, this reference is thought to be the parent element of the one to which the percentage is applied. While this is generally true, it's not always the case. The correct reference is the "containing block," which may not necessarily be the direct parent element but any ancestor element that provides the context for the percentage value. Misunderstandings can arise when percentages are expected to be relative to a different dimension or element than they are.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calculating percentage values from the containing block:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Box model properties and offset properties calculate their CSS percentage values as:

&lt;ul&gt;
&lt;li&gt;The height, top, and bottom properties compute percentage values from the height of the containing block.&lt;/li&gt;
&lt;li&gt;The width, left, right, padding, and margin properties compute percentage values from the width of the containing block.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Common scenarios where percentage values may not work as expected:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Percentage values can behave differently depending on the property they are applied to:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Font-size&lt;/strong&gt;: Percentages are relative to the parent element’s font size.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transform&lt;/strong&gt;: Percentages refer to the element’s dimensions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Width, Padding, Margin&lt;/strong&gt;: Percentages are relative to the parent element’s dimensions.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Layout issues often occur when the parent element's dimensions aren't explicitly defined or when intrinsic sizing rules come into play. For instance, let's say you have a parent container without explicitly defined dimensions and a child element that uses percentage-based width and height. In such cases, the child element may not size correctly because the parent's size isn't defined:&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Padding Top 20%&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When you set padding-top: 20%, this value resolves to 20% of the parent element’s &lt;strong&gt;width&lt;/strong&gt;, not its height. This can often lead to unexpected layouts if you’re assuming it’s relative to the height.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Scenario and Potential Layout Issues:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/yLdYryG?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;br&gt;
In this example, the padding-top of the .child element will be 20% of the .parent element’s width (40px), not its height (20px). This might not be the intended behavior and can lead to unexpected layouts.&lt;/p&gt;

&lt;p&gt;Potential Layout Issues: The padding-top for the .box is calculated as 20% of the .container's width (300px), which results in 60px of padding. If you were expecting the padding to be relative to the height of the .container (200px), you would anticipate 40px of padding instead. This discrepancy can lead to unexpected layout issues, especially if you are not aware that padding percentages are based on the parent's width.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;2. Font Size&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Percentage values for font-size are relative to the font-size of the parent element. So, if you set font-size: 150%, it will be 1.5 times the size of the parent’s font-size.&lt;/p&gt;

&lt;p&gt;When you use percentage values for font-size, they are calculated relative to the font size of the parent element. This means that the computed font size of a child element will scale proportionally based on the parent element’s font size.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/oNrjOxL?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;br&gt;
In this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The .parent element has a font size of 16px.&lt;/li&gt;
&lt;li&gt;The .child element’s font size is set to 150%, which is 1.5 times the parent’s font size.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The computed font size of the .child element will be 24px (16px * 1.5).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This demonstrates how percentage-based font sizes scale relative to their parent element, ensuring consistent and proportional text sizing within a hierarchy of elements.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;3. Transform Translate&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When using transform: translate(), the percentage values are relative to the element’s dimensions, not its parent’s.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt; When you apply transform: translate() with percentage values, these percentages are calculated based on the dimensions of the element itself, not the parent. This can take you by surprise and you might expect the translation to be relative to the parent element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/topeogunleye21/pen/rNEObeX" rel="noopener noreferrer"&gt;https://codepen.io/topeogunleye21/pen/rNEObeX&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The .container element has a width of 300px and a height of 200px.&lt;/li&gt;
&lt;li&gt;The .box element has a width of 100px and a height of 100px.&lt;/li&gt;
&lt;li&gt;The transform: translate(50%, 50%) on the .box translates it by 50% of its width (50px) and 50% of its height (50px).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The .box element will be shifted 50px to the right and 50px down from its original position.&lt;/li&gt;
&lt;li&gt;This behavior can be unexpected if you assume the translation is relative to the parent element's dimensions.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;
  
  
  &lt;strong&gt;Why Isn’t body { height: 100% } Filling the Viewport?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The reason body { height: 100% } doesn’t fill the viewport is because the body element isn’t the first element in the document. It’s easy to think of the body as the top-level element, but it’s actually inside the html element, also known as the root element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation of the hierarchy of HTML and body elements:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In an HTML document, the body element is nested inside the html element. This means that for the body to fully utilize the viewport height, the html element also needs to be set to 100% height.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps to ensure body height fills the viewport:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set html height to 100%:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;html {
  height: 100%;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;Set body min-height to 100%:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;body {
  min-height: 100%;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is a crucial step and should be included in your CSS reset. Setting the html height to 100% ensures that the body can then have a minimum height of 100% of the viewport. By doing this, the body element can properly resolve to 100% of its parent’s height (the html element), which now has a defined height.&lt;/p&gt;

&lt;p&gt;By understanding these nuances, you can better control your layouts and ensure your CSS works as expected. Happy coding!&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Viewport Units&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Another solution to sizing issues in CSS is using viewport units instead of percentages. Viewport units provide concrete values based on the size of the viewport, offering a more reliable approach. Here’s how you can think about it:&lt;/p&gt;

&lt;p&gt;When you don't have any content in the body, it might not fill the entire viewport. Content determines the intrinsic height of an element. To address this, you can use vw (viewport width) and vh (viewport height) units. For example, you can set an element's height to 100vh to make it equal to the height of the viewport.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction to viewport units (vh, vw):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;vh (Viewport Height)&lt;/strong&gt;: 1vh is equal to 1% of the height of the viewport.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;vw (Viewport Width)&lt;/strong&gt;: 1vw is equal to 1% of the width of the viewport.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Benefits and use cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Viewport units are particularly useful for creating responsive designs that need to adapt to different screen sizes.&lt;/li&gt;
&lt;li&gt;They provide a more consistent and predictable sizing mechanism compared to percentages, which can be affected by the parent element's dimensions.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/xxowegZ?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In this example, the full-height section uses height: 100dvh, which adjusts its height based on the viewport height dynamically. This ensures that the section always fills the entire height of the viewport, even if the viewport size changes (e.g., due to a mobile device's browser header appearing or disappearing).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction to dynamic viewport units (svh, lvh, dvh, dvw):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;svh (Small Viewport Height)&lt;/strong&gt;: Based on the smallest possible height of the viewport.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;lvh (Large Viewport Height)&lt;/strong&gt;: Based on the largest possible height of the viewport.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dvh (Dynamic Viewport Height)&lt;/strong&gt;: Adjusts dynamically based on changes in the viewport, such as the appearance of a header on mobile devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dvw (Dynamic Viewport Width)&lt;/strong&gt;: Adjusts dynamically based on changes in the viewport width.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By using viewport units, you can achieve more reliable and responsive layouts that adapt to different screen sizes and conditions. These units offer a robust alternative to percentages, providing more consistent and predictable results.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Handling Different Device Types&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Using dynamic viewport units like dvh can be particularly useful for projects where you want the html element to stretch to 100% of the dynamic viewport height. This is ideal for layouts with fixed headers and footers, ensuring the content area fills the remaining space.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps to ensure the content area fills the remaining space:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use Dynamic Viewport Units:&lt;/strong&gt; Utilize dvh to make sure the content area adapts to changes in the viewport.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set HTML and Body to 100%:&lt;/strong&gt; Ensure both html and body elements stretch to the full height of the viewport.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adjust Content Height:&lt;/strong&gt; Use min-height and dvh units to make sure the content area fills the remaining space between the header and footer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Example Scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/XWLmQMW?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Header and Footer:&lt;/strong&gt; Both are fixed at the top and bottom of the viewport, respectively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Area:&lt;/strong&gt; The min-height is set using calc(100dvh - 2 * 3rem), which ensures that the content area fills the remaining space after accounting for the height of the header and footer. The height of the header and footer are both 3rem, so the calculation adjusts accordingly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Viewport Units:&lt;/strong&gt; By using 100dvh, the content area adapts to changes in the viewport height, ensuring a responsive design.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach ensures that the content area dynamically adjusts its height, filling the space between the fixed header and footer, making the layout adaptable to different device types and viewport changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Absolute and Fixed Positioning&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you have elements that are absolutely or fixed positioned, using viewport units (vh or vw) instead of percentages can help maintain their size relative to the viewport. To explain the use of dvh (Dynamic Viewport Height) with an example where something very important, like a notification or a footer, must be stuck to the bottom of the viewport, we'll use a layout that includes a header, a main content section, and a footer that always sticks to the bottom of the viewport.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML and CSS
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/oNrjOZY?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;HTML Structure:&lt;/strong&gt; The layout includes a header, a main content section, and a footer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS Styling:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The header is styled to take up 10vh (10% of the viewport height).&lt;/li&gt;
&lt;li&gt;The .main-content section has a min-height of 80dvh (80% of the dynamic viewport height). This ensures that the main content section takes up at least 80% of the viewport height, adjusting dynamically to changes in the viewport size.&lt;/li&gt;
&lt;li&gt;The footer is positioned fixed at the bottom with a height of 10dvh (10% of the dynamic viewport height). This ensures that the footer always stays at the bottom of the viewport, regardless of the content height in the main section.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Benefits of Using dvh&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Adjustments:&lt;/strong&gt; The dvh unit adjusts dynamically based on changes in the viewport, such as the appearance of on-screen keyboards or browser toolbars, especially on mobile devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent Layout:&lt;/strong&gt; Ensures that important elements like footers remain consistently positioned relative to the viewport, providing a reliable user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility:&lt;/strong&gt; Allows for more flexible and adaptive designs that respond well to different device types and viewport changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Limitations of Viewport Units&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Viewport units don't account for the scrollbar, which can lead to slight inaccuracies in sizing. Despite this, they are generally easier to work with in stylesheets compared to percentages. However, there are several limitations and potential issues to be aware of:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Sizing Inaccuracies&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scrollbars:&lt;/strong&gt; When a scrollbar appears, it reduces the usable width of the viewport. Viewport units like vw (viewport width) don't account for this, potentially causing content to overflow or misalign.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixed and Absolute Positioning:&lt;/strong&gt; Elements positioned with viewport units can behave unexpectedly when scrollbars appear, as their size remains constant relative to the viewport but not to the available content area.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Managing Sizing Inaccuracies&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Media Queries:&lt;/strong&gt; Use media queries to adjust styles for different viewport sizes and conditions. This can help manage issues arising from scrollbars and ensure a more consistent layout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Box-Sizing and Overflow:&lt;/strong&gt; Set the box-sizing property to border-box and use overflow: auto or overflow: hidden to control how content behaves within its container, minimizing the impact of scrollbars.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&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;h3&gt;
  
  
  &lt;strong&gt;Font Size and Zooming&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Viewport Units for Text:&lt;/strong&gt; Using viewport units for text sizes can cause issues when users zoom in. As the viewport width remains constant, the text size doesn't increase proportionally, making it difficult to read.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using Clamp:&lt;/strong&gt; Instead of using viewport units for text, use the clamp function to ensure text remains readable and scales appropriately with zoom.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2vw&lt;/span&gt; &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3rem&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;h3&gt;
  
  
  &lt;strong&gt;Example Scenario&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/gONayWo?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Explanation&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Text Scaling with Clamp:&lt;/strong&gt; The text inside the .content div uses the clamp function to ensure it scales properly with viewport changes and zooming, maintaining readability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fixed Element:&lt;/strong&gt; The .fixed-element div at the bottom of the viewport remains fixed in place, demonstrating how viewport units can maintain positioning while accommodating content changes and scrollbars.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overflow Management:&lt;/strong&gt; Setting overflow: auto on the body and html elements helps manage content overflow and minimize the impact of scrollbars on the layout.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding and addressing these limitations, you can create more robust and responsive web designs that handle various viewport conditions and user interactions effectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Flexbox and Grid Layouts&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When using Flexbox or Grid layouts, percentages can be challenging due to their intrinsic sizing rules. Flexbox and Grid use their own rules to determine the size of elements, and percentages might not behave as expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example with Flexbox:&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;span class="nc"&gt;.child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the .container uses Flexbox to distribute space among its children. The .child elements will flex to fill the available height of the container, but using percentages within these children can lead to unexpected results due to the way Flexbox calculates sizes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Challenges of Using Percentages with Flexbox and Grid&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Intrinsic Sizing Rules:&lt;/strong&gt; Flexbox and Grid layouts have their own intrinsic sizing rules, which can override the expected behavior of percentage values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Undefined Heights in Grid Layouts:&lt;/strong&gt; In Grid layouts, child elements might not have a defined height, making it difficult to use percentages effectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Container Queries:&lt;/strong&gt; Container queries can struggle with grid items as they might not have an intrinsic size, leading to challenges in querying their block size.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Recommendations for Using Flexbox and Grid Layouts&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Flexbox:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use flex properties to distribute space rather than relying on percentages. For example, flex: 1 allows a child to take up available space proportionally.&lt;/li&gt;
&lt;li&gt;Combine Flexbox with viewport units or fixed sizes when percentages don't yield the expected results.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example with Flexbox:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/wvLKZex?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Grid:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use fr units to define fractional space within the grid. This is more intuitive and flexible than percentages.&lt;/li&gt;
&lt;li&gt;Define explicit row and column sizes when needed, and use minmax() for more control over item sizing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example with Grid:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/mdZegMq?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In this example, the .grid-container uses the fr unit to distribute space between columns, ensuring a flexible and predictable layout. The grid-template-rows: auto allows rows to size based on their content, making it easier to manage item heights.&lt;/p&gt;

&lt;p&gt;Flexbox and Grid layouts offer powerful tools for responsive design, but they require a different approach than traditional percentage-based layouts. By leveraging Flexbox's flex properties and Grid's fr units, you can create more reliable and adaptable layouts. Combining these techniques with viewport units and fixed sizes can further enhance your control over the design.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Background Size and Gradients&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When using percentages for background size, the percentages are relative to the background positioning area of the element. This principle is similar to how gradients work with percentages:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Background Size:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The background-size property can use percentage values to set the size of the background image relative to the background positioning area of the element.&lt;/li&gt;
&lt;li&gt;For example, background-size: 50% means the background image will cover 50% of the background positioning area.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/QWXjPMz?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gradients:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When using percentages in linear or radial gradients, they refer to the position within the background area.&lt;/li&gt;
&lt;li&gt;This can be useful for creating responsive gradient backgrounds that adjust to the size of the element.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example with Gradients:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/OJeyGZw?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Potential Issues and How to Handle Them:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using percentages for background size and gradients can lead to unexpected squishing or stretching if the element’s size changes.&lt;/li&gt;
&lt;li&gt;To avoid these issues, consider using other units like pixels or viewport units, or combine percentages with other CSS techniques to ensure the background and gradients scale properly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding how percentages work with background sizes and gradients, you can create visually appealing designs that adapt to different screen sizes and maintain their intended appearance.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Percentages in SVGs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;SVGs (Scalable Vector Graphics) are inherently responsive, making them a powerful tool for creating scalable and flexible web graphics. Using percentages in SVGs can help ensure they adapt seamlessly to different viewport sizes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How Percentages Apply to SVGs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you set the width or height of an SVG to a percentage, it scales relative to its containing element.&lt;/li&gt;
&lt;li&gt;The viewBox attribute defines the coordinate system and aspect ratio of the SVG, allowing for flexible scaling.&lt;/li&gt;
&lt;li&gt;Percentages can be used within the SVG elements to position and size shapes relative to the SVG container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Best Practices for Responsive SVGs:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Define a ViewBox:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Always define the viewBox attribute to enable scaling. This attribute sets up an internal coordinate system for the SVG.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/jOjbRKR?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Percentages for Positioning and Sizing:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Use percentage values for attributes like x, y, width, and height to create flexible layouts within the SVG.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/mdZegjx?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unitless Path Data:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Use unitless values for path data to ensure paths scale properly with the SVG.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/rNEObZO?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example of a Responsive SVG:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/OJeyGoo?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;By following these best practices and understanding how percentages apply to SVGs, you can create graphics that are both responsive and visually consistent across different devices and screen sizes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Cyclical Percentage Issues&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Sometimes, the height of a container depends on its children, which may use percentages that reference the parent. This can create cyclical dependencies, causing layout issues. For example, if a parent wants to contain its child, and the child is set to be 50% of the parent, it can create an endless loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good News&lt;/strong&gt;: The CSS spec provides instructions on how to resolve these intrinsic percentage issues. Understanding and applying these rules can help you avoid common pitfalls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions and Best Practices Based on CSS Specifications:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Avoid Circular Dependencies::&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure that parent and child elements do not have interdependent percentage-based sizes.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Avoid setting both parent and child heights in percentages if they reference each other.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/eYwpoxp?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Use Min-Height and Max-Height:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use min-height and max-height to provide a fallback size for elements, preventing endless loops.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/BagoEMG?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Specify One Dimension Explicitly:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define either the parent or child element’s height explicitly to break the cyclical dependency.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/oNrjOVG?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;By implementing these best practices, you can avoid common cyclical percentage issues in CSS and create beautiful, stable layouts.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Utilize Flexbox or Grid Layouts to Resolve Cyclical Percentage Issues&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Utilize Flexbox or Grid Layouts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Flexbox or Grid for layout purposes to manage the size and alignment of child elements without direct dependency on percentage-based heights.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example with Flexbox:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://codepen.io/topeogunleye21/pen/JjQYVqN" rel="noopener noreferrer"&gt;https://codepen.io/topeogunleye21/pen/JjQYVqN&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example with Grid:
&lt;/h3&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/topeogunleye21/embed/WNqQWBB?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;br&gt;
Using Flexbox and Grid layouts, you can easily manage the size and alignment of child elements, avoiding the complexities of percentage-based heights. These modern CSS techniques provide more flexibility and control, ensuring your layouts are both beautiful and functional.&lt;/p&gt;

&lt;p&gt;By following these best practices and understanding the underlying principles of cyclical percentage dependencies, you can create more robust and predictable layouts, avoiding common pitfalls that can lead to rendering issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Understanding CSS percentage values and their nuances is crucial for creating flexible and responsive web designs. Percentages can behave differently depending on the property and the context in which they are used, leading to unexpected layout behaviors if not properly understood.&lt;/p&gt;

&lt;p&gt;By leveraging a mix of units and properties—percentages, viewport units, fixed units, and flexible layouts like Flexbox and Grid—you can build robust and responsive web designs that adapt well to different screen sizes and content requirements. Experiment with these techniques, understand their behaviors and apply them strategically to create seamless and adaptive user experiences.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;References and Further Reading&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here are some additional resources for in-depth understanding and advanced techniques:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://dev.to/khangnd/understanding-css-percentage-44gd"&gt;Understanding CSS Percentage&lt;/a&gt; by &lt;a href="https://dev.to/khangnd"&gt;Khang&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/percentage" rel="noopener noreferrer"&gt;Percentage&lt;/a&gt; documentation from MDN.&lt;/li&gt;
&lt;li&gt;The &lt;a href="https://www.youtube.com/watch?v=veEqYQlfNx8&amp;amp;t=360s" rel="noopener noreferrer"&gt;problem with viewports units&lt;/a&gt; by &lt;a href="https://www.youtube.com/@KevinPowell" rel="noopener noreferrer"&gt;Kevin Powell&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Part Two: Creating Our Recipe Reusable Skeleton Component</title>
      <dc:creator>topeogunleye</dc:creator>
      <pubDate>Wed, 19 Jun 2024 21:11:23 +0000</pubDate>
      <link>https://dev.to/topeogunleye/part-two-creating-our-recipe-reusable-skeleton-component-cgj</link>
      <guid>https://dev.to/topeogunleye/part-two-creating-our-recipe-reusable-skeleton-component-cgj</guid>
      <description>&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%2F1dyfeq5y7xq4o06k6ils.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%2F1dyfeq5y7xq4o06k6ils.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Reusable Skeleton Component
&lt;/h3&gt;

&lt;p&gt;Welcome to part two of Skeleton Loaders: Simplifying Data Loading in React! In the &lt;a href="https://dev.to/topeogunleye/skeleton-loaders-simplifying-data-loading-in-react-part-1-1kmo"&gt;first article&lt;/a&gt;, we learned how Facebook and LinkedIn leverage skeleton loading screens in managing users' expectations while data is fetched, built our React app from scratch, and added styles to our React application. In part two, we'll guide you through the practical steps of implementing skeleton loading screens in your React applications including animations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Reusable Skeleton Component
&lt;/h3&gt;

&lt;p&gt;We aim to create a reusable base skeleton element component that can be configured into different shapes. To achieve this, let's start by creating a new folder named &lt;code&gt;skeletons&lt;/code&gt; within our &lt;code&gt;src&lt;/code&gt; directory. Inside this folder, we'll create a file named &lt;code&gt;skeletonElement.jsx&lt;/code&gt;. This file will house our base skeleton component, which is designed to be reusable and customizable.&lt;/p&gt;

&lt;p&gt;Here's the code to include in the &lt;code&gt;skeletonElement.jsx&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Skeleton.css&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;SkeletonElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`skeleton &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="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="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="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;classes&lt;/span&gt;&lt;span class="si"&gt;}&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;)&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;SkeletonElement&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code, we define a &lt;code&gt;SkeletonElement&lt;/code&gt; component that accepts a &lt;code&gt;type&lt;/code&gt; prop. This &lt;code&gt;type&lt;/code&gt; prop allows us to customize the shape of the skeleton element by applying different CSS classes. The component then returns a &lt;code&gt;div&lt;/code&gt; with the CSS classes applied.&lt;/p&gt;

&lt;p&gt;Let’s create the style for our skeleton component by creating a file named Skeleton.css and adding the below styles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* basic styles */&lt;/span&gt;
&lt;span class="nc"&gt;.skeleton&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ddd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.skeleton.title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.imageBig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;240px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;240px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.imageMealInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;92vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;48vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.mealInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;176px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.textBig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;240px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1152px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.liText&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.imageSmall&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;240px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;240px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1080px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.imageMealInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;320px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;max-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;320px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;767px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.imageSmall&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;208px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;224px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="nc"&gt;.title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="nc"&gt;.imageBig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;320px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="nc"&gt;.imageMealInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;max-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="nc"&gt;.mealInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;512px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="nc"&gt;.textBig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;576px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;456px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="nc"&gt;.liText&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;475px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.imageSmall&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;208px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;212px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="nc"&gt;.imageMealInfo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;92vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;62vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

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


&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;425px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.imageBig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;312px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;312px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="nc"&gt;.textBig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;318.75px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;840px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;375px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.imageBig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;281.25px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;281.25px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="nc"&gt;.textBig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;281.25px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;960px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;



&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;/* skeleton profile */&lt;/span&gt;
&lt;span class="nc"&gt;.skeleton-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* margin: 20px auto; */&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c"&gt;/* Category */&lt;/span&gt;
&lt;span class="nc"&gt;.catImg&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;177px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;110px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.catName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;75px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;28px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c"&gt;/* themes */&lt;/span&gt;
&lt;span class="nc"&gt;.light&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f2f2f2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.dark&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#444&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.dark&lt;/span&gt; &lt;span class="nc"&gt;.skeleton&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#777&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c"&gt;/* animation effects */&lt;/span&gt;
&lt;span class="nc"&gt;.shimmer-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;loading&lt;/span&gt; &lt;span class="m"&gt;2.5s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.shimmer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;skewX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-20deg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.dark&lt;/span&gt; &lt;span class="nc"&gt;.shimmer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;loading&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-150%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-60%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;150%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c"&gt;/* skeleton profile */&lt;/span&gt;
&lt;span class="nc"&gt;.skeleton-profile&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c"&gt;/* themes */&lt;/span&gt;
&lt;span class="nc"&gt;.skeleton-wrapper.light&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f2f2f2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.skeleton-wrapper.dark&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#444&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.skeleton-wrapper.dark&lt;/span&gt; &lt;span class="nc"&gt;.skeleton&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#777&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;h4&gt;
  
  
  Explanation of Styles for Skeleton Loading
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Skeleton Element Styles: The &lt;code&gt;SkeletonElement.js&lt;/code&gt; file defines a reusable skeleton component that can be configured with different shapes. These shapes are defined in the accompanying &lt;code&gt;Skeleton.css&lt;/code&gt; file. By applying different CSS classes, we can customize the appearance of skeleton elements, such as their size, color, and animation effects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wrapper Styles: The &lt;code&gt;SkeletonHome.js&lt;/code&gt; file wraps the skeleton elements in a &lt;code&gt;div&lt;/code&gt; with the class &lt;code&gt;wrapper&lt;/code&gt;. This wrapper provides a container for the skeleton elements and allows for additional styling or layout adjustments if needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shimmer Effect: The &lt;code&gt;Shimmer&lt;/code&gt; component adds a subtle shimmer effect to the skeleton elements. This effect is achieved through CSS animations and helps indicate to the user that content is loading.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Creating Our Shimmer:
&lt;/h3&gt;

&lt;p&gt;Let’s create a Shimmer.js file and add this code below to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Shimmer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="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;"shimmer-wrapper"&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;"shimmer"&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="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;Shimmer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Creating our Skeleton Home page
&lt;/h3&gt;

&lt;p&gt;Let’s create a SkeletonHome.js file and add this code below to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Shimmer&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;./Shimmer&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;SkeletonElement&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;./SkeletonElement&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;SkeletonHome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;themeClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&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="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="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`wrapper &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;themeClass&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="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;"meals grid grid-cols-1  gap-5 mt-5 xs:grid-cols-2 sm:grid-cols-3 xl:grid-cols-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="nc"&gt;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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;SkeletonElement&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"imageSmall"&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="nc"&gt;Shimmer&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;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;SkeletonHome&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s make use of our SkeletonHome.js component in our Home.js component so that we have a skeleton loader on our home component. Copy the code below and paste it into our Home.js component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="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="nx"&gt;SkeletonHome&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;../skeletons/SkeletonHome&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;Home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMeals&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;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;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://www.themealdb.com/api/json/v1/1/search.php?s=chicken&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;meals&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="nf"&gt;setMeals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;meals&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="nx"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meals&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="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;


  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&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;"container"&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;"m-auto max-w-3xl flex flex-col items-center justify-center text-center"&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;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"meals"&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;"meals"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;meals&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
              &lt;span class="nx"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meals&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;meal&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;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"meal"&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;meal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;idMeal&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="nt"&gt;img&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;"meal-img"&lt;/span&gt;
                    &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;meal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strMealThumb&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;meal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strMeal&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="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;"meal-info"&lt;/span&gt; &lt;span class="na"&gt;data-mealid&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;meal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;idMeal&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="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;meal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strMeal&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;h3&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;))&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;meals&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&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;n&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SkeletonHome&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;n&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dark"&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;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="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;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Explanation of Theme Customization in SkeletonHome.js Component:
&lt;/h4&gt;

&lt;p&gt;The SkeletonHome.js component offers theme customization through the &lt;code&gt;theme&lt;/code&gt; prop. This prop allows users to specify the color scheme for the skeleton elements, providing flexibility in integrating the skeleton loading experience with different application designs.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Theme Prop Handling&lt;/strong&gt;: Within the SkeletonHome.js component, the &lt;code&gt;theme&lt;/code&gt; prop is utilized to determine the color scheme. By default, if no theme is provided, the component falls back to the "light" theme. This ensures that the component remains functional even if the theme prop is not explicitly set.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SkeletonHome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;themeClass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Default to "light" theme if no theme is provided&lt;/span&gt;
  &lt;span class="c1"&gt;// Rest of the component code...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Applying Theme Classes&lt;/strong&gt;: The determined theme, either "light" or the provided value, is used to dynamically generate CSS classes. These classes are then applied to the wrapper &lt;code&gt;div&lt;/code&gt; of the skeleton elements, enabling the styling of the skeleton components based on the selected theme.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&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="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`wrapper &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;themeClass&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Skeleton elements go here */&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Theme Flexibility&lt;/strong&gt;: By allowing users to specify the theme, developers can seamlessly integrate the skeleton loading experience with their application's design language. For example, setting the theme to "dark" can complement dark mode interfaces, ensuring consistency in visual presentation across different application states.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SkeletonHome&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;n&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dark"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In summary, the SkeletonHome.js component facilitates theme customization through the &lt;code&gt;theme&lt;/code&gt; prop, providing users with the ability to tailor the skeleton loading experience to match their application's design requirements. This flexibility enhances the overall user experience by ensuring a cohesive and visually appealing transition between content loading and display.&lt;/p&gt;

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

&lt;p&gt;In wrapping up, adding skeleton loading screens to your React app can make it feel faster and more user-friendly. With components like &lt;code&gt;SkeletonHome&lt;/code&gt;, you can easily create these loading screens for different parts of your app. By using CSS and React, you can customize how these loading screens look and behave to match your app's style. Ultimately, using skeleton loading screens improves how users perceive your app's speed and makes it more enjoyable to use.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Skeleton Loaders: Simplifying Data Loading in React: Part 1</title>
      <dc:creator>topeogunleye</dc:creator>
      <pubDate>Wed, 19 Jun 2024 20:58:40 +0000</pubDate>
      <link>https://dev.to/topeogunleye/skeleton-loaders-simplifying-data-loading-in-react-part-1-1kmo</link>
      <guid>https://dev.to/topeogunleye/skeleton-loaders-simplifying-data-loading-in-react-part-1-1kmo</guid>
      <description>&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%2F9c14c5lgckohbd8qkhap.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%2F9c14c5lgckohbd8qkhap.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Part One: Creating Our React App
&lt;/h2&gt;

&lt;p&gt;Welcome to our two-part series on Skeleton Loaders: Simplifying Data Loading in React! In part one of this series, we'll create our modern react application from scratch, fetch the data, and add styling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Power of Skeleton Loading Screens
&lt;/h2&gt;

&lt;p&gt;Many modern websites handle data fetching in the browser instead of on the server. This is good because it means that a user doesn’t have to wait long before getting their content loaded from the server but then has to wait for their data to be loaded from the browser once it arrives. &lt;/p&gt;

&lt;p&gt;Developers often use loaders or spinners to manage user expectations during this data-fetching process. A particularly effective and popular approach, adopted by major websites like Facebook and LinkedIn, is the use of skeleton loading screens. These screens display placeholder elements that mimic the layout of the actual content, providing a visual representation of the incoming data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of React.&lt;/li&gt;
&lt;li&gt;Familiarity with React Hooks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting Up the Project
&lt;/h2&gt;

&lt;p&gt;First, we'll create a new React application using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-react-app react-skeleton-screens
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, navigate into the newly created project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;react-skeleton-screens
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the project in Visual Studio Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;code &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Removing Boilerplate Code
&lt;/h2&gt;

&lt;p&gt;Let's clean up the default files created by &lt;code&gt;create-react-app&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open the &lt;code&gt;src&lt;/code&gt; folder and delete the following files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;App.css&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;App.test.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;logo.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setupTests.js&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In &lt;code&gt;index.js&lt;/code&gt;, remove the import and invocation of the service worker.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In &lt;code&gt;App.js&lt;/code&gt;, remove the import of &lt;code&gt;logo.svg&lt;/code&gt; and &lt;code&gt;App.css&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Replace the code in &lt;code&gt;App.js&lt;/code&gt; with the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="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;User&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/User&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;Articles&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/Articles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;"App"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;React Skeletons&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&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="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;"content"&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;);&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;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating Components
&lt;/h2&gt;

&lt;p&gt;Now, let's create the necessary components. In the &lt;code&gt;src&lt;/code&gt; directory, create a new folder called &lt;code&gt;components&lt;/code&gt;. Inside this folder, create one file: &lt;code&gt;Home.jsx&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="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;"home"&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;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these steps, you've set up a basic React application structure and created components for our landing page, which will serve as the foundation for implementing skeleton screens. This setup ensures a clean slate, allowing you to focus on building the skeleton loading screens that enhance user experience during data fetching.&lt;/p&gt;

&lt;p&gt;Now we’re going to nest the Home component inside the content div in our App.js component. Copy the code below into your app.js to do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Home&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;./Home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;"App"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Meal Recipes&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&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="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;"content"&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;Home&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;);&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;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding Styles to the Application
&lt;/h2&gt;

&lt;p&gt;To enhance the appearance of our application, we'll apply some styles to the header in &lt;code&gt;App.js&lt;/code&gt;. Follow the steps below to update the styles in your &lt;code&gt;index.css&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update &lt;code&gt;index.css&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Open &lt;code&gt;index.css&lt;/code&gt; and replace its contents with the following styles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;border-box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;900&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nt"&gt;header&lt;/span&gt; &lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#6b7280&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-timing-function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.meals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Equivalent to gap-5 in Tailwind */&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Equivalent to mt-5 in Tailwind */&lt;/span&gt;
  &lt;span class="nl"&gt;transition-property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-timing-function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;640px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.meals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;768px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.meals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1280px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.meals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c"&gt;/* .meal class */&lt;/span&gt;
&lt;span class="nc"&gt;.meal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Equivalent to rounded overflow-hidden shadow-md cursor-pointer relative h-60 w-60 xs:h-56 xs:w-52 sm:h-56 sm:w-52 lg:h-56 lg:w-52 text-left; */&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;-1px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.06&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Equivalent to h-60 */&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Equivalent to w-60 */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.meal-img&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;15px&lt;/span&gt; &lt;span class="m"&gt;-3px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;147&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;6px&lt;/span&gt; &lt;span class="m"&gt;-2px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.05&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;transition-property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-timing-function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c"&gt;/* .meal-img class */&lt;/span&gt;
&lt;span class="nc"&gt;.meal-img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Equivalent to w-full h-full border-solid border-4 border-white; */&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* Assuming white border */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation of Styles
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The universal selector (&lt;code&gt;*&lt;/code&gt;) is used to apply the following styles to all elements on the page:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;margin: 0;&lt;/code&gt; and &lt;code&gt;padding: 0;&lt;/code&gt; set the margin and padding of all elements to zero, effectively removing any default spacing.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;box-sizing: border-box;&lt;/code&gt; ensures that the total width and height of an element include both its content and padding, but not the margin.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;header&lt;/code&gt; element:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;font-size: 1.5rem;&lt;/code&gt; sets the font size to 1.5 times the default font size.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;font-weight: 900;&lt;/code&gt; makes the text bold.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;display: grid;&lt;/code&gt; uses CSS Grid for layout.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;align-items: center;&lt;/code&gt; vertically centers the content within the header.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;.container&lt;/code&gt; class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;background-color: #6b7280;&lt;/code&gt; sets the background color to a shade of gray (#6b7280).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;color: #ffffff;&lt;/code&gt; sets the text color to white.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;min-height: 100vh;&lt;/code&gt; ensures that the container takes up at least the full viewport height.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;transition&lt;/code&gt; properties control the animation duration and timing function when transitioning styles.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;.meals&lt;/code&gt; class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses CSS Grid to create a responsive grid layout with varying column numbers based on screen width.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gap: 1.25rem;&lt;/code&gt; adds spacing between grid items.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;margin-top: 1.25rem;&lt;/code&gt; provides top margin.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;transition&lt;/code&gt; properties control the animation when transitioning styles.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;padding: 10px 50px;&lt;/code&gt; adds padding to the container.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Media queries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adjust the number of columns in the &lt;code&gt;.meals&lt;/code&gt; grid based on screen width.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;.meal&lt;/code&gt; class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates a card-like styling for meal items.&lt;/li&gt;
&lt;li&gt;Sets border radius, overflow behavior, box shadow, cursor, and dimensions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;.meal-img&lt;/code&gt; class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sets the image dimensions and adds a white border.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These styles will ensure that your application's header looks clean and visually appealing. The header will have a consistent blue background with white text, providing a professional look.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Steps
&lt;/h3&gt;

&lt;p&gt;After adding the styles, your header in the application should now have a distinct appearance, with a blue background and centered white text.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running the Application
&lt;/h3&gt;

&lt;p&gt;To see your changes in action, make sure to start your development server if it's not already running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to &lt;code&gt;http://localhost:3000&lt;/code&gt; in your browser to view the updated header with the new styles applied.&lt;/p&gt;

&lt;p&gt;With these styling updates, your React application now has a polished header, setting a solid foundation for building out the rest of the skeleton loading screens and other features.&lt;/p&gt;

&lt;p&gt;Fetching Data&lt;/p&gt;

&lt;p&gt;We're going to use the MealDB API for our data fetching: &lt;a href="https://www.themealdb.com/api.php" rel="noopener noreferrer"&gt;https://www.themealdb.com/api.php&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In our &lt;code&gt;App.js&lt;/code&gt;, let's create a state to store our data when we fetch it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMeals&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;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initially, our &lt;code&gt;meals&lt;/code&gt; state will be &lt;code&gt;null&lt;/code&gt; because we don't have any meal data yet. However, when this component is rendered to the DOM, we need to fetch the data. To do this, we'll use the &lt;code&gt;useEffect&lt;/code&gt; hook, which runs automatically after the component has been rendered.&lt;/p&gt;

&lt;p&gt;Let's create a &lt;code&gt;useEffect&lt;/code&gt; and use a &lt;code&gt;setTimeout&lt;/code&gt; so that we can see the effect of the skeleton loader for a bit longer. Note that we wouldn't typically use a delay like this in a production application. Copy and paste the code below into the &lt;code&gt;App.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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;Home&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/Home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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;meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMeals&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;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// runs automatically after initial render&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;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://www.themealdb.com/api/json/v1/1/search.php?s=chicken&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;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;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="nf"&gt;setMeals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;


  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="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;"App"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Meal Recipes&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&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="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;"content"&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;Home&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;);&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;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to check if we have our meal results. Let's use conditional rendering in React to display our meal recipe results. Copy and paste the code below into the &lt;code&gt;Home.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Link&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-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Home&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMeals&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;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;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://www.themealdb.com/api/json/v1/1/search.php?s=chicken&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;meals&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="nf"&gt;setMeals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;meals&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="nx"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meals&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="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;


  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&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-gray-900 text-white min-h-screen"&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;"m-auto max-w-3xl flex flex-col items-center justify-center text-center"&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;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"meals"&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;"meals"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;meals&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
              &lt;span class="nx"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meals&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;meal&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;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"meal"&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;meal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;idMeal&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;Link&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`/MealInfo/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;meal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;idMeal&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="nt"&gt;img&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;"meal-img"&lt;/span&gt;
                      &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;meal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strMealThumb&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                      &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;meal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strMeal&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="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;"meal-info"&lt;/span&gt; &lt;span class="na"&gt;data-mealid&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;meal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;idMeal&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="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;meal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strMeal&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;h3&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="nc"&gt;Link&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;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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;}&lt;/span&gt;&lt;span class="dl"&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;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding React Router
&lt;/h2&gt;

&lt;p&gt;Since you're using &lt;code&gt;Link&lt;/code&gt; from &lt;code&gt;react-router-dom&lt;/code&gt;, we need to install &lt;code&gt;react-router-dom&lt;/code&gt; in your project. Follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your terminal or command prompt.&lt;/li&gt;
&lt;li&gt;Navigate to your project directory.&lt;/li&gt;
&lt;li&gt;Run the following command to install &lt;code&gt;react-router-dom&lt;/code&gt; using npm:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;react-router-dom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, if you're using Yarn, you can use this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add react-router-dom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Once the installation is complete, you can import the necessary components from &lt;code&gt;react-router-dom&lt;/code&gt; and start defining your routes in your &lt;code&gt;Home.js&lt;/code&gt; file.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Wrapping the App with BrowserRouter
&lt;/h3&gt;

&lt;p&gt;Let’s wrap our App in main.js with BrowserRouter from react-router-dom. This is because we're using Link from react-router-dom in our Home component, which is calling useContext. The context it is looking for is provided by BrowserRouter, but our app is not wrapped by a BrowserRouter. Your main.js should be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import { BrowserRouter } from 'react-router-dom'


ReactDOM.createRoot(document.getElementById("root")).render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;BrowserRouter&amp;gt;
      &amp;lt;App /&amp;gt;
    &amp;lt;/BrowserRouter&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;In conclusion, in Part One of our series, we've laid the groundwork for implementing skeleton loading screens in React applications. By setting up a basic React project, creating components, adding styles, and fetching data from an API, we've prepared the foundation for integrating skeleton loading screens into our application.&lt;/p&gt;

&lt;p&gt;In Part Two, we'll dive deeper into the implementation details of skeleton loading screens. We'll explore how to create reusable skeleton components, customize loading animations, and handle various loading scenarios efficiently. Click &lt;a href="https://dev.to/topeogunleye/part-two-creating-our-recipe-reusable-skeleton-component-cgj"&gt;here&lt;/a&gt; for Part Two, where we'll take our skeleton loading screens to the next level!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Supercharge Your React Development with Vite, ESLint, and Prettier in VSCode</title>
      <dc:creator>topeogunleye</dc:creator>
      <pubDate>Fri, 12 Apr 2024 02:57:34 +0000</pubDate>
      <link>https://dev.to/topeogunleye/building-a-modern-react-app-with-vite-eslint-and-prettier-in-vscode-13fj</link>
      <guid>https://dev.to/topeogunleye/building-a-modern-react-app-with-vite-eslint-and-prettier-in-vscode-13fj</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq581e2psd4zge6tmq0hf.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq581e2psd4zge6tmq0hf.jpg" alt="Silent Code, Loud Impact: The Web Dev Ninja Strikes Again! 🥷💻🌟"&gt;&lt;/a&gt;&lt;br&gt;
You can find the finished project at &lt;a href="https://github.com/topeogunleye/modern-react-app-vite-eslint-prettier" rel="noopener noreferrer"&gt;https://github.com/topeogunleye/modern-react-app-vite-eslint-prettier&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Boost your React projects by combining Vite’s fast development server, ESLint’s strong linting features, and Prettier’s consistent formatting. With these tools, your VSCode becomes a productivity powerhouse. As you read this article, you’ll learn how to set up Prettier and ESLint to automatically format your files when you save them, maintaining a polished codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Ensure Node.js and Yarn are installed on your computer. If they’re not already set up, visit the &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js official website&lt;/a&gt; to download and install Node.js, and visit the &lt;a href="https://classic.yarnpkg.com/en/docs/install" rel="noopener noreferrer"&gt;Yarn official website&lt;/a&gt; to download and install Yarn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Package Versions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Yarn: &lt;strong&gt;1.22.22&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Node: &lt;strong&gt;20.12.2&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;See full package.json on this &lt;a href="https://gist.github.com/topeogunleye/2fdfccd2ea17bcc40899fa047ea9a8f2" rel="noopener noreferrer"&gt;gist&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Initializing the Project with Vite
&lt;/h2&gt;

&lt;p&gt;To kick off our project, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a new project directory and initialize it:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-react-app
&lt;span class="nb"&gt;cd &lt;/span&gt;my-react-app
yarn init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install Vite with the React template:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn create vite my-react-app &lt;span class="nt"&gt;--template&lt;/span&gt; react
&lt;span class="nb"&gt;cd &lt;/span&gt;my-react-app
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 2: Installing ESLint
&lt;/h2&gt;

&lt;p&gt;ESLint is a powerful tool that statically analyzes your code to identify and fix problems quickly. It integrates seamlessly with most text editors and can be incorporated into your continuous integration pipeline for automated code quality checks.&lt;/p&gt;

&lt;p&gt;To install ESLint, run the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn create @eslint/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This command initializes ESLint in your project, guiding you through the configuration process to suit your coding style and requirements. You will see a series of prompts similar to this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? How would you like to use ESLint? …
  To check syntax only
▸ To check syntax and find problems

? What type of modules does your project use? …
▸ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

? Which framework does your project use? …
▸ React
  Vue.js
  None of these

? Does your project use TypeScript? …
▸ No
  Yes

? Where does your code run? …  (Press &amp;lt;space&amp;gt; to select, &amp;lt;a&amp;gt; to toggle all, &amp;lt;i&amp;gt; to invert selection)
✔ Browser
✔ Node

? Would you like to install them now? ‣ No / Yes
✔ Would you like to install them now? · Yes

? Which package manager do you want to use? …
▸ npm
  yarn
  pnpm
  bun
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Select the appropriate options based on your needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose "To check syntax and find problems" for comprehensive code quality checks.&lt;/li&gt;
&lt;li&gt;Select "JavaScript modules (import/export)" if you are using ES6 modules (ESM).&lt;/li&gt;
&lt;li&gt;Choose "React" as your framework.&lt;/li&gt;
&lt;li&gt;Specify whether your project uses TypeScript.&lt;/li&gt;
&lt;li&gt;Indicate where your code runs by selecting "Browser" and/or "Node" as applicable.&lt;/li&gt;
&lt;li&gt;Choose "Yes" to install the required dependencies.&lt;/li&gt;
&lt;li&gt;Select your preferred package manager (e.g., yarn).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This thorough step-by-step setup will configure ESLint to effectively lint your project's code according to your specific requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Installing the ESLint Plugin for VSCode
&lt;/h2&gt;

&lt;p&gt;Enhance your coding experience by integrating ESLint into VSCode. Follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open VSCode Extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access the Extensions view by clicking the VSCode sidebar’s square icon or pressing &lt;code&gt;Ctrl+Shift+X&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for ESLint:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type &lt;code&gt;ESLint&lt;/code&gt; into the search bar.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install the Plugin:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Find the ESLint plugin by Microsoft and click ‘Install’. This will help you maintain code quality and adhere to best practices directly within your editor.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By adding the ESLint plugin to VSCode, you can automatically lint and format your code as you write, ensuring consistency and readability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Setting Up Prettier
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install Prettier:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; prettier
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create and Configure &lt;code&gt;.prettierrc.json&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; .prettierrc.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Define your formatting preferences within &lt;code&gt;.prettierrc.json&lt;/code&gt;. For example, to use single quotes:&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"singleQuote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 5: Sync Prettier &amp;amp; ESLint
&lt;/h2&gt;

&lt;p&gt;To make Prettier and ESLint work together without issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install &lt;code&gt;eslint-config-prettier&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; eslint-config-prettier
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Update &lt;code&gt;.eslintrc.cjs&lt;/code&gt;:&lt;br&gt;
Add &lt;code&gt;eslint-config-prettier&lt;/code&gt; to the &lt;code&gt;extends&lt;/code&gt; array in your &lt;code&gt;.eslintrc.cjs&lt;/code&gt; file to ensure that Prettier’s formatting doesn’t conflict with ESLint rules:&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// other configs...&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;prettier&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="c1"&gt;// other settings...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Check for Conflicts:&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx eslint-config-prettier ./src/main.jsx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you see the message "No rules that are unnecessary or conflict with Prettier were found," it means that Prettier and ESLint are properly integrated.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 6: Integrating Prettier for Code Formatting
&lt;/h2&gt;

&lt;p&gt;To ensure consistent code style across your project, integrate Prettier by adding a format script to your &lt;code&gt;package.json&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vite"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc &amp;amp;&amp;amp; vite build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"preview"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vite preview"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"prettier --write &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;src/**/*.{ts,tsx,js,jsx,json,css}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Usage:&lt;br&gt;
Execute the command &lt;code&gt;yarn format&lt;/code&gt; to automatically format all files in the &lt;code&gt;src&lt;/code&gt; directory, including subdirectories. Prettier will apply formatting rules to TypeScript, JavaScript, JSON, and CSS files, ensuring a uniform coding style throughout your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Installing the Prettier Plugin for VSCode
&lt;/h2&gt;

&lt;p&gt;To streamline your development workflow, install the Prettier extension for Visual Studio Code. This will allow you to automatically format your code as you write, ensuring consistent style without manual effort.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open VSCode Extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Launch Visual Studio Code and navigate to the Extensions view by clicking on the Extensions icon in the Activity Bar on the side of the window, or by pressing &lt;code&gt;Ctrl+Shift+X&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Search for Prettier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the Extensions view, type &lt;code&gt;Prettier-Code Formatter&lt;/code&gt; in the search bar. Look for the official extension published by Prettier.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install Extension:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the &lt;code&gt;Install&lt;/code&gt; button to add the Prettier extension to your Visual Studio Code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Executing Code Formatting with Prettier
&lt;/h3&gt;

&lt;p&gt;To format your code using Prettier within Visual Studio Code, utilize the Command Palette for quickly accessing all available commands.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open Command Palette:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Press &lt;code&gt;Ctrl+Shift+P&lt;/code&gt; to open the Command Palette. This shortcut brings up a search bar where you can run various commands.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run Format Document:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type &lt;code&gt;Format Document&lt;/code&gt; into the Command Palette’s search bar. Select the command when it appears in the dropdown menu. This action will apply Prettier formatting to your currently open file.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Verify Formatting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After executing the command, check your code to ensure that Prettier has formatted it according to your project’s style guide.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Optional Settings: Customizing Prettier Behavior in VSCode
&lt;/h3&gt;

&lt;p&gt;To fine-tune how Prettier formats your code in Visual Studio Code, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Set Prettier as Default Formatter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;code&gt;File &amp;gt; Preferences &amp;gt; Settings&lt;/code&gt; (or &lt;code&gt;Code &amp;gt; Preferences &amp;gt; Settings&lt;/code&gt; on macOS), search for &lt;code&gt;Default Formatter&lt;/code&gt;, and select &lt;code&gt;Prettier-Code Formatter&lt;/code&gt; from the dropdown menu.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Enable Format On Save:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Still in Settings, find &lt;code&gt;Format On Save&lt;/code&gt; and check the box to have Prettier format your files each time you save.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Activate Format On Paste:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Look for &lt;code&gt;Format On Paste&lt;/code&gt; in the Settings and enable it to format content automatically when you paste it into your document.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Adopting Vite, ESLint, and Prettier in VSCode enhances our development with efficiency and quality. These tools help us maintain and scale projects, keeping us at the forefront of technology. As developers, we must continually evolve with the ever-changing tech landscape, and leveraging tools like Vite, ESLint, and Prettier helps us stay ahead of the curve. Thanks for exploring these tools with me. Happy coding!&lt;/p&gt;

&lt;p&gt;You can find the full app setup in this &lt;a href="https://github.com/topeogunleye/modern-react-app-vite-eslint-prettier" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
