RepoPilot

Is there a slugify-with-counter helper? How does it work?

About sindresorhus/slugify · 2 messages · last activity 7/20/2026

Question

Is there a slugify-with-counter helper? How does it work?

RepoPilot

Yes — it's called slugifyWithCounter().

How it works:

slugifyWithCounter() is a factory function that returns a new stateful slugify function (typed as CountableSlugify) which keeps track of previously seen slugs so it can disambiguate repeats [index.js:L112-L140].

Internally:

  1. It creates a Map called occurrences to track how many times each slug has been generated [index.js:L113].
  2. The returned function countable(string, options) first runs the normal slugify(string, options) on the input [index.js:L116].
  3. If the result is an empty string, it just returns '' [index.js:L118-L120].
  4. Otherwise, it lowercases the slug (stringLower) for consistent lookups [index.js:L122].
  5. It checks numberless — the count for the "base" version of the string with any trailing -N counter suffix stripped via the regex /(?:-\d+?)+?$/ [index.js:L123].
  6. It gets the current counter for the exact stringLower key, increments it in the map (or sets it to 1 if it doesn't exist yet), and reads the new counter value [index.js:L124-L126].
  7. If newCounter >= 2 or numberless > 2, it appends -${newCounter} to the slug to make it unique [index.js:L127-L129].
  8. It returns the (possibly suffixed) slug [index.js:L131].

The returned function also exposes a .reset() method that clears the occurrences map, letting you start counting fresh [index.js:L134-L136].

Example usage (from the README and type docs):

import {slugifyWithCounter} from '@sindresorhus/slugify';

const slugify = slugifyWithCounter();

slugify('foo bar');
//=> 'foo-bar'

slugify('foo bar');
//=> 'foo-bar-2'

slugify.reset();

slugify('foo bar');
//=> 'foo-bar'

This pattern is documented as CountableSlugify in the type definitions [index.d.ts:L220-L285] and exported as slugifyWithCounter(): CountableSlugify [index.d.ts:L286-L287].

A practical use case mentioned in the README: generating unique HTML ids for headings/anchors when a document has repeated section names (e.g., multiple "Example" subsections across different sections), so anchor links resolve to the correct heading [readme.md:L279-L283].

FOLLOW_UPS:

  • What does the decamelize option actually transform?
  • How do customReplacements override default replacements?
  • What transliteration languages does @sindresorhus/transliterate support?

Want to ask your own question?

Open chat for sindresorhus/slugify

Public Q&A. Generated by RepoPilot from the actual source of sindresorhus/slugify. AI answers can be incomplete or stale — verify before relying on them.