<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Anderson Osayerie</title>
    <description>The latest articles on Forem by Anderson Osayerie (@andemosa).</description>
    <link>https://forem.com/andemosa</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%2F386485%2F6f7d5790-10ad-423d-b1ba-a652c0b19b4b.jpeg</url>
      <title>Forem: Anderson Osayerie</title>
      <link>https://forem.com/andemosa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/andemosa"/>
    <language>en</language>
    <item>
      <title>Build a Responsive NavBar in React with Chakra UI v3</title>
      <dc:creator>Anderson Osayerie</dc:creator>
      <pubDate>Tue, 02 Sep 2025 10:06:14 +0000</pubDate>
      <link>https://forem.com/andemosa/build-a-responsive-navbar-in-react-with-chakra-ui-v3-25hb</link>
      <guid>https://forem.com/andemosa/build-a-responsive-navbar-in-react-with-chakra-ui-v3-25hb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Every landing page or app needs a robust navigation bar that works across all screen sizes. With Chakra UI v3, we can build a fully responsive NavBar in React with minimal code, while leveraging Chakra’s composable components, theming, and responsive props.&lt;/p&gt;

&lt;p&gt;Why Chakra UI, you might ask?&lt;/p&gt;

&lt;p&gt;Here's how I actually ended up with Chakra UI: I recently joined a new team, and they were already deep into using Chakra for their project. I had my own preferred stack, but the team needed consistency. So I dove in. And wow, was I pleasantly surprised.&lt;/p&gt;

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

&lt;p&gt;We'll create a navbar that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Collapses into a hamburger menu on mobile devices&lt;/li&gt;
&lt;li&gt;Displays all navigation items on desktop&lt;/li&gt;
&lt;li&gt;Includes a logo, navigation links, and a call-to-action button&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Desktop View
&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%2Fpg40w68m90f5b9erxwci.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%2Fpg40w68m90f5b9erxwci.png" alt="Navbar on desktop" width="800" height="62"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Mobile View
&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%2Few2mqj9jtig4dmgkguf7.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%2Few2mqj9jtig4dmgkguf7.png" alt="Navbar on mobile" width="800" height="706"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Let’s start a new React project using Vite, but create-react-app or Next.js also works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create vite@latest chakra-navbar -- --template react-ts
cd chakra-navbar
npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we’ll install Chakra UI and some dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i @chakra-ui/react @emotion/react lucide-react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For setting up Chakra UI with React, we'll need to wrap our app with the ChakraProvider and a custom theme, or the default system theme. You can check the &lt;a href="https://chakra-ui.com/docs/get-started/frameworks/vite" rel="noopener noreferrer"&gt;documentation for full installation instructions&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// main.tsx

import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { ChakraProvider, defaultSystem } from "@chakra-ui/react";

import App from "./App.tsx";

createRoot(document.getElementById("root")!).render(
  &amp;lt;StrictMode&amp;gt;
    &amp;lt;ChakraProvider value={defaultSystem}&amp;gt;
      &amp;lt;App /&amp;gt;
    &amp;lt;/ChakraProvider&amp;gt;
  &amp;lt;/StrictMode&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building the Navbar Components
&lt;/h2&gt;

&lt;p&gt;Let's break our navbar into smaller, manageable components. This approach makes our code cleaner and easier to maintain.&lt;/p&gt;

&lt;p&gt;Our NavBar will have three parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Logo&lt;/strong&gt; → Branding text or an image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Menu Links&lt;/strong&gt; → Navigation links and a call-to-action button, horizontal on desktop, vertical on mobile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile Drawer&lt;/strong&gt; → A hamburger button and slide-in drawer for smaller screens.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We’ll compose these inside a &lt;code&gt;Flex&lt;/code&gt; container that adapts at breakpoints.&lt;/p&gt;

&lt;h3&gt;
  
  
  Logo Component
&lt;/h3&gt;

&lt;p&gt;The Logo is the brand identity of the NavBar. It’s often the first thing users notice, so we want it to be simple yet clear.&lt;/p&gt;

&lt;p&gt;In this tutorial, we’ll just use a styled text element as our logo, but you could easily swap it out for an actual image.&lt;/p&gt;

&lt;p&gt;Here’s the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Box, Text } from "@chakra-ui/react";

const Logo = () =&amp;gt; {
  return (
    &amp;lt;Box&amp;gt;
      &amp;lt;Text fontSize="lg" fontWeight="bold" color="blue.600"&amp;gt;
        Logo
      &amp;lt;/Text&amp;gt;
      {/* Or use an actual image */}
      {/* &amp;lt;Image src="/logo.png" alt="Logo" height="40px" /&amp;gt; */}
    &amp;lt;/Box&amp;gt;
  );
};

export default Logo;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Menu Links
&lt;/h3&gt;

&lt;p&gt;It’s the part of the NavBar that includes the navigation links and a call-to-action button.&lt;/p&gt;

&lt;p&gt;Instead of writing raw  tags every time, we’ll define our navigation items in a simple array and map through them. Each item is styled consistently and gets hover transitions for a smooth effect.&lt;/p&gt;

