DEV Community

Cover image for IMPLEMENTING APP SESSION TIMEOUT IN React.JS
Daniel Musembi
Daniel Musembi

Posted on

IMPLEMENTING APP SESSION TIMEOUT IN React.JS

Introduction

Let's start by defining what a session timeout is in web applications. A session timeout occurs when inactivity on a webpage is detected after a certain amount of time. If you have not selected to persist, your session will time out, and you will be logged out. I'm sure most of us have experienced something similar to this:

Image description

Is a timeout truly necessary?

Most web applications may not require timeout functionality; however, if you are developing a project that handles sensitive user information or a financial application where users perform transactions and leave their money in your care, timeout functionality that monitors user activity and triggers some action when a set time elapses is critical. Some of the benefits are as follows:

Resource Management The timeout feature allows you to release and free server resources associated with a user session. This is especially important when resources are limited, and it is crucial to manage and release resources when they are no longer needed.

Compliance with Security Standards Many security standards and best practices advocate the use of timeouts to avoid session hijacking and unauthorized access. Adherence to these standards contributes to the security and compliance of the application.

Security and Privacy Enhancement Timeouts reduce the risk of unauthorized access to a user's account. An automatic timeout ensures that the session finishes after a certain length of time if the user forgets to log out or leaves the app alone.

Prevention of Accidental Data Exposure Timeouts limit the possibility of unintentional data disclosure in cases where users forget to log out by terminating sessions automatically.

Let's go ahead and integrate timeout functionality into an app now that we've demonstrated its importance.

Timeout implementation in React.

We begin by using Vite to bootstrap our React app. Vite is a build tool that improves the development process for modern web applications that use JavaScript frameworks such as Vue.js and React. It focuses on delivering a quick and efficient development environment by using browsers' native ES Module (ESM) capabilities. To learn more about Vite see here Vite.

We will start by bootstrapping our React app using Vite, to do this we first navigate to a directory where we will create our project.

Let's start by creating a new folder 📂 on the desktop, and give it the name app.

Open Visual Studio Code and drag the app-timeout folder we just created onto it. And after pressing Ctrl + Tab Keys, you can see we're in our app directory.

Image description

Let's add the following commands to set up our app.

npm create vite@latest
// select Typescript as the preferred language, and
// specify the project name, here it is app-timeout
Enter fullscreen mode Exit fullscreen mode

Image description
Run the following command to open our project directory:

cd app-timeout
Enter fullscreen mode Exit fullscreen mode

Image description

Run the following command to add the required dependencies:

npm install
Enter fullscreen mode Exit fullscreen mode

To run our application, add the following command and hit enter:

npm run dev
Enter fullscreen mode Exit fullscreen mode

Image description

Click the http://localhost:5173/ and see your app in action.

Image description

We also need to install react-router-dom and @types/node, to help with routing and provide the appropriate types we need respectively. Run the code below to do this:

npm i react-router-dom 
npm install --save-dev @types/node

Enter fullscreen mode Exit fullscreen mode

In the src folder, create a new folder named components, in there create another folder called providers and in there create a file and name it timeout-provider.tsx. In this file, add the following code:


Enter fullscreen mode Exit fullscreen mode

Image description

import { ReactNode, useEffect, useRef } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';

export function TimeoutProvider({ children }: { children: ReactNode }) {
  const navigate = useNavigate();
  const location = useLocation();
  const timeoutRef = useRef<NodeJS.Timeout>();

  useEffect(() => {
    if (exemptedRoutes.includes(location.pathname)) return;
    const handleWindowEvents = () => {
      clearTimeout(timeoutRef.current);

      timeoutRef.current = setTimeout(() => {
        //Perform whatever logic you want in here, clear localStorage and log user out, show a popup modal or just navigate to another page
        navigate('/2024');
      }, 10000);
    };

    // listen for specific window events to ensure user is still active
    window.addEventListener('mousemove', handleWindowEvents);
    window.addEventListener('keydown', handleWindowEvents);
    window.addEventListener('click', handleWindowEvents);
    window.addEventListener('scroll', handleWindowEvents);

    handleWindowEvents();

    //cleanup function
    return () => {
      window.removeEventListener('mousemove', handleWindowEvents);
      window.removeEventListener('keydown', handleWindowEvents);
      window.removeEventListener('click', handleWindowEvents);
      window.removeEventListener('scroll', handleWindowEvents);
    };
  }, [navigate, location.pathname]);

  return children;
}

