seo-slug
v0.2.0
Published
SEO-friendly slugs with official Ukrainian transliteration (КМУ №55/2010 default, ДСТУ 9112:2021 optional). Tiny, zero-dependency, ESM-only TypeScript.
Maintainers
Readme
seo-slug
SEO-friendly slugs with official Ukrainian transliteration. Tiny, zero-dependency, TypeScript, ESM.
import { slug, transliterateUk } from 'seo-slug'
slug('Запоріжжя — це Україна!') // 'zaporizhzhia-tse-ukraina'
slug('Œuvre für São Paulo') // 'oeuvre-fur-sao-paulo'
transliterateUk('Київ') // 'Kyiv'Why another slugger?
Generic sluggers transliterate Ukrainian with Russian-ish or ISO-9 tables (и→i, Київ→Kiyv/Kijev). Ukraine has an official romanization — Cabinet of Ministers Resolution No. 55 (2010) — with positional rules generic tables can't express: Київ→Kyiv, Згорани→Zghorany, word-initial Я→Ya vs mid-word я→ia. It's what passports, road signs, and the world's press use. This library makes it the default.
Ukrainian schemes
kmu-2010(default) — КМУ №55/2010: passports, geographic names, official documents. Positional rules (word-initial Є/Ї/Й/Ю/Я,зг→zgh), soft sign and in-word apostrophe omitted. Still in force, unchanged.dstu-9112— ДСТУ 9112:2021 System B (ASCII), the national technical standard (in force since 2022; complements, does not replace, КМУ №55):Київ→Kyjiv,ь→j,г→gh. Slug-grade: the standard's retransliteration disambiguation marks are omitted (slugs strip apostrophes anyway). For faithful, reversible ДСТУ 9112 — both systems, 11 languages — useuklatn.
slug('Хмельницький') // 'khmelnytskyi'
slug('Хмельницький', { scheme: 'dstu-9112' }) // 'khmeljnycjkyj'API
slug(input, options?)
Ukrainian romanization → Latin diacritics folding (NFKD + æ/ø/ß/đ/ł/þ/œ/…) → ASCII word runs joined by the separator.
| Option | Default | |
|-------------|--------------|---|
| scheme | 'kmu-2010' | Ukrainian romanization scheme |
| separator | '-' | word separator |
| lowercase | true | lowercase the result |
| maxLength | ∞ | cut at the last full word within the limit |
| ampersand | 'and' | what & becomes ('ta', '' to drop, …) |
Word semantics: in-word apostrophes glue their word (Gojira's → gojiras — the
github-slugger/slugify behavior, and the КМУ apostrophe rule extended to Latin);
& becomes a real word instead of vanishing (S&M2 → s-and-m2).
transliterateUk(input, scheme?)
Ukrainian Cyrillic → Latin, casing-aware (ШАПКА→SHAPKA, Шапка→Shapka). Non-Ukrainian characters pass through.
fold(input)
Latin diacritics → ASCII.
Correctness
Tested against every canonical example in the resolution's own annex (Алушта→Alushta … Феодосія→Feodosiia) and cross-checked against uklatn's generated fixtures, including casing torture tests (зГ→zGH, зГин→zGhyn) and stressed-vowel combining marks.
License
MIT © Annexare Studio. Successor in spirit to toURI.