&lt;p&gt;Here’s how it looks in our component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { HStack, VStack, Link, Button } from "@chakra-ui/react";

const links = [
  { name: "Home", href: "#home" },
  { name: "About", href: "#about" },
  { name: "Services", href: "#services" },
  { name: "Contact", href: "#contact" },
];

const MenuLinks = ({ isMobile = false }) =&amp;gt; {
  const LinkComponent = isMobile ? VStack : HStack;

  return (
    &amp;lt;LinkComponent gap={isMobile ? 4 : 8} align="center"&amp;gt;
      {links.map((link) =&amp;gt; (
        &amp;lt;Link
          key={link.name}
          href={link.href}
          fontWeight="medium"
          color="blue.600"
          _hover={{
            color: "blue.500",
            textDecoration: "underline",
          }}
          transition="color 0.2s ease"
        &amp;gt;
          {link.name}
        &amp;lt;/Link&amp;gt;
      ))}

      &amp;lt;Button
        bg="blue.600"
        color="white"
        size="sm"
        borderRadius="full"
        px={6}
        _hover={{
          transform: "translateY(-2px)",
          shadow: "lg",
        }}
        transition="all 0.2s ease"
      &amp;gt;
        Get Started
      &amp;lt;/Button&amp;gt;
    &amp;lt;/LinkComponent&amp;gt;
  );
};

export default MenuLinks;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the component dynamically switches between VStack and HStack depending on the screen size. On mobile, the navigation items are stacked vertically, while on desktop, they are aligned horizontally. &lt;/p&gt;

&lt;p&gt;This is controlled by the optional &lt;code&gt;isMobile&lt;/code&gt; prop. We also fine-tune the &lt;code&gt;gap&lt;/code&gt; to control spacing and alignment. At the end of the navigation links, we include a “Get Started” call-to-action button.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mobile Drawer Component
&lt;/h3&gt;

&lt;p&gt;On smaller screens, we don’t want the links taking up horizontal space. Instead, we replace them with a hamburger button. When clicked, this button opens a full-screen Drawer that slides in with the menu items.&lt;/p&gt;

&lt;p&gt;For this, we’ll use Chakra UI’s Drawer component. You can check the &lt;a href="https://chakra-ui.com/docs/components/drawer" rel="noopener noreferrer"&gt;Drawer docs&lt;/a&gt; for more details, but here’s a simple MobileDrawer component for our nav:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {
  useDisclosure,
  Drawer,
  Button,
  Portal,
  CloseButton,
  Icon,
} from "@chakra-ui/react";
import { Menu } from "lucide-react";
import Logo from "./Logo";
import MenuLinks from "./MenuLinks";

const MobileDrawer = () =&amp;gt; {
  const { open, onToggle } = useDisclosure();

  return (
    &amp;lt;Drawer.Root open={open} onOpenChange={onToggle} size="full"&amp;gt;
      &amp;lt;Drawer.Trigger asChild&amp;gt;
        &amp;lt;Button variant="outline" size="sm"&amp;gt;
          &amp;lt;Icon color="blue.600"&amp;gt;
            &amp;lt;Menu /&amp;gt;
          &amp;lt;/Icon&amp;gt;
        &amp;lt;/Button&amp;gt;
      &amp;lt;/Drawer.Trigger&amp;gt;
      &amp;lt;Portal&amp;gt;
        &amp;lt;Drawer.Backdrop /&amp;gt;
        &amp;lt;Drawer.Positioner&amp;gt;
          &amp;lt;Drawer.Content&amp;gt;
            &amp;lt;Drawer.Header&amp;gt;
              &amp;lt;Drawer.Title&amp;gt;
                &amp;lt;Logo /&amp;gt;
              &amp;lt;/Drawer.Title&amp;gt;
            &amp;lt;/Drawer.Header&amp;gt;
            &amp;lt;Drawer.Body&amp;gt;
              &amp;lt;MenuLinks isMobile /&amp;gt;
            &amp;lt;/Drawer.Body&amp;gt;
            &amp;lt;Drawer.CloseTrigger asChild&amp;gt;
              &amp;lt;CloseButton size="md" /&amp;gt;
            &amp;lt;/Drawer.CloseTrigger&amp;gt;
          &amp;lt;/Drawer.Content&amp;gt;
        &amp;lt;/Drawer.Positioner&amp;gt;
      &amp;lt;/Portal&amp;gt;
    &amp;lt;/Drawer.Root&amp;gt;
  );
};

export default MobileDrawer;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This component uses Chakra’s &lt;code&gt;useDisclosure&lt;/code&gt; hook to handle opening and closing. We add the &lt;code&gt;Logo&lt;/code&gt; in the &lt;em&gt;header&lt;/em&gt; and reuse &lt;code&gt;MenuLinks&lt;/code&gt; (this time with the &lt;code&gt;isMobile&lt;/code&gt; prop) inside the drawer. The &lt;em&gt;close button&lt;/em&gt; provides a simple way to exit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Putting It All Together
&lt;/h3&gt;