const exemptedRoutes = ['/404', '/sign-up', '/forgot-password'];

Enter fullscreen mode Exit fullscreen mode

Let's get straight to the business and understand what's happening here in this code.

This code implements a feature for a web application that aids in the management of user activity by automatically redirecting users to a specified page if they have been idle for some time.

This code implements a feature for a web application that aids in the management of user activity by automatically redirecting users to a specified page if they have been idle for a period of time.

Let's break down the code:

TimeoutProvider: Think of it as a controller or manager. It watches what you're doing on the website.

Hooks and References: These are like tools it uses to understand what's happening. It listens to where you are on the website (location) and how to move you around (navigate).

Setting a Timer: The code sets a timer for 10 seconds. If you're not moving the mouse, pressing keys, clicking, or scrolling during this time, it decides you're inactive and triggers an action (like going to a specific page).

Ignoring Certain Pages: Some pages don't trigger this timer, like when you're signing up or recovering a forgotten password. It doesn't redirect you from these pages.

Let's update the code in the main.tsx file with the code below:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import './index.css';

import { RouterProvider, createBrowserRouter } from 'react-router-dom';
import { Home } from './pages/Home.tsx';
import { NextYear } from './pages/2024.tsx';

const router = createBrowserRouter([
  {
    path: '/',
    element: <App />,
    children: [
      {
        path: '/',
        element: <Home />,
      },
      {
        path: '/2024',
        element: <NextYear />,
      },
    ],
  },
]);

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <RouterProvider router={router} />
  </React.StrictMode>
);

Enter fullscreen mode Exit fullscreen mode

In the code above, we create our router and map each route to its corresponding component.

In the src folder, create a new folder called pages and in there create two new files called Home.tsx and 2024.tsx

In Home.tsx put the following code:

export function Home() {
  return (
    <div>
      <p style={{ fontSize: '2rem', fontWeight: 'bold' }}>Goodbye 2023, you were the year that made us laugh, cry, and Google everything!🫡</p>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

In 2024.tsx put the following code:

export function NextYear() {
  return (
    <div>
      <p style={{ fontSize: '2rem', fontWeight: 'bold' }}>Welcome to 2024!!!🎉🍾🎊</p>
    </div>
  );
}

Enter fullscreen mode Exit fullscreen mode

Finally, update the code in App.tsx to the following:

import './App.css';
import { Outlet } from 'react-router-dom';
import { TimeoutProvider } from './components/providers/timeout-provider';

function App() {
  return (
    <TimeoutProvider>
      <Outlet />
    </TimeoutProvider>
  );
}

export default App;

Enter fullscreen mode Exit fullscreen mode

We've ensured that our timeout feature is available to all pages in the React project, save those that are exempted, by wrapping Outlet in the TimeoutProvider we developed. As a result, the purpose of adding a timeout for a React application is met.

See the photo below before the session timeout:

Image description

And a photo after the session timeout:

Image description

Conclusion

As I'm about to wrap up this article, it feels like I've reached a timeout for the year 2023. Just like a session that's naturally timed out, bidding farewell to the quirky bugs, unexpected errors, and delightful surprises of 2023.

Now, as the clock ticks and the page refreshes to 2024, let's gear up for a new session in the software of life! May this new year be as bug-free as a perfectly coded app and filled with updates that bring joy, laughter, and perhaps a few pleasant surprises, just like discovering an Easter egg in the code.

So, here's to embracing the unknowns, debugging life's glitches, and exploring new routes in the journey ahead. Wishing everyone a happy new year—may your sessions never time out, except when it's for a well-deserved break!

Top comments (0)