ComponentsForms & inputs

Slug input

A URL segment derived from a title with locale transliteration — "İşe Alım & Oryantasyon" becomes ise-alim-ve-oryantasyon in Turkish. It follows the title until someone edits it, sanitises as you type without moving the caret, and can check uniqueness and suggest a free alternative.

Input · slugify (lib/text) components/slug-input.tsx, lib/text.ts, lib/use-formatted-input.tstheme · material · accent · density · font

Installation

$ pnpm add @vamos-ui/react

The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";

Usage

import { Field, SlugInput } from "@vamos-ui/react";

<Field label="URL">
  <SlugInput
    source={title}
    prefix="vamos.ist/blog/"
    validate={(slug, signal) => api.checkSlug(slug, { signal })}  // true | "Used by …"
    suggestUnique={(slug) => api.suggestSlug(slug)}
    name="slug"
  />
</Field>

Redirects on slug change ("Create a 301") belong to your publishing flow: listen to onValueChange and keep the previous value.

Examples

Field variant

Always an input. New content follows the source (Auto badge); saved content starts locked; the refresh button regenerates from the title.

vamos.ist/pricing/Auto

Shows Auto while it follows the name. Edit it to lock it; the refresh button re-derives it.

vamos.ist/

Uniqueness check

validate is debounced and aborted when the slug changes; the result is announced politely and linked to the input.

go.vamos.ist/

Locale rules

slugify() lowercases with the locale, transliterates (tr ç→c ı→i, de ä→ae ß→ss), strips marks and turns & into the locale's word.

LocaleTitleSlug
enQ3 Results & Next Stepsq3-results-and-next-steps
trİşe Alım & Oryantasyon Süreciise-alim-ve-oryantasyon-sureci
trÇağrı Merkezi Yönetimicagri-merkezi-yonetimi
deGröße & Übersicht für Bäckereiengroesse-und-uebersicht-fuer-baeckereien

States

Disabled and a Field error, small size.

vamos.ist/legal/
shop.vamos.ist/c/

Slugs can't be reserved words like admin or api.

API

SlugInput

PropTypeDefault
value / defaultValue / onValueChange
The slug.
string—
source
Text to derive from (the title) while unlocked.
string—
locked / defaultLocked / onLockedChange
Manual mode: stops following source. Editing the slug locks it.
booleantrue when there is an initial slug
prefix
Shown before the slug (vamos.ist/blog/). A URL prefix also makes the permalink a link.
string—
variant
permalink: a link with Edit; Enter confirms, Escape restores and returns focus.
"field" | "permalink""field"
href
Permalink target override.
string—
maxLength
Cut at a word boundary when possible.
number80
locale
Transliteration rules.
stringprovider locale
validate
Uniqueness check: true when free, else a message.
(slug, signal: AbortSignal) => Promise<string | true>—
suggestUnique
Offers "Use spring-menu-2" after a failed check.
(slug) => Promise<string>—
validateDelay
Debounce in ms.
number350
name
Hidden input with the slug (falls back to the Field's name).
string—
size · disabled · invalid · placeholder
Same box as Input.
Input props—
labels
Built-in strings (slug namespace).
Partial<SlugInputLabels>—