slugify — URL-safe slugs from Persian text
import {
slugify,
createSlug,
slugifyWithNumbers,
slugifySimple,
} from "@persian-tools/persian-tools";
// CommonJS
const {
slugify,
createSlug,
slugifyWithNumbers,
slugifySimple,
} = require("@persian-tools/persian-tools");
Public exports
slugify(text: string, options?: SlugifyOptions): string
createSlug(text: string, separator?: string): string
slugifyWithNumbers(text: string, separator?: string): string
slugifySimple(text: string): string
interface SlugifyOptions {
separator?: string; // default "-"
lowercase?: boolean; // default true (lowercases Latin only — Persian has no case)
removeRepeatedSeparators?: boolean; // collapse "--" → "-", default true
maxLength?: number; // truncate after slug build
preserveNumbers?: boolean; // default true — Persian digits kept; English digits stay as-is
customReplacements?: Record<string, string>;
}
Basic usage
import { slugify } from "@persian-tools/persian-tools";
slugify("سلام دنیا"); // "سلام-دنیا"
slugify("چگونه برنامهنویسی یاد بگیریم؟"); // "چگونه-برنامه-نویسی-یاد-بگیریم"
slugify("Hello سلام 2024"); // "hello-سلام-2024"
With options
slugify("سلام دنیا", { separator: "_" }); // "سلام_دنیا"
slugify("سلام دنیا", { maxLength: 8 }); // "سلام-دن"
slugify("سلام دنیا", { lowercase: false }); // doesn't lowercase Latin
slugify("سال ۱۴۰۰", { preserveNumbers: true }); // "سال-۱۴۰۰" (Persian digits preserved)
Convenience exports
createSlug(text, separator?) — slugify with the same separator default-overridable.
slugifyWithNumbers(text, separator?) — slugify keeping digits intact.
slugifySimple(text) — barebones slugification (no options).
These are thin wrappers; you can always call slugify(text, ...) directly.
What it does internally
- Validates input is a non-empty string. Otherwise throws (likely
Error, not TypeError — see src/modules/slugify/index.ts:65).
- Normalises Arabic characters → Persian via
toPersianChars.
- Applies
SLUG_REPLACEMENTS (e.g. آ → ا, ة → ه, drops Arabic diacritics).
- Applies
PUNCTUATION_REPLACEMENTS (strips ؟ ، « » etc.; converts Arabic-Indic digits to English).
- Applies any
customReplacements.
- Replaces whitespace runs with
separator, optionally collapses repeated separators, optionally truncates to maxLength.
Common pitfalls
- Throws on empty string. Pre-check
text.trim().length > 0.
lowercase: true affects only Latin characters; Persian doesn't have case.
preserveNumbers: true keeps Persian digits, which may NOT be URL-safe in some contexts (browsers handle them fine, but some servers reject non-ASCII paths). For pure-ASCII URLs, set preserveNumbers: false and pre-convert digits with digitsFaToEn.
maxLength truncates after slug building — the final slug may end on a separator if you're unlucky. Trim trailing separators yourself if it matters.
- Custom replacements run after defaults — they can override punctuation handling. Useful for vocabulary-specific tweaks (e.g. brand-name expansions).
References
- Tests:
test/slugify.spec.ts
- Related:
URLfix skill (decode percent-encoded URLs before slugifying)
1---2name: slugify3description: Generate URL-safe slugs from Persian text, with options for separator, lowercase, max length, custom replacements, and Persian digit handling. Use when building URL paths from article titles, file names from user-typed strings, or anchor IDs. Triggers on mentions of slugify, createSlug, URL-safe Persian, slug from Farsi, prettify URL.4license: MIT5---67# slugify — URL-safe slugs from Persian text89```ts10import {11 slugify,12 createSlug,13 slugifyWithNumbers,14 slugifySimple,15} from "@persian-tools/persian-tools";16// CommonJS17const {18 slugify,19 createSlug,20 slugifyWithNumbers,21 slugifySimple,22} = require("@persian-tools/persian-tools");23```2425## Public exports2627```ts28slugify(text: string, options?: SlugifyOptions): string29createSlug(text: string, separator?: string): string30slugifyWithNumbers(text: string, separator?: string): string31slugifySimple(text: string): string3233interface SlugifyOptions {34 separator?: string; // default "-"35 lowercase?: boolean; // default true (lowercases Latin only — Persian has no case)36 removeRepeatedSeparators?: boolean; // collapse "--" → "-", default true37 maxLength?: number; // truncate after slug build38 preserveNumbers?: boolean; // default true — Persian digits kept; English digits stay as-is39 customReplacements?: Record<string, string>;40}41```4243## Basic usage4445```ts46import { slugify } from "@persian-tools/persian-tools";4748slugify("سلام دنیا"); // "سلام-دنیا"49slugify("چگونه برنامهنویسی یاد بگیریم؟"); // "چگونه-برنامه-نویسی-یاد-بگیریم"50slugify("Hello سلام 2024"); // "hello-سلام-2024"51```5253## With options5455```ts56slugify("سلام دنیا", { separator: "_" }); // "سلام_دنیا"57slugify("سلام دنیا", { maxLength: 8 }); // "سلام-دن"58slugify("سلام دنیا", { lowercase: false }); // doesn't lowercase Latin59slugify("سال ۱۴۰۰", { preserveNumbers: true }); // "سال-۱۴۰۰" (Persian digits preserved)60```6162## Convenience exports6364- `createSlug(text, separator?)` — `slugify` with the same `separator` default-overridable.65- `slugifyWithNumbers(text, separator?)` — slugify keeping digits intact.66- `slugifySimple(text)` — barebones slugification (no options).6768These are thin wrappers; you can always call `slugify(text, ...)` directly.6970## What it does internally71721. Validates input is a non-empty string. Otherwise throws (likely `Error`, not `TypeError` — see `src/modules/slugify/index.ts:65`).732. Normalises Arabic characters → Persian via `toPersianChars`.743. Applies `SLUG_REPLACEMENTS` (e.g. `آ → ا`, `ة → ه`, drops Arabic diacritics).754. Applies `PUNCTUATION_REPLACEMENTS` (strips `؟ ، « »` etc.; converts Arabic-Indic digits to English).765. Applies any `customReplacements`.776. Replaces whitespace runs with `separator`, optionally collapses repeated separators, optionally truncates to `maxLength`.7879## Common pitfalls8081- **Throws on empty string.** Pre-check `text.trim().length > 0`.82- **`lowercase: true`** affects only Latin characters; Persian doesn't have case.83- **`preserveNumbers: true` keeps Persian digits**, which may NOT be URL-safe in some contexts (browsers handle them fine, but some servers reject non-ASCII paths). For pure-ASCII URLs, set `preserveNumbers: false` and pre-convert digits with `digitsFaToEn`.84- **`maxLength` truncates *after* slug building** — the final slug may end on a separator if you're unlucky. Trim trailing separators yourself if it matters.85- **Custom replacements run after defaults** — they can override punctuation handling. Useful for vocabulary-specific tweaks (e.g. brand-name expansions).8687## References8889- Tests: `test/slugify.spec.ts`90- Related: `URLfix` skill (decode percent-encoded URLs before slugifying)