Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Sluggable Laravel Package

nunomaduro/laravel-sluggable

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require nunomaduro/laravel-sluggable
    

    Publish the config (optional):

    php artisan vendor:publish --provider="NunoMaduro\LaravelSluggable\SluggableServiceProvider"
    
  2. First Use Case: Apply the #[Sluggable] attribute to an Eloquent model:

    use NunoMaduro\LaravelSluggable\Sluggable;
    
    class Post extends Model
    {
        use Sluggable;
    
        #[Sluggable(['source' => 'title', 'unique' => true])]
        public function getSlugOptions(): array
        {
            return [];
        }
    }
    
    • Key Fields:
      • source: The attribute to generate the slug from (e.g., title).
      • unique: Ensure slugs are unique (default: false).
  3. Trigger Slug Generation: Call save() on the model. The slug will auto-generate and populate the slug column (default column name, configurable in config/sluggable.php).


Implementation Patterns

Core Workflows

  1. Basic Slug Generation:

    $post = new Post(['title' => 'How to Slug in Laravel']);
    $post->save(); // Auto-generates slug: `how-to-slug-in-laravel`
    
  2. Custom Slug Logic: Override getSlugOptions() for dynamic behavior:

    public function getSlugOptions(): array
    {
        return [
            'source' => 'title',
            'unique' => true,
            'separator' => '-',
            'maxLength' => 100,
            'onUpdate' => true, // Regenerate on update
        ];
    }
    
  3. Multi-Field Slugs: Combine multiple fields:

    #[Sluggable(['source' => ['category', 'title'], 'separator' => '/'])]
    
  4. Manual Slug Updates: Force regeneration:

    $post->updateSlug();
    

Integration Tips

  • APIs: Use #[Sluggable] with API resources to ensure consistent slugs in responses.
  • SEO: Pair with Route::modelBinding() for clean URLs:
    Route::get('/posts/{post:slug}', [PostController::class, 'show']);
    
  • Validation: Add rules to ensure slugs are present:
    use Illuminate\Validation\Rule;
    
    $request->validate([
        'slug' => ['required', Rule::unique('posts')->ignore($post)],
    ]);
    

Gotchas and Tips

Pitfalls

  1. Unique Slugs:

    • If unique: true is set, the package appends a suffix (e.g., -2) to avoid collisions.
    • Debug Tip: Check config/sluggable.php for unique_strategy (default: suffix).
  2. Case Sensitivity:

    • Slugs are lowercase by default. Override with lowercase: false in getSlugOptions().
  3. Column Mismatch:

    • Ensure the slug column exists in the database. Default: slug.
    • Fix: Run migrations or update config/sluggable.php:
      'column' => 'custom_slug_column',
      
  4. Performance:

    • Unique slug checks add overhead. Disable unique: true if not needed.

Debugging

  • Log Slug Generation: Enable debug mode in config/sluggable.php:

    'debug' => env('SLUGGABLE_DEBUG', false),
    

    Check Laravel logs for slug generation details.

  • Test Edge Cases:

    // Test slug collision handling
    $post1 = new Post(['title' => 'Test']);
    $post2 = new Post(['title' => 'Test']);
    $post1->save(); // slug: `test`
    $post2->save(); // slug: `test-2` (if unique: true)
    

Extension Points

  1. Custom Slug Generator: Implement NunoMaduro\LaravelSluggable\Contracts\SlugGenerator:

    class CustomSlugGenerator implements SlugGenerator
    {
        public function generate($value, array $options): string
        {
            return str_replace(' ', '_', strtolower($value));
        }
    }
    

    Register in config/sluggable.php:

    'generator' => \App\Services\CustomSlugGenerator::class,
    
  2. Event Listeners: Listen for sluggable.generated events to log or transform slugs:

    Sluggable::generated(function ($model, $slug) {
        // Custom logic (e.g., analytics)
    });
    
  3. Translatable Slugs: Use spatie/laravel-translatable + #[Sluggable] for multilingual slugs:

    #[Sluggable(['source' => 'title', 'translatable' => true])]
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle