npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-modal-back-button

v1.0.10

Published

A lightweight React hook that enables native back button support for modals and dialogs. Press the back button to close modals instead of navigating away.

Readme

react-modal-back-button

A lightweight React hook that enables native back button support for modals and dialogs. Press the back button to close modals instead of navigating away from the page.

npm version Bundle size License: MIT

Features

  • 🎯 Simple API - Built-in state management, no need for extra useState
  • 📱 Mobile-First - Perfect UX for mobile users
  • Lightweight - Zero dependencies, minimal footprint
  • 🔧 Flexible - Works with any modal library or custom implementation
  • 🎨 TypeScript - Full type safety included
  • ⚙️ SSR Safe - Works with Next.js and other SSR frameworks

Installation

npm install react-modal-back-button
yarn add react-modal-back-button
pnpm add react-modal-back-button

The Problem

When a modal is open and users press the back button (especially on mobile), the browser navigates to the previous page instead of closing the modal. This breaks the expected user experience and can cause data loss.

The Solution

This hook intercepts back button presses and closes your modal instead, creating an intuitive mobile-native experience that users expect.

Usage

Basic Example

import { useModalBackButton } from 'react-modal-back-button';

function MyComponent() {
  const { isOpen, open, close } = useModalBackButton();

  return (
    <div>
      <button onClick={open}>
        Open Modal
      </button>

      {isOpen && (
        <div className="modal">
          <h2>My Modal</h2>
          <button onClick={close}>
            Close
          </button>
        </div>
      )}
    </div>
  );
}

With Popular Modal Libraries

React Modal

import Modal from 'react-modal';
import { useModalBackButton } from 'react-modal-back-button';

function MyComponent() {
  const { isOpen, open, close } = useModalBackButton();

  return (
    <>
      <button onClick={open}>Open Modal</button>
      
      <Modal isOpen={isOpen} onRequestClose={close}>
        <h2>Hello Modal</h2>
        <button onClick={close}>Close</button>
      </Modal>
    </>
  );
}

Material-UI (MUI)

import { Dialog, DialogTitle, DialogContent, Button } from '@mui/material';
import { useModalBackButton } from 'react-modal-back-button';

function MyComponent() {
  const { isOpen, open, close } = useModalBackButton();

  return (
    <>
      <Button onClick={open}>Open Dialog</Button>
      
      <Dialog open={isOpen} onClose={close}>
        <DialogTitle>Hello Dialog</DialogTitle>
        <DialogContent>
          Content here
        </DialogContent>
      </Dialog>
    </>
  );
}

Headless UI

import { Dialog } from '@headlessui/react';
import { useModalBackButton } from 'react-modal-back-button';

function MyComponent() {
  const { isOpen, open, close } = useModalBackButton();

  return (
    <>
      <button onClick={open}>Open</button>
      
      <Dialog open={isOpen} onClose={close}>
        <Dialog.Panel>
          <Dialog.Title>Title</Dialog.Title>
        </Dialog.Panel>
      </Dialog>
    </>
  );
}

Options

const { isOpen, open, close, toggle } = useModalBackButton({
  key: 'my-modal',
  enabled: true,
  pushStateOnOpen: true,
  cleanupOnClose: true
});

Option Details

  • key: A unique identifier for the modal. Useful when you have multiple modals. Auto-generated if not provided.

  • enabled: Set to false to temporarily disable the hook without unmounting.

  • pushStateOnOpen: When true (default), adds a history entry when the modal opens. Set to false if you manage history yourself.

  • cleanupOnClose: When true (default), removes the history entry when you close the modal programmatically (e.g., clicking a close button). Set to false to keep the history entry.

How It Works

The hook manages browser history to create seamless back button support:

  1. Modal Opens: Pushes a new history entry to the browser stack
  2. Back Button Pressed: Intercepts the popstate event and closes the modal
  3. Modal Closed Programmatically: Automatically removes the history entry to prevent navigation issues
  4. Smart Detection: Distinguishes between back button closes and programmatic closes to handle cleanup correctly

This ensures the back button works exactly as users expect, without breaking browser navigation.

API Reference

useModalBackButton(options?)

Parameters

| Parameter | Type | Required | Description | |-----------|------|----------|-------------| | options | UseModalBackButtonOptions | No | Configuration options |

Returns

| Property | Type | Description | |----------|------|-------------| | isOpen | boolean | Current state of the modal | | open | () => void | Function to open the modal | | close | () => void | Function to close the modal | | toggle | () => void | Function to toggle modal state |

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | key | string | auto-generated | Unique identifier for the modal. Useful when managing multiple modals | | enabled | boolean | true | Enable or disable the hook without unmounting | | pushStateOnOpen | boolean | true | Whether to push a history entry when modal opens | | cleanupOnClose | boolean | true | Whether to remove history entry when modal closes programmatically |

TypeScript

Full TypeScript support is included with complete type definitions.

import { 
  useModalBackButton, 
  UseModalBackButtonOptions,
  UseModalBackButtonReturn 
} from 'react-modal-back-button';

const options: UseModalBackButtonOptions = {
  key: 'my-modal',
  enabled: true,
  pushStateOnOpen: true,
  cleanupOnClose: true
};

const { isOpen, open, close, toggle }: UseModalBackButtonReturn = useModalBackButton(options);

Advanced Usage

Multiple Modals

When working with multiple modals, provide unique keys to avoid conflicts:

function App() {
  const settings = useModalBackButton({ key: 'settings-modal' });
  const profile = useModalBackButton({ key: 'profile-modal' });

  return (
    <>
      <button onClick={settings.open}>Open Settings</button>
      <button onClick={profile.open}>Open Profile</button>
      
      {settings.isOpen && <SettingsModal onClose={settings.close} />}
      {profile.isOpen && <ProfileModal onClose={profile.close} />}
    </>
  );
}

Toggle Function

Use the built-in toggle function for convenience:

function App() {
  const { isOpen, toggle } = useModalBackButton();

  return (
    <>
      <button onClick={toggle}>
        {isOpen ? 'Close' : 'Open'} Modal
      </button>
      
      {isOpen && <Modal onClose={toggle} />}
    </>
  );
}

Conditional Enabling

Disable the hook based on conditions without unmounting:

const isMobile = useMediaQuery('(max-width: 768px)');

const { isOpen, open, close } = useModalBackButton({
  enabled: isMobile
});

Custom History Management

If you manage history yourself, disable automatic pushing:

const { isOpen, open, close } = useModalBackButton({
  pushStateOnOpen: false
});

Browser Support

Works in all modern browsers that support the History API:

  • Chrome/Edge (latest)
  • Firefox (latest)
  • Safari (latest)
  • iOS Safari (latest)
  • Chrome Android (latest)

FAQ

Q: Does this work with Next.js?
A: Yes! The hook is SSR-safe and works perfectly with Next.js and other SSR frameworks.

Q: Can I use this with multiple modals?
A: Yes, provide a unique key option for each modal instance.

Q: Does this affect my router?
A: No, the hook only manages history when the modal is open and cleans up properly.

Q: What happens if I press back multiple times?
A: Only the modal close is handled. Further back presses will navigate normally through your app's history.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT