Skip to content

Registering Models

The easiest way to register a model is using the provided Artisan command:

Terminal window
php artisan scoutify:searchable User

This command will:

  1. Implement the GloballySearchable contract.
  2. Add the Searchable trait.
  3. Automatically resolve the URL for the search results.

You can also register models manually by adding the contract and trait yourself:

use Matheusmarnt\Scoutify\Concerns\Searchable;
use Matheusmarnt\Scoutify\Contracts\GloballySearchable;
use Illuminate\Database\Eloquent\Model;
class Article extends Model implements GloballySearchable
{
use Searchable;
public function globalSearchUrl(): string
{
return route('articles.show', $this);
}
}

Tailor how your models appear in the search results by overriding these methods:

Control the primary and secondary text for each result.

public function globalSearchTitle(): string
{
return $this->full_name;
}
public function globalSearchSubtitle(): ?string
{
return "Department: {$this->department->name} • Joined {$this->created_at->diffForHumans()}";
}

The action taken when a user selects the result.

public function globalSearchUrl(): string
{
return route('users.profile', $this->username);
}

Scoutify allows for deep integration with your business logic. Here is an example of a high-power implementation:

namespace App\Models;
use Matheusmarnt\Scoutify\Concerns\Searchable;
use Matheusmarnt\Scoutify\Contracts\GloballySearchable;
use Matheusmarnt\Scoutify\Contracts\HasGlobalSearchVisibility; // Optional for auth
use Illuminate\Database\Eloquent\Model;
class Project extends Model implements GloballySearchable, HasGlobalSearchVisibility
{
use Searchable;
/**
* Context-aware titles: show status if project is archived.
*/
public function globalSearchTitle(): string
{
return $this->is_archived
? "[Archived] {$this->name}"
: $this->name;
}
/**
* Dynamic icons based on model state.
*/
public static function globalSearchIcon(): string
{
return 'heroicon-o-folder-open';
}
/**
* Authorization: only show projects the user can actually view.
* This works at the database query level for performance.
*/
public static function globalSearchVisibility(): VisibilityRule
{
return VisibilityRule::make()
->gate('view-project')
->callback(fn ($query) => $query->where('team_id', auth()->user()->current_team_id));
}
public function globalSearchUrl(): string
{
return route('projects.show', $this);
}
}

Scoutify automatically looks for common fields to use as a subtitle, such as description, subtitle, excerpt, summary, bio, or body.

HTML content in these fields is automatically sanitized to plain text and truncated to 150 characters.

Scoutify integrates with Blade Icons. You can use icons from any installed pack:

public static function globalSearchIcon(): string
{
return 'ri-customer-service-2-fill';
}

Use the --dry-run flag to see what changes the scoutify:searchable command would make without actually modifying any files:

Terminal window
php artisan scoutify:searchable User --dry-run