Columns

Getting started

Column classes can be found in the Filament\Tables\Columns namespace.

If you're using the columns in a Livewire component, you can put them in the getTableColumns() method:

protected function getTableColumns(): array
{
return [
// ...
];
}

If you're using them in admin panel resources or relation managers, you must put them in the $table->columns() method:

public static function table(Table $table): Table
{
return $table
->columns([
// ...
]);
}

Columns may be created using the static make() method, passing its name. The name of the column should correspond to a column or accessor on your model. You may use "dot syntax" to access columns within relationships.

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('title')
 
TextColumn::make('author.name')

Setting a label

By default, the label of the column, which is displayed in the header of the table, is generated from the name of the column. You may customize this using the label() method:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('title')->label('Post title')

Sorting

Columns may be sortable, by clicking on the column label. To make a column sortable, you must use the sortable() method:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('title')->sortable()

If you're using an accessor column, you may pass sortable() an array of database columns to sort by:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('full_name')->sortable(['first_name', 'last_name'])

You may customize how the sorting is applied to the Eloquent query using a callback:

use Filament\Tables\Columns\TextColumn;
use Illuminate\Database\Eloquent\Builder;
 
TextColumn::make('full_name')
->sortable(query: function (Builder $query, string $direction): Builder {
return $query
->orderBy('last_name', $direction)
->orderBy('first_name', $direction);
})

Searching

Columns may be searchable, by using the text input in the top right of the table. To make a column searchable, you must use the searchable() method:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('title')->searchable()

If you're using an accessor column, you may pass searchable() an array of database columns to search within:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('full_name')->searchable(['first_name', 'last_name'])

You may customize how the search is applied to the Eloquent query using a callback:

use Filament\Tables\Columns\TextColumn;
use Illuminate\Database\Eloquent\Builder;
 
TextColumn::make('full_name')
->searchable(query: function (Builder $query, string $search): Builder {
return $query
->where('first_name', 'like', "%{$search}%")
->where('last_name', 'like', "%{$search}%");
})

Cell actions and URLs

When a cell is clicked, you may run an "action", or open a URL.

Running actions

To run an action, you may use the action() method, passing a callback or the name of a Livewire method to run. Each method accepts a $record parameter which you may use to customize the behaviour of the action:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('title')
->action(function (Post $record): void {
$this->dispatchBrowserEvent('open-post-edit-modal', [
'post' => $record->getKey(),
]);
})

Opening URLs

To open a URL, you may use the url() method, passing a callback or static URL to open. Callbacks accept a $record parameter which you may use to customize the URL:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('title')
->url(fn (Post $record): string => route('posts.edit', ['post' => $record]))

You may also choose to open the URL in a new tab:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('title')
->url(fn (Post $record): string => route('posts.edit', ['post' => $record]))
->openUrlInNewTab()

Setting a default value

To set a default value for fields with a null state, you may use the default() method:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('title')->default('Untitled')

Hiding columns

To hide a column conditionally, you may use the hidden() and visible() methods, whichever you prefer:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('role')->hidden(! auth()->user()->isAdmin())
// or
TextColumn::make('role')->visible(auth()->user()->isAdmin())

Toggling column visibility

Users may hide or show columns themselves in the table. To make a column toggleable, use the toggleable() method:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('id')->toggleable()

By default, toggleable columns are visible. To make them hidden instead:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('id')->toggleable(isToggledHiddenByDefault: true)

Responsive layouts

You may choose to show and hide columns based on the responsive breakpoint of the browser. To do this, you may use a visibleFrom() or hiddenFrom() method:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('slug')->visibleFrom('md')

Tooltips

If you want to use tooltips outside of the admin panel, make sure you have @ryangjchandler/alpine-tooltip installed in your app, including tippy.css. You'll also need to install tippy.css if you're using a custom admin theme.

You may specify a tooltip to display when you hover over a cell:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('title')
->tooltip('Title')

This method also accepts a closure that can access the current table record:

use Filament\Tables\Columns\TextColumn;
use Illuminate\Database\Eloquent\Model;
 
TextColumn::make('title')
->tooltip(fn (Model $record): string => "By {$record->author->name}")

Custom attributes

The HTML of columns can be customized, by passing an array of extraAttributes():

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('slug')->extraAttributes(['class' => 'bg-gray-200'])

These get merged onto the outer <div> element of each cell in that column.

Global settings

If you wish to change the default behaviour of all columns globally, then you can call the static configureUsing() method inside a service provider's boot() method, to which you pass a Closure to modify the columns using. For example, if you wish to make all columns sortable() and toggleable(), you can do it like so:

use Filament\Tables\Columns\Column;
 
Column::configureUsing(function (Column $column): void {
$column
->toggleable()
->sortable();
});