&lt;p&gt;Now that we have &lt;code&gt;Logo&lt;/code&gt;, &lt;code&gt;MenuLinks&lt;/code&gt;, and &lt;code&gt;MobileDrawer&lt;/code&gt;, let’s combine them into our final NavBar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Flex, Box } from "@chakra-ui/react";
import Logo from "./Logo";
import MenuLinks from "./MenuLinks";
import MobileDrawer from "./MobileDrawer";

function App() {
  return (
    &amp;lt;Flex
      as="nav"
      align="center"
      justify="space-between"
      wrap="wrap"
      gap={{ base: 8, lg: 16 }}
      px={{ base: 6, lg: 12 }}
      py={3}
      maxW={{ base: "full", xl: "1440px" }}
      mx="auto"
    &amp;gt;
      &amp;lt;Logo /&amp;gt;

      {/* Desktop Menu */}
      &amp;lt;Box display={{ base: "none", md: "block" }}&amp;gt;
        &amp;lt;MenuLinks /&amp;gt;
      &amp;lt;/Box&amp;gt;

      {/* Mobile Drawer */}
      &amp;lt;Box display={{ base: "block", md: "none" }}&amp;gt;
        &amp;lt;MobileDrawer /&amp;gt;
      &amp;lt;/Box&amp;gt;
    &amp;lt;/Flex&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we conditionally render the navigation by placing &lt;code&gt;MenuLinks&lt;/code&gt; inside a &lt;code&gt;Box&lt;/code&gt; that only appears on &lt;em&gt;desktop (md and above)&lt;/em&gt;, while the &lt;code&gt;MobileDrawer&lt;/code&gt; is wrapped in a &lt;code&gt;Box&lt;/code&gt; that only displays on &lt;em&gt;mobile (base)&lt;/em&gt;.&lt;/p&gt;

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

&lt;p&gt;We built a responsive navigation bar using Chakra UI, complete with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A reusable Logo component.&lt;/li&gt;
&lt;li&gt;A flexible MenuLinks component that adapts to desktop or mobile layouts.&lt;/li&gt;
&lt;li&gt;A MobileDrawer that slides in on small screens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Chakra UI handling layout and styling, plus React’s component-based architecture, we end up with a clean, responsive NavBar.&lt;/p&gt;

&lt;p&gt;I have attached a &lt;a href="https://github.com/andemosa/chakra-navbar" rel="noopener noreferrer"&gt;link to the code on github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>navbar</category>
      <category>react</category>
      <category>chakraui</category>
      <category>nav</category>
    </item>
    <item>
      <title>Integrating Pinata for Seamless Image Uploads in Nfticket</title>
      <dc:creator>Anderson Osayerie</dc:creator>
      <pubDate>Sun, 13 Oct 2024 21:40:48 +0000</pubDate>
      <link>https://forem.com/andemosa/integrating-pinata-for-seamless-image-uploads-in-nfticket-37ef</link>
      <guid>https://forem.com/andemosa/integrating-pinata-for-seamless-image-uploads-in-nfticket-37ef</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/pinata"&gt;The Pinata Challenge &lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built NFTicket, a decentralized application (dApp) that allows event organizers to mint, sell, and distribute event tickets as NFTs on the blockchain. Each NFTicket grants holders access to exclusive events, digital content, or experiences.&lt;/p&gt;

&lt;p&gt;To enhance this dApp, I’ve integrated &lt;a href="https://pinata.cloud/" rel="noopener noreferrer"&gt;Pinata’s Files API&lt;/a&gt; for efficient, decentralized file storage and delivery. Using Pinata’s CDN and image optimization features, I’m able to ensure fast, secure, and reliable access to these files, greatly improving the overall performance and user experience of the dApp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Check out the working version of the app here: &lt;a href="https://nfticket-andemosa.vercel.app/" rel="noopener noreferrer"&gt;Nfticket&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Screenhots:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Image upload form
&lt;/h4&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%2Fp8lqkkvqi812ufhmshy6.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%2Fp8lqkkvqi812ufhmshy6.png" alt="Image upload form" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Events view
&lt;/h4&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%2Fzsat47osfl6ui6qn2fke.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%2Fzsat47osfl6ui6qn2fke.png" alt="Events view" width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Code
&lt;/h2&gt;

&lt;p&gt;Feel free to take a look at the full project code over on GitHub:&lt;br&gt;
&lt;a href="https://github.com/andemosa/nfticket" rel="noopener noreferrer"&gt;Nfticket&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  More Details
&lt;/h2&gt;
&lt;h3&gt;
  
  
  How I Used Pinata
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Setting Up Pinata API in the dApp
&lt;/h4&gt;

&lt;p&gt;First, I had to set up access to Pinata’s API using my JWT and Gateway URL. I obtained these by signing up for a Pinata account and following the &lt;a href="https://docs.pinata.cloud/frameworks/react-ipfs#start-up-react-project" rel="noopener noreferrer"&gt;Getting Started Docs for React&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  Image Upload for Event Organizers
&lt;/h4&gt;

&lt;p&gt;In NFTicket, event organizers can easily upload images, like posters or banners, to visually boost their event listings. This makes the events more attractive to potential ticket buyers.&lt;/p&gt;

&lt;p&gt;I built a simple &lt;a href="https://github.com/andemosa/nfticket/blob/main/src/components/Create/ImageComp.tsx" rel="noopener noreferrer"&gt;image upload form&lt;/a&gt; that lets organizers select an image, preview it, and then upload it to Pinata. Using the Files API, these images are stored on IPFS, ensuring they’re decentralized and permanently linked to the event through the IPFS hash in the event metadata.&lt;/p&gt;

&lt;p&gt;Here’s the code I used for image uploads via Pinata’s API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const [file, setFile] = useState&amp;lt;File&amp;gt;();
  const [fileUrl, setFileUrl] = useState("");
  const [uploading, setUploading] = useState(false);

  const uploadFile = async () =&amp;gt; {
    if (!file) {
      alert("No file selected");
      return;
    }

    try {
      setUploading(true);
      const upload = await pinata.upload.file(file);

      const ipfsUrl = await pinata.gateways.convert(upload.IpfsHash);
      setFileUrl(ipfsUrl);
      setUploading(false);
    } catch (e) {
      console.log(e);
      setUploading(false);
      alert("Trouble uploading file");
    }
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Displaying Images with Pinata’s CDN
&lt;/h4&gt;

&lt;p&gt;Once the image is uploaded and the IPFS hash is stored, I use Pinata’s CDN to serve the image efficiently. This ensures that images load quickly, providing an optimal user experience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  &amp;lt;div className="flex flex-col gap-2"&amp;gt;
      &amp;lt;img
        src="https://blush-impossible-raven-254.mypinata.cloud/ipfs/bafkreifndvxnxuk52tq2mx5fgnm2bzqdlfpogt67wwc3e3vephxsao4ooa"
        alt=""
        className="h-96 w-full object-cover object-center rounded-lg overflow-hidden"
      /&amp;gt;
      &amp;lt;div className="flex gap-2"&amp;gt;
        &amp;lt;p&amp;gt;Tickets Available for minting:&amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;MintButton {...props} /&amp;gt;
    &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why I Chose Pinata
&lt;/h3&gt;

&lt;p&gt;Pinata offered the perfect combination of decentralized storage, performance, and flexibility that I needed for NFTicket. By using Pinata’s Files API, I was able to build a smooth image upload experience for event organizers while keeping everything secure and decentralized.&lt;/p&gt;

&lt;p&gt;Thanks to Pinata’s CDN and file optimization tools, the dApp runs efficiently and provides a great user experience for both organizers and NFT holders. And because files are stored on IPFS, they’re tamper-proof and accessible, even if traditional storage services fail. This aligns perfectly with Web3’s values, making Pinata an ideal choice for handling media in NFTicket.&lt;/p&gt;

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

&lt;p&gt;Integrating Pinata’s Files API into NFTicket has significantly improved how images are uploaded and managed. Pinata not only delivered high performance, but its API was also really easy to work with, allowing me to focus on the core features of the dApp, knowing that Pinata had file storage and delivery handled.&lt;/p&gt;

&lt;p&gt;Overall, Pinata has been an invaluable tool in building a reliable, decentralized image management solution for NFTicket.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>pinatachallenge</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Building a Dynamic Nested Mobile Navigation Menu with React</title>
      <dc:creator>Anderson Osayerie</dc:creator>
      <pubDate>Wed, 11 Sep 2024 17:30:29 +0000</pubDate>
      <link>https://forem.com/andemosa/building-a-dynamic-nested-mobile-navigation-menu-with-react-5b8i</link>
      <guid>https://forem.com/andemosa/building-a-dynamic-nested-mobile-navigation-menu-with-react-5b8i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As developers, we all encounter tricky problems that require creative solutions. One such problem I recently faced was creating a nested mobile navigation menu in React. &lt;/p&gt;

&lt;p&gt;I needed to build a menu where clicking on a parent menu item expands a list of related submenus, which may contain additional nested submenus.&lt;/p&gt;

&lt;p&gt;In this article, I’ll walk you through how I solved the problem step by step, using React and state management. If you’ve ever wanted to build a dynamic, multi-level mobile navigation menu for your website, this guide is for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Problem
&lt;/h2&gt;

&lt;p&gt;Nested menus allow users to navigate through hierarchical levels of content. Each subcategory can lead to more specific sections, creating a multi-level navigation structure.&lt;/p&gt;

&lt;p&gt;For instance, in an e-commerce app, a menu might have a “Products” category, which opens into subcategories like “Men’s Clothing” or “Electronics”.&lt;/p&gt;

&lt;p&gt;I wanted users to be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on a parent menu item (like "Products") to see its child items.&lt;/li&gt;
&lt;li&gt;Click on an item with a URL (like "Home") and go directly to that page.&lt;/li&gt;
&lt;li&gt;Click on an item with more children and dive even deeper into the menu.&lt;/li&gt;
&lt;li&gt;Go back up a level smoothly without reloading the page.&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%2Fuxal6q3jhcpim3ix6trh.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%2Fuxal6q3jhcpim3ix6trh.png" alt="Image showing nested menu" width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Planning the Solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Data Structure
&lt;/h3&gt;

&lt;p&gt;The foundation of the navigation system is a structured data array representing the menu hierarchy. The data contains both parent and child elements, with each element either having a direct URL or a set of child elements. Here’s the data structure I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const menuData = [
  { title: "Home", url: "/home" },
  {
    title: "Products",
    children: [
      {
        title: "Men",
        url: "/products/men",
      },
      {
        title: "Women",
        url: "/products/women",
      },
      {
        title: "Electronics",
        children: [
          {
            title: "Phones",
            url: "/products/electronics/phones",
          },
          {
            title: "Laptops",
            url: "/products/electronics/laptops",
          },
        ],
      },
    ],
  },
  {
    title: "Services",
    children: [
      {
        title: "Same Day Delivery",
        url: "/services/same-day-delivery",
      },
      {
        title: "Customized Services",
        url: "/services/customized-services",
      },
    ],
  },
  {
    title: "About",
    url: "/about",
  },
  {
    title: "Contact",
    url: "/contact",
  },
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The menu structure is simple—it’s just an array of objects. Each object represents an item in the menu, and some of these items have children (submenus), while others have url (links to specific pages).&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing the Dynamic Nested Mobile Navigation Menu
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setting Up the Project
&lt;/h3&gt;

&lt;p&gt;To begin, I created a new Nextjs project with &lt;a href="https://ui.shadcn.com/docs/installation/next" rel="noopener noreferrer"&gt;Shadcn&lt;/a&gt; as the component library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx shadcn@latest init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also installed &lt;a href="https://www.framer.com/motion/introduction/" rel="noopener noreferrer"&gt;Framer Motion&lt;/a&gt; to add subtle animations when menu items load, giving a nice, smooth experience when navigating between levels.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Catch-all Page
&lt;/h3&gt;

&lt;p&gt;For our navigation menu, each menu item may have multiple sub-levels, requiring a flexible route handler. &lt;/p&gt;

&lt;p&gt;By using &lt;a href="https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes#optional-catch-all-segments" rel="noopener noreferrer"&gt;Next.js Optional Catch-all Segments&lt;/a&gt;, we can define a single route in Next.js to handle multiple layers of navigation without creating a separate file for each level.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;[[...route]]/page.tsx&lt;/code&gt; file would catch all routes and display the current route as a heading on the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Link from "next/link";
import { Menu } from "lucide-react";

import { Button } from "@/components/ui/button";
import { Sheet, SheetTrigger, SheetContent } from "@/components/ui/sheet";

import MobileNav from "./_components/MobileNav";

export default function CurrPage({ params }: { params: { route: string[] } }) {
  const showParams = (route: string[]) =&amp;gt; {
    if (!route) return "Index Page";

    return `${route.join(", ")} Page`;
  };

  return (
    &amp;lt;div className="flex flex-col h-screen bg-white text-slate-800"&amp;gt;
      &amp;lt;header className="flex items-center justify-between px-4 py-3 border-b"&amp;gt;
        &amp;lt;Link href="#" className="text-lg font-semibold" prefetch={false}&amp;gt;
          Mobile Navigation
        &amp;lt;/Link&amp;gt;
        &amp;lt;Sheet&amp;gt;
          &amp;lt;SheetTrigger asChild&amp;gt;
            &amp;lt;Button variant="ghost" size="icon" className="rounded-full"&amp;gt;
              &amp;lt;Menu className="w-6 h-6" /&amp;gt;
              &amp;lt;span className="sr-only"&amp;gt;Toggle menu&amp;lt;/span&amp;gt;
            &amp;lt;/Button&amp;gt;
          &amp;lt;/SheetTrigger&amp;gt;
          &amp;lt;SheetContent
            side="right"
            className="w-full max-w-xs bg-white p-4 pt-8"
          &amp;gt;
            &amp;lt;MobileNav /&amp;gt;
          &amp;lt;/SheetContent&amp;gt;
        &amp;lt;/Sheet&amp;gt;
      &amp;lt;/header&amp;gt;

      &amp;lt;section className="my-4 text-center text-2xl font-bold capitalize px-4"&amp;gt;
        {showParams(params.route)}
      &amp;lt;/section&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;The CurrPage component is a Next.js page that utilizes a &lt;a href="https://ui.shadcn.com/docs/components/sheet" rel="noopener noreferrer"&gt;Shadcn Sheet component&lt;/a&gt; for a mobile navigation drawer and dynamically renders the current route on the page based on route parameters.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;showParams&lt;/code&gt; function checks whether there is a route provided, and based on the dynamic segments, it generates a string to display which page is currently being viewed. If there’s no route, it shows "&lt;em&gt;Index Page"&lt;/em&gt; otherwise it concatenates the route segments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Navigation Component
&lt;/h3&gt;

&lt;p&gt;Next, I built the core component responsible for rendering the current menu and handling navigation between parent and child menus. Here's how I structured the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client";

import { useState } from "react";
import Link from "next/link";
import { Link as LinkIcon } from "lucide-react";
import { motion } from "framer-motion";

import { navigation, NavigationType } from "@/lib/constants";

const MobileNav = () =&amp;gt; {
  // `currList` holds the current list of navigation items, initially set to the main navigation.
  const [currList, setCurrList] = useState(navigation);

  // `navStack` holds the navigation history as an array, used for back navigation.
  const [navStack, setNavStack] = useState&amp;lt;NavigationType[]&amp;gt;([]);
  // `titleStack` holds the title history as an array, used for showing the title.
  const [titleStack, setTitleStack] = useState&amp;lt;string[]&amp;gt;([]);

  // Handle when an item in the navigation list is clicked.
  const handleItemClick = (item: NavigationType[0]) =&amp;gt; {
    if (item.children) {
      setNavStack([...navStack, currList]);
      setTitleStack([...titleStack, item.title]);
      setCurrList(item.children);
    }
  };

  // Handle the "Back" button click to return to the previous navigation level.
  const handleBackClick = () =&amp;gt; {
    if (navStack.length &amp;gt; 0) {
      const previousItems = navStack[navStack.length - 1];
      setCurrList(previousItems);
      setNavStack(navStack.slice(0, -1));
      setTitleStack(titleStack.slice(0, -1));
    }
  };

  return (
    &amp;lt;div className="w-full max-w-md mx-auto bg-white overflow-hidden mt-2"&amp;gt;
      {/* Show the back button if there is navigation history */}
      {navStack.length &amp;gt; 0 &amp;amp;&amp;amp; (
        &amp;lt;div className="flex items-center p-4 bg-gray-100 border-b text-slate-800"&amp;gt;
          &amp;lt;button onClick={handleBackClick} className="mr-2"&amp;gt;
            &amp;lt;svg
              xmlns="http://www.w3.org/2000/svg"
              width="1em"
              height="1em"
              viewBox="0 0 24 24"
            &amp;gt;
              &amp;lt;path
                fill="currentColor"
                d="M7.828 11H20v2H7.828l5.364 5.364l-1.414 1.414L4 12l7.778-7.778l1.414 1.414z"
              /&amp;gt;
            &amp;lt;/svg&amp;gt;
          &amp;lt;/button&amp;gt;
          {/* Show the current navigation title */}
          &amp;lt;span className="font-semibold text-slate-800"&amp;gt;{titleStack.slice(-1)}&amp;lt;/span&amp;gt;
        &amp;lt;/div&amp;gt;
      )}

      {/* Display the list of current navigation items */}
      &amp;lt;ul className="divide-y divide-gray-200"&amp;gt;
        {currList.map((item) =&amp;gt; (
          &amp;lt;motion.li
            key={item.title}
            className="p-4"
            initial={{ y: 20, opacity: 0 }}
            animate={{ y: 0, opacity: 1 }}
            transition={{ ease: "easeInOut", duration: 0.75 }}
          &amp;gt;
            {item.url ? (
              &amp;lt;Link
                key={item.title}
                href={item.url}
                className="w-full text-left flex justify-between items-center hover:text-slate-500 text-slate-800 transition-colors"
                prefetch={false}
              &amp;gt;
                &amp;lt;span&amp;gt;{item.title}&amp;lt;/span&amp;gt;
                &amp;lt;LinkIcon className="h-5 w-5" /&amp;gt;
              &amp;lt;/Link&amp;gt;
            ) : (
              &amp;lt;button
                onClick={() =&amp;gt; handleItemClick(item)}
                className="w-full text-left flex justify-between items-center hover:text-slate-500 text-slate-800"
              &amp;gt;
                &amp;lt;span&amp;gt;{item.title}&amp;lt;/span&amp;gt;
                {/* Show the right arrow icon if the item has children */}
                {item.children &amp;amp;&amp;amp; (
                  &amp;lt;svg
                    xmlns="http://www.w3.org/2000/svg"
                    width="24"
                    height="24"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  &amp;gt;
                    &amp;lt;path d="m9 18 6-6-6-6" /&amp;gt;
                  &amp;lt;/svg&amp;gt;
                )}
              &amp;lt;/button&amp;gt;
            )}
          &amp;lt;/motion.li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default MobileNav;

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

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;MobileNav&lt;/code&gt; component contains the navigation functionality. It handles nested menus using a &lt;code&gt;currList&lt;/code&gt; state to represent the current items and a &lt;code&gt;navStack&lt;/code&gt; state to store the previous levels of navigation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Walkthrough of Key Features
&lt;/h3&gt;

&lt;h4&gt;
  
  
  State Initialization
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [currList, setCurrList] = useState(navigation);
const [navStack, setNavStack] = useState&amp;lt;NavigationType[]&amp;gt;([]);
const [titleStack, setTitleStack] = useState&amp;lt;string[]&amp;gt;([]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;currList&lt;/code&gt; holds the current menu items displayed to the user, initialized to the top-level navigation.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;navStack&lt;/code&gt; is an array that keeps track of the previously visited menus, allowing users to go back to the previous navigation level.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;titleStack&lt;/code&gt; keeps track of the titles of the currently displayed menu, used to show where the user is within the navigation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Item Click Handling
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleItemClick = (item: NavigationType[0]) =&amp;gt; {
  if (item.children) {
    setNavStack([...navStack, currList]);
    setTitleStack([...titleStack, item.title]);
    setCurrList(item.children);
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function gets triggered when a navigation item is clicked. If the clicked item has child elements (children), the current list is added to the &lt;code&gt;navStack&lt;/code&gt; array, and the &lt;code&gt;currList&lt;/code&gt; state is updated to display the children.&lt;/p&gt;

&lt;h4&gt;
  
  
  Back Navigation
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleBackClick = () =&amp;gt; {
  if (navStack.length &amp;gt; 0) {
    const previousItems = navStack[navStack.length - 1];
    setCurrList(previousItems);
    setNavStack(navStack.slice(0, -1));
    setTitleStack(titleStack.slice(0, -1));
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;handleBackClick&lt;/code&gt; function restores the previous navigation items from the stack and removes the latest entry in &lt;code&gt;navStack&lt;/code&gt; and &lt;code&gt;titleStack&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rendering the Navigation
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Back Button and Sub-menu title:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{navStack.length &amp;gt; 0 &amp;amp;&amp;amp; (
        &amp;lt;div className="flex items-center p-4 bg-gray-100 border-b text-slate-800"&amp;gt;
          &amp;lt;button onClick={handleBackClick} className="mr-2"&amp;gt;
            &amp;lt;svg
              xmlns="http://www.w3.org/2000/svg"
              width="1em"
              height="1em"
              viewBox="0 0 24 24"
            &amp;gt;
              &amp;lt;path
                fill="currentColor"
                d="M7.828 11H20v2H7.828l5.364 5.364l-1.414 1.414L4 12l7.778-7.778l1.414 1.414z"
              /&amp;gt;
            &amp;lt;/svg&amp;gt;
          &amp;lt;/button&amp;gt;
          {/* Show the current navigation title */}
          &amp;lt;span className="font-semibold text-slate-800"&amp;gt;{titleStack.slice(-1)}&amp;lt;/span&amp;gt;
        &amp;lt;/div&amp;gt;
      )}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only shown when &lt;code&gt;navStack&lt;/code&gt; is not empty.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Current Menu List:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;ul className="divide-y divide-gray-200"&amp;gt;
        {currList.map((item) =&amp;gt; (
          &amp;lt;motion.li
            key={item.title}
            className="p-4"
            initial={{ y: 20, opacity: 0 }}
            animate={{ y: 0, opacity: 1 }}
            transition={{ ease: "easeInOut", duration: 0.75 }}
          &amp;gt;
            {item.url ? (
              &amp;lt;Link
                key={item.title}
                href={item.url}
                className="w-full text-left flex justify-between items-center hover:text-slate-500 text-slate-800 transition-colors"
                prefetch={false}
              &amp;gt;
                &amp;lt;span&amp;gt;{item.title}&amp;lt;/span&amp;gt;
                &amp;lt;LinkIcon className="h-5 w-5" /&amp;gt;
              &amp;lt;/Link&amp;gt;
            ) : (
              &amp;lt;button
                onClick={() =&amp;gt; handleItemClick(item)}
                className="w-full text-left flex justify-between items-center hover:text-slate-500 text-slate-800"
              &amp;gt;
                &amp;lt;span&amp;gt;{item.title}&amp;lt;/span&amp;gt;
                {/* Show the right arrow icon if the item has children */}
                {item.children &amp;amp;&amp;amp; (
                  &amp;lt;svg
                    xmlns="http://www.w3.org/2000/svg"
                    width="24"
                    height="24"
                    viewBox="0 0 24 24"
                    fill="none"
                    stroke="currentColor"
                    strokeWidth="2"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                  &amp;gt;
                    &amp;lt;path d="m9 18 6-6-6-6" /&amp;gt;
                  &amp;lt;/svg&amp;gt;
                )}
              &amp;lt;/button&amp;gt;
            )}
          &amp;lt;/motion.li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dynamically displays the current level of the navigation, with either a link or a button depending on whether the item has a url or children.&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%2Fm595woxa1rpa11o93xit.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%2Fm595woxa1rpa11o93xit.png" alt=" " width="720" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Building a dynamic nested mobile navigation menu in React required a careful balance of state management and user experience design.&lt;/p&gt;

&lt;p&gt;Using React's &lt;code&gt;useState&lt;/code&gt; for dynamic rendering, I was able to create an intuitive navigation system that can handle complex menu structures.&lt;/p&gt;

&lt;p&gt;If you’re building a web app with multi-level menus, I hope this guide has given you the tools and inspiration to tackle the challenge.&lt;/p&gt;

&lt;p&gt;I have attached a link to &lt;a href="https://github.com/andemosa/mobile-navigation" rel="noopener noreferrer"&gt;the code on github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>webdev</category>
      <category>navbar</category>
    </item>
    <item>
      <title>Build a Guessing Game with Python</title>
      <dc:creator>Anderson Osayerie</dc:creator>
      <pubDate>Mon, 18 May 2020 22:41:55 +0000</pubDate>
      <link>https://forem.com/andemosa/building-a-guessing-game-with-python-g7m</link>
      <guid>https://forem.com/andemosa/building-a-guessing-game-with-python-g7m</guid>
      <description>&lt;p&gt;In this article, we will be building a simple guessing game using Python. This was a task done during the StartNG Beginner Software Development Training. The game would have three modes corresponding to levels of difficulty.&lt;/p&gt;

&lt;p&gt;In the Easy mode, the player would try to guess the random number generated by the program between 1 to 10. The player would have 6 tries at guessing the correct number.&lt;/p&gt;

&lt;p&gt;In the Medium mode, the player would try to guess the random number generated by the program between 1 to 20. The player would have 4 tries at guessing the correct number.&lt;/p&gt;

&lt;p&gt;In the Hard mode, the player would try to guess the random number generated by the program between 1 to 50. The player would have 3 tries at guessing the correct number.&lt;/p&gt;

&lt;p&gt;Before heading into the actual solution of the task, it is usually best practice to make a rough sketch (pseudo-code) of how the program should be. &lt;/p&gt;

&lt;p&gt;To achieve the aim of the program, we would need to have a means of generating a random number. We could choose to select a particular number within each range to be the number, but that would not be fun. We need the number to change at every iteration of the program. &lt;/p&gt;

&lt;p&gt;So to generate the random number, we would be making use of a Python module called “random”. This enables us to have a different random number every time the game is played.&lt;/p&gt;

&lt;p&gt;It is possible to use if/else statements for the three different modes of the game, but it is usually best practice to write functions wherever possible to make for more readable code. So we would be making use of functions.&lt;/p&gt;

&lt;p&gt;First of all, we would be creating a function called guess_game. This function would have two parameters which are limit and number. Below is a pictorial illustration of the code.&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%2Fympb1q5r5i3pz6dpmnq7.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%2Fympb1q5r5i3pz6dpmnq7.png" alt="Guess_game function" width="800" height="716"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A variable for the random number was created and the variable makes use of the “random” module. The “randint” built-in function of the “random” module is used to generate a random number between 1 and another variable (number) that corresponds to the highest number in the range from which the player should make their guess.&lt;/p&gt;

&lt;p&gt;The function would need two arguments each time that the function is called. These two arguments correspond to the number of tries and the highest number in the range for the different modes. &lt;/p&gt;

&lt;p&gt;So in the case of the Easy mode, we would call the guess_game function and pass 6 as the argument for limit, which is the number of tries a player has to make the correct guess. &lt;/p&gt;

&lt;p&gt;For the other parameter number, the argument would be 10, since that corresponds to the highest number in the range of which the player should guess a number for the Easy mode.&lt;/p&gt;

&lt;p&gt;In the rare case where our player enters anything other than a number, the try and except block handles that exception and tells the user that only numbers are allowed.&lt;/p&gt;

&lt;p&gt;So we will pass the arguments for each mode, and this results in the functions below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhg522zst5ui5fv8c9s7s.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%2Fhg522zst5ui5fv8c9s7s.png" alt="functions for different modes" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating the functions that would enable the game to run smoothly, we would need a function that would allow the player to choose what mode they want to play in. For that, we would be creating a function called welcome.&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%2Fbcphjshcqx5y8z0v1ppr.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%2Fbcphjshcqx5y8z0v1ppr.png" alt="welcome function" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we have a program that runs. Unfortunately, our program only runs once. You know what that means? If our game were to be a mobile app, our game would exit after one round and the user would have to launch the application to play a second round. &lt;/p&gt;

&lt;p&gt;I guess we do not want that. We would want to give our users the opportunity to choose to play again without having to launch the application every single time. &lt;/p&gt;

&lt;p&gt;Well, like always, we would create a function for that. We never get tired of creating functions, right? So we would create a try_again function.&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%2F90yhtxgn859wqcbrz5wc.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%2F90yhtxgn859wqcbrz5wc.png" alt="try_again function" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have to add the try_again function to the welcome function so that our player has the option to try again after one round of the game has ended without having to start the program entirely.&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%2F61yab3bsm2dlm3096dc2.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%2F61yab3bsm2dlm3096dc2.png" alt="final welcome function" width="799" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now our players can choose to play the game as much as they want.&lt;br&gt;
So voila, we have been able to use a couple of functions to build a simple guessing game. It was fun, right? Yeah, I sure had fun building it too.&lt;/p&gt;

&lt;p&gt;Feel free to drop your comments, and questions below&lt;/p&gt;

&lt;p&gt;The source code can be found here — &lt;a href="https://github.com/ema-mimus/guess_game/blob/master/Guess_game.py" rel="noopener noreferrer"&gt;https://github.com/ema-mimus/guess_game/blob/master/Guess_game.py&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>guess</category>
      <category>game</category>
      <category>python3</category>
    </item>
  </channel>
</rss>
