<?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: Deepak Yadav</title>
    <description>The latest articles on DEV Community by Deepak Yadav (@thedeepakyadav).</description>
    <link>https://dev.to/thedeepakyadav</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%2F1012331%2F3210de44-e629-4fe6-a889-21ecb5c2dcea.jpg</url>
      <title>DEV Community: Deepak Yadav</title>
      <link>https://dev.to/thedeepakyadav</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thedeepakyadav"/>
    <language>en</language>
    <item>
      <title>Enhance User Engagement: Web Push Notifications with Firebase Cloud Messaging (FCM)</title>
      <dc:creator>Deepak Yadav</dc:creator>
      <pubDate>Sat, 20 Jan 2024 16:22:17 +0000</pubDate>
      <link>https://dev.to/thedeepakyadav/enhance-user-engagement-web-push-notifications-with-firebase-cloud-messaging-fcm-34h2</link>
      <guid>https://dev.to/thedeepakyadav/enhance-user-engagement-web-push-notifications-with-firebase-cloud-messaging-fcm-34h2</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Web push notifications have become a key component in enhancing user engagement on modern web applications. Firebase Cloud Messaging (FCM) provides a robust and easy-to-use solution for implementing push notifications across various platforms, including the web. Here, we will explore integrating FCM into a NextJs application to enable web push notifications for browsers. This blog covers sending background notifications to the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preliminary Step
&lt;/h2&gt;

&lt;p&gt;Before jumping on the NextJs code, we need to configure the Firebase project and add a web app to our project to obtain the Firebase configuration object.&lt;/p&gt;

&lt;p&gt;Also, we need to install FIrebase in our NextJs App using&lt;code&gt;npm install firebase&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;There are a few steps that need to be done in the NextJs App before sending out our first push notification&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initialize Firebase app&lt;/li&gt;
&lt;li&gt;Request for notification permission&lt;/li&gt;
&lt;li&gt;Sending firebase config to the service worker&lt;/li&gt;
&lt;li&gt;Handle Incoming Messages through service worker&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When it comes to the art of sending notifications, Firebase Cloud Messaging (FCM) bestows two distinct methods upon developers —&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Firebase Messaging Console&lt;/li&gt;
&lt;li&gt;FCM V1 API&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this article, we'll navigate through these essential steps, ensuring your Next.js app is primed for delivering engaging and timely push notifications&lt;/p&gt;

&lt;p&gt;In the realm of implementing web push notifications through Firebase Cloud Messaging (FCM), certain nuanced aspects arise, especially when utilizing the FCM API for notification dispatch. While the default messaging.onBackgroundMessage() adeptly manages notifications from the Firebase console, a unique challenge surfaces when images are involved, requiring the explicit use of showNotification.&lt;/p&gt;

&lt;p&gt;Notably, this issue doesn't persist when leveraging the FCM v1 API. In this article, we'll explore the nuances of handling web push notifications in React/Next.js, shedding light on effective practices and workarounds. Additionally, we'll delve into the FCM v1 API for server-side notification dispatch and provide insights on optimizing the notification handling process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Initialize Firebase app and messaging
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//File: lib/authHook/firebase
//Initialise firebase app
import { initializeApp } from "firebase/app";
import { getMessaging } from "firebase/messaging";

export const firebaseConfig = {
  apiKey: "API_KEY",
  authDomain: "PROJECT_ID.firebaseapp.com",
  databaseURL: "https://DATABASE_NAME.firebaseio.com",
  projectId: "PROJECT_ID",
  storageBucket: "PROJECT_ID.appspot.com",
  messagingSenderId: "SENDER_ID",
  appId: "APP_ID",
  measurementId: "G-MEASUREMENT_ID",
};

  export const app = initializeApp(firebaseConfig);
  let messaging
  if (typeof window !== 'undefined'){
    messaging = getMessaging(app);
  }
  export {messaging}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Seeking notification permission
&lt;/h2&gt;

