Core Examples

Common patterns using the core API

Form Fields

Accessible label + input pairing with unique IDs.

import { useUniqueId } from 'react-unique-id-generator';

function TextField({ label }: { label: string }) {
  const id = useUniqueId('field-');
  return (
    <div>
      <label htmlFor={id}>{label}</label>
      <input id={id} type="text" />
    </div>
  );
}

ARIA Attributes

Link descriptions and controls to elements.

function Accordion({ title, children }) {
  const [headId, panelId] = useUniqueIds(2, 'acc-');
  return (
    <div>
      <h3 id={headId}>
        <button aria-controls={panelId}
                aria-expanded="true">
          {title}
        </button>
      </h3>
      <div id={panelId}
           role="region"
           aria-labelledby={headId}>
        {children}
      </div>
    </div>
  );
}

Server-Side Rendering

Per-request isolation with createServerIdManager.

import { createServerIdManager } from 'react-unique-id-generator';

export default function handler(req, res) {
  const ids = createServerIdManager('req-');

  const formId = ids.nextId();   // "req-1"
  const labelId = ids.nextId();  // "req-2"

  res.send(renderToString(
    <form id={formId}>...</form>
  ));
}

Automation Testing

Consistent test selectors via generateAutomationId.

import { useAutomationId } from 'react-unique-id-generator';

function LoginForm() {
  const testId = useAutomationId('login');
  return (
    <form data-testid={testId}>
      <input data-testid={`${testId}-email`} />
      <button data-testid={`${testId}-submit`}>
        Sign In
      </button>
    </form>
  );
}

Secure Tokens

Cryptographic random IDs for CSRF tokens and nonces.

import { generateSecureId } from 'react-unique-id-generator';

function SecureForm() {
  const csrfToken = generateSecureId();
  return (
    <form>
      <input
        type="hidden"
        name="_csrf"
        value={csrfToken}
      />
      {/* form fields */}
    </form>
  );
}

Scoped Modules

Independent counters per feature via nextIdForScope.

import { nextIdForScope } from 'react-unique-id-generator';

const navId  = nextIdForScope('nav', 'nav-');   // "nav-1"
const navId2 = nextIdForScope('nav', 'nav-');   // "nav-2"
const formId = nextIdForScope('form', 'frm-'); // "frm-1"

Dynamic Lists

Stable keys for dynamically rendered items.

import { useUniqueIds } from 'react-unique-id-generator';

function DynamicList({ items }) {
  const ids = useUniqueIds(items.length, 'item-');
  return (
    <ul>
      {items.map((item, i) => (
        <li key={ids[i]}>{item}</li>
      ))}
    </ul>
  );
}

Dev Dashboard

Live metrics with useIdMetrics and useTrackedUniqueId.

import {
  useTrackedUniqueId,
  useIdMetrics
} from 'react-unique-id-generator';

function Widget() {
  const id = useTrackedUniqueId('widget-');
  const metrics = useIdMetrics();
  return <div id={id}>
    Active: {metrics.activeCount}
  </div>;
}

v2.2 Examples

New features introduced in v2.2

Custom BEM Strategy

Define a BEM-style ID strategy for component-scoped class names.

import {
  generateIdWithStrategy
} from 'react-unique-id-generator';

const bemStrategy = {
  generate(prefix, suffix, counter) {
    return `${prefix}__element--${counter}${suffix}`;
  }
};

const id = generateIdWithStrategy(
  bemStrategy, 'block', '-mod'
);
// "block__element--1-mod"

Collision-Safe Generation

Detect and prevent duplicate IDs across your application.

import {
  CollisionDetector
} from 'react-unique-id-generator';

const detector = new CollisionDetector({
  action: 'throw'
});

detector.register('nav-1');   // OK
detector.register('nav-2');   // OK
detector.register('nav-1');   // Throws!

// Or use the convenience function:
import { checkCollision } from 'react-unique-id-generator';
checkCollision('my-id'); // uses global detector

