<?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: Anik Deb Nath</title>
    <description>The latest articles on Forem by Anik Deb Nath (@anikdebnath).</description>
    <link>https://forem.com/anikdebnath</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%2F1505300%2Fbc32f4a3-6d02-4a34-9094-379b73aec36e.jpg</url>
      <title>Forem: Anik Deb Nath</title>
      <link>https://forem.com/anikdebnath</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/anikdebnath"/>
    <language>en</language>
    <item>
      <title>Infinite Scrollable Image Slider with Framer Motion in Next.js</title>
      <dc:creator>Anik Deb Nath</dc:creator>
      <pubDate>Fri, 04 Jul 2025 07:08:46 +0000</pubDate>
      <link>https://forem.com/anikdebnath/infinite-scrollable-image-slider-with-framer-motion-in-nextjs-52f6</link>
      <guid>https://forem.com/anikdebnath/infinite-scrollable-image-slider-with-framer-motion-in-nextjs-52f6</guid>
      <description>&lt;h2&gt;
  
  
  ✨ Overview
&lt;/h2&gt;

&lt;p&gt;In this blog, we’ll walk through how I built an infinite scrolling image slider using Framer Motion, Next.js, and Tailwind CSS. The slider is powered by scroll velocity and it supports a "Show More" grid view with pagination!&lt;/p&gt;

&lt;h2&gt;
  
  
  🧱 Tools &amp;amp; Technologies Used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Next.js (App Router)&lt;/li&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Framer Motion&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;li&gt;Lucide Icons&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1. 👉Create a New Next.js Project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app@latest scroll-slider-demo
cd scroll-slider-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. 👉Install Required Packages
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Framer Motion for animation
npm install framer-motion

# Tailwind CSS and its dependencies
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

# Lucide React for icons
npm install lucide-react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. 👉Configure Tailwind
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. 👉globals.css (./app/globals.css)
&lt;/h3&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;h3&gt;
  
  
  5. 👉Add the Scroll Slider Component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client";
import React, { useState, useRef } from "react";
import Image from "next/image";
import {
  motion,
  useScroll,
  useSpring,
  useTransform,
  useMotionValue,
  useVelocity,
  useAnimationFrame,
  wrap,
} from "framer-motion";
import {
  ChevronDown,
  ChevronUp,
  ChevronLeft,
  ChevronRight,
} from "lucide-react";

const images = [
  {
    id: 1,
    title: "Moonbeam",
    description: "Serene moonlit landscape with ethereal beauty",
    thumbnail:
      "https://images.unsplash.com/photo-1534528741775-53994a69daeb?q=40&amp;amp;w=640",
  },
  {
    id: 2,
    title: "Cursor",
    description: "Digital innovation meets creative design",
    thumbnail:
      "https://images.unsplash.com/photo-1469474968028-56623f02e42e?q=40&amp;amp;w=640",
  },
  {
    id: 3,
    title: "Rogue",
    description: "Adventure awaits in uncharted territories",
    thumbnail:
      "https://images.unsplash.com/photo-1506748686214-e9df14d4d9d0?q=40&amp;amp;w=640",
  },
  {
    id: 4,
    title: "Editorially",
    description: "Crafting stories that inspire and engage",
    thumbnail:
      "https://images.unsplash.com/photo-1510784722466-f2aa9c52fff6?q=80&amp;amp;w=640",
  },
  {
    id: 5,
    title: "Editrix AI",
    description: "Artificial intelligence meets human creativity",
    thumbnail:
      "https://images.unsplash.com/photo-1470252649378-9c29740c9fa8?q=80&amp;amp;w=640",
  },
  {
    id: 6,
    title: "Cosmic Dreams",
    description: "Journey through the vast expanse of space",
    thumbnail:
      "https://images.unsplash.com/photo-1446776877081-d282a0f896e2?q=80&amp;amp;w=640",
  },
  {
    id: 7,
    title: "Urban Pulse",
    description: "The heartbeat of modern city life",
    thumbnail:
      "https://images.unsplash.com/photo-1449824913935-59a10b8d2000?q=80&amp;amp;w=640",
  },
  {
    id: 8,
    title: "Natural Wonder",
    description: "Discovering the beauty in untamed nature",
    thumbnail:
      "https://images.unsplash.com/photo-1506905925346-21bda4d32df4?q=80&amp;amp;w=640",
  },
  {
    id: 9,
    title: "Tech Horizon",
    description: "Where technology meets tomorrow",
    thumbnail:
      "https://images.unsplash.com/photo-1451187580459-43490279c0fa?q=80&amp;amp;w=640",
  },
  {
    id: 10,
    title: "Ocean Depths",
    description: "Exploring the mysteries beneath the waves",
    thumbnail:
      "https://images.unsplash.com/photo-1439066615861-d1af74d74000?q=80&amp;amp;w=640",
  },
];