&lt;p&gt;To enable the delivery of notifications, a crucial step involves seeking the user's consent, a common experience encountered when visiting websites. This permission is typically obtained through the Notification API, allowing developers to seamlessly set up the necessary permissions for notification delivery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: _app.js
import { messaging } from "@/lib/authHook/firebase";
import { useEffect } from "react";
function MyApp({ Component, pageProps }) {

 async function requestPermission() {
    const permission = await Notification.requestPermission();
    if (permission === "granted") {
      // Generate Device Token for notification
      const token = await getToken(messaging, {
        vapidKey:  process.env.NEXT_PUBLIC_FIREBASE_VAPID_KEY,
      });
      console.log("Token Gen", token);
    } else if (permission === "denied") {
      console.log("Denied for the notification");
    }
  }
  useEffect(() =&amp;gt; {
    requestPermission()
  }, []);
return
  &amp;lt;Component {...pageProps} /&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handle incoming messages in the Service Worker
&lt;/h2&gt;

&lt;p&gt;To facilitate the seamless handling of notifications in your web application, it's essential to create a dedicated service worker, often named 'firebase-messaging-sw.js.' This service worker plays a pivotal role in managing the background processes associated with Firebase Cloud Messaging, ensuring efficient handling of notifications and ensuring a seamless 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;// File: firebase-messaging-sw.js
importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js");

// Set Firebase configuration, once available
self.addEventListener('fetch', () =&amp;gt; {
  try {
    const urlParams = new URLSearchParams(location.search);
    self.firebaseConfig = Object.fromEntries(urlParams);
  } catch (err) {
    console.error('Failed to add event listener', err);
  }
});

// "Default" Firebase configuration (prevents errors)
const defaultConfig = {
  apiKey: true,
  projectId: true,
  messagingSenderId: true,
  appId: true,
};
// Initialize Firebase app
firebase.initializeApp(self.firebaseConfig || defaultConfig);
let messaging;
try {
   messaging = firebase.messaging.isSupported() ? firebase.messaging() : null
} catch (err) {
  console.error('Failed to initialize Firebase Messaging', err);
}

// To dispaly background notifications
if (messaging) {
  try {
    messaging.onBackgroundMessage((payload) =&amp;gt; {
    console.log('Received background message: ', payload);
    const notificationTitle = payload.notification.title;
    const notificationOptions = { 
      body: payload.notification.body,
      tag: notificationTitle, // tag is added to ovverride the notification with latest update
      icon: payload.notification?.image || data.image,
      data: {
        url: payload?.data?.openUrl,// This should contain the URL you want to open
      },
    }
    // Optional
       /*
        * This condition is added because notification triggers from firebase messaging console doesn't handle image by default.
        * collapseKey comes only when the notification is triggered from firebase messaging console and not from hitting fcm google api.
        */
        if (payload?.collapseKey &amp;amp;&amp;amp; notification?.image) {
          self.registration.showNotification(notificationTitle, notificationOptions);
        } else {
           // Skipping the event handling for notification
           return new Promise(function(resolve, reject) {});
        }
    });
  } catch (err) {
    console.log(err);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The inclusion of the optional section becomes particularly relevant when utilizing the Firebase Cloud Messaging (FCM) API to send notifications. It's noteworthy that when notifications are dispatched through the Firebase console, the &lt;code&gt;messaging.onBackgroundMessage()&lt;/code&gt; function seamlessly manages the notification handling process on its own.&lt;/p&gt;

&lt;p&gt;Notifications initiated from the Firebase Console lack automatic handling of images, necessitating the explicit use of showNotification to manage image display. However, this approach introduces a challenge, causing notifications to be triggered twice – once from the default &lt;code&gt;messaging.onBackgroundMessage()&lt;/code&gt; and the second from &lt;code&gt;self.registration.showNotification()&lt;/code&gt;. Addressing this duality becomes a key consideration when refining the notification handling process.&lt;br&gt;
This is not the case when notification is triggered through FCM v1 API.&lt;br&gt;
Request:** If you know how to overcome this do mention it in the comments, it will help me too :)&lt;/p&gt;

&lt;p&gt;Use the FCM v1 API to send notifications from your server. Ensure your server sends a valid notification payload with the necessary data.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://fcm.googleapis.com/v1/projects/${projectName}/messages:send&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For handling the notification click in the service worker for opening the action URL we need to add an event listener in the same service worker file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File: firebase-messaging-sw.js
// Handling Notification click
self.addEventListener('notificationclick', (event) =&amp;gt; {
    event.notification.close(); // CLosing the notification when clicked
    const urlToOpen = event?.notification?.data?.url || 'https://www.test.com/';
    // Open the URL in the default browser.
    event.waitUntil(
      clients.matchAll({
        type: 'window',
      })
      .then((windowClients) =&amp;gt; {
        // Check if there is already a window/tab open with the target URL
        for (const client of windowClients) {
          if (client.url === urlToOpen &amp;amp;&amp;amp; 'focus' in client) {
            return client.focus();
          }
        }
        // If not, open a new window/tab with the target URL
        if (clients.openWindow) {
          return clients.openWindow(urlToOpen);
        }
      })
    );
  });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Secure firebase config in the service worker
&lt;/h2&gt;

&lt;p&gt;As we cannot use env variables in the service worker one way to use the Firebase config is to send the Firebase config to the service worker file through URLSearchParams as it is good to hide the keys from the public file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const UrlFirebaseConfig = new URLSearchParams(
    {
      apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
      authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
      databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL ,
      projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID  ,
      storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET ,
      messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID ,
      appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID ,
      measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID ,
    }.toString()
  );

  const swUrl = `${process.env.NEXT_PUBLIC_SERVER_URL}/firebase-messaging-sw.js?${UrlFirebaseConfig}`;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;By following the insights shared in this article, you can seamlessly establish web push notifications via Firebase Cloud Messaging (FCM) in your React or Next.js application. While certain drawbacks have been discussed earlier, the inclusion of effective workarounds ensures a smooth initiation into the world of web push notifications. Reflecting on my own experience implementing this setup, I've found that despite the challenges, the enhanced user engagement and communication capabilities offered by FCM make it a valuable addition to any web development toolkit.&lt;/p&gt;

</description>
      <category>firebase</category>
      <category>notificaiton</category>
      <category>fcm</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>The Basics you need to know to start with TypeScript</title>
      <dc:creator>Deepak Yadav</dc:creator>
      <pubDate>Mon, 27 Feb 2023 05:17:19 +0000</pubDate>
      <link>https://dev.to/thedeepakyadav/the-basics-you-need-to-know-to-start-with-typescript-1pem</link>
      <guid>https://dev.to/thedeepakyadav/the-basics-you-need-to-know-to-start-with-typescript-1pem</guid>
      <description>&lt;h2&gt;
  
  
  💻 Intro
&lt;/h2&gt;

&lt;p&gt;TypeScript is a superset of JavaScript and adds optional static typing, classes, interfaces, and other advanced features to the language. It helps to improve the development experience for large-scale JavaScript applications by enabling developers to catch errors at compile-time rather than runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Why TypeScript is awesome
&lt;/h2&gt;

&lt;p&gt;We often spend hours debugging our code because of silly mistakes like passing the wrong props, typos in variable names, messing with the types, and much more.&lt;/p&gt;

&lt;p&gt;Typescript helps us the developer to save time by providing static typing. It allows specifying the types of variables, parameters, props and function return types, which helps to catch errors at compile-time rather than the runtime and definitely helps in reducing the breaking of code in production.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;TypeScript could be painful &amp;amp; seems extra work but it is worth the pain &amp;amp; effort !!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔧 How to use Typescript with React
&lt;/h2&gt;

&lt;p&gt;Using Typescript can be a little tricky sometimes, I have tried to provide examples of typescript with constructs for React application use.&lt;/p&gt;

&lt;p&gt;⇒ Variables&lt;/p&gt;

&lt;p&gt;Variables can be assigned to the various primitive data types like string, number, boolean, etc. Below is how we add types to variables&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var name : string = 'John';
var age : number = 18;  
var isPresent : boolean = true;

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

&lt;/div&gt;



&lt;p&gt;⇒ Array&lt;/p&gt;

&lt;p&gt;There are a couple of ways to give the type to the array&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var nameArray : string[];                 //declaration
nameArray = ["John", "David" , "Tom"];   //initialization
/* Another way of declaring array is 
var nameArray : Array&amp;lt;string&amp;gt;   */

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

&lt;/div&gt;



&lt;p&gt;Also, we can give an optional type to the array which can take two or more types in the array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//Optional type either string or number
let values : (string | number)[]= ['Apple', 2, 'Orange', 3, 4, 'Banana']

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

&lt;/div&gt;



&lt;p&gt;⇒Tuple&lt;/p&gt;

&lt;p&gt;Tuple is similar to the multi-type array only catch is that we don't have an optional type but a mandatory type which an array will contain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Tuple */
var person : [number, string] = [18, "John"];

/* Tuple Array */
var users : [number, string, string][];
users = [[18, "John", "Admin"],[23, "David", "Accountant"],
[40, "Tom", "Admin"]];

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

&lt;/div&gt;



&lt;p&gt;⇒ Types and Interfaces&lt;/p&gt;

&lt;p&gt;Types and Interfaces are used to define custom types for variables, functions, and other constructs. Both types and interfaces serve a similar purpose, but they have some key differences.&lt;/p&gt;

&lt;p&gt;One of the key differences between types and interfaces is that interfaces can be extended, while types cannot.&lt;/p&gt;

&lt;p&gt;Another difference between types and interfaces is that interfaces can define optional and read-only properties, while types cannot.&lt;/p&gt;

&lt;p&gt;In general, both improve code readability and maintainability.&lt;/p&gt;

&lt;p&gt;⇒Types&lt;/p&gt;

&lt;p&gt;Defining custom types with Type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type TagType = {
  id: string;
  label: string;
};
var Tag : TagType = {
    id: "123",
    label: "TypeScript"
  };

// Extending type with another type
type BlogType = {
  title: "string;"
  body: string;
}&amp;amp; TagType;

var Blog : BlogType = {
title: "\"Typescript Fundamentals\","
id: "101",
label: "Typescript",
body: "Things you need to know to start ..."
}

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

&lt;/div&gt;



&lt;p&gt;⇒Interfaces&lt;/p&gt;

&lt;p&gt;Defining custom types with Interface&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface TagInterface { 
   id: string;
   label: string;
   showTag: ()=&amp;gt;string; 
} 

var Tag : TagInterface = {
    id: "123",
    label: "TypeScript",
    showTag?    : () =&amp;gt;{return "Hi there"} // Optional properties '?'
  };

// Extending interface with another interface
interface BlogInterface extends TagInterface{
  title: "string;"
  body?: string;
};

 var Blog: BlogInterface = {
   title: "\"Typescript Fundamentals\","
   id: "101",
   label: "Typescript",
   showTag: () =&amp;gt; {
      return "Hi Tags";
   },
 };

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

&lt;/div&gt;



&lt;p&gt;⇒Function&lt;/p&gt;

&lt;p&gt;Functions in typescript can have typed parameters, typed return values, and optional parameters. Here's 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;//TagType is defined in the previous examples
const [tags, setTags] = useState&amp;lt;TagType[]&amp;gt;([]);
const addTag = (tag: Tag) =&amp;gt; {
   setTags((prev: Tag[]) =&amp;gt; [...prev, tag]);
 };

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

&lt;/div&gt;



&lt;p&gt;⇒Components&lt;/p&gt;

&lt;p&gt;Functional components in TypeScript provide a simple and powerful way to build user interfaces with type safety and code clarity. The React.FC type is used to define the type of functional component. This provides additional type safety by ensuring that the component returns a valid JSX element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { FC } from "react";
type NewTagProps = {
  onAddTag: (tag: TagType) =&amp;gt; void;
  availableTags: TagType[];
};
export const NewTag: FC&amp;lt;NewTagProps&amp;gt; = ({
  onAddTag,
  availableTags,
}) =&amp;gt; {
console.log("Availble Tags ",availableTags);
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h3 className="text-center my-3"&amp;gt;New Tags Availble&amp;lt;/h3&amp;gt;
      {
        // Map the available tags ${availableTags}
      }
    &amp;lt;/div&amp;gt;
  );
};

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Typescript Types
&lt;/h2&gt;

&lt;p&gt;Some special TypeScript types that need to be highlighted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;any - Type &lt;em&gt;any&lt;/em&gt; is a special type&lt;/li&gt;
&lt;li&gt;As the name presents it represents any type (all kinds of) of value it will help to escape the type checking&lt;/li&gt;
&lt;li&gt;unknown - Type &lt;em&gt;unknown&lt;/em&gt; is the type-safe version of any.&lt;/li&gt;
&lt;li&gt;void - Type &lt;em&gt;void&lt;/em&gt; is the absence of any type.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💡Tips
&lt;/h2&gt;

&lt;p&gt;You would probably be using VS code editor and the best way to get started with typescript is to download a typescript extension which will help you to provide autocomplete suggestions. This will help to get started with ease.&lt;/p&gt;

&lt;p&gt;To improve the hands-on experience, one can explore &lt;a href="https://www.typescriptlang.org/play" rel="noopener noreferrer"&gt;Typescript Playground&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;TypeScript is a powerful programming language that offers several benefits over JavaScript. With TypeScript, developers can write code that is more reliable, easier to maintain, and more scalable than traditional JavaScript.&lt;/p&gt;

&lt;p&gt;TypeScript has gained significant popularity recently and is now widely used in large-scale applications such as Angular, React, and Node.js. By learning TypeScript, developers can improve their skills and stay up-to-date with the latest trends in software development.&lt;/p&gt;

&lt;p&gt;Leave a ❤️ if you found this article helpful.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>careeradvice</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Infinite Scroll Using Intersection Observer API 😉</title>
      <dc:creator>Deepak Yadav</dc:creator>
      <pubDate>Sat, 21 Jan 2023 14:35:46 +0000</pubDate>
      <link>https://dev.to/thedeepakyadav/infinite-scroll-using-intersection-observer-api-3527</link>
      <guid>https://dev.to/thedeepakyadav/infinite-scroll-using-intersection-observer-api-3527</guid>
      <description>&lt;p&gt;Intersection Observer API helps to asynchronously observe changes in the intersection of a target element and perform some actions based on the intersection.&lt;br&gt;
This can be used to determine if an element is visible within the viewport or if it has been scrolled out of view, allowing for efficient implementation of things like lazy loading of images, infinite scrolling, and element tracking for analytics.&lt;/p&gt;




&lt;p&gt;One common use case for the Intersection Observer API is the lazy loading of images. Lazy loading is a technique used to delay the loading of images on a web page until the user actually needs them. This can greatly improve the performance of a web page, especially on mobile devices or slow internet connections. By using the Intersection Observer API to determine when an image is about to enter the viewport, developers can load the image just before it is needed, reducing the amount of data that needs to be loaded upfront and improving the overall loading time of the web page.&lt;/p&gt;

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

&lt;p&gt;Another use case for the Intersection Observer API is infinite scrolling. Infinite scrolling is a technique used to load additional content as the user scrolls down the web page. By using the Intersection Observer API to determine when the user has reached the bottom of the page, developers can load additional content seamlessly, providing a more fluid and seamless experience for the user.&lt;/p&gt;




&lt;p&gt;We are going to cover the implementation of infinite scrolling of products using Intersection Observer API in this article 🫡.&lt;/p&gt;

&lt;p&gt;One of the great things about this API is that it allows for the creation of custom hooks that can be easily reused across multiple components.&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%2Fcpvcyltwmlaun2g8f932.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcpvcyltwmlaun2g8f932.gif" alt="Let's do this" width="480" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, first, let's start by creating a new function called useIntersectionObserver:&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating CustomHook
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function useIntersectionObserver(options) { 

const { 
root = null, 
target, 
onIntersect, 
threshold = 0.9, 
rootMargin = "0px", 
enabled = true, 
} = options; 

useEffect(() =&amp;gt; {  
// Intersection Observer logic here 
 }, [target.current,enabled]);  

}

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

&lt;/div&gt;



&lt;p&gt;This function takes in an options object (which is destructured in this example) that can be used to customize the behaviour of the Intersection Observer. The useEffect hook is used to run the Intersection Observer logic when the element is intersected or enables is set as true.&lt;/p&gt;

&lt;p&gt;Next, we can use the IntersectionObserver constructor to create a new observer inside the UseEffect we defined:&lt;/p&gt;

&lt;h2&gt;
  
  
  Intersection Observer Object
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const observer = new IntersectionObserver((entries) =&amp;gt;  
entries.forEach((entry) =&amp;gt; entry.isIntersecting &amp;amp;&amp;amp; onIntersect()),  
   {
    root: root &amp;amp;&amp;amp; root.current, 
    rootMargin, 
    threshold, 
   } 
); 

const el = target &amp;amp;&amp;amp; target.current; 
if (!el) { 
    return; 
} 
observer.observe(el); 
return () =&amp;gt; { 
    observer.unobserve(el); 
};

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

&lt;/div&gt;



&lt;p&gt;This observer takes in two arguments: a callback function that will be called whenever an intersection event occurs, and an options object that can be used to customize the behaviour of the observer. In this case, we are using the callback function to check the isIntersecting property and call the onIntersect function.&lt;/p&gt;

&lt;p&gt;Make sure to unobserve the Intersection Observer as unobserving unnecessary elements can help to avoid unnecessary use of resources such as memory and CPU power, this can be especially important in situations where an observer is monitoring a large number of elements, or when the web page is running on a device with limited resources.&lt;/p&gt;

&lt;p&gt;Finally, we can use the current property of the useRef hook to attach the observer to the target element in our component where we need to implement infinite scrolling:&lt;/p&gt;

&lt;p&gt;The useRef hook creates a reference to the target element, and the useEffect hook is used to attach the observer to the element when it is intersected.&lt;/p&gt;

&lt;p&gt;Now that we have our custom hook, we can use it to determine when an element is visible within the viewport:&lt;/p&gt;

&lt;h2&gt;
  
  
  Calling Intersection CustoomHook
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function MyComponent() {
  const loadMoreButtonRef = useRef();
  useIntersectionObserver({
    target: loadMoreProductsRef,
    onIntersect: fetchNextPage,
    enabled: hasNextPage
  });
  return (
    &amp;lt;div&amp;gt;
      {page.results.products.map((product, index) =&amp;gt; {
        return (
          &amp;lt;div key={product.product_id}&amp;gt;
            {/* Insert Product Card Component */}
          &amp;lt;/div&amp;gt;
        );
      })}
      &amp;lt;div ref={loadMoreProductsRef}&amp;gt;
        {/* Last Product Reached */}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;In conclusion, creating a custom hook for the Intersection Observer API can greatly simplify the process of monitoring the visibility of elements on a web page.&lt;/p&gt;

&lt;p&gt;And we are almost there in implementing the infinite scroll. Create a useEffect to call the update the next page state and make the API call.&lt;/p&gt;

&lt;h2&gt;
  
  
  API call
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [currentPage, setCurrentPage] = useState(1); 
const [hasNextPage, setHasNextPage] = useState(false);
const fetchNextPage = () =&amp;gt; { 
  setCurrentPage((prev) =&amp;gt; prev + 1); 
} 
useEffect(() =&amp;gt; { 
  (async () =&amp;gt; { 
    try { 
      await fetchproducts(currentPage); 
      //Make api call with the updated page count and set hasNextPage
    } catch (error) { 
      // Handle the error 
    } 
  })() 
},[currentPage])

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

&lt;/div&gt;



&lt;p&gt;And it's done, and infinite scrolling is up and running ! 🔥&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Giving heads-up for a stale state, closures situation which may eat up some of your hair. Make sure to handle those with a coffee🧋.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;This sums up the implementation of Intersection Observer API for infinite scrolling. Using the intersection observer can be helpful and has quite a few use cases and also it helps to avoid using some different libraries.&lt;/p&gt;

&lt;p&gt;Hit 👍🏼 if you find this helpful, and share your thoughts below :)&lt;/p&gt;

&lt;p&gt;Connect with me 🙋🏻‍♂️ on &lt;a href="https://www.linkedin.com/in/deepak-yadav2672/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; ~ &lt;a href="https://twitter.com/_DeepakYadav_?t=9utJbQjnvhr4lZhnK0mMTg&amp;amp;s=09" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>welcome</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