Additionally, you can call this code on specific column types as well:

use Filament\Tables\Columns\BooleanColumn;
 
BooleanColumn::configureUsing(function (BooleanColumn $column): void {
$column
->toggleable()
->sortable();
});

Of course, you are still able to overwrite this on each column individually:

use Filament\Tables\Columns\BooleanColumn;
 
BooleanColumn::make('is_admin')->toggleable(false)

Displaying data from relationships

You may use "dot syntax" to access columns within relationships. The name of the relationship comes first, followed by a period, followed by the name of the column to display:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('author.name')

Counting relationships

If you wish to count the number of related records in a column, you may use the counts() method:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('users_count')->counts('users')

In this example, users is the name of the relationship to count from. The name of the column must be users_count, as this is the convention that Laravel uses for storing the result.

Determining relationship existence

If you simply wish to indicate whether related records exist in a column, you may use the exists() method:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('users_exists')->exists('users')

In this example, users is the name of the relationship to check for existence. The name of the column must be users_exists, as this is the convention that Laravel uses for storing the result.

Aggregating relationships

Filament provides several methods for aggregating a relationship field, including avg(), max(), min() and sum(). For instance, if you you wish to show the average of a field on all related records in a column, you may use the avg() method:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('users_avg_age')->avg('users', 'age')

In this example, users is the name of the relationship, while age is the field that is being averaged. The name of the column must be users_avg_age, as this is the convention that Laravel uses for storing the result.

Text column

You may use the date() and dateTime() methods to format the column's state using PHP date formatting tokens:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('created_at')->dateTime()

You may use the since() method to format the column's state using Carbon's diffForHumans():

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('created_at')->since()

The money() method allows you to easily format monetary values, in any currency. This functionality uses akaunting/laravel-money internally:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('price')->money('eur')

You may limit() the length of the cell's value:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('description')->limit(50)

You may also reuse the value that is being passed to limit():

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('description')
->limit(50)
->tooltip(function (TextColumn $column): ?string {
$state = $column->getState();
 
if (strlen($state) <= $column->getLimit()) {
return null;
}
 
// Only render the tooltip if the column contents exceeds the length limit.
return $state;
})

If your column value is HTML, you may render it using html():

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('description')->html()

You may also transform a set of known cell values using the enum() method:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('status')->enum([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])

You may instead pass a custom formatting callback to formatStateUsing(), which accepts the $state of the cell, and optionally its $record:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('status')
->formatStateUsing(fn (string $state): string => __("statuses.{$state}"))

If you'd like your column's content to wrap if it's too long, you may use the wrap() method:

use Filament\Tables\Columns\TextColumn;
 
TextColumn::make('description')->wrap()

Boolean column

Boolean columns render a check or cross icon representing their state:

use Filament\Tables\Columns\BooleanColumn;
 
BooleanColumn::make('is_featured')

You may customize the icon representing each state. Icons are the name of a Blade component present. By default, Heroicons are installed:

use Filament\Tables\Columns\BooleanColumn;
 
BooleanColumn::make('is_featured')
->trueIcon('heroicon-o-badge-check')
->falseIcon('heroicon-o-x-circle')

You may customize the icon color representing each state. These may be either primary, secondary, success, warning or danger:

use Filament\Tables\Columns\BooleanColumn;
 
BooleanColumn::make('is_featured')
->trueColor('primary')
->falseColor('warning')

Image column

use Filament\Tables\Columns\ImageColumn;
 
ImageColumn::make('header_image')

You may make the image fully rounded(), which is useful for rendering avatars:

use Filament\Tables\Columns\ImageColumn;
 
ImageColumn::make('author.avatar')->rounded()

You may customize the image size by passing a width() and height(), or both with size():

use Filament\Tables\Columns\ImageColumn;
 
ImageColumn::make('header_image')->width(200)
 
ImageColumn::make('header_image')->height(50)
 
ImageColumn::make('author.avatar')->size(40)

By default, the public disk will be used to retrieve images. You may pass a custom disk name to the disk() method:

use Filament\Tables\Columns\ImageColumn;
 
ImageColumn::make('header_image')->disk('s3')

Private images

Filament can generate temporary URLs to render private images, you may set the visibility() to private:

use Filament\Tables\Columns\ImageColumn;
 
ImageColumn::make('header_image')->visibility('private')

You may customize the extra HTML attributes of the image using extraImgAttributes():

use Filament\Tables\Columns\ImageColumn;
 
ImageColumn::make('logo')
->extraImgAttributes(['title' => 'Company logo']),

Icon column

Icon columns render a Blade icon component representing their contents:

use Filament\Tables\Columns\IconColumn;
 
