<?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: Jumbo Daniel</title>
    <description>The latest articles on DEV Community by Jumbo Daniel (@jumbo02).</description>
    <link>https://dev.to/jumbo02</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%2F407706%2F53504b64-a7a6-4752-974b-c62389f3ca4c.png</url>
      <title>DEV Community: Jumbo Daniel</title>
      <link>https://dev.to/jumbo02</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jumbo02"/>
    <language>en</language>
    <item>
      <title>Filtering Nested Data in Tanstack Table</title>
      <dc:creator>Jumbo Daniel</dc:creator>
      <pubDate>Thu, 06 Mar 2025 13:57:32 +0000</pubDate>
      <link>https://dev.to/jumbo02/filtering-nested-data-in-tanstack-table-1011</link>
      <guid>https://dev.to/jumbo02/filtering-nested-data-in-tanstack-table-1011</guid>
      <description>&lt;p&gt;When working with TanStack Table, filtering over nested data, we are faced with a unique issue. About 9 out of 10 times, our data for tables comes directly from a backend API, and while the table’s default behavior is simple for flat structures, handling deeply nested properties works differently.&lt;br&gt;
⁠&lt;br&gt;
⁠Let's look through this code first&lt;br&gt;
⁠&lt;br&gt;
⁠Imagine we are fetching from our api, the goal is to populate our table with customers payment data&lt;br&gt;
We can write our type based on the response&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export type Payment = {
  id: string
  amount: number
  status: "pending" | "processing" | "success" | "failed"
  email: string
}

//then we define our columns 
export const columns: ColumnDef&amp;lt;Payment&amp;gt;[] = [
  {
    accessorKey: "status",
    header: "Status",
  },
  {
    accessorKey: "email",
    header: "Email",
  },
  {
    accessorKey: "amount",
    header: "Amount",
  },
];
We can write the ui using the table properties, and then add a search:⁠
         &amp;lt;Input
          placeholder="Filter nin status..."
          value={
            (table.getColumn("nin-status")?.getFilterValue() as string) ?? ""
          }
          onChange={(event) =&amp;gt;
            table.getColumn("nin-status")?.setFilterValue(event.target.value)
          }
          className="max-w-sm"
        /&amp;gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⁠Still simple and straightforward but our challenge lies in filtering over nested data &lt;br&gt;