Dynamic List with ID Pool

Pre-allocate and reuse IDs for frequently changing lists.

import { useIdPool } from 'react-unique-id-generator';

function ChatMessages() {
  const acquire = useIdPool(20, 'msg-');
  const [messages, setMessages] = useState([]);

  const addMessage = (text) => {
    setMessages(prev => [
      ...prev,
      { id: acquire(), text }
    ]);
  };

  return (
    <ul>
      {messages.map(m => (
        <li key={m.id}>{m.text}</li>
      ))}
    </ul>
  );
}

SSR with Request-Scoped IDs

Isolate ID counters per server request with SSRProvider.

import {
  SSRProvider,
  useSSRSafeId
} from 'react-unique-id-generator';

// Server entry
function handleRequest(req) {
  return renderToString(
    <SSRProvider requestId={req.id}>
      <App />
    </SSRProvider>
  );
}

// Component
function FormField() {
  const id = useSSRSafeId('field');
  // "req-abc123-field-1"
  return <input id={id} />;
}

Dot-Delimited Namespace IDs

Join prefix, counter, and suffix with custom delimiters.

import {
  generateDelimitedId,
  useDelimitedId
} from 'react-unique-id-generator';

// Dot-separated namespace
const id = generateDelimitedId({
  prefix: 'app.nav',
  suffix: 'item',
  delimiter: '.'
});
// "app.nav.1.item"

// Hook variant
function NavItem() {
  const id = useDelimitedId('nav', '.', 'link');
  // "nav.1.link"
  return <a id={id}>...</a>;
}

v2.3 Examples

Stable CSS selector generation for analytics, testing, and session replay

Analytics Click Tracking

Generate stable selectors for analytics events without manual data-* attributes.

import { useRef } from 'react';
import { useStableSelector } from 'react-unique-id-generator';

function TrackedButton({ label }) {
  const ref = useRef(null);
  const selector = useStableSelector(ref);

  return (
    <button ref={ref}
      onClick={() =>
        analytics.track('click', { selector })
      }>
      {label}
    </button>
  );
}

Global Click Listener

Capture selectors for any clicked element, filtering out CSS-in-JS noise.

import { generateSelector } from 'react-unique-id-generator';

document.addEventListener('click', (e) => {
  const target = e.target;
  const selector = generateSelector(target, {
    ignoreClassPattern: /^css-|^sc-/,
    maxDepth: 3,
  });

  console.log('Clicked:', selector);
  // e.g. "#nav button.menu-toggle"
});

Scoped Selectors

Generate selectors scoped to a specific container element.

import { generateSelector } from 'react-unique-id-generator';

const modal = document.getElementById('modal');
const btn = modal.querySelector('button');

const selector = generateSelector(btn, {
  root: modal,
});
// Unique within the modal, not the whole page

Migration Guide

Upgrade from v1.x to v2.x in three steps

1

Wrap in IdProvider

Add the provider at your app root for scoped, predictable counters.

// Before (v1)
import nextId from 'react-unique-id-generator';

function App() {
  return <Form />;
}

// After (v2)
import { IdProvider } from 'react-unique-id-generator';

function App() {
  return (
    <IdProvider prefix="app-">
      <Form />
    </IdProvider>
  );
}
2

Replace Global Prefix/Suffix

Move from setGlobalPrefix/setGlobalSuffix to provider props.

// Before (v1)
import nextId, { setGlobalPrefix } from 'react-unique-id-generator';
setGlobalPrefix('app-');
const id = nextId();  // "app-1"

// After (v2)
import { useUniqueId } from 'react-unique-id-generator';

function Component() {
  const id = useUniqueId('app-');  // "app-1"
  return <div id={id} />;
}
3

Done!

The v1 API (nextId, resetId, setGlobalPrefix, setGlobalSuffix, generateId) is still fully available as legacy exports. No breaking changes — upgrade at your own pace.