IconColumn::make('is_featured')
->options([
'heroicon-o-x-circle',
'heroicon-o-pencil' => 'draft',
'heroicon-o-clock' => 'reviewing',
'heroicon-o-check-circle' => 'published',
])

You may also pass a callback to activate an option, accepting the cell's $state:

use Filament\Tables\Columns\IconColumn;
 
IconColumn::make('is_featured')
->options([
'heroicon-o-x-circle',
'heroicon-o-pencil' => fn ($state): bool => $state === 'draft',
'heroicon-o-clock' => fn ($state): bool => $state === 'reviewing',
'heroicon-o-check-circle' => fn ($state): bool => $state === 'published',
])

Icon columns may also have a set of icon colors, using the same syntax. They may be either primary, secondary, success, warning or danger:

use Filament\Tables\Columns\IconColumn;
 
IconColumn::make('is_featured')
->options([
'heroicon-o-x-circle',
'heroicon-o-pencil' => 'draft',
'heroicon-o-clock' => 'reviewing',
'heroicon-o-check-circle' => 'published',
])
->colors([
'secondary',
'danger' => 'draft',
'warning' => 'reviewing',
'success' => 'published',
])

Badge column

Badge columns render a colored badge with the cell's contents. You may use the same formatting methods as for text columns:

use Filament\Tables\Columns\BadgeColumn;
 
BadgeColumn::make('status')
->enum([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])

Badges may have a color. It may be either primary, success, warning or danger:

use Filament\Tables\Columns\BadgeColumn;
 
BadgeColumn::make('status')
->colors([
'primary',
'danger' => 'draft',
'warning' => 'reviewing',
'success' => 'published',
])

You may instead activate a color using a callback, accepting the cell's $state:

use Filament\Tables\Columns\BadgeColumn;
 
BadgeColumn::make('status')
->colors([
'primary',
'danger' => fn ($state): bool => $state === 'draft',
'warning' => fn ($state): bool => $state === 'reviewing',
'success' => fn ($state): bool => $state === 'published',
])

Badges may also have an icon:

use Filament\Tables\Columns\BadgeColumn;
 
BadgeColumn::make('status')
->icons([
'heroicon-o-x',
'heroicon-o-document' => 'draft',
'heroicon-o-refresh' => 'reviewing',
'heroicon-o-truck' => 'published',
])

Alternatively, you may conditionally display an icon using a closure:

use Filament\Tables\Columns\BadgeColumn;
 
BadgeColumn::make('status')
->icons([
'heroicon-o-x',
'heroicon-o-document' => fn ($state): bool => $state === 'draft',
'heroicon-o-refresh' => fn ($state): bool => $state === 'reviewing',
'heroicon-o-truck' => fn ($state): bool => $state === 'published',
])

You may set the position of an icon using iconPosition():

use Filament\Tables\Columns\BadgeColumn;
 
BadgeColumn::make('status')
->icons([
'heroicon-o-x',
'heroicon-o-document' => 'draft',
'heroicon-o-refresh' => 'reviewing',
'heroicon-o-truck' => 'published',
])
->iconPosition('after') // `before` or `after`

Tags column

Tags columns render a list of tags from an array:

use Filament\Tables\Columns\TagsColumn;
 
TagsColumn::make('tags')

Be sure to add an array cast to the model property:

use Illuminate\Database\Eloquent\Model;
 
class BlogPost extends Model
{
protected $casts = [
'tags' => 'array',
];
 
// ...
}

Instead of using an array, you may use a separated string by passing the separator into separator():

use Filament\Tables\Columns\TagsColumn;
 
TagsColumn::make('tags')->separator(',')

View column

You may render a custom view for a cell using the view() method:

use Filament\Tables\Columns\ViewColumn;
 
ViewColumn::make('status')->view('filament.tables.columns.status-switcher')

Inside your view, you may retrieve the state of the cell using the $getState() method:

<div>
{{ $getState() }}
</div>

Building custom columns

You may create your own custom column classes and cell views, which you can reuse across your project, and even release as a plugin to the community.

If you're just creating a simple custom column to use once, you could instead use a view column to render any custom Blade file.

To create a custom column class and view, you may use the following command:

php artisan make:table-column StatusSwitcher

This will create the following column class:

use Filament\Tables\Columns\Column;
 
class StatusSwitcher extends Column
{
protected string $view = 'filament.tables.columns.status-switcher';
}

Inside your view, you may retrieve the state of the cell using the $getState() method:

<div>
{{ $getState() }}
</div>

Still need help? Join our Discord community or open a GitHub discussion

Enjoying Filament?

We are open source at heart. To allow us to build new features, fix bugs, and run the community, we require your financial support.

Sponsor Filament on GitHub