Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

slugify-ts

A comprehensive TypeScript library for converting strings into URL-friendly slugs with support for unicode, emojis, multiple languages, custom separators, max length limits, validation, and utility functions.

Features

  • ✅ Unicode Support: Handles accented characters, Cyrillic, Greek, and other unicode characters
  • ✅ Emoji Handling: Removes or preserves emojis based on configuration
  • ✅ Multi-language: Supports diacritics and special characters from multiple languages
  • ✅ Locale Support: 13+ locale-specific character and word replacements (bg, sr-c, sr-l, tr, ka, kk, vi, de, es, fr, pt, nb, sv)
  • ✅ Custom Separators: Configurable separator character (default: -)
  • ✅ Max Length: Truncate slugs to maximum length while preserving word boundaries
  • ✅ Strict Mode: Option to remove all non-alphanumeric characters
  • ✅ Case Preservation: Option to preserve original case
  • ✅ Custom Replacements: Define custom character replacement maps
  • ✅ Utility Functions: Validate slugs, deslugify, and generate unique slugs
  • ✅ TypeScript: Full TypeScript support with type definitions
  • ✅ Zero Dependencies: No external dependencies required

Installation

# Using Bun
bun add slugify-ts

# Using npm
npm install slugify-ts

# Using pnpm
pnpm add slugify-ts

# Using yarn
yarn add slugify-ts

Quick Start

import slugify from 'slugify-ts';

// Basic usage
slugify('Hello World!'); // 'hello-world'

// With options
slugify('Café & Restaurant', { separator: '_' }); // 'cafe_restaurant'
slugify('Very Long Title', { maxLength: 10 }); // 'very-long'

API Documentation

slugify(input, options?)

Converts a string into a URL-friendly slug.

Parameters:

  • input (string | null | undefined): The string to convert to a slug
  • options (SlugifyOptions, optional): Configuration options

Returns: string - A URL-friendly slug

Options:

  • separator (string, default: '-'): Character to use as separator between words
  • maxLength (number, optional): Maximum length of the resulting slug
  • strict (boolean, default: false): Remove all non-alphanumeric characters (except separator)
  • preserveCase (boolean, default: false): Keep the original case of the input
  • replacementMap (Record<string, string>, optional): Custom character replacement map
  • removeEmojis (boolean, default: true): Remove emojis from the input
  • locale (string, optional): Locale code for locale-specific character and word replacements. Supported locales: 'bg', 'sr-c', 'sr-l', 'tr', 'ka', 'kk', 'vi', 'de', 'es', 'fr', 'pt', 'nb', 'sv'

isValidSlug(slug, separator?)

Validates if a string is a valid slug.

Parameters:

  • slug (string): The string to validate
  • separator (string, default: '-'): The separator character used in the slug

Returns: boolean - True if the string is a valid slug

deslugify(slug, separator?)

Converts a slug back to readable text (approximate).

Parameters:

  • slug (string): The slug to convert back to readable text
  • separator (string, default: '-'): The separator character used in the slug

Returns: string - A readable text approximation of the slug

slugifyWithCounter(slug, existingSlugs, separator?)

Generates a unique slug by appending a counter if the slug already exists.

Parameters:

  • slug (string): The base slug to make unique
  • existingSlugs (string[]): Array of existing slugs to check against
  • separator (string, default: '-'): The separator character to use before the counter

Returns: string - A unique slug with a counter appended if necessary

uniqueSlugify(input, existingSlugs?, options?)

Convenience function that combines slugify and slugifyWithCounter.

Parameters:

  • input (string | null | undefined): The string to convert to a slug
  • existingSlugs (string[], default: []): Array of existing slugs to check against
  • options (SlugifyOptions, optional): Configuration options for slugification

Returns: string - A unique slug

Usage Examples

Basic Usage

import slugify from 'slugify-ts';

slugify('Hello World!'); // 'hello-world'
slugify('My Awesome Blog Post'); // 'my-awesome-blog-post'

Unicode and Special Characters

import slugify from 'slugify-ts';

