Search code examples
reactjsnext.jsfirebase-analyticsnext-router

How to include useRouter in function from one place with Next.js?


I have a function in Next.js project that collects events for Firebase analytics.

import analytics from '@utility/firebase';

const handleLogEvents = (event) => {
  const currentDate = new Date();
  logEvent(analytics, event.event_name, {
    branch_slug: event.branch_slug,
    timestamp: currentDate,
    ...event.properties,
  });
};

For example, when a category is clicked, I ensure that the event is sent to Firebase.

const handleCategoryClick = (id, title, branchSlug) => {
  const event = {
    event_name: 'category_click',
    properties: {
      branch_slug: branchSlug,
      category_id: id,
      category_name: title,
    },
  };
  handleLogEvents(event);
};

const { query } = useRouter(); 
const { branch } = query; // I have to call events on every page I post.

return(
  <div onClick={() => handleCategoryClick(id, title, branch)}>Example Div</div>
)

I call events in multiple functions (product, category etc.). The routes I use in my project are dynamic. Every time I send an event to Firebase, I need to get the route name. Every time I call handleLogEvents I have to write the following code on the page:

const { query } = useRouter();
const { branch } = query;

Do I have a chance to use handleLogEvents in a function instead of calling this useRouter every time I call it? Every time I use this function, it seems unnecessary to go and call the router.


Solution

  • You can move handleLogEvents to a re-usable custom hook where you enclose the useRouter value.

    import { useCallback } from 'react'
    import { useRouter } from 'next/router'
    import analytics from '@utility/firebase';
    
    export const useLogEvents = () => {
        const { query } = useRouter();
        const { branch } = query;
    
        const handleLogEvents = useCallback((event) => {
            const currentDate = new Date();
            logEvent(analytics, event.event_name, {
                branch_slug: branch,
                timestamp: currentDate,
                ...event.properties
            });
        }, [branch]);
    
        return { handleLogEvents }
    };
    

    Then, you simply have to call the custom hook to retrieve the handleLogEvents function with the right branch value from the router.

    const SomeComponent = () => {
        const { handleLogEvents } = useLogEvents();
    
        const handleCategoryClick = (id, title) => {
            const event = {
                event_name: 'category_click',
                properties: {
                    category_id: id,
                    category_name: title
                }
            };
            handleLogEvents(event);
        };
    
        return (
            <div onClick={() => handleCategoryClick(id, title)}>Example Div</div>
        )
    }