Understanding Column IDs in TanStack Table&lt;br&gt;
By default, the column ID is determined as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;accessorKey: Uses the provided key directly as the ID. &lt;code&gt;{ accessorKey: "status", header: "Status" }&lt;/code&gt; // ID: "status"&lt;/li&gt;
&lt;li&gt;accessorFn: Derives the ID from the header (converted to lowercase, spaces replaced with underscores). &lt;code&gt;{accessorFn: (row) =&amp;gt; row.creator?.email header: "Creator Email" // ID: "creator_email"}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Explicit id: Uses the manually provided ID. &lt;code&gt;{ id: "nin_status", header: "NIN Status" }&lt;/code&gt;// ID: "nin_status"
So accessorKey &amp;gt; accessorFn &amp;gt; id&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;accessorKey: Uses the provided key as the ID.&lt;/li&gt;
&lt;li&gt;accessorFn: Defaults to deriving the ID from the header (typically lowercased with underscores) unless an ID is explicitly provided.&lt;/li&gt;
&lt;li&gt;Explicit id: Always uses the provided ID, giving you full control.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  The Challenge: Nested Data
&lt;/h2&gt;

&lt;p&gt;When fetching data from a backend, you might deal with nested objects. For example, consider the following type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export type CustomerType = {
  id: number;
  token: string;
  name: string;
  created_at: string;
  status: string;
  creator?: {
    email: string | null;
    phone_number: string | null;
    bvn_verification_status: string | null;
    nin_verification_status: string | null;
    paystack_wallet_total: string | null;
    first_name: string | null;
    last_name: string | null;
  } | null;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When filtering nested data in TanStack Table, two things to look out for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Column IDs ≠ Nested Paths: Filters rely on column IDs, which don’t automatically resolve nested paths like creator.email.&lt;/li&gt;
&lt;li&gt;Dot Notation Traps: Using accessorKey: "creator.email" displays data but breaks filtering (searches for literal row["creator.email"]).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1. Dot Notation Accessor (Simple but Limited)&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;{
  accessorKey: "creator.email", // Auto-flattens data
  header: "Creator Email",
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We might be tempted to use this solution but it doesnt work as well. While dot notation in accessorKey (e.g., "creator.email") displays nested data correctly, TanStack Table’s default filtering doesn’t automatically traverse nested objects. The filter looks for literal top-level keys like "creator.email" in your data (which don’t exist), rather than following the nested path creator → email. You’d need a custom filterFn to handle this (which isn’t set up by default).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Accessor Function + Explicit ID (Recommended)&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; {
    id: "nin-status",
    accessorFn: (row) =&amp;gt; row.creator?.nin_verification_status ?? "",
    header: "Status",
    cell: ({ row }) =&amp;gt; {
      return &amp;lt;div&amp;gt;{row.original.creator?.nin_verification_status}&amp;lt;/div&amp;gt;;
    },
  },
//then filter here
        &amp;lt;Input
          placeholder="Filter nin status..."
          value={
            (table.getColumn("nin-status")?.getFilterValue() as string) ?? ""
          }
          onChange={(event) =&amp;gt;
            table.getColumn("nin-status")?.setFilterValue(event.target.value)
          }
          className="max-w-sm"
        /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Explicit ID (Simplest)&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;{
    accessorKey: "creator.first_name",
    id:"firstname"
    header: "Firstname",
  },
//then filter here 
        &amp;lt;Input
          placeholder="Filter nin status..."
          value={
            (table.getColumn("firstname")?.getFilterValue() as string) ?? ""
          }
          onChange={(event) =&amp;gt;
            table.getColumn("firstname")?.setFilterValue(event.target.value)
          }
          className="max-w-sm"
        /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Filtering nested data in TanStack Table requires understanding how column IDs map to your data structure. While the accessorKey dot notation might seem tempting for nested properties, its filtering limitations make it unsuitable for real-world use cases.&lt;br&gt;
The recommended approach combines explicit column IDs with accessor functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use id to create predictable filter bindings&lt;/li&gt;
&lt;li&gt;Leverage accessorFn to safely navigate nested objects&lt;/li&gt;
&lt;li&gt;Maintain type safety with TypeScript path helpers
For simple cases, explicit IDs with accessorKey provide a quick solution, but complex nested data demands the robustness of accessorFn. Remember: your filter's effectiveness depends on how well your column IDs align with your data access patterns.
In my next post, we'll explain how I use dynamic filtering architectures for my tables and how we can use them with nested datasets.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Adding Spotify Now Playing to Your React App</title>
      <dc:creator>Jumbo Daniel</dc:creator>
      <pubDate>Tue, 30 Jul 2024 10:06:02 +0000</pubDate>
      <link>https://dev.to/jumbo02/adding-spotify-now-playing-to-your-react-app-39f0</link>
      <guid>https://dev.to/jumbo02/adding-spotify-now-playing-to-your-react-app-39f0</guid>
      <description>&lt;p&gt;I was trying to build a currently playing Spotify feature recently, but still, I didn't want to do this the "traditional" way of getting my keys, fetching the access token, and then adding the respective APIs...... It is way too tedious, I searched around, and then I found this React Package Now Playing. &lt;br&gt;
Shout out to bolajiolajide and lilpolymath. It is lightweight and easy to understand and reduces a lot of boilerplate code compared to using the APIs ourselves. Let's get started. There are three steps: creating the application on the Spotify developer dashboard and authentication.&lt;/p&gt;

&lt;p&gt;⁠Note that in this tutorial I'll assume that you have a React app running already, If not you can run:&lt;br&gt;
&lt;code&gt;npx create-next-app@latest&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating an Application
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visit the Spotify Developer Dashboard (&lt;a href="https://developer.spotify.com/dashboard/" rel="noopener noreferrer"&gt;https://developer.spotify.com/dashboard/&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Log in with your Spotify account or create one if needed.&lt;/li&gt;
&lt;li&gt;Click the "Create an App" button.&lt;/li&gt;
&lt;li&gt;Enter a name and description for your application.&lt;/li&gt;
&lt;li&gt;Click "Create" to generate your app.&lt;/li&gt;
&lt;li&gt;On your app's page, find your Client ID and Client Secret(copy them; you'll need them soon).&lt;/li&gt;
&lt;li&gt;Add &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; as your Redirect URIs in the app settings.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Authenticating the App
&lt;/h2&gt;

&lt;p&gt;We will use &lt;a href="https://developer.spotify.com/documentation/web-api/concepts/authorization#authorization-code-flow" rel="noopener noreferrer"&gt;Authorization Code Flow&lt;/a&gt; since we need to authenticate our users once. There are different ways of authenticating Spotify apps, more on that &lt;a href="https://developer.spotify.com/documentation/web-api/concepts/authorization" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
⁠Firstly we can request authorization for our apps by adding our scopes, client_id, and redirect_uri to this URL.&lt;br&gt;
&lt;strong&gt;Tip:&lt;/strong&gt; The now-playing package requires these two scopes user-read-currently-playing and user-read-recently-played so be sure to add them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://accounts.spotify.com/authorize?client_id=e2c197e9......d3f35ee5&amp;amp;response_type=code&amp;amp;redirect_uri=http://localhost:3000&amp;amp;scope=user-read-currently-playing user-read-recently-played
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use Postman to generate the URL, here is a &lt;a href="https://reine.hashnode.dev/how-to-connect-your-react-vitejs-app-to-spotifys-api#heading-authenticating-with-postman-get-refresh-token" rel="noopener noreferrer"&gt;blogpost&lt;/a&gt; that uses Postman&lt;br&gt;
⁠Note that the redirect_uri here has to be the same as the one you added to your Spotify dashboard.&lt;br&gt;
After adding your client_id and scopes, paste the URL into your browser. You'll need to authorize your app afterwards it will redirect you to your app(the redirect_uri you specified). In the URL there is a code parameter, copy it out.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:3000/?code=AQBKvAjSrH............7o7wZ6g6fENyVIxfUqNF&lt;/code&gt;&lt;br&gt;
Next up, you will have to generate the refresh_token, we will have to generate the base64 string from the client_id and client_secret. You can use any of these tools &lt;a href="https://www.base64encode.org/" rel="noopener noreferrer"&gt;⁠Base 64 Encode&lt;/a&gt;, &lt;a href="https://codepen.io/xdesro/pen/QWyEWxB" rel="noopener noreferrer"&gt;Henry's Codepen&lt;/a&gt;. With the format client_id:client_secret.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl.exe -H 'Authorization: Basic &amp;lt;Base 64 encoded client_id:client_secret&amp;gt;' -X POST https://accounts.spotify.com/api/token -d code=&amp;lt;code&amp;gt; -d redirect_uri=http://localhost:3000 -d grant_type=authorization_code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tip: remove the .exe if you are using a mac&lt;br&gt;
This should return a JSON with the refresh and access token, copy the refresh token(it is valid until revoked access)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "access_token": "....",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": ".....",
  "scope": "user-read-currently-playing user-read-recently-played"
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using the Now Playing Package
&lt;/h2&gt;

&lt;p&gt;Install the package&lt;/p&gt;

&lt;p&gt;&lt;code&gt;⁠pnpm i @bolajiolajide/now-playing&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add your refresh_token, client_id, client_secret to your env.local file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEXT_PUBLIC_SPOTIFY_CLIENT_ID= 
NEXT_PUBLIC_SPOTIFY_CLIENT_SECRET= 
NEXT_PUBLIC_SPOTIFY_REFRESH_TOKEN= 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: In this tutorial, I'm using NEXT_PUBLIC prefix for the Spotify credentials. It's worth noting, this is more of an experimental setup for me to test Next Export later on. Here's the deal: using NEXT_PUBLIC on these variables isn't exactly best practice. It's like leaving your house keys under the doormat - not the safest move. You're exposing your Spotify API credentials to the client side, which is risky. If you haven't worked with environment variables in Next before, &lt;a href="https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables" rel="noopener noreferrer"&gt;read this first&lt;/a&gt;&lt;br&gt;
Instead, you might want to check out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API routes&lt;/li&gt;
&lt;li&gt;Server-side props&lt;/li&gt;
&lt;li&gt;Serverside components(App Router)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create a Now Playing component, import the now-playing package, and write this code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NowPlaying, Providers } from "@bolajiolajide/now-playing";

export async function SpotifyPlaying() {
  const client_id = process.env.NEXT_PUBLIC_SPOTIFY_CLIENT_ID;
  const client_secret = process.env.NEXT_PUBLIC_SPOTIFY_CLIENT_SECRET;
  const refresh_token = process.env.NEXT_PUBLIC_SPOTIFY_REFRESH_TOKEN;
  const np = new NowPlaying(Providers.SPOTIFY, {
    useCache: true, // (optional) default is true
    cacheDuration: 30000, // (optional) in milliseconds
    streamerArgs: {
      clientId: client_id,
      clientSecret: client_secret,
      refreshToken: refresh_token,
    },

  });
  const Playing = await np.fetchCurrentlyPlayingOrLastPlayed();
  return Playing;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Afterward, the function returns the recently played or currently playing song already formatted to return title,artiste, image_url&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "is_playing": true,
    "title": "Doomsday",
    "artiste": "MF DOOM, Pebbles The Invisible Girl",
    "image_url": "https://i.scdn.co/image/ab67616d0000b2736ce90ec627a0198a8efd127f",
    "preview_url": "https://p.scdn.co/mp3-preview/245f1806f86179d9707001d803c94f7e33d07e0b?cid=e2c197e9a1904790b76c1d07d3f35ee5",
    "url": "https://open.spotify.com/track/7EQvdUJqZ2i7SWvSB2VqGA"
}  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Feel free to style it however you like&lt;/p&gt;

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

&lt;p&gt;This blog post isn't opinionated or one-size-fits-all of building a Now Playing component. I've shown you one way to do it, but there's a whole lot of possibilities out there. You might want to explore using API routes to keep your Spotify credentials safe on the server side. Or maybe you want to turn it up a notch and try out TanStack Query and handle loading, fetching and caching. These methods could give you better performance and security compared to our direct approach. The key is to find what works best for your project and coding style.&lt;/p&gt;

&lt;p&gt;⁠A big shoutout to Lee Rob for his fantastic &lt;a href="https://leerob.io/blog/spotify-api-nextjs#using-spotifys-api" rel="noopener noreferrer"&gt;blogpost&lt;/a&gt;, which heavily influenced the setup in this tutorial.&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>spotify</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to Setup Path Alias Vite + React</title>
      <dc:creator>Jumbo Daniel</dc:creator>
      <pubDate>Sat, 27 Jul 2024 13:21:08 +0000</pubDate>
      <link>https://dev.to/jumbo02/how-to-setup-path-alias-vite-react-5426</link>
      <guid>https://dev.to/jumbo02/how-to-setup-path-alias-vite-react-5426</guid>
      <description>&lt;h2&gt;
  
  
  Why Path Aliases?
&lt;/h2&gt;

&lt;p&gt;Path Aliases in Vite allow us to use custom paths to our project directory when importing our modules.&lt;br&gt;
⁠Say we are working on a React project, in our cards component we want to import about three different components to build our card. Let's say a button, header, image. &lt;/p&gt;
&lt;h2&gt;
  
  
  We can write it as this
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Button from '../../components/Button'
import Header from '../../components/ui/Header'
import Image from '../../components/Image'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;⁠&lt;br&gt;
It looks good for now, but think of when we want to refactor or improve our component and have to import about 5 or 6 more components. Then it starts to get messy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Button from '../../components/Button'
import Header from '../../components/ui/Header'
import Image from '../../components/Image'
import Panel from "../../components/Dashboard/Panel";
import Input from "../../components/Forms/Input";
import Submit from "../../components/Forms/Submit"

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

&lt;/div&gt;



&lt;p&gt;That's where path imports become useful, they make our import statements cleaner and more manageable. With Path Alias what we have above becomes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Button from '@/src/components/Button'
import Header from '@/src/components/ui/Header'
import Image from '@/src/components/Image'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For those that don't use auto import, you do not need to remember how far the directory is from the component you are working on. It just simplifies code organization when you need to move files or refactor your project structure, you won't have to update numerous relative import paths across your codebase&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Path Alias to Your Project
&lt;/h2&gt;

&lt;p&gt;First, you need to install React + Vite&lt;br&gt;
&lt;code&gt;⁠pnpm create vite setup-path-alias --template react&lt;/code&gt;&lt;br&gt;
Next, you will go into the project directory you just created then run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd setup-path-alias                                                                                                                                         pnpm install 
pnpm run dev    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I used the shortcut to create the Vite app with the template, you can use any other method you prefer. So as long you create the app. I also used pnpm but you can use your preferred package manager (npm, yarn, bun....).&lt;/p&gt;

&lt;p&gt;After that is completed, the Vite project directory looks like this&lt;br&gt;
⁠├── public&lt;br&gt;
├── src/&lt;br&gt;
│   └── components/&lt;br&gt;
│       └── HelloWorld.jsx&lt;br&gt;
├── .gitignore&lt;br&gt;
├── index.html&lt;br&gt;
├── package.json&lt;br&gt;
├── README.md&lt;br&gt;
└── vite.config.js&lt;/p&gt;

&lt;p&gt;⁠Now go to vite.config.js file, this is how the file should look by default&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will install Path module, we use it to use the path.resolve() method, which helps create absolute paths.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pnpm i path&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we will resolve the path alias in our vite.config.js file and the result should look 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 { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import path from "path";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    }
  },
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring VS Code IntelliSense
&lt;/h2&gt;

&lt;p&gt;To ensure VS Code recognizes your aliases, create or update jsconfig.json in your project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "compilerOptions": {
      "paths": {
        "@/*": [
          "./src/*"
        ]
      }
    }
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can update our imports from&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Button from '../../components/Button'
//to this
⁠import Button from '@/src/components/Button'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that we can make the path alias like this, and resolve as many paths as we want, then update our intellisense. I left my own simpler since my project is small and by default, the src folder contains all the project files, then I can just point it to src but when you use the components folder a lot of times in your code you can just add it to the path alias to keep your imports clean. Then again it is advised to avoid the overuse of aliases: because while they can simplify imports, overusing them can make your code less intuitive for new team members. Use aliases for common, frequently accessed directories.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;⁠    alias: {
      '@': path.resolve(__dirname, './src'),
      '@components': path.resolve(__dirname, './src/components'),
  },

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Potential Issues and How to Avoid Them
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Circular Dependencies: Be cautious when using aliases to avoid creating circular dependencies. Always structure your imports in a way that maintains a clear hierarchy.&lt;/li&gt;
&lt;li&gt;Overuse of Aliases: While aliases can simplify imports, overusing them can make your code less intuitive for new team members. Use aliases for common, frequently accessed directories.&lt;/li&gt;
&lt;li&gt;Inconsistent Naming: Stick to a consistent naming convention for your aliases across the project. For example, always use the '@' prefix for aliased paths.&lt;/li&gt;
&lt;li&gt;Forgetting to Update jsconfig.json: If you add new aliases in vite.config.js, remember to update jsconfig.json as well to maintain IDE support.&lt;/li&gt;
&lt;li&gt;Alias Conflicts: Ensure your alias names don't conflict with npm package names or browser globals to avoid confusion and potential errors.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thanks for reading&lt;/p&gt;

</description>
      <category>vite</category>
      <category>react</category>
      <category>javascript</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Migrating from Create React App(CRA) to NextJS (Pages Router)</title>
      <dc:creator>Jumbo Daniel</dc:creator>
      <pubDate>Sat, 11 May 2024 07:09:15 +0000</pubDate>
      <link>https://dev.to/jumbo02/migrating-from-create-react-appcra-to-nextjs-pages-router-697</link>
      <guid>https://dev.to/jumbo02/migrating-from-create-react-appcra-to-nextjs-pages-router-697</guid>
      <description>&lt;h2&gt;
  
  
  This blog post talks about the migration process from Create React App (CRA) to Next.js
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Understanding CRA
&lt;/h2&gt;

&lt;p&gt;Create React App (CRA) is a tool that helps set up a modern React development environment with minimal configuration. It provides a preconfigured environment with a development server, bundling, linting, and other useful features, making it easy to get started with React projects quickly.&lt;/p&gt;

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

&lt;p&gt;Next.js is a React framework that enables server-side rendering, static site generation, file-based routing, and more out-of-the-box. It provides a robust foundation for building production-ready React applications with enhanced performance, SEO, and developer experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Next.js&lt;/th&gt;
&lt;th&gt;Create React App&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server-Side Rendering&lt;/td&gt;
&lt;td&gt;Built-in support&lt;/td&gt;
&lt;td&gt;Not supported out of the box&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Static Site Generation&lt;/td&gt;
&lt;td&gt;Built-in support&lt;/td&gt;
&lt;td&gt;Not supported out of the box&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File-based Routing&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No (requires a routing library like React Router)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code Splitting&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;td&gt;Requires additional configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production Build&lt;/td&gt;
&lt;td&gt;Optimized for performance&lt;/td&gt;
&lt;td&gt;Basic production build&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Supports various hosting platforms&lt;/td&gt;
&lt;td&gt;Requires additional configuration for deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Developer Experience&lt;/td&gt;
&lt;td&gt;Enhanced with features like Fast Refresh&lt;/td&gt;
&lt;td&gt;Basic Features&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why Switch to Next.js?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Better Performance&lt;/strong&gt;: Next.js provides server-side rendering and static site generation out of the box, which can significantly improve the performance and SEO of your web applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Routing&lt;/strong&gt;: Next.js uses a file-based routing system, which makes it easier to reason about your application's structure and removes the need for complex routing setups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Developer Experience&lt;/strong&gt;: Next.js offers features like Fast Refresh, which improves the development experience by providing near-instant updates to your application without losing state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimized for Production&lt;/strong&gt;: Next.js builds are optimized for production, with features like automatic code splitting and bundling, ensuring better performance and smaller bundle sizes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ecosystem and Community&lt;/strong&gt;: Next.js has a thriving ecosystem and a large community, providing access to a wide range of third-party libraries, tools, and resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future-Proof&lt;/strong&gt;: Next.js is actively maintained and continuously updated, ensuring that your applications remain compatible with the latest React features and best practices.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;An existing CRA project&lt;/li&gt;
&lt;li&gt;Basic understanding of React and JavaScript&lt;/li&gt;
&lt;li&gt;Node installed on your system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Are you looking to take your React application to the next level? If you've been using Create React App (CRA) and are interested in exploring the powerful features of Next.js, this blog post will guide you through the migration process step-by-step. Next.js offers server-side rendering, static site generation, file-based routing, and more, allowing you to build high-performance, SEO-friendly, and scalable web applications.&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Start the development server
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open your CRA project in your preferred code editor.&lt;/li&gt;
&lt;li&gt;In the terminal, navigate to your project directory.&lt;/li&gt;
&lt;li&gt;Run the following command to start the development server:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;p&gt;(Note: use the package manager you have set up on your project already...)&lt;/p&gt;

&lt;p&gt;This will ensure that your CRA application is running correctly before we begin the migration process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Uninstall the development script
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open your &lt;code&gt;package.json&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Remove the &lt;code&gt;react-scripts&lt;/code&gt; dependency from the &lt;code&gt;dependencies&lt;/code&gt; section.&lt;/li&gt;
&lt;li&gt;Remove the following scripts from the &lt;code&gt;scripts&lt;/code&gt; section:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Install Next.js
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create the Next.js Configuration File:
&lt;/h3&gt;

&lt;p&gt;Next.js provides a configuration file where you can customize various settings for your application. Create a new file called &lt;code&gt;next.config.js&lt;/code&gt; in the root directory of your project with the following content:&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="cm"&gt;/** @type {import('next').NextConfig} */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;reactStrictMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="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="nx"&gt;nextConfig&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;Or&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="cm"&gt;/** @type {import('next').NextConfig} */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;export&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Outputs a Single-Page Application (SPA).&lt;/span&gt;
  &lt;span class="na"&gt;distDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dist&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Changes the build output directory to `./dist/`.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should note that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you want to enable React's strict mode and use the default Next.js behavior (server-rendered application with client-side hydration), you would use the first snippet.&lt;/li&gt;
&lt;li&gt;If you want to generate a static Single-Page Application (SPA) and change the output directory for the built files, you would use the second snippet. The configuration sets up Next.js to generate a Single-Page Application (SPA) and changes the build output directory to &lt;code&gt;./dist/&lt;/code&gt;. You can modify these settings based on your preferences.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The decision should be based on whether you need a server-rendered application or a fully client-side rendered SPA, and whether you want to change the output directory for the built files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Update Typescript Config File (optional)
&lt;/h3&gt;

&lt;p&gt;If you're using TypeScript, update your &lt;code&gt;tsconfig.json&lt;/code&gt; file to make it compatible with Next.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compilerOptions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"es5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dom.iterable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esnext"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allowJs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"skipLibCheck"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"forceConsistentCasingInFileNames"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"noEmit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"esModuleInterop"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"esnext"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"moduleResolution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"resolveJsonModule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"isolatedModules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jsx"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"preserve"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"incremental"&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;span class="nl"&gt;"include"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"next-env.d.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"**/*.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"**/*.tsx"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exclude"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"node_modules"&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;Note: If you're not using TypeScript, you can skip this step. And Remember you can always add typescript to your Next.js project by just adding a new file with &lt;code&gt;.ts&lt;/code&gt;, &lt;code&gt;.tsx&lt;/code&gt; file extension, and it will be installed automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Remove React Router
&lt;/h3&gt;

&lt;p&gt;If you were using React Router in your CRA project, you'll need to remove it since Next.js has built-in file-based routing. Simply uninstall the &lt;code&gt;react-router-dom&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm uninstall react-router-dom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Create the Root Directory (Pages)
&lt;/h3&gt;

&lt;p&gt;Next.js uses a file-based routing system, where each file in the &lt;code&gt;pages&lt;/code&gt; directory represents a route in your application. Create a new directory called &lt;code&gt;pages&lt;/code&gt; in the root of your project, and add an &lt;code&gt;index.js&lt;/code&gt; or &lt;code&gt;index.tsx&lt;/code&gt; file inside it. This file will serve as the entry point for your application. Also add this &lt;code&gt;_app.jsx&lt;/code&gt; file if you are using JavaScript or &lt;code&gt;_app.tsx&lt;/code&gt; for TypeScript.&lt;/p&gt;

&lt;p&gt;_app.jsx&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&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="nc"&gt;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&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;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;_app.tsx&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppProps&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;next/app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;AppProps&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="nc"&gt;Component&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&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;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For styles, I'll be using Tailwind CSS with Next.js (if you set it up already in CRA you can skip this step as it already works the same way). If you want to set up Tailwind CSS with Next.js, follow the official guide: &lt;a href="https://tailwindcss.com/docs/guides/nextjs"&gt;https://tailwindcss.com/docs/guides/nextjs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: If you want to use regular CSS with Next.js, you can import CSS files directly into your components with CSS modules or create a global CSS file in the &lt;code&gt;styles&lt;/code&gt; directory and import it in your &lt;code&gt;_app.tsx&lt;/code&gt;/&lt;code&gt;_app.jsx&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Update Image Imports
&lt;/h3&gt;

&lt;p&gt;Next.js handles static image imports differently from CRA. Use these steps to update your image imports.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert absolute import paths for images imported from &lt;code&gt;/public&lt;/code&gt; into relative imports:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;logo&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;/logo.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="c1"&gt;// After&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;logo&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;../public/logo.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Pass the &lt;code&gt;image.src&lt;/code&gt; property instead of the whole image object to your &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag:
&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="c1"&gt;// Before&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;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;logo&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// After&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;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;logo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="si"&gt;}&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;Alternatively, you can reference the public path/URL for the image file based on the filename. For example, &lt;code&gt;public/logo.png&lt;/code&gt; will serve the image at &lt;code&gt;/logo.png&lt;/code&gt; for your application, which would be the &lt;code&gt;src&lt;/code&gt; value.&lt;/p&gt;

&lt;p&gt;The benefit of using the Next.js &lt;code&gt;Image&lt;/code&gt; component is that it automatically optimizes images for performance, including lazy loading and resizing images on the fly. This can lead to significant improvements in page load times and overall user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: Migrate the Environment Variables
&lt;/h3&gt;

&lt;p&gt;Next.js has an inbuilt support for &lt;code&gt;.env&lt;/code&gt; environment variables similar to CRA. The major difference is the prefix used to expose environment variables on the client side. Change all environment variables with the &lt;code&gt;REACT_APP_&lt;/code&gt; prefix to &lt;code&gt;NEXT_PUBLIC_&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8: Update Scripts in package.json
&lt;/h3&gt;

&lt;p&gt;You should now be able to run your application to test if you've successfully migrated to Next.js. Before that, you need to update your scripts in your &lt;code&gt;package.json&lt;/code&gt; with Next.js related commands, and add &lt;code&gt;.next&lt;/code&gt;, next-env.d.ts, and dist to your .gitignore file:&lt;/p&gt;

&lt;p&gt;package.json&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next start"&lt;/span&gt;&lt;span class="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;.gitignore&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.next
next-env.d.ts
dist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run you can start the development server using your command (I'm using)&lt;code&gt;npm run dev&lt;/code&gt;, and open &lt;code&gt;http://localhost:3000&lt;/code&gt;. You should see your application now running on Next.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clean Up:
&lt;/h3&gt;

&lt;p&gt;Finally, you can clean up your codebase from Create React App-related files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete &lt;code&gt;public/index.html&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Delete the &lt;code&gt;reportWebVitals&lt;/code&gt; setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Congratulations! You've successfully migrated your Create React App project to Next.js. With this migration, you can now take advantage of Next.js's powerful features, such as server-side rendering, static site generation, file-based routing, and more, enabling you to build high-performance, SEO-friendly, and scalable web applications.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>createreactapp</category>
      <category>react</category>
    </item>
    <item>
      <title>How to fix: error: 'invalid path' When working with Git on Windows.</title>
      <dc:creator>Jumbo Daniel</dc:creator>
      <pubDate>Sun, 25 Jun 2023 20:32:28 +0000</pubDate>
      <link>https://dev.to/jumbo02/how-to-fix-error-invalid-path-when-working-with-git-on-windows-16kf</link>
      <guid>https://dev.to/jumbo02/how-to-fix-error-invalid-path-when-working-with-git-on-windows-16kf</guid>
      <description>&lt;p&gt;I was trying to clone a repository from gitbucket client when I got this error on my PC&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git -c filter.lfs.smudge= -c filter.lfs.required=false -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks clone --branch master https://JumboDaniel@bitbucket.org/fedacash-dev/fedhagap-web-ui.git C:\Users\hp\Documents\HTML\Jobs\Fedha
Cloning into 'C:\Users\hp\Documents\HTML\Jobs\Fedha\...
error: invalid path 'src/Assets/fonts/TTF/THICCCBOI-Black.ttf:Zone.Identifier'
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry with 'git restore --source=HEAD :/'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I tried working my way around the issues; I even tried deleting the 'THICCCBOI-Black.ttf' file from the gitbucket repo, but this didn't solve the issue.&lt;br&gt;
After hours of searching through the internet, I found the cause of the error:&lt;br&gt;
The Git cloning of a repository fails on Windows with an "invalid path" error because the Windows OS reserves some filenames; hence, a file name may be legal in Linux or Mac (in my case) but illegal in Windows.&lt;/p&gt;

&lt;p&gt;**&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution:
&lt;/h2&gt;

&lt;p&gt;**&lt;br&gt;
Whilst this may workaround the issue, care should be taken as the default for a Windows client was set to core.protectNTFS=true to close a potential security issue CVE-2019-1353 as described here.&lt;/p&gt;

&lt;p&gt;Depending on the filename, you can configure Git to ignore the NTFS naming may fix the issue.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git config --global core.protectNTFS false&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Turning off protectNTFS will stop Git from complaining about files that have a base name that is reserved but will not prevent an error if the filename is one of the reserved names.&lt;/p&gt;

&lt;p&gt;The best solution is to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identify the offending file(s) mentioned in the error message, such as ('src/Assets/fonts/TTF/THICCCBOI-Black.ttf:Zone.Identifier') as in my case.&lt;/li&gt;
&lt;li&gt;Rename the file(s) to something that does not conflict with any reserved names. For example, I can rename it to 'THICCCBOI-Black-Font.ttf'.
NB. Check windows file naming documentation &lt;a href="https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Update the reference to the renamed file(s) in your code or configuration, if necessary.&lt;/li&gt;
&lt;li&gt;Commit the changes to the repository.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Reference:&lt;a href="https://confluence.atlassian.com/bitbucketserverkb/error-invalid-path-during-git-clone-to-windows-client-1085186345.html"&gt;Link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>help</category>
      <category>git</category>
      <category>window</category>
    </item>
    <item>
      <title>How to fix "Remote Host Identification Has Changed" Issue with GitHub and Git</title>
      <dc:creator>Jumbo Daniel</dc:creator>
      <pubDate>Fri, 16 Jun 2023 04:07:39 +0000</pubDate>
      <link>https://dev.to/jumbo02/how-to-fix-remote-host-identification-has-changed-issue-with-github-and-git-fa1</link>
      <guid>https://dev.to/jumbo02/how-to-fix-remote-host-identification-has-changed-issue-with-github-and-git-fa1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;Git and GitHub are being used more and more frequently by developers to collaborate on projects, thus seeing different error messages is unavoidable. The error "Remote Host Identification Has Changed" is one error that can be annoying.&lt;/p&gt;

&lt;p&gt;In this blog post, we will examine the reasons for this problem and offer detailed steps on how to successfully resolve it when using Git CLI &amp;amp; GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Causes of the Error:
&lt;/h2&gt;

&lt;p&gt;The "Remote Host Identification Has Changed" error occurs when the fingerprint of the remote host (GitHub) you are connecting to has changed. There are a few common causes for this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server Changes: GitHub might update its server infrastructure, leading to changes in host fingerprints.&lt;/li&gt;
&lt;li&gt;Security Updates: GitHub periodically enhances its security measures, which can result in altered fingerprints.&lt;/li&gt;
&lt;li&gt;Man-in-the-Middle Attacks: In rare cases, this error can indicate an unauthorized entity intercepting your connection, posing a security risk.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to Fix the Error:
&lt;/h2&gt;

&lt;p&gt;To fix the "Remote Host Identification Has Changed" error, follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Clear Old SSH Fingerprints: Remove the outdated SSH fingerprints stored on your local machine. Use the following command to delete the relevant line from your known_hosts file:&lt;br&gt;
&lt;code&gt;ssh-keygen -R github.com&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Establish a new connection to GitHub to update the SSH known_hosts file with the new fingerprint. You can do this simply by attempting make a connection the a remote repository using SSH e.g push, pull, clone. The updated fingerprint will be automatically added.&lt;br&gt;
&lt;code&gt;The authenticity of host 'github.com (20.201.28.151)' can't be established.&lt;br&gt;
ED25519 key fingerprint is SHA256:br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ.&lt;br&gt;
This key is not known by any other names&lt;br&gt;
Are you sure you want to continue connecting (yes/no/[fingerprint])?&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify the New Fingerprint: After updating the SSH known_hosts file, verify the authenticity of the new fingerprint. GitHub provides instructions on how to verify fingerprints for different operating systems.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure it matches one of &lt;a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints"&gt;GitHub's public key fingerprints:&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SHA256:uNiVztksCsDhcc0u9e8BujQXVUpKZIDTMczCvj3tD2s (RSA)&lt;/li&gt;
&lt;li&gt;SHA256:br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ (DSA - deprecated)&lt;/li&gt;
&lt;li&gt;SHA256:p2QAMXNIC1TJYWeIOttrVc98/R1BUFWu3/LiyKgUfQM (ECDSA)&lt;/li&gt;
&lt;li&gt;SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU (Ed25519)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Avoiding the Error:
&lt;/h2&gt;

&lt;p&gt;To prevent encountering the "Remote Host Identification Has Changed" error in the future, consider these practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Regularly Update Your SSH Known Hosts: Periodically updating the SSH known_hosts file ensures that you have the most up-to-date fingerprints stored locally.&lt;/li&gt;
&lt;li&gt;Enable Two-Factor Authentication (2FA): Enabling 2FA adds an extra layer of security to your GitHub account, reducing the risk of unauthorized access.&lt;/li&gt;
&lt;li&gt;Stay Informed: Keep track of GitHub announcements and updates to stay informed about any changes that may affect host fingerprints.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The "Remote Host Identification Has Changed" error in GitHub can be resolved by understanding its causes and following the provided steps to fix it. Additionally, adopting preventive measures like regularly updating your SSH known_hosts file and staying informed about GitHub changes will help you avoid this error in the future. By mastering these troubleshooting techniques, you can ensure secure and uninterrupted collaboration on your Git projects with GitHub.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>git</category>
      <category>github</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Upgrading React Router From V5 to V6</title>
      <dc:creator>Jumbo Daniel</dc:creator>
      <pubDate>Sun, 08 May 2022 12:44:11 +0000</pubDate>
      <link>https://dev.to/jumbo02/upgrading-react-router-from-v5-to-v6-4286</link>
      <guid>https://dev.to/jumbo02/upgrading-react-router-from-v5-to-v6-4286</guid>
      <description>&lt;p&gt;React Router version 6 was released some months it is really important because React Router is one of the most used  React packages.&lt;/p&gt;

&lt;p&gt;React itself doesn't come with a router package so majority of React projects from small single page apps to big organizations use React Router.&lt;/p&gt;

&lt;p&gt;Some weeks ago while I was trying to work on an old project I ran into an error  when I updated my development packages because of my React Router update that caused breaking changes. I tried going through the documentation but sometimes you know they can be long and tedious, so I decided to write this post to help anyone who is also trying to update their project.&lt;/p&gt;

&lt;p&gt;In the end, it’s quite simple to upgrade and not much has changed, just little code difference. Version 6 is a lot better and easier to understand than version 5, if you can upgrade, you should.&lt;/p&gt;

&lt;p&gt;So first you can open your old project in vscode and install react-router version 6, do this by running npm install react-router-dom@6 which ensures that you install the latest version 6 and that’s what we can do here:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install react-router-dom@6&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When you get react-router version 6 installed. Try running npm start in the terminal, you will get a failed to compile error(switch is not exported from react-router-dom).&lt;/p&gt;

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

&lt;p&gt;This brings us to the first change. When we used react-router v5, we imported the switch component from the react-router package to wrap our routes, but instead in react-router v6 we use the routes component to wrap the route component.&lt;/p&gt;

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

&lt;p&gt;N.B You still have to import BrowserRouter from react-router-dom to wrap your root app component. And also only Route component can be a child of Routes any other component will lead to an error.&lt;/p&gt;

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

&lt;p&gt;Another important change is that your component should no longer be a child of your route component but instead the route takes in an element prop and then you pass a dynamic value to element and that dynamic value is that to be rendered component as JSX.&lt;/p&gt;

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

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

&lt;p&gt;And lastly note that dynamic routing still works as you normal(some new features were added but it works the same).&lt;/p&gt;

&lt;p&gt;Thanks for reading and please comment on any corrections or additions you will like to add.&lt;br&gt;
Link to upgrade &lt;a href="https://reactrouter.com/docs/en/v6/upgrading/v5" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Setting up Local MongoDB Using Mongo Compass on Windows
</title>
      <dc:creator>Jumbo Daniel</dc:creator>
      <pubDate>Thu, 22 Jul 2021 01:51:00 +0000</pubDate>
      <link>https://dev.to/jumbo02/setting-up-local-mongodb-using-mongo-compass-on-windows-465a</link>
      <guid>https://dev.to/jumbo02/setting-up-local-mongodb-using-mongo-compass-on-windows-465a</guid>
      <description>&lt;p&gt;Follow this &lt;a href="https://www.mongodb.com/try/download/community"&gt;link&lt;/a&gt; to visit the download page for the MongoDB Community Server and and download the latest MSI installer for Windows:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UpppubDs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l3gcb6x7he6dn9fe0r6v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UpppubDs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l3gcb6x7he6dn9fe0r6v.png" alt="Mongodb community server"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As soon as the download completes double click the file and run the installer.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QffvNJ_R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6o59xrg6xmztt2e23ej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QffvNJ_R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6o59xrg6xmztt2e23ej.png" alt="Mongo installation screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the next page to continue.&lt;br&gt;
Read the end-user license agreements and make sure you click the checkbox to agree with the user terms so that you can proceed to the next page. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Tk8i8J8q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u07j72jy0of2q248cth9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Tk8i8J8q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u07j72jy0of2q248cth9.png" alt="Mongo installation screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the complete button to install all MongoDB features and components.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---WrE4m6b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xr4rvk96qoh3nsx40mp6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---WrE4m6b--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xr4rvk96qoh3nsx40mp6.png" alt="Mongo installation screen"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The default values should work well for most scenarios. Click Next when you are satisfied with your selections.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Xu-vRM_i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6hsoukzunrpv5px8bweu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Xu-vRM_i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6hsoukzunrpv5px8bweu.png" alt="Mongo installation screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, click the checkbox to to install MongoDB Compass, a graphical interface that you can use to connect to and manage MongoDB servers. &lt;br&gt;
(Here we have to tick the checkbox to install MongoDB Compass since this tutorial was made for using MongoDB and Compass)&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dK2GP7vG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysj2w6iovbp2hbrigkth.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dK2GP7vG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysj2w6iovbp2hbrigkth.png" alt="Mongo installation screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, click Install to begin installing all of the MongoDB components on your computer.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3jLMDiuo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4astdbsyuo12arj04wp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3jLMDiuo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4astdbsyuo12arj04wp.png" alt="Mongo installation screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the installation is complete, MongoDB Compass will open automatically. If it doesn't open immediately, you can open it by just searching for it from your taskbar.&lt;br&gt;
The next step is to understand how to use MongoDB Compass (it is a very simple and straightforward process). Once it is open, the initial screen will give you the opportunity to connect to a running MongoDB server by providing a connection string: &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--su3xy8Di--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sjtg0dko6iyl458ogzq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--su3xy8Di--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sjtg0dko6iyl458ogzq6.png" alt="Mongo Compass"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you click connect without entering any connection string, mongo will just connect to the local database running with the default configurations.&lt;/p&gt;

&lt;p&gt;Click Connect to connect to the MongoDB server running on your machine. As soon as you click connect, Compass connects to your local server and shows information about the databases within and allow you to manage your data using the graphical user interface. The admin, config, and local are default databases and you shouldn't delete them.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0VBfXRIt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gqoqf7fcj6zz59kogui4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0VBfXRIt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gqoqf7fcj6zz59kogui4.png" alt="Mongo Compass connect screen"&gt;&lt;/a&gt;&lt;br&gt;
When you to stop the components after you are done working, click the connect menu in the menu bar and select disconnect to stop the connection to your MongoDB server. Afterwards, you can safely close the MongoDB Compass application. &lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>database</category>
      <category>mongocompass</category>
    </item>
    <item>
      <title>How to use Tailwind CSS in an ExpressJS app.</title>
      <dc:creator>Jumbo Daniel</dc:creator>
      <pubDate>Wed, 14 Jul 2021 23:40:10 +0000</pubDate>
      <link>https://dev.to/jumbo02/how-to-use-tailwind-css-in-an-expressjs-app-2c7c</link>
      <guid>https://dev.to/jumbo02/how-to-use-tailwind-css-in-an-expressjs-app-2c7c</guid>
      <description>&lt;h1&gt;
  
  
  This post will guide you if you want to use Tailwind CSS without having to use any bundler.
&lt;/h1&gt;

&lt;p&gt;First use your terminal to change directory to your express application. Then install tailwind in your express app using:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm i tailwindcss&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Run this command to generate the tailwind configuration file. This will create a tailwind.config.js file in your root directory.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx tailwindcss init&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Create a tailwind.css file in your public folder, I would advice you to create a stylesheets folder under the public folder to properly seperate your files(public/stylesheets/tailwind.css). After that copy and paste the following code in the tailwind.css file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@tailwind base;

@tailwind components;

@tailwind utilities; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install postcss globally. This allows us to use postcss in other projects without reinstalling for each projects.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install -g postcss-cli&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Create a postcss configuration file in your root directory and call it postcss.config.js. Then copy the following configuration into your postcss.config.js file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  plugins: [
    // ...
    require('tailwindcss'),
    require('autoprefixer'),
    // ...
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a build:css script to your package.json file so you can always build your css by running the command:&lt;br&gt;
&lt;br&gt;
 &lt;code&gt;npm run build:css&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"scripts": {
     "build:css": "postcss public/stylesheets/tailwind.css -o public/stylesheets/style.css"
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Import style.css in your application as you normally would and run your app. Congratulations.&lt;/p&gt;

</description>
      <category>node</category>
      <category>tailwindcss</category>
      <category>express</category>
      <category>npm</category>
    </item>
    <item>
      <title>How to Fix Nodemon (nodemon.ps1) Cannot Be Loaded Because Running Scripts is Disabled on This System.</title>
      <dc:creator>Jumbo Daniel</dc:creator>
      <pubDate>Sun, 20 Jun 2021 12:25:36 +0000</pubDate>
      <link>https://dev.to/jumbo02/how-to-fix-nodemon-nodemon-ps1-cannot-be-loaded-because-running-scripts-is-disabled-on-this-system-27km</link>
      <guid>https://dev.to/jumbo02/how-to-fix-nodemon-nodemon-ps1-cannot-be-loaded-because-running-scripts-is-disabled-on-this-system-27km</guid>
      <description>&lt;h1&gt;
  
  
  This is a simple solution for solving this error on windows
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;nodemon : File C:\Users\hp\AppData\Roaming\npm\nodemon.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see 
about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:1
+ nodemon app
+ ~~~~~~~

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;First Step&lt;/strong&gt;&lt;br&gt;
First search and run PowerShell as administrator&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second Step&lt;/strong&gt;&lt;br&gt;
If you read through the error message you will see this error was generated from &lt;strong&gt;Execution_Policies&lt;/strong&gt;. In you powershell window type and enter the get execution policiy command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Get-ExecutionPolicy

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Final Step&lt;/strong&gt;&lt;br&gt;
After running the command it will return restricted as the result. We have to set the execution policy to unrestricted using the Set-ExecutionPolicy 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-ExecutionPolicy Unrestricted

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

&lt;/div&gt;



&lt;p&gt;After this you will get a prompt message. Press Y to change it.&lt;br&gt;
To be sure you have changed the get execution policy you can simply run it again to check the result. You'll get the output 'Unrestricted'&lt;/p&gt;

&lt;p&gt;Now you can use nodemon on your machine.&lt;/p&gt;

</description>
      <category>node</category>
      <category>nodemon</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