// Accented characters
slugify('Café'); // 'cafe'
slugify('Résumé'); // 'resume'
slugify('São Paulo'); // 'sao-paulo'

// Cyrillic
slugify('Москва'); // 'moskva'

// Greek
slugify('Αθήνα'); // 'Athina'

// Special symbols
slugify('Copyright © 2024'); // 'copyright-c-2024'
slugify('Price: $100'); // 'price-dollar100'

Custom Separator

import slugify from 'slugify-ts';

slugify('Hello World', { separator: '_' }); // 'hello_world'
slugify('Test String', { separator: '.' }); // 'test.string'

Max Length

import slugify from 'slugify-ts';

slugify('Very Long Title Here', { maxLength: 10 }); // 'very-long'
slugify('Hello World Test', { maxLength: 12 }); // 'hello-world'

Strict Mode

import slugify from 'slugify-ts';

slugify('Hello-World!', { strict: true }); // 'hello-world'
slugify('Test@123', { strict: true }); // 'test123'

Preserve Case

import slugify from 'slugify-ts';

slugify('Hello World', { preserveCase: true }); // 'Hello-World'
slugify('MY TITLE', { preserveCase: true }); // 'MY-TITLE'

Custom Replacement Map

import slugify from 'slugify-ts';

slugify('Hello & World', {
  replacementMap: { '&': 'and' },
}); // 'hello-and-world'

Emoji Handling

import slugify from 'slugify-ts';

// Emojis are removed by default
slugify('Hello 👋 World'); // 'hello-world'

// To preserve emojis (they'll still be converted to separators)
slugify('Hello 👋 World', { removeEmojis: false }); // 'hello-world'

Locale Support

import slugify from 'slugify-ts';

// German locale - umlauts become 'ae', 'oe', 'ue'
slugify('Ä ö Ü', { locale: 'de' }); // 'ae-oe-ue'

// Spanish locale - symbols get Spanish translations
slugify('% & < >', { locale: 'es' }); // 'por-ciento-y-menor-que-mayor-que'

// Vietnamese locale - 'đ' becomes 'd' instead of 'dj'
slugify('Đ đ', { locale: 'vi' }); // 'd-d'

// Norwegian locale - special characters
slugify('& Å Æ Ø', { locale: 'nb' }); // 'og-aa-ae-oe'

// Supported locales: bg, sr-c, sr-l, tr, ka, kk, vi, de, es, fr, pt, nb, sv

Utility Functions

import {
  isValidSlug,
  deslugify,
  slugifyWithCounter,
  uniqueSlugify,
} from 'slugify-ts';

// Validate slugs
isValidSlug('hello-world'); // true
isValidSlug('hello--world'); // false (consecutive separators)
isValidSlug('-hello-world'); // false (starts with separator)

// Convert slug back to readable text
deslugify('hello-world'); // 'Hello World'
deslugify('my-awesome-blog-post'); // 'My Awesome Blog Post'

// Generate unique slugs
const existing = ['hello-world', 'hello-world-1'];
slugifyWithCounter('hello-world', existing); // 'hello-world-2'

// Convenience function
uniqueSlugify('Hello World!', existing); // 'hello-world-2'

TypeScript Usage

import slugify, { type SlugifyOptions } from 'slugify-ts';

const options: SlugifyOptions = {
  separator: '_',
  maxLength: 20,
  strict: false,
};

const slug = slugify('My Title', options);

Edge Cases

The library handles various edge cases:

  • Empty/null/undefined inputs: Returns empty string
  • Consecutive separators: Automatically removed
  • Leading/trailing separators: Automatically trimmed
  • Very long strings: Handled efficiently
  • Special characters: Converted or removed based on options
  • Numbers: Preserved in slugs

Testing

Run tests using Bun:

bun test

Or watch mode:

bun test --watch

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Changelog

1.0.0

  • Initial release
  • Core slugify function with unicode support
  • Utility functions (isValidSlug, deslugify, slugifyWithCounter)
  • Comprehensive test suite
  • Full TypeScript support

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages