Examples & Migration
Real-world usage patterns, integration recipes, and a step-by-step migration guide from v1 to v2.
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
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>
);
}
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} />;
}
Done!
The v1 API (nextId, resetId, setGlobalPrefix, setGlobalSuffix, generateId) is still fully available as legacy exports. No breaking changes — upgrade at your own pace.