slug

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2026 License: MIT Imports: 4 Imported by: 0

README

go-slug

CI Go Reference License

URL-safe slug generator for Go. Handles Unicode, configurable, zero dependencies

Installation

go get github.com/philiprehberger/go-slug

Usage

Basic
import "github.com/philiprehberger/go-slug"

slug.Make("Hello, World!")        // "hello-world"
slug.Make("Über Café & Naïve")   // "uber-cafe-and-naive"
slug.Make("Item 42")              // "item-42"
Options
// Custom separator
s := slug.New(slug.WithSeparator("_"))
s.Make("Hello World") // "hello_world"

// Max length (truncates at word boundary)
s = slug.New(slug.WithMaxLen(10))
s.Make("this is a long title") // "this-is-a"

// Custom substitutions (applied before transliteration)
s = slug.New(slug.WithCustomSubs(map[string]string{
    "C++": "cpp",
    "C#":  "csharp",
}))
s.Make("Learning C++ and C#") // "learning-cpp-and-csharp"
Stop Words
// Remove specific words
s := slug.New(slug.WithStopWords("the", "a", "and"))
s.Make("The quick and a fox") // "quick-fox"

// Use built-in stop word list
s = slug.New(slug.WithStopWords(slug.DefaultStopWords()...))
s.Make("The cat is on the mat") // "cat-mat"
Strict Mode
// Only allow ASCII letters, digits, and separator (no transliteration)
s := slug.New(slug.WithStrict())
s.Make("Über Café")          // "ber-caf"
s.Make("Hello World 123")    // "hello-world-123"
s.Make("rock & roll @ night") // "rock-roll-night"
Case Conversion
// Kebab-case (splits on spaces, underscores, camelCase boundaries)
slug.ToKebab("camelCaseString")  // "camel-case-string"
slug.ToKebab("PascalCaseString") // "pascal-case-string"
slug.ToKebab("snake_case_string") // "snake-case-string"

// Snake_case (same splitting, underscore separator)
slug.ToSnake("camelCaseString")  // "camel_case_string"
slug.ToSnake("Hello World")     // "hello_world"
slug.ToSnake("kebab-case-string") // "kebab_case_string"
Validation
slug.IsSlug("hello-world")   // true
slug.IsSlug("hello")         // true
slug.IsSlug("Hello-World")   // false (uppercase)
slug.IsSlug("hello--world")  // false (consecutive hyphens)
slug.IsSlug("-hello")        // false (leading hyphen)
slug.IsSlug("")              // false (empty)
Unique Slugs
existing := map[string]bool{
    "hello-world":   true,
    "hello-world-2": true,
}

result := slug.Unique("Hello World", func(s string) bool {
    return existing[s]
})
// result: "hello-world-3"

API

Function / Type Description
Make(s string) string Generate a slug with default settings
Unique(input string, exists func(string) bool) string Generate a unique slug with default settings
New(opts ...Option) *Slugger Create a configured slugger
(*Slugger) Make(input string) string Generate a slug with configured options
(*Slugger) Unique(input string, exists func(string) bool) string Generate a unique slug with configured options
WithSeparator(sep string) Option Set the word separator (default: "-")
WithMaxLen(n int) Option Set max slug length with word-boundary truncation
WithCustomSubs(subs map[string]string) Option Set custom string substitutions
WithStopWords(words ...string) Option Remove specified words from the slug
DefaultStopWords() []string Returns built-in list of common English stop words
WithStrict() Option Strict mode: ASCII only, no transliteration
ToKebab(s string) string Convert string to kebab-case
ToSnake(s string) string Convert string to snake_case
IsSlug(s string) bool Check if string is a valid slug

Development

go test ./...
go vet ./...

License

MIT

Documentation

Overview

Package slug provides URL-safe slug generation from strings.

It handles Unicode transliteration, configurable separators, max length truncation at word boundaries, and unique slug generation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DefaultStopWords added in v0.2.0

func DefaultStopWords() []string

DefaultStopWords returns a built-in list of common English stop words.

func IsSlug added in v0.2.0

func IsSlug(s string) bool

IsSlug checks if a string is a valid slug. A valid slug contains only lowercase ASCII letters, digits, and hyphens, with no leading, trailing, or consecutive hyphens, and is not empty.

func Make

func Make(s string) string

Make generates a URL-safe slug from the given string using default settings. It transliterates Unicode to ASCII, lowercases the result, replaces non-alphanumeric characters with hyphens, collapses consecutive hyphens, and trims hyphens from the start and end.

func ToKebab added in v0.2.0

func ToKebab(s string) string

ToKebab converts a string to kebab-case. It splits on spaces, underscores, and camelCase boundaries. No Unicode transliteration is performed.

func ToSnake added in v0.2.0

func ToSnake(s string) string

ToSnake converts a string to snake_case. It splits on spaces, underscores, and camelCase boundaries. No Unicode transliteration is performed.

func Unique

func Unique(input string, exists func(slug string) bool) string

Unique generates a unique slug by appending -2, -3, etc. if the slug already exists. The exists function should return true if the slug is already taken.

Types

type Option

type Option func(*Slugger)

Option configures a Slugger.

func WithCustomSubs

func WithCustomSubs(subs map[string]string) Option

WithCustomSubs sets custom string substitutions that are applied before transliteration. Keys are matched case-sensitively.

func WithMaxLen

func WithMaxLen(n int) Option

WithMaxLen sets the maximum length of the generated slug. The slug is truncated at the last word boundary (separator) before maxLen. A value of 0 means no limit.

func WithSeparator

func WithSeparator(sep string) Option

WithSeparator sets the separator character used between words. The default separator is "-".

func WithStopWords added in v0.2.0

func WithStopWords(words ...string) Option

WithStopWords sets words to be removed from the slug. Words are removed after splitting but before joining. Matching is case-insensitive.

func WithStrict added in v0.2.0

func WithStrict() Option

WithStrict enables strict mode that only allows ASCII lowercase letters, digits, and the separator. Any non-matching characters are removed entirely (no transliteration).

type Slugger

type Slugger struct {
	// contains filtered or unexported fields
}

Slugger generates URL-safe slugs with configurable options.

func New

func New(opts ...Option) *Slugger

New creates a new Slugger with the given options.

func (*Slugger) Make

func (sl *Slugger) Make(input string) string

Make generates a URL-safe slug from the given string.

The algorithm is:

  1. Apply custom substitutions
  2. Transliterate Unicode to ASCII (skipped in strict mode)
  3. Lowercase
  4. Replace any non [a-z0-9] with separator
  5. Collapse consecutive separators
  6. Trim separators from start/end
  7. Remove stop words
  8. If maxLen is set, truncate at word boundary

func (*Slugger) Unique

func (sl *Slugger) Unique(input string, exists func(slug string) bool) string

Unique generates a unique slug by appending -2, -3, etc. if the base slug already exists. The exists function should return true if a given slug is already taken.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL