Skip to content

truncateMiddle

Edit

Truncates the middle of text by grapheme while preserving both ends.

truncateMiddle.ts
const segmenter =
typeof Intl !== "undefined" && typeof Intl.Segmenter === "function"
? new Intl.Segmenter(undefined, { granularity: "grapheme" })
: undefined;
const splitGraphemes = (value: string): string[] => {
if (!segmenter) return Array.from(value);
return Array.from(segmenter.segment(value), ({ segment }) => segment);
};
/** Truncates the middle of text by grapheme while preserving both ends. */
export const truncateMiddle = (
value: string,
maxLength: number,
omission: string = "…"
): string => {
if (!Number.isSafeInteger(maxLength) || maxLength < 0) {
throw new RangeError("maxLength must be a non-negative safe integer");
}
const graphemes = splitGraphemes(value);
if (graphemes.length <= maxLength) return value;
const marker = splitGraphemes(omission);
if (marker.length >= maxLength) return marker.slice(0, maxLength).join("");
const available = maxLength - marker.length;
const start = Math.ceil(available / 2);
const end = Math.floor(available / 2);
return (
graphemes.slice(0, start).join("") +
omission +
graphemes.slice(graphemes.length - end).join("")
);
};
Terminal
wget -O src/lib/truncateMiddle.ts https://raw.githubusercontent.com/jrTilak/lazykit/HEAD/registry/functions/truncateMiddle.ts
truncateMiddle.example.ts
import { truncateMiddle } from "./truncateMiddle";
const commit = truncateMiddle("a1b2c3d4e5f6", 8);
// "a1b2…5f6"
const account = truncateMiddle("👨‍👩‍👧‍👦-account-owner-👍🏽", 10);
// "👨‍👩‍👧‍👦-acc…er-👍🏽"
  • value (string) — Text to shorten.
  • maxLength (number) — Non-negative safe-integer maximum number of visible characters.
  • omission (string) — Marker included within the maximum, defaulting to .
  • Uses Intl.Segmenter to preserve emoji sequences, flags, and combining marks. Environments without it fall back to Unicode code points.