Skip to content

Slug

The Slug field renders a text input that may generate a URL-safe slug from another field in the same generated form.

Basic Usage

Example
php
use InertiaUI\Forms\Fields\Slug;
use InertiaUI\Forms\Fields\TextInput;

TextInput::make('title');

Slug::make('slug')
    ->from('title');

As the source field changes, the frontend component slugifies the source value in the browser. No additional JavaScript dependency is required. The field adds a Laravel string rule by default.

Manual Overrides

By default, a manual edit locks the slug so later source-field changes do not overwrite the custom value:

Example
php
Slug::make('slug')
    ->from('title')
    ->lockOnManualEdit();

Disable that lock when the slug should always follow the source field:

php
Slug::make('slug')
    ->from('title')
    ->lockOnManualEdit(false);

Update Strategy

The default behavior updates the slug whenever the source changes, until the slug is manually locked. Use onlyWhenEmpty() when an existing value should be preserved:

Example
php
Slug::make('slug')
    ->from('title')
    ->onlyWhenEmpty();

You may switch back to source-edit updates explicitly:

php
Slug::make('slug')
    ->from('title')
    ->updateOnEdit();

onlyWhenEmpty(false) is the inverse and restores updateOnEdit(true).

Separator and Case

Example
php
Slug::make('slug')
    ->from('title')
    ->separator('_')
    ->lowercase(false);

Separators may not be empty.

Length and Placeholder

php
Slug::make('slug')
    ->minLength(3)
    ->maxLength(80)
    ->placeholder('launch-readiness-checklist');

minLength() and maxLength() set native attributes and add matching Laravel rules. Passing null clears a generated limit and rule. placeholder(null) clears the text.

Slug-specific methods compose with the shared field APIs. Use Form Class for labels, help text, and placeholders, Model Binding for default(), Validation for rules, required fields, and precognition, Styling for classes, presentation helpers, and invalid state, Conditional Visibility, and Authorization.

Using the Component Directly

You may render Slug with local state, or pass serialized field props during manual form rendering. Standalone controls pass the source text with sourceValue.

vue
<script setup lang="ts">
import { ref } from 'vue'
import { Slug, TextInput } from '@inertiaui/form-vue/components'

const title = ref('Launch Readiness Checklist')
const slug = ref('')

const trackBlur = () => {}
</script>

<template>
    <div class="grid gap-4">
        <TextInput v-model="title" name="title" label="Title" />

        <Slug
            v-model="slug"
            id="article-slug"
            name="slug"
            label="Slug"
            help="Used in the public URL."
            placeholder="launch-readiness-checklist"
            from="title"
            :source-value="title"
            separator="-"
            :lowercase="true"
            :lock-on-manual-edit="true"
            :update-on-edit="true"
            :min-length="3"
            :max-length="80"
            required
            data-testid="article-slug"
            @blur="trackBlur"
        />
    </div>
</template>
tsx
import { useState } from 'react'
import { Slug, TextInput } from '@inertiaui/form-react/components'

export default function SlugControls() {
    const [title, setTitle] = useState('Launch Readiness Checklist')
    const [slug, setSlug] = useState('')

    const trackBlur = () => {}

    return (
        <div className="grid gap-4">
            <TextInput
                value={title}
                onValueChange={(value) => setTitle(String(value ?? ''))}
                name="title"
                label="Title"
            />

            <Slug
                value={slug}
                onValueChange={setSlug}
                id="article-slug"
                name="slug"
                label="Slug"
                help="Used in the public URL."
                placeholder="launch-readiness-checklist"
                from="title"
                sourceValue={title}
                separator="-"
                lowercase
                lockOnManualEdit
                updateOnEdit
                minLength={3}
                maxLength={80}
                required
                data-testid="article-slug"
                onBlur={trackBlur}
            />
        </div>
    )
}

Vue uses v-model. React uses controlled value plus onValueChange. Native attributes and listeners target the underlying <input>; see Native Attributes And Events.