Weave 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

Filament Sqids Laravel Package

qopiku/filament-sqids

Filament plugin for Sqids: automatically encode and decode model IDs into short, obfuscated, URL-friendly strings. Integrates with Filament resources and tables to hide sequential primary keys while keeping routes and links clean and portable.

View on GitHub
Deep Wiki
Context7

Getting Started

korfra/filament-sqids integrates Sqids (the Hashids successor) into Filament so resource URLs expose short, reversible, non-sequential identifiers instead of raw auto-increment keys. v0.1.0 is the first tagged release after 0.0.1, so treat the API as pre-stable and pin the version in composer.json.

Minimal setup:

  1. Install and publish config:
    composer require korfra/filament-sqids:^0.1
    php artisan vendor:publish --tag="filament-sqids-config"
    
  2. Register the plugin in your panel provider (app/Providers/Filament/AdminPanelProvider.php):
    ->plugins([
        \Korfra\FilamentSqids\FilamentSqidsPlugin::make(),
    ])
    
  3. Add the package trait to any model whose routes you want encoded:
    use Korfra\FilamentSqids\Concerns\HasSqids;
    
    class User extends Model
    {
        use HasSqids;
    }
    

First use case: open a Filament resource (e.g. UserResource) and visit the edit page. Instead of /admin/users/1/edit you should see the encoded segment (/admin/users/<sqid>/edit). If you see a 404, the trait is not applied or the panel plugin is not registered — check those two first before anything else. The package config file (config/filament-sqids.php) is the place to look next: it typically exposes min_length, alphabet, and blocklist, which are the knobs you will actually touch day-to-day.

Implementation Patterns

Model-level encoding (single source of truth). Put the trait on the Eloquent model rather than encoding at the resource layer. That way route model binding, route('filament...edit', $user), and any getRouteKey() usage all stay consistent without per-resource wiring. The trait is expected to override getRouteKey() (returns the sqid) and resolveRouteBinding()/resolveRouteBindingQuery() (decodes then queries by primary key). Verify both are honoured on your Filament version — Filament v3 and v4 differ slightly in how resource route binding resolves models.

Scoping encoded segments to specific resources only. If you do not want every model encoded, apply the trait selectively. This is the safer rollout: enable it on one resource group, confirm URLs and deep links behave, then expand.

Generating URLs in custom actions and notifications. Once the trait is on the model, pass the model instance rather than the ID:

Notification::make()
    ->actions([
        Action::make('view')
            ->url(UserResource::getUrl('edit', ['record' => $user])),
    ]);

Avoid building URLs from $user->id manually — that is the fastest way to reintroduce raw IDs into the UI.

Custom sqid columns / non-increment keys. If a model uses UUIDs or a slug already, the trait likely needs the underlying key to be numeric for Sqids to encode it. For non-numeric keys, prefer a dedicated numeric surrogate column or leave the model unencoded. Do not mix a UUID primary key with sqid encoding unless the package documents that path.

Relation managers and nested resources. Encoded route keys propagate through Filament's relation manager URLs because they reuse the parent record's route key. Test one nested resource (e.g. UserResource → PostsRelationManager) early; that is where route-key assumptions usually surface.

Testing. In feature tests, decode the URL segment with Sqids::decode() (or the package's helper, if exposed) to assert against the real primary key rather than hard-coding sqids — sqids are deterministic for a given alphabet/min_length, but hard-coded values become brittle the moment you change config.

Gotchas and Tips

  • Sqids are obfuscation, not encryption. Anyone can decode them with the same alphabet. Never treat an encoded segment as an authorization boundary; keep Filament policies and canView/canEdit checks in place. If you need unguessable URLs, use UUIDs instead.
  • Config changes invalidate existing URLs. Changing alphabet, min_length, or blocklist changes every generated sqid. Bookmarks, emailed links, and cached pages will 404. Set the config once, before launch, and treat it as effectively immutable.
  • min_length is a floor, not a fixed length. Sqids grow as the underlying number grows. Do not assume a fixed-length segment in route regex constraints or validation rules.
  • Changing the trait after launch breaks inbound links. Any existing external link with a raw ID will no longer resolve unless you keep a fallback. If you are migrating a live panel, consider a temporary resolveRouteBinding that accepts both forms.
  • Global search and tables still show raw keys internally. Filament's table sorting, global search, and bulk actions operate on the model key, not the sqid. This is fine, but do not assume the sqid appears in exports or API payloads — it will not unless you add an accessor.
  • Multiple panels with different configs. Sqids are decoded with a single global alphabet. If two panels need different encodings, this package is likely the wrong tool; use per-model UUIDs or a custom route key instead.
  • Debugging a 404 on an encoded route. Decode the segment manually first:
    Sqids::decode($segment); // returns [] if the alphabet/blocklist rejects it
    
    An empty array means the segment was generated with a different config or is genuinely invalid — not a route registration problem.
  • Pre-1.0 stability. v0.1.0 has no documented breaking-change policy. Pin the exact version ("korfra/filament-sqids": "0.1.*") and read the changelog before every bump. The 0.0.1 → 0.1.0 jump is the kind of release that can silently rename config keys or trait namespaces.
  • Extension points to watch. The config file and the trait are the two places the package invites customisation. If you need behaviour the trait does not cover (e.g. encoding composite keys), prefer a small custom trait over forking — the package surface is small enough that wrapping it is cheap.
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.
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support