// ScrollVelocity Component
const ScrollVelocity = React.forwardRef(
  (
    {
      children,
      velocity = 5,
      movable = true,
      clamp = false,
      className,
      initialOffset = 0, // New prop for initial offset
      ...props
    },
    ref
  ) =&amp;gt; {
    const baseX = useMotionValue(initialOffset); // Use initialOffset here
    const { scrollY } = useScroll();
    const scrollVelocity = useVelocity(scrollY);

    const smoothVelocity = useSpring(scrollVelocity, {
      damping: 100,
      stiffness: 20,
    });
    const velocityFactor = useTransform(smoothVelocity, [0, 10000], [0, 0.6], {
      clamp,
    });
    const x = useTransform(baseX, (v) =&amp;gt; `${wrap(-20, -50, v)}%`); // Adjusted wrap values

    const directionFactor = useRef(1);
    const scrollThreshold = useRef(5);

    useAnimationFrame((t, delta) =&amp;gt; {
      if (movable) {
        move(delta);
      } else {
        if (Math.abs(scrollVelocity.get()) &amp;gt;= scrollThreshold.current) {
          move(delta);
        }
      }
    });

    function move(delta) {
      let moveBy = directionFactor.current * velocity * (delta / 1000);
      if (velocityFactor.get() &amp;lt; 0) {
        directionFactor.current = -1;
      } else if (velocityFactor.get() &amp;gt; 0) {
        directionFactor.current = 1;
      }
      moveBy += directionFactor.current * moveBy * velocityFactor.get();
      baseX.set(baseX.get() + moveBy);
    }

    return (
      &amp;lt;div
        ref={ref}
        className={`relative m-0 flex flex-nowrap overflow-hidden whitespace-nowrap leading-[0.8] ${className}`}
        {...props}
      &amp;gt;
        &amp;lt;motion.div
          className="flex flex-row flex-nowrap whitespace-nowrap"
          style={{ x }}
        &amp;gt;
          {children}
        &amp;lt;/motion.div&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }
);

ScrollVelocity.displayName = "ScrollVelocity";

// Image Card Component
const ImageCard = ({ image, isGrid = false }) =&amp;gt; {
  return (
    &amp;lt;div
      className={`relative cursor-pointer mr-6 ${
        isGrid ? "w-full h-80" : "h-[15rem] w-[25rem] flex-shrink-0" // Fixed width of 400px (25rem = 400px, adjust as needed)
      }`}
    &amp;gt;
      &amp;lt;Image
        src={image.thumbnail}
        alt={image.title}
        width={400} // Fixed width
        height={240} // Fixed height (adjust aspect ratio as needed)
        className="w-full h-full object-cover object-center rounded-lg"
        priority={isGrid}
      /&amp;gt;

      {/* Prime Badge - Top Left Corner */}
      &amp;lt;div className="absolute top-2 left-2 z-10"&amp;gt;
        &amp;lt;div className="tracking-wide bg-gradient-to-r from-yellow-400 to-yellow-600 text-black px-2 py-1 rounded-md text-xs font-bold shadow-lg"&amp;gt;
          Popular
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;

      {/* Gradient Overlay - Black to White from bottom to top */}
      &amp;lt;div className="rounded-lg absolute inset-0 bg-gradient-to-t from-black/90 via-black/60 to-transparent" /&amp;gt;

      {/* Content - Always visible with improved spacing */}
      &amp;lt;div
        className={`absolute bottom-0 left-0 right-0 text-white ${
          isGrid ? "p-4" : "p-3 md:p-4"
        }`}
      &amp;gt;
        &amp;lt;h3
          className={`font-semibold ${
            isGrid
              ? "text-lg mb-3 leading-7 tracking-wide"
              : "text-base mb-2 leading-6 tracking-wide"
          }`}
        &amp;gt;
          {image.title}
        &amp;lt;/h3&amp;gt;

        &amp;lt;p
          className={`text-gray-300 font-normal ${
            isGrid ? "text-sm tracking-wide" : "text-sm tracking-wide"
          } drop-shadow-md truncate`}
        &amp;gt;
          {image.description}
        &amp;lt;/p&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

// Grid Layout Component
const GridLayout = ({ images, onClose }) =&amp;gt; {
  const [currentPage, setCurrentPage] = useState(0);
  const imagesPerPage = 6;
  const totalPages = Math.ceil(images.length / imagesPerPage);

  const getCurrentImages = () =&amp;gt; {
    const start = currentPage * imagesPerPage;
    const end = start + imagesPerPage;
    return images.slice(start, end);
  };

  const goToNext = () =&amp;gt; {
    setCurrentPage((prev) =&amp;gt; (prev + 1) % totalPages);
  };

  const goToPrevious = () =&amp;gt; {
    setCurrentPage((prev) =&amp;gt; (prev - 1 + totalPages) % totalPages);
  };

  return (
    &amp;lt;motion.div
      className="w-full"
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: -20 }}
      transition={{ duration: 0.5 }}
    &amp;gt;
      &amp;lt;div className="mb-6 flex justify-between items-center"&amp;gt;
        &amp;lt;h2 className="text-2xl font-bold text-gray-800"&amp;gt;All Projects&amp;lt;/h2&amp;gt;
        &amp;lt;button
          onClick={onClose}
          className="flex items-center gap-2 px-5 py-2 rounded-full text-white bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 transition-all shadow-md"
        &amp;gt;
          &amp;lt;ChevronUp className="w-4 h-4" /&amp;gt;
          Show Less
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8"&amp;gt;
        {getCurrentImages().map((image) =&amp;gt; (
          &amp;lt;ImageCard key={image.id} image={image} isGrid={true} /&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;

      {/* Navigation Controls - Below the grid */}
      &amp;lt;div className="flex justify-center items-center flex-wrap gap-4 mt-8"&amp;gt;
        {/* Pagination buttons */}
        &amp;lt;div className="flex items-center gap-4 flex-wrap"&amp;gt;
          &amp;lt;button
            onClick={goToPrevious}
            disabled={totalPages &amp;lt;= 1}
            className="flex items-center gap-2 px-5 py-2 rounded-full text-white bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 transition-all shadow-md disabled:opacity-50 disabled:cursor-not-allowed"
          &amp;gt;
            &amp;lt;ChevronLeft className="w-4 h-4" /&amp;gt;
            Previous
          &amp;lt;/button&amp;gt;

          &amp;lt;span className="text-sm font-medium text-gray-700"&amp;gt;
            Page {currentPage + 1} of {totalPages}
          &amp;lt;/span&amp;gt;

          &amp;lt;button
            onClick={goToNext}
            disabled={totalPages &amp;lt;= 1}
            className="flex items-center gap-2 px-5 py-2 rounded-full text-white bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 transition-all shadow-md disabled:opacity-50 disabled:cursor-not-allowed"
          &amp;gt;
            Next
            &amp;lt;ChevronRight className="w-4 h-4" /&amp;gt;
          &amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/motion.div&amp;gt;
  );
};

// Main Component
const EnhancedScrollVelocityDemo = () =&amp;gt; {
  const [showGrid, setShowGrid] = useState(false);
  const velocity = [0.2, -0.2];

  if (showGrid) {
    return (
      &amp;lt;div className="w-full p-6"&amp;gt;
        &amp;lt;GridLayout images={images} onClose={() =&amp;gt; setShowGrid(false)} /&amp;gt;
      &amp;lt;/div&amp;gt;
    );
  }

  return (
    &amp;lt;div className="w-full"&amp;gt;
      &amp;lt;div className="flex flex-col space-y-10 py-10"&amp;gt;
        {velocity.map((v, index) =&amp;gt; (
          &amp;lt;ScrollVelocity
            key={index}
            velocity={v}
            initialOffset={index % 2 === 0 ? -10 : 10} // Alternate initial offsets
          &amp;gt;
            {images.map((image) =&amp;gt; (
              &amp;lt;ImageCard key={image.id} image={image} /&amp;gt;
            ))}
            {/* Duplicate images to create infinite scroll effect */}
            {images.map((image) =&amp;gt; (
              &amp;lt;ImageCard key={`dup-${image.id}`} image={image} /&amp;gt;
            ))}
          &amp;lt;/ScrollVelocity&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;

      {/* Show More Button */}
      &amp;lt;div className="flex justify-center"&amp;gt;
        &amp;lt;motion.button
          onClick={() =&amp;gt; setShowGrid(true)}
          className="flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-blue-600 to-purple-600 text-white rounded-full hover:from-blue-700 hover:to-purple-700 transition-all shadow-lg hover:shadow-xl"
          whileHover={{ scale: 1.05 }}
          whileTap={{ scale: 0.95 }}
        &amp;gt;
          &amp;lt;span className="font-semibold"&amp;gt;Show More&amp;lt;/span&amp;gt;
          &amp;lt;ChevronDown className="w-5 h-5" /&amp;gt;
        &amp;lt;/motion.button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. 👉Use It in a Page or Other where you need
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import EnhancedScrollVelocityDemo from "./components/EnhancedScrollVelocityDemo";

export default function Home() {
  return (
    &amp;lt;main className="min-h-screen bg-white"&amp;gt;
      &amp;lt;EnhancedScrollVelocityDemo /&amp;gt;
    &amp;lt;/main&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. 👉Run the Project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
Visit: http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fnn6hyoxgd1rq4r4eqona.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnn6hyoxgd1rq4r4eqona.jpg" alt="grid view" width="800" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should see your animated scrollable slider with a “Show More” grid view. 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips &amp;amp; Enhancements
&lt;/h2&gt;

&lt;p&gt;Here are a few ways you can further enhance the experience:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add drag support (drag="x") for mobile swiping&lt;/li&gt;
&lt;li&gt;Animate image hover state for interactivity&lt;/li&gt;
&lt;li&gt;Fetch image data dynamically from API&lt;/li&gt;
&lt;li&gt;Add a modal/lightbox on card click&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project was a fun experiment combining Framer Motion’s powerful animation utilities with clean, scalable UI design. It showcases how scroll velocity can create visually stunning effects with minimal code.&lt;/p&gt;

&lt;p&gt;If you're building a portfolio, product showcase, or creative gallery — this layout can provide a delightful user experience that stands out.❤️&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>slider</category>
    </item>
    <item>
      <title>Deploying a Node.js + Express Server to Vercel Using the CLI</title>
      <dc:creator>Anik Deb Nath</dc:creator>
      <pubDate>Mon, 18 Nov 2024 21:10:53 +0000</pubDate>
      <link>https://forem.com/anikdebnath/deploying-a-nodejs-express-server-to-vercel-using-the-cli-2g0e</link>
      <guid>https://forem.com/anikdebnath/deploying-a-nodejs-express-server-to-vercel-using-the-cli-2g0e</guid>
      <description>&lt;p&gt;Deploying your Node.js, Express, and MongoDB backend to Vercel is an excellent way to make your application accessible to users worldwide. Vercel offers a simple, serverless, and high-performance deployment platform that integrates seamlessly with the Node.js ecosystem.&lt;/p&gt;

&lt;p&gt;In this blog, you'll learn how to deploy your backend server to Vercel using the command line, step-by-step.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Node.js and npm installed on your machine.&lt;/li&gt;
&lt;li&gt;A Vercel account. Sign up here.&lt;/li&gt;
&lt;li&gt;Vercel CLI installed globally on your system.&lt;/li&gt;
&lt;li&gt;A MongoDB instance, either locally or on a cloud provider like MongoDB Atlas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Install Vercel CLI
&lt;/h2&gt;

&lt;p&gt;First, install the Vercel CLI globally:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Verify the installation:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Prepare Your Node.js Application
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8rxmomp6luhmrchbm0e0.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8rxmomp6luhmrchbm0e0.JPG" alt="Folder structure" width="199" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;app.js: Defines your Express app.&lt;/li&gt;
&lt;li&gt;server.js: Handles the server setup.&lt;/li&gt;
&lt;li&gt;.env: Contains sensitive information like your MongoDB connection string&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Configure Your vercel.json File
&lt;/h2&gt;

&lt;p&gt;Create a vercel.json file in the root of your project(where package.json file in include) to configure your deployment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "version": 2,
  "builds": [
    {
      "src": "dist/server.js",
      "use": "@vercel/node"
    }
  ],
  "routes": [
    {
      "src": "/(.*)",
      "dest": "dist/server.js"
    }
  ]
}

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;builds: Specifies which file to use for the build.&lt;/li&gt;
&lt;li&gt;routes: Redirects all traffic to the server.js file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 4: Build Your Application First
&lt;/h2&gt;

&lt;p&gt;Build your application without any error. If any kind of error is occured , remove it then build your application.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Deploy Your Application
&lt;/h2&gt;



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

&lt;/div&gt;



&lt;p&gt;During deployment Vercel detects your server.js file as the entry point. Environment variables like MONGO_URI are injected automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Verify Your Deployment
&lt;/h2&gt;

&lt;p&gt;After the deployment is complete, you'll get a URL like:&lt;br&gt;
Domain: &lt;a href="https://your-project-name.vercel.app" rel="noopener noreferrer"&gt;https://your-project-name.vercel.app&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 7: Update Your Code
&lt;/h2&gt;

&lt;p&gt;To redeploy updated code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vercel --prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;You've successfully deployed your Node.js + Express + MongoDB server to Vercel using the command line! Vercel makes it incredibly simple to host backend applications, thanks to its serverless capabilities and ease of use.&lt;/p&gt;

&lt;p&gt;If you encounter any issues, consult the Vercel documentation or leave a comment below. Happy coding! 🚀&lt;/p&gt;

&lt;p&gt;[&lt;a href="https://www.linkedin.com/in/anikdebnath/" rel="noopener noreferrer"&gt;Anik Deb Nath&lt;/a&gt;]&lt;/p&gt;

</description>
      <category>vercel</category>
      <category>node</category>
      <category>express</category>
    </item>
    <item>
      <title>Create a Responsive Navbar Using Tailwind CSS and Next.js</title>
      <dc:creator>Anik Deb Nath</dc:creator>
      <pubDate>Wed, 13 Nov 2024 04:26:11 +0000</pubDate>
      <link>https://forem.com/anikdebnath/create-a-responsive-navbar-using-tailwind-css-and-nextjs-5h73</link>
      <guid>https://forem.com/anikdebnath/create-a-responsive-navbar-using-tailwind-css-and-nextjs-5h73</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvq3d285d4ooo1ffsrloj.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvq3d285d4ooo1ffsrloj.JPG" alt="Desktop view of navbar" width="800" height="108"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Intorduction
&lt;/h2&gt;

&lt;p&gt;Creating a responsive and visually appealing navbar is an essential part of building a modern website. This tutorial will guide you through building a navbar using Next.js and Tailwind CSS. The navbar will be fully responsive, including a mobile menu that slides in from the left.&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%2Fk5fkrr0idyia9wxlhi94.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk5fkrr0idyia9wxlhi94.JPG" alt="Responsive view of navbar" width="501" height="635"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Make sure you have - &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;are installed; if not, install first and create a new next js project by running following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-next-app@latest my-navbar-app
cd my-navbar-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 1: Setting Up the Navbar Component
&lt;/h2&gt;

&lt;p&gt;In the components folder, create a new file called Navbar.js (or Navbar.jsx):&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 Link from "next/link";
import { useState } from "react";

export default function Navbar() {
  const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
  const toggleMobileMenu = () =&amp;gt; {
    setIsMobileMenuOpen(!isMobileMenuOpen);
  };

  // Navigation items array
  const navItems = [
    { name: "Home", href: "/" },
    { name: "About", href: "/about" },
    { name: "News", href: "/news" },
    { name: "Contact", href: "/contact" },
  ];

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;nav className="block w-full max-w-screen px-4 py-4 mx-auto bg-white bg-opacity-90 sticky top-3 shadow lg:px-8 backdrop-blur-lg backdrop-saturate-150 z-[9999]"&amp;gt;
        &amp;lt;div className="container flex flex-wrap items-center justify-between mx-auto text-slate-800"&amp;gt;
          &amp;lt;Link
            href="/"
            className="mr-4 block cursor-pointer py-1.5 text-red-600 font-bold text-2xl"
          &amp;gt;
            NEXTNEWS
          &amp;lt;/Link&amp;gt;

          &amp;lt;div className="lg:hidden"&amp;gt;
            &amp;lt;button
              className="relative ml-auto h-6 max-h-[40px] w-6 max-w-[40px] select-none rounded-lg text-center align-middle text-xs font-medium uppercase text-inherit transition-all hover:bg-transparent focus:bg-transparent active:bg-transparent disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
              onClick={toggleMobileMenu}
              type="button"
            &amp;gt;
              &amp;lt;span className="absolute transform -translate-x-1/2 -translate-y-1/2 top-1/2 left-1/2"&amp;gt;
                &amp;lt;svg
                  xmlns="http://www.w3.org/2000/svg"
                  className="w-8 h-8"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                &amp;gt;
                  &amp;lt;path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M4 6h16M4 12h16M4 18h16"
                  &amp;gt;&amp;lt;/path&amp;gt;
                &amp;lt;/svg&amp;gt;
              &amp;lt;/span&amp;gt;
            &amp;lt;/button&amp;gt;
          &amp;lt;/div&amp;gt;

          {/* Mobile Menu */}
          &amp;lt;div
            className={`fixed top-0 left-0 min-h-screen w-64 bg-slate-100 shadow-lg transform transition-transform duration-300 ease-in-out ${
              isMobileMenuOpen ? "translate-x-0" : "-translate-x-full"
            } lg:hidden z-50`}
          &amp;gt;
            &amp;lt;div className="flex flex-row items-center border-b pb-4"&amp;gt;
              &amp;lt;Link
                href="/"
                className="cursor-pointer text-red-600 font-bold text-xl pt-4 ps-4"
              &amp;gt;
                NEXTNEWS
              &amp;lt;/Link&amp;gt;
              &amp;lt;button
                onClick={toggleMobileMenu}
                className="absolute top-4 right-4 text-slate-600 hover:text-red-500"
              &amp;gt;
                &amp;lt;svg
                  xmlns="http://www.w3.org/2000/svg"
                  className="w-8 h-8"
                  fill="none"
                  stroke="currentColor"
                  strokeWidth="2"
                &amp;gt;
                  &amp;lt;path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    d="M6 18L18 6M6 6l12 12"
                  /&amp;gt;
                &amp;lt;/svg&amp;gt;
              &amp;lt;/button&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;ul className="flex flex-col h-full gap-4 p-4"&amp;gt;
              {navItems.map((item, index) =&amp;gt; (
                &amp;lt;li
                  key={index}
                  className="flex items-center p-1 text-lg gap-x-2 text-slate-600 hover:text-red-500"
                &amp;gt;
                  &amp;lt;Link onClick={() =&amp;gt; {setIsMobileMenuOpen(false);}} href={item.href} className="flex items-center"&amp;gt;
                    {item.name}
                  &amp;lt;/Link&amp;gt;
                &amp;lt;/li&amp;gt;
              ))}
              &amp;lt;li className="mt-4"&amp;gt;
                &amp;lt;button className="bg-red-600 text-white px-8 py-2 rounded-md hover:bg-red-500"&amp;gt;
                  Login
                &amp;lt;/button&amp;gt;
              &amp;lt;/li&amp;gt;
            &amp;lt;/ul&amp;gt;
          &amp;lt;/div&amp;gt;

          {/* Desktop Menu */}
          &amp;lt;div className="hidden lg:block"&amp;gt;
            &amp;lt;ul className="flex flex-col gap-2 mt-2 mb-4 lg:mb-0 lg:mt-0 lg:flex-row lg:items-center lg:gap-6"&amp;gt;
              {navItems.map((item, index) =&amp;gt; (
                &amp;lt;li
                  key={index}
                  className="flex items-center p-1 text-lg gap-x-2 text-slate-600 hover:text-red-500"
                &amp;gt;
                  &amp;lt;Link href={item.href} className="flex items-center"&amp;gt;
                    {item.name}
                  &amp;lt;/Link&amp;gt;
                &amp;lt;/li&amp;gt;
              ))}
              &amp;lt;li&amp;gt;
                &amp;lt;button className="bg-red-600 hover:bg-red-500 text-white px-8 py-2 rounded-md"&amp;gt;
                  Login
                &amp;lt;/button&amp;gt;
              &amp;lt;/li&amp;gt;
            &amp;lt;/ul&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/nav&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Use your Navbar Component
&lt;/h2&gt;

&lt;p&gt;Use this navbar component in layout.js file of app folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default function RootLayout({ children }) {
return (
&amp;lt;html lang="en"&amp;gt;
&amp;lt;body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
&amp;gt;
&amp;lt;Navbar /&amp;gt; //use here
{children}
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
);
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Testing Responsiveness
&lt;/h2&gt;

&lt;p&gt;To see your navbar in action, run your Next.js local server:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

&lt;p&gt;This responsive navbar combines the power of Next.js with the flexibility of Tailwind CSS, creating a modern and functional user interface. With a few customizations, you can tailor this navbar to suit any project’s needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy coding!&lt;/strong&gt;&lt;br&gt;
[&lt;a href="https://www.linkedin.com/in/anikdebnath/" rel="noopener noreferrer"&gt;Anik Deb Nath&lt;/a&gt;]&lt;/p&gt;

</description>
      <category>navbar</category>
      <category>nextjs</category>
      <category>tailwindcss</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Union and intersection type in Typescript</title>
      <dc:creator>Anik Deb Nath</dc:creator>
      <pubDate>Mon, 20 May 2024 05:27:27 +0000</pubDate>
      <link>https://forem.com/anikdebnath/union-and-intersection-type-in-typescript-5481</link>
      <guid>https://forem.com/anikdebnath/union-and-intersection-type-in-typescript-5481</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3gtx3vcm07lfmgxdd2t.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%2Fb3gtx3vcm07lfmgxdd2t.png" alt="Union and intersection type in Typescript blog by anik deb nath" width="800" height="457"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Union:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In typescript we can use union type when we need to use more than a single type. We can also say that union means “OR”. To use union type we can use pipe (‘|’) symbol as union type. By this type we can also combine multiple data types in typescript. Let’s see union type’s syntax below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const checkNum : number | string ; 
checkNum = 10; 
checkNum = "Hello"; 
checkNum = true; // give here error becasue checkNum value should be number or string.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So here we see that myNum can be number or string which is provide more flexibility in our code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Union as function parameters:&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;const sayHi = (param:string | number) =&amp;gt; {
 return console.log(param);
}
sayHi("Hello!")
sayHi(89.6)
sayHi(true) //Argument of type 'boolean' is not assignable to parameter of type 'string | number'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Union of Literal Types:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;we can declare a union type including of literal types, such as string literals, number literals or boolean literals etc. Example :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Sports = 'cricket' | 'football' | 'tenis';
function watchMovie(game: Sports) {
    console.log(`You are playing ${game}.`);
}
watchMovie('cricket');
watchMovie('football');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will make our code more type-safe and error-free, and help us to avoid unnecessary type checks or type assertions.&lt;/p&gt;

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

&lt;p&gt;Intersection type is allowing us to combine multiple types into a single type with all of the properties. We must use “&amp;amp;” and operator to create intersection type in typescript. Let’s see union type’s syntax below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type Name = variable_1 &amp;amp; variable_2;
let var: variable_3;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Intersection can Combine interface:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In typescript we can define a type by combining two different interface using intersection that means type can get all properties of both interfaces. Let’s see the example below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Student{
    name: string;
    age: number;
    stdId: number;
}
interface Teacher{
    teachingId: string;
}
type User = Student &amp;amp; Teacher;
User.age = 5;
User.teachingId ="CSE123";
User.name = 'Karim';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the order of the types in an intersection does not concern. Suppose Student &amp;amp; Teacher is equivalent to Teacher &amp;amp; Student.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use intersection types to extend or override existing types&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s see an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type area = {
  width:string;
  height:string;
};
type volume = area &amp;amp; { depth: string };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In short union and intersection types in TypeScript:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Union&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can combine one or more types into one type.&lt;/li&gt;
&lt;li&gt;By using the pipe ‘|’ operator, we can perform union.&lt;/li&gt;
&lt;li&gt;Example: type value = string | number;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In functions or variables, union types are useful for accepting various types of values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intersection&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can merge properties from one or more types.&lt;/li&gt;
&lt;li&gt;By using the ampersand ‘&amp;amp;’ operator, we can perform intersection.&lt;/li&gt;
&lt;li&gt;Example: type User = Student &amp;amp; Teacher;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In composing types and enforcing strict type contracts, intersection types are useful.&lt;/p&gt;

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

&lt;p&gt;In summary we can say that union types provide versatility by allowing variables to hold values from many types, whereas intersection types combine numerous types into a single, more exact type. Depending on the needs of our code, we may opt to utilize union types to handle a variety of data circumstances or intersection types to compose exact type structures and execute strict type contracts.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>union</category>
      <category>intersection</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
