<IdProvider>

Context provider that scopes ID state to its subtree. Each provider has an independent counter.

PropTypeDefaultDescription
prefixstring""Prefix for all IDs in this scope
suffixstring""Suffix for all IDs in this scope
startIdnumber0Initial counter value
<IdProvider prefix="page-">
  <Header />          {/* "page-1" */}
  <IdProvider prefix="modal-">
    <ModalContent />  {/* "modal-1" */}
  </IdProvider>
  <Footer />          {/* "page-2" */}
</IdProvider>

useIdContext(): IdContextValue | null

Access the current provider's context. Returns null outside a provider.

const ctx = useIdContext();
if (ctx) console.log(ctx.prefix);

useUniqueId(localPrefix?: string): string

Stable unique ID on mount. Persists across re-renders.

function MyInput() {
  const id = useUniqueId('input-');  // "input-1"
  return (
    <div>
      <label htmlFor={id}>Name</label>
      <input id={id} />
    </div>
  );
}

useUniqueIds(count: number, localPrefix?: string): string[]

Multiple stable IDs at once.

const [emailId, passId] = useUniqueIds(2, 'login-');
// ["login-1", "login-2"]

createServerIdManager(options?): ServerIdManager

Isolated ID manager for SSR. One instance per request.

OptionTypeDefault
prefixstring""
suffixstring""
startIdnumber0
import { createServerIdManager } from 'react-unique-id-generator';

app.get('*', (req, res) => {
  const ids = createServerIdManager({ prefix: 'ssr-' });

  const headerId  = ids.nextId();        // "ssr-1"
  const contentId = ids.nextId();        // "ssr-2"
  const navId     = ids.nextId('nav-');  // "nav-3"
});
MethodReturnsDescription
nextId(localPrefix?)stringNext ID
resetId()voidReset counter
getCurrentId()numberCurrent counter
setId(id)voidSet counter

Naming Strategies

sequential
"Button-1"
kebab-case
"user-profile-1"
camelCase
"myButton-1"
custom
"e2e__Btn__1"

generateAutomationId(componentName, options?): string

generateAutomationId('Button')                                    // "Button-1"
generateAutomationId('UserProfile', { strategy: 'kebab-case' })   // "user-profile-2"
generateAutomationId('myButton', { strategy: 'camelCase' })       // "myButton-3"
generateAutomationId('Btn', { prefix: 'qa-', separator: '_' })   // "qa-Btn_4"

useAutomationId(componentName, options?): string

Hook version. Stable across re-renders.

function SubmitButton() {
  const testId = useAutomationId('SubmitButton', { strategy: 'kebab-case' });
  return <button data-testid={testId}>Submit</button>;
  // <button data-testid="submit-button-1">
}

AutomationIdPool

Pre-allocate IDs for large apps. Acquire, release, reuse.

const pool = new AutomationIdPool(100, 'component', {
  strategy: 'kebab-case',
  prefix: 'test-',
});

pool.acquire();   // "test-component-1"
pool.acquire();   // "test-component-2"
pool.release(id); // return to pool

generateSecureId(length?: number): string

Generates a cryptographically random ID. Uses crypto.randomUUID when available, falls back to crypto.getRandomValues, then Math.random.

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

generateSecureId();    // "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
generateSecureId(16); // "a1b2c3d4e5f67890" (hex fallback)

nextIdForScope(scope, prefix?): string

Generate sequential IDs within a named scope. Each scope has an independent counter.

nextIdForScope('form', 'field-');   // "field-1"
nextIdForScope('modal', 'modal-'); // "modal-1"
nextIdForScope('form', 'field-');   // "field-2"

Other Scope Utilities

resetIdForScope('form');   // reset one scope
resetAllScopes();          // reset all scope counters
getScopeCounter('form');   // 2 (current counter value)
getActiveScopes();         // ["form", "modal"]

useTrackedUniqueId(localPrefix?): string

Like useUniqueId, but tracks the ID and automatically removes it from the registry on unmount.

function ListItem({ label }) {
  const id = useTrackedUniqueId('item-');  // tracked + auto-cleaned
  return <li id={id}>{label}</li>;
}

useIdMetrics(): IdMetrics

React hook that subscribes to real-time ID metrics. Re-renders when metrics change.

FieldTypeDescription
totalGeneratednumberTotal tracked IDs ever created
activeCountnumberCurrently mounted tracked IDs
peakActiveCountnumberHighest simultaneous active count
function DebugPanel() {
  const metrics = useIdMetrics();
  return (
    <pre>
      Active: {metrics.activeCount}
      Peak:   {metrics.peakActiveCount}
      Total:  {metrics.totalGenerated}
    </pre>
  );
}

Utility Functions

getIdMetrics();         // { totalGenerated, activeCount, peakActiveCount }
getActiveIdCount();     // number of currently tracked IDs
resetIdMetrics();       // reset totalGenerated counter
cleanupInactiveIds();  // clear the entire tracking registry

Overflow Protection

All counters emit a dev-mode warning when they exceed OVERFLOW_THRESHOLD (1,000,000). Fires once per counter, resets with the counter.

import { OVERFLOW_THRESHOLD } from 'react-unique-id-generator';
// OVERFLOW_THRESHOLD === 1_000_000

generateSelector(element, options?): string

Generate a unique, human-readable CSS selector for a DOM element. Tries strategies in priority order: stable ID, data attributes, ARIA roles, semantic attributes, CSS classes, landmark tags, then ancestor traversal.

OptionTypeDefaultDescription
rootElementdocumentScope uniqueness checks to a subtree
dataAttributesstring[]['data-testid', ...]Data attributes to check (in priority order)
maxDepthnumber5Max ancestor levels to traverse
ignoreIdPatternRegExp/^[:.]|^\d/IDs matching this are skipped as dynamic
ignoreClassPatternRegExp-Classes matching this are excluded
import { generateSelector } from 'react-unique-id-generator';

const btn = document.querySelector('button.submit');
const selector = generateSelector(btn);
// e.g. "button.submit" or "#form button.submit"

// Custom options
generateSelector(el, {
  dataAttributes: ['data-qa'],
  ignoreClassPattern: /^css-|^sc-/,
  maxDepth: 3,
});

useStableSelector(ref, options?): string | null

React hook that computes a stable CSS selector for a ref'd element once on mount. Returns null until the ref is attached.

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

function TrackedButton() {
  const ref = useRef<HTMLButtonElement>(null);
  const selector = useStableSelector(ref);

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

Selector Priority Chain

PriorityStrategyExample
1Stable ID#my-element
2Data attributes[data-testid="submit"]
3ARIA role[role="navigation"]
4Semantic attributesinput[name="email"]
5CSS classesbutton.primary
6Landmark tagsnav, header
7Ancestor traversal#form button.submit

resetSelectorCache(): void

No-op reset function included for API consistency. The selector module is stateless.

These use global state. Still functional in v2.x with deprecation warnings.

nextId(localPrefix?: string | null): string

nextId()           // "1"
nextId()           // "2"
nextId('input-')   // "input-3"

generateId(prefix?, suffix?): string

generateId('btn-', '-primary') // "btn-1-primary"
generateId('icon-')            // "icon-2"

setGlobalPrefix(prefix) Deprecated

Use <IdProvider prefix="..."> instead.

setGlobalSuffix(suffix) Deprecated

Use <IdProvider suffix="..."> instead.

Other

resetId();          // reset counter to 0
getCurrentId();     // get current counter value
setId(10);           // set counter to specific value