# Table of Contents - [Upgrade guide - Filament](#upgrade-guide-filament) - [Unknown](#unknown) - [Overview - Filament](#overview-filament) - [Getting started - Filament](#getting-started-filament) - [Overview - Filament](#overview-filament) - [Overview - Filament](#overview-filament) - [Overview - Filament](#overview-filament) - [Overview - Filament](#overview-filament) - [Select filters - Filament](#select-filters-filament) - [Select column - Filament](#select-column-filament) - [Toggle column - Filament](#toggle-column-filament) - [Icon column - Filament](#icon-column-filament) - [Custom columns - Filament](#custom-columns-filament) - [Custom filters - Filament](#custom-filters-filament) - [Filter layout - Filament](#filter-layout-filament) - [Text column - Filament](#text-column-filament) - [Overview - Filament](#overview-filament) - [Ternary filters - Filament](#ternary-filters-filament) - [Query builder - Filament](#query-builder-filament) - [Overview - Filament](#overview-filament) - [Image column - Filament](#image-column-filament) - [Color column - Filament](#color-column-filament) - [Text input column - Filament](#text-input-column-filament) - [Checkbox column - Filament](#checkbox-column-filament) --- # Upgrade guide - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/upgrade-guide#content-area) If you see anything missing from this guide, please don’t hesitate to [make a pull request](https://github.com/filamentphp/filament/edit/5.x/docs/14-upgrade-guide.md) to our repository! Any help is appreciated! [​](https://filamentphp.com/docs/5.x/upgrade-guide#new-requirements) New requirements ---------------------------------------------------------------------------------------- * PHP 8.2+ * Laravel v11.28+ * Livewire v4.0+ * Tailwind CSS v4.0+ [​](https://filamentphp.com/docs/5.x/upgrade-guide#running-the-automated-upgrade-script) Running the automated upgrade script -------------------------------------------------------------------------------------------------------------------------------- Some plugins you’re using may not be available in v5 just yet. You could temporarily remove them from your `composer.json` file until they’ve been upgraded, replace them with a similar plugins that are v5-compatible, wait for the plugins to be upgraded before upgrading your app, or even write PRs to help the authors upgrade them. The first step to upgrade your Filament app is to run the automated upgrade script. This script will automatically upgrade your application to the latest version of Filament and make changes to your code, which handles breaking changes: composer require filament/upgrade:"^5.0" -W --dev vendor/bin/filament-v5 # Run the commands output by the upgrade script, they are unique to your app composer require filament/filament:"^5.0" -W --no-update composer update When using Windows PowerShell to install Filament, you may need to run the command below, since it ignores `^` characters in version constraints: composer require filament/upgrade:"~5.0" -W --dev vendor/bin/filament-v5 # Run the commands output by the upgrade script, they are unique to your app composer require filament/filament:"~5.0" -W --no-update composer update Make sure to carefully follow the instructions, and review the changes made by the script. You may need to make some manual changes to your code afterwards, but the script should handle most of the repetitive work for you. You can now `composer remove filament/upgrade --dev` as you don’t need it anymore. [​](https://filamentphp.com/docs/5.x/upgrade-guide#upgrading-livewire) Upgrading Livewire -------------------------------------------------------------------------------------------- Filament v5 requires Livewire v4.0+. You can upgrade your Livewire code by following the [Livewire upgrade guide](https://livewire.laravel.com/docs/4.x/upgrading) . [Edit this page on GitHub](https://github.com/filamentphp/filament/edit/5.x/docs/14-upgrade-guide.md) Sponsored by ------------ [![Kirschbaum](https://filamentphp.com/docs/images/sponsors/footer/kirschbaum.svg)](https://kirschbaumdevelopment.com/solutions/filament-development "Kirschbaum") [![CMS Max](https://filamentphp.com/docs/images/sponsors/footer/cms-max.svg)](https://cmsmax.com/?ref=filamentphp.com "CMS Max") [![Mailtrap](https://filamentphp.com/docs/images/sponsors/footer/mailtrap.svg)](https://mailtrap.io/email-sending?utm_source=community&utm_medium=referral&utm_campaign=filament "Mailtrap") [![SerpApi](https://filamentphp.com/docs/images/sponsors/footer/serpapi.svg)](https://serpapi.com/?utm_source=filamentphp "SerpApi") [![Baiz.ai](https://filamentphp.com/docs/images/sponsors/footer/baiz-ai.svg)](https://baiz.ai/ "Baiz.ai") [![Agiledrop](https://filamentphp.com/docs/images/sponsors/footer/agiledrop.svg)](https://www.agiledrop.com/laravel?utm_source=filament "Agiledrop") [Your logo here](https://github.com/sponsors/danharrin) [Deploying to production](https://filamentphp.com/docs/5.x/deployment) Ctrl+I [![ads via Carbon](https://srv.carbonads.net/static/30242/21c3eefc14e27e78570545267ef2c3fc02c22d7b)](https://srv.carbonads.net/ads/click/x/GTND427YCESDCK77CKALYKQUFTBDT2QWCTYDCZ3JCAADC5QLFTAILK3KCY7I427NCEYDK53YCYYDE27NCYBD5K3KC6SIE23NCVYDEK3EHJNCLSIZ) [Secure software faster with GitLab. Start your free trial.](https://srv.carbonads.net/ads/click/x/GTND427YCESDCK77CKALYKQUFTBDT2QWCTYDCZ3JCAADC5QLFTAILK3KCY7I427NCEYDK53YCYYDE27NCYBD5K3KC6SIE23NCVYDEK3EHJNCLSIZ) [ads via Carbon](http://carbonads.net/?utm_source=filamentphpcom&utm_medium=ad_via_link&utm_campaign=in_unit&utm_term=carbon) --- # Unknown \# Filament ## Docs - \[Create action\](https://filamentphp.com/docs/5.x/actions/create.md) - \[Delete action\](https://filamentphp.com/docs/5.x/actions/delete.md) - \[Edit action\](https://filamentphp.com/docs/5.x/actions/edit.md) - \[Export action\](https://filamentphp.com/docs/5.x/actions/export.md) - \[Force-delete action\](https://filamentphp.com/docs/5.x/actions/force-delete.md) - \[Grouping actions\](https://filamentphp.com/docs/5.x/actions/grouping-actions.md) - \[Import action\](https://filamentphp.com/docs/5.x/actions/import.md) - \[Modals\](https://filamentphp.com/docs/5.x/actions/modals.md) - \[Overview\](https://filamentphp.com/docs/5.x/actions/overview.md) - \[Replicate action\](https://filamentphp.com/docs/5.x/actions/replicate.md) - \[Restore action\](https://filamentphp.com/docs/5.x/actions/restore.md) - \[View action\](https://filamentphp.com/docs/5.x/actions/view.md) - \[Registering assets\](https://filamentphp.com/docs/5.x/advanced/assets.md) - \[Enum tricks\](https://filamentphp.com/docs/5.x/advanced/enums.md) - \[File generation\](https://filamentphp.com/docs/5.x/advanced/file-generation.md) - \[Modular architecture (DDD)\](https://filamentphp.com/docs/5.x/advanced/modular-architecture.md) - \[Render hooks\](https://filamentphp.com/docs/5.x/advanced/render-hooks.md) - \[Security\](https://filamentphp.com/docs/5.x/advanced/security.md) - \[Rendering an action in a Livewire component\](https://filamentphp.com/docs/5.x/components/action.md) - \[Avatar Blade component\](https://filamentphp.com/docs/5.x/components/avatar.md) - \[Badge Blade component\](https://filamentphp.com/docs/5.x/components/badge.md) - \[Breadcrumbs Blade component\](https://filamentphp.com/docs/5.x/components/breadcrumbs.md) - \[Button Blade component\](https://filamentphp.com/docs/5.x/components/button.md) - \[Callout Blade component\](https://filamentphp.com/docs/5.x/components/callout.md) - \[Checkbox Blade component\](https://filamentphp.com/docs/5.x/components/checkbox.md) - \[Dropdown Blade component\](https://filamentphp.com/docs/5.x/components/dropdown.md) - \[Empty State Blade component\](https://filamentphp.com/docs/5.x/components/empty-state.md) - \[Fieldset Blade component\](https://filamentphp.com/docs/5.x/components/fieldset.md) - \[Rendering a form in a Blade view\](https://filamentphp.com/docs/5.x/components/form.md) - \[Icon button Blade component\](https://filamentphp.com/docs/5.x/components/icon-button.md) - \[Rendering an infolist in a Blade view\](https://filamentphp.com/docs/5.x/components/infolist.md) - \[Input Blade component\](https://filamentphp.com/docs/5.x/components/input.md) - \[Input wrapper Blade component\](https://filamentphp.com/docs/5.x/components/input-wrapper.md) - \[Link Blade component\](https://filamentphp.com/docs/5.x/components/link.md) - \[Loading indicator Blade component\](https://filamentphp.com/docs/5.x/components/loading-indicator.md) - \[Modal Blade component\](https://filamentphp.com/docs/5.x/components/modal.md) - \[Rendering notifications outside of a panel\](https://filamentphp.com/docs/5.x/components/notifications.md) - \[Overview\](https://filamentphp.com/docs/5.x/components/overview.md) - \[Pagination Blade component\](https://filamentphp.com/docs/5.x/components/pagination.md) - \[Rendering a schema in a Blade view\](https://filamentphp.com/docs/5.x/components/schema.md) - \[Section Blade component\](https://filamentphp.com/docs/5.x/components/section.md) - \[Select Blade component\](https://filamentphp.com/docs/5.x/components/select.md) - \[Rendering a table in a Blade view\](https://filamentphp.com/docs/5.x/components/table.md) - \[Tabs Blade component\](https://filamentphp.com/docs/5.x/components/tabs.md) - \[Rendering a widget in a Blade view\](https://filamentphp.com/docs/5.x/components/widget.md) - \[Deploying to production\](https://filamentphp.com/docs/5.x/deployment.md) - \[Builder\](https://filamentphp.com/docs/5.x/forms/builder.md) - \[Checkbox\](https://filamentphp.com/docs/5.x/forms/checkbox.md) - \[Checkbox list\](https://filamentphp.com/docs/5.x/forms/checkbox-list.md) - \[Code editor\](https://filamentphp.com/docs/5.x/forms/code-editor.md) - \[Color picker\](https://filamentphp.com/docs/5.x/forms/color-picker.md) - \[Custom fields\](https://filamentphp.com/docs/5.x/forms/custom-fields.md) - \[Date-time picker\](https://filamentphp.com/docs/5.x/forms/date-time-picker.md) - \[File upload\](https://filamentphp.com/docs/5.x/forms/file-upload.md) - \[Hidden\](https://filamentphp.com/docs/5.x/forms/hidden.md) - \[Key-value\](https://filamentphp.com/docs/5.x/forms/key-value.md) - \[Markdown editor\](https://filamentphp.com/docs/5.x/forms/markdown-editor.md) - \[Overview\](https://filamentphp.com/docs/5.x/forms/overview.md) - \[Radio\](https://filamentphp.com/docs/5.x/forms/radio.md) - \[Repeater\](https://filamentphp.com/docs/5.x/forms/repeater.md) - \[Rich editor\](https://filamentphp.com/docs/5.x/forms/rich-editor.md) - \[Select\](https://filamentphp.com/docs/5.x/forms/select.md) - \[Slider\](https://filamentphp.com/docs/5.x/forms/slider.md) - \[Tags input\](https://filamentphp.com/docs/5.x/forms/tags-input.md) - \[Text input\](https://filamentphp.com/docs/5.x/forms/text-input.md) - \[Textarea\](https://filamentphp.com/docs/5.x/forms/textarea.md) - \[Toggle\](https://filamentphp.com/docs/5.x/forms/toggle.md) - \[Toggle buttons\](https://filamentphp.com/docs/5.x/forms/toggle-buttons.md) - \[Validation\](https://filamentphp.com/docs/5.x/forms/validation.md) - \[Getting started\](https://filamentphp.com/docs/5.x/getting-started.md) - \[Code entry\](https://filamentphp.com/docs/5.x/infolists/code-entry.md) - \[Color entry\](https://filamentphp.com/docs/5.x/infolists/color-entry.md) - \[Custom entries\](https://filamentphp.com/docs/5.x/infolists/custom-entries.md) - \[Icon entry\](https://filamentphp.com/docs/5.x/infolists/icon-entry.md) - \[Image entry\](https://filamentphp.com/docs/5.x/infolists/image-entry.md) - \[Key-value entry\](https://filamentphp.com/docs/5.x/infolists/key-value-entry.md) - \[Overview\](https://filamentphp.com/docs/5.x/infolists/overview.md) - \[Repeatable entry\](https://filamentphp.com/docs/5.x/infolists/repeatable-entry.md) - \[Text entry\](https://filamentphp.com/docs/5.x/infolists/text-entry.md) - \[AI-assisted development\](https://filamentphp.com/docs/5.x/introduction/ai.md) - \[Contributing\](https://filamentphp.com/docs/5.x/introduction/contributing.md) - \[Help\](https://filamentphp.com/docs/5.x/introduction/help.md) - \[Installation\](https://filamentphp.com/docs/5.x/introduction/installation.md) - \[Optimizing local development\](https://filamentphp.com/docs/5.x/introduction/optimizing-local-development.md) - \[What is Filament?\](https://filamentphp.com/docs/5.x/introduction/overview.md) - \[Version support policy\](https://filamentphp.com/docs/5.x/introduction/version-support-policy.md) - \[Clusters\](https://filamentphp.com/docs/5.x/navigation/clusters.md) - \[Custom pages\](https://filamentphp.com/docs/5.x/navigation/custom-pages.md) - \[Overview\](https://filamentphp.com/docs/5.x/navigation/overview.md) - \[User menu\](https://filamentphp.com/docs/5.x/navigation/user-menu.md) - \[Broadcast notifications\](https://filamentphp.com/docs/5.x/notifications/broadcast-notifications.md) - \[Database notifications\](https://filamentphp.com/docs/5.x/notifications/database-notifications.md) - \[Overview\](https://filamentphp.com/docs/5.x/notifications/overview.md) - \[Panel configuration\](https://filamentphp.com/docs/5.x/panel-configuration.md) - \[Build a panel plugin\](https://filamentphp.com/docs/5.x/plugins/building-a-panel-plugin.md) - \[Build a standalone plugin\](https://filamentphp.com/docs/5.x/plugins/building-a-standalone-plugin.md) - \[Configurable resources and pages\](https://filamentphp.com/docs/5.x/plugins/configurable-resources-and-pages.md) - \[Getting started\](https://filamentphp.com/docs/5.x/plugins/getting-started.md) - \[Plugin development\](https://filamentphp.com/docs/5.x/plugins/panel-plugins.md) - \[Code quality tips\](https://filamentphp.com/docs/5.x/resources/code-quality-tips.md) - \[Creating records\](https://filamentphp.com/docs/5.x/resources/creating-records.md) - \[Custom resource pages\](https://filamentphp.com/docs/5.x/resources/custom-pages.md) - \[Deleting records\](https://filamentphp.com/docs/5.x/resources/deleting-records.md) - \[Editing records\](https://filamentphp.com/docs/5.x/resources/editing-records.md) - \[Global search\](https://filamentphp.com/docs/5.x/resources/global-search.md) - \[Listing records\](https://filamentphp.com/docs/5.x/resources/listing-records.md) - \[Managing relationships\](https://filamentphp.com/docs/5.x/resources/managing-relationships.md) - \[Nested resources\](https://filamentphp.com/docs/5.x/resources/nesting.md) - \[Overview\](https://filamentphp.com/docs/5.x/resources/overview.md) - \[Singular resources\](https://filamentphp.com/docs/5.x/resources/singular.md) - \[Viewing records\](https://filamentphp.com/docs/5.x/resources/viewing-records.md) - \[Using widgets on resource pages\](https://filamentphp.com/docs/5.x/resources/widgets.md) - \[Callouts\](https://filamentphp.com/docs/5.x/schemas/callouts.md) - \[Custom components\](https://filamentphp.com/docs/5.x/schemas/custom-components.md) - \[Empty states\](https://filamentphp.com/docs/5.x/schemas/empty-states.md) - \[Layouts\](https://filamentphp.com/docs/5.x/schemas/layouts.md) - \[Overview\](https://filamentphp.com/docs/5.x/schemas/overview.md) - \[Prime components\](https://filamentphp.com/docs/5.x/schemas/primes.md) - \[Sections\](https://filamentphp.com/docs/5.x/schemas/sections.md) - \[Tabs\](https://filamentphp.com/docs/5.x/schemas/tabs.md) - \[Wizards\](https://filamentphp.com/docs/5.x/schemas/wizards.md) - \[Colors\](https://filamentphp.com/docs/5.x/styling/colors.md) - \[CSS hooks\](https://filamentphp.com/docs/5.x/styling/css-hooks.md) - \[Icons\](https://filamentphp.com/docs/5.x/styling/icons.md) - \[Overview\](https://filamentphp.com/docs/5.x/styling/overview.md) - \[Actions\](https://filamentphp.com/docs/5.x/tables/actions.md) - \[Checkbox column\](https://filamentphp.com/docs/5.x/tables/columns/checkbox.md) - \[Color column\](https://filamentphp.com/docs/5.x/tables/columns/color.md) - \[Custom columns\](https://filamentphp.com/docs/5.x/tables/columns/custom-columns.md) - \[Icon column\](https://filamentphp.com/docs/5.x/tables/columns/icon.md) - \[Image column\](https://filamentphp.com/docs/5.x/tables/columns/image.md) - \[Overview\](https://filamentphp.com/docs/5.x/tables/columns/overview.md) - \[Select column\](https://filamentphp.com/docs/5.x/tables/columns/select.md) - \[Text column\](https://filamentphp.com/docs/5.x/tables/columns/text.md) - \[Text input column\](https://filamentphp.com/docs/5.x/tables/columns/text-input.md) - \[Toggle column\](https://filamentphp.com/docs/5.x/tables/columns/toggle.md) - \[Custom data\](https://filamentphp.com/docs/5.x/tables/custom-data.md) - \[Empty state\](https://filamentphp.com/docs/5.x/tables/empty-state.md) - \[Custom filters\](https://filamentphp.com/docs/5.x/tables/filters/custom.md) - \[Filter layout\](https://filamentphp.com/docs/5.x/tables/filters/layout.md) - \[Overview\](https://filamentphp.com/docs/5.x/tables/filters/overview.md) - \[Query builder\](https://filamentphp.com/docs/5.x/tables/filters/query-builder.md) - \[Select filters\](https://filamentphp.com/docs/5.x/tables/filters/select.md) - \[Ternary filters\](https://filamentphp.com/docs/5.x/tables/filters/ternary.md) - \[Grouping rows\](https://filamentphp.com/docs/5.x/tables/grouping.md) - \[Layout\](https://filamentphp.com/docs/5.x/tables/layout.md) - \[Overview\](https://filamentphp.com/docs/5.x/tables/overview.md) - \[Summaries\](https://filamentphp.com/docs/5.x/tables/summaries.md) - \[Overview\](https://filamentphp.com/docs/5.x/testing/overview.md) - \[Testing actions\](https://filamentphp.com/docs/5.x/testing/testing-actions.md) - \[Testing notifications\](https://filamentphp.com/docs/5.x/testing/testing-notifications.md) - \[Testing resources\](https://filamentphp.com/docs/5.x/testing/testing-resources.md) - \[Testing schemas\](https://filamentphp.com/docs/5.x/testing/testing-schemas.md) - \[Testing tables\](https://filamentphp.com/docs/5.x/testing/testing-tables.md) - \[Upgrade guide\](https://filamentphp.com/docs/5.x/upgrade-guide.md) - \[Multi-factor authentication\](https://filamentphp.com/docs/5.x/users/multi-factor-authentication.md) - \[Overview\](https://filamentphp.com/docs/5.x/users/overview.md) - \[Multi-tenancy\](https://filamentphp.com/docs/5.x/users/tenancy.md) - \[Chart widgets\](https://filamentphp.com/docs/5.x/widgets/charts.md) - \[Overview\](https://filamentphp.com/docs/5.x/widgets/overview.md) - \[Stats overview widgets\](https://filamentphp.com/docs/5.x/widgets/stats-overview.md) --- # Overview - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/components#content-area) [​](https://filamentphp.com/docs/5.x/components#introduction) Introduction ----------------------------------------------------------------------------- Filament packages consume a set of core components that aim to provide a consistent and maintainable foundation for all interfaces. Some of these components are also available for use in your own applications and Filament plugins. [​](https://filamentphp.com/docs/5.x/components#package-components) Package components ----------------------------------------------------------------------------------------- The various packages in the Filament project can be used outside of a panel: * [Action](https://filamentphp.com/docs/5.x/action) * [Form](https://filamentphp.com/docs/5.x/form) * [Infolist](https://filamentphp.com/docs/5.x/infolist) * [Notifications](https://filamentphp.com/docs/5.x/notifications) * [Schema](https://filamentphp.com/docs/5.x/schema) * [Table](https://filamentphp.com/docs/5.x/table) * [Widget](https://filamentphp.com/docs/5.x/widget) [​](https://filamentphp.com/docs/5.x/components#blade-components) Blade components ------------------------------------------------------------------------------------- Aside from the core packages, all Filament projects can also consume the Blade components that Filament uses internally: * [Avatar](https://filamentphp.com/docs/5.x/avatar) * [Badge](https://filamentphp.com/docs/5.x/badge) * [Button](https://filamentphp.com/docs/5.x/button) * [Breadcrumbs](https://filamentphp.com/docs/5.x/breadcrumbs) * [Callout](https://filamentphp.com/docs/5.x/callout) * [Checkbox](https://filamentphp.com/docs/5.x/checkbox) * [Dropdown](https://filamentphp.com/docs/5.x/dropdown) * [Empty state](https://filamentphp.com/docs/5.x/empty-state) * [Fieldset](https://filamentphp.com/docs/5.x/fieldset) * [Icon button](https://filamentphp.com/docs/5.x/icon-button) * [Input](https://filamentphp.com/docs/5.x/input) * [Input wrapper](https://filamentphp.com/docs/5.x/input-wrapper) * [Link](https://filamentphp.com/docs/5.x/link) * [Loading indicator](https://filamentphp.com/docs/5.x/loading-indicator) * [Modal](https://filamentphp.com/docs/5.x/modal) * [Pagination](https://filamentphp.com/docs/5.x/pagination) * [Section](https://filamentphp.com/docs/5.x/section) * [Select](https://filamentphp.com/docs/5.x/select) * [Tabs](https://filamentphp.com/docs/5.x/tabs) [Configurable resources and pages](https://filamentphp.com/docs/5.x/plugins/configurable-resources-and-pages) [Rendering an action in a Livewire component](https://filamentphp.com/docs/5.x/components/action) ⌘I --- # Getting started - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/plugins#content-area) [​](https://filamentphp.com/docs/5.x/plugins#introduction) Introduction -------------------------------------------------------------------------- While Filament comes with virtually any tool you’ll need to build great apps, sometimes you’ll need to add your own functionality either for just your app or as redistributable packages that other developers can include in their own apps. This is why Filament offers a plugin system that allows you to extend its functionality. Before we dive in, it’s important to understand the different contexts in which plugins can be used. There are two main contexts: 1. **Panel Plugins**: These are plugins that are used with [Panel Builders](https://filamentphp.com/docs/introduction/installation) . They are typically used only to add functionality when used inside a Panel or as a complete Panel in and of itself. Examples of this are: 1. A plugin that adds specific functionality to the dashboard in the form of Widgets. 2. A plugin that adds a set of Resources / functionality to an app like a Blog or User Management feature. 2. **Standalone Plugins**: These are plugins that are used in any context outside a Panel Builder. Examples of this are: 1. A plugin that adds custom fields to be used with the [Form Builders](https://filamentphp.com/docs/forms/overview) . 2. A plugin that adds custom columns or filters to the [Table Builders](https://filamentphp.com/docs/tables/overview) . Although these are two different mental contexts to keep in mind when building plugins, they can be used together inside the same plugin. They do not have to be mutually exclusive. [​](https://filamentphp.com/docs/5.x/plugins#important-concepts) Important concepts -------------------------------------------------------------------------------------- Before we dive into the specifics of building plugins, there are a few concepts that are important to understand. You should familiarize yourself with the following before building a plugin: 1. [Laravel Package Development](https://laravel.com/docs/packages) 2. [Spatie Package Tools](https://github.com/spatie/laravel-package-tools) 3. [Filament Asset Management](https://filamentphp.com/docs/advanced/assets) ### [​](https://filamentphp.com/docs/5.x/plugins#the-plugin-object) The Plugin object Filament introduces the concept of a Plugin object that is used to configure the plugin. This object is a simple PHP class that implements the `Filament\Contracts\Plugin` interface. This class is used to configure the plugin and is the main entry point for the plugin. It is also used to register Resources and Icons that might be used by your plugin. While the plugin object is extremely helpful, it is not required to build a plugin. You can still build plugins without using the plugin object as you can see in the [building a panel plugin](https://filamentphp.com/docs/5.x/building-a-panel-plugin) tutorial. The Plugin object is only used for Panel Providers. Standalone Plugins do not use this object. All configuration for Standalone Plugins should be handled in the plugin’s service provider. ### [​](https://filamentphp.com/docs/5.x/plugins#registering-assets) Registering assets All [asset registration](https://filamentphp.com/docs/advanced/assets) , including CSS, JS and Alpine Components, should be done through the plugin’s service provider in the `packageBooted()` method. This allows Filament to register the assets with the Asset Manager and load them when needed. [​](https://filamentphp.com/docs/5.x/plugins#creating-a-plugin) Creating a plugin ------------------------------------------------------------------------------------ While you can certainly build plugins from scratch, we recommend using the [Filament Plugin Skeleton](https://github.com/filamentphp/plugin-skeleton) to quickly get started. This skeleton includes all the necessary boilerplate to get you up and running quickly. ### [​](https://filamentphp.com/docs/5.x/plugins#usage) Usage To use the skeleton, simply go to the GitHub repo and click the “Use this template” button. This will create a new repo in your account with the skeleton code. After that, you can clone the repo to your machine. Once you have the code on your machine, navigate to the root of the project and run the following command: php ./configure.php This will ask you a series of questions to configure the plugin. Once you’ve answered all the questions, the script will stub out a new plugin for you, and you can begin to build your amazing new extension for Filament. [​](https://filamentphp.com/docs/5.x/plugins#upgrading-existing-plugins) Upgrading existing plugins ------------------------------------------------------------------------------------------------------ Since every plugin varies greatly in its scope of use and functionality, there is no one size fits all approaches to upgrading existing plugins. However, one thing to note, that is consistent to all plugins is the deprecation of the `PluginServiceProvider`. In your plugin service provider, you will need to change it to extend the PackageServiceProvider instead. You will also need to add a static `$name` property to the service provider. This property is used to register the plugin with Filament. Here is an example of what your service provider might look like: class MyPluginServiceProvider extends PackageServiceProvider { public static string $name = 'my-plugin'; public function configurePackage(Package $package): void { $package->name(static::$name); } } ### [​](https://filamentphp.com/docs/5.x/plugins#helpful-links) Helpful links Please read this guide in its entirety before upgrading your plugin. It will help you understand the concepts and how to build your plugin. 1. [Filament Asset Management](https://filamentphp.com/docs/advanced/assets) 2. [Panel Plugin Development](https://filamentphp.com/docs/plugins) 3. [Icon Management](https://filamentphp.com/docs/styling/icons) 4. [Colors Management](https://filamentphp.com/docs/styling/colors) 5. [CSS Hooks](https://filamentphp.com/docs/styling/css-hooks) [Testing notifications](https://filamentphp.com/docs/5.x/testing/testing-notifications) [Plugin development](https://filamentphp.com/docs/5.x/plugins/panel-plugins) ⌘I --- # Overview - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/styling#content-area) [​](https://filamentphp.com/docs/5.x/styling#changing-the-colors) Changing the colors ---------------------------------------------------------------------------------------- In the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) , you can easily change the colors that are used. Filament ships with 6 predefined colors that are used everywhere within the framework. They are customizable as follows: use Filament\Panel; use Filament\Support\Colors\Color; public function panel(Panel $panel): Panel { return $panel // ... ->colors([\ 'danger' => Color::Rose,\ 'gray' => Color::Gray,\ 'info' => Color::Blue,\ 'primary' => Color::Indigo,\ 'success' => Color::Emerald,\ 'warning' => Color::Orange,\ ]); } The `Filament\Support\Colors\Color` class contains color options for all [Tailwind CSS color palettes](https://tailwindcss.com/docs/customizing-colors) . You can also pass in a function to `register()` which will only get called when the app is getting rendered. This is useful if you are calling `register()` from a service provider, and want to access objects like the currently authenticated user, which are initialized later in middleware. Alternatively, you may pass your own palette in as an array of OKLCH colors: $panel ->colors([\ 'primary' => [\ 50 => 'oklch(0.969 0.015 12.422)',\ 100 => 'oklch(0.941 0.03 12.58)',\ 200 => 'oklch(0.892 0.058 10.001)',\ 300 => 'oklch(0.81 0.117 11.638)',\ 400 => 'oklch(0.712 0.194 13.428)',\ 500 => 'oklch(0.645 0.246 16.439)',\ 600 => 'oklch(0.586 0.253 17.585)',\ 700 => 'oklch(0.514 0.222 16.935)',\ 800 => 'oklch(0.455 0.188 13.697)',\ 900 => 'oklch(0.41 0.159 10.272)',\ 950 => 'oklch(0.271 0.105 12.094)',\ ],\ ]) ### [​](https://filamentphp.com/docs/5.x/styling#generating-a-color-palette) Generating a color palette If you want us to attempt to generate a palette for you based on a singular hex or RGB value, you can pass that in: $panel ->colors([\ 'primary' => '#6366f1',\ ]) $panel ->colors([\ 'primary' => 'rgb(99, 102, 241)',\ ]) [​](https://filamentphp.com/docs/5.x/styling#changing-the-font) Changing the font ------------------------------------------------------------------------------------ By default, we use the [Inter](https://fonts.google.com/specimen/Inter) font. You can change this using the `font()` method in the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) file: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->font('Poppins'); } All [Google Fonts](https://fonts.google.com/) are available to use. ### [​](https://filamentphp.com/docs/5.x/styling#changing-the-font-provider) Changing the font provider [Bunny Fonts CDN](https://fonts.bunny.net/) is used to serve the fonts. It is GDPR-compliant. If you’d like to use [Google Fonts CDN](https://fonts.google.com/) instead, you can do so using the `provider` argument of the `font()` method: use Filament\FontProviders\GoogleFontProvider; $panel->font('Inter', provider: GoogleFontProvider::class) Or if you’d like to serve the fonts from a local stylesheet, you can use the `LocalFontProvider`: use Filament\FontProviders\LocalFontProvider; $panel->font( 'Inter', url: asset('css/fonts.css'), provider: LocalFontProvider::class, ) [​](https://filamentphp.com/docs/5.x/styling#creating-a-custom-theme) Creating a custom theme ------------------------------------------------------------------------------------------------ Filament allows you to change the CSS used to render the UI by compiling a custom stylesheet to replace the default one. This custom stylesheet is called a “theme”. Themes use [Tailwind CSS](https://tailwindcss.com/) . To create a custom theme for a panel, you can use the `php artisan make:filament-theme` command: php artisan make:filament-theme If you have multiple panels, you can specify the panel you want to create a theme for: php artisan make:filament-theme admin By default, this command will use NPM to install dependencies. If you want to use a different package manager, you can use the `--pm` option: php artisan make:filament-theme --pm=bun This command will: 1. Install the required Tailwind CSS dependencies 2. Generate a CSS file in `resources/css/filament/{panel}/theme.css` 3. Attempt to automatically add the theme to your `vite.config.js` input array 4. Attempt to automatically register `->viteTheme()` in your panel provider 5. Offer to compile the theme with Vite If the command cannot automatically configure your files (due to non-standard formatting), it will display manual instructions instead. In that case, follow these steps: ### [​](https://filamentphp.com/docs/5.x/styling#manual-configuration) Manual configuration Add the theme’s CSS file to the Laravel plugin’s `input` array in `vite.config.js`: input: [\ // ...\ 'resources/css/filament/admin/theme.css',\ ] Register the Vite-compiled theme CSS file in the panel’s provider: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->viteTheme('resources/css/filament/admin/theme.css'); } Then compile the theme with Vite: npm run build Check the command output for the exact file path (e.g., `admin/theme.css`), as it may vary depending on your panel’s ID. You can now customize the theme by editing the CSS file in `resources/css/filament`. [​](https://filamentphp.com/docs/5.x/styling#using-tailwind-css-classes-in-your-blade-views-or-php-files) Using Tailwind CSS classes in your Blade views or PHP files ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ **A custom theme is required to use Tailwind CSS classes in your own code.** Filament’s default compiled stylesheet does not include arbitrary Tailwind classes - it only contains the styles needed for Filament’s own UI components. If you want to use Tailwind CSS utility classes (like `text-primary-600`, `bg-gray-100`, `p-4`, etc.) in your own Blade views, Livewire components, or PHP files, **you must create a custom theme first**. Without a custom theme, any Tailwind classes you add to your code will simply not work - the styles won’t be applied because they’re not included in the compiled CSS. ### [​](https://filamentphp.com/docs/5.x/styling#setting-up-tailwind-css-for-your-project) Setting up Tailwind CSS for your project To use Tailwind CSS classes in your project, you need to set up a [custom theme](https://filamentphp.com/docs/5.x/styling#creating-a-custom-theme) . Run the following command: php artisan make:filament-theme In the generated `theme.css` file, you will find `@source` directives that tell Tailwind CSS where to scan for classes: @source '../../../../app/Filament/**/*'; @source '../../../../resources/views/filament/**/*'; **Add your own directories** where you use Tailwind classes. For example: @source '../../../../app/Filament/**/*'; @source '../../../../resources/views/filament/**/*'; @source '../../../../resources/views/components/**/*'; @source '../../../../resources/views/livewire/**/*'; @source '../../../../app/Livewire/**/*'; After adding your directories, rebuild your theme: npm run build You can [learn more about the `@source` directive](https://tailwindcss.com/docs/detecting-classes-in-source-files#explicitly-registering-sources) in the Tailwind CSS documentation. [​](https://filamentphp.com/docs/5.x/styling#dark-mode) Dark mode -------------------------------------------------------------------- By default, Filament allows users to switch between light and dark mode. The following sections cover how to customize this behavior. ### [​](https://filamentphp.com/docs/5.x/styling#disabling-dark-mode) Disabling dark mode To disable dark mode entirely, you can use the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) file: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->darkMode(false); } ### [​](https://filamentphp.com/docs/5.x/styling#hiding-the-theme-switcher) Hiding the theme switcher By default, users can switch between light and dark mode using the theme switcher in the user menu. If you want to keep dark mode enabled but prevent users from manually switching (so that Filament follows the [default theme mode](https://filamentphp.com/docs/5.x/styling#changing-the-default-theme-mode) or the user’s system preference), you can hide the theme switcher using the `themeSwitcher(false)` method: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->themeSwitcher(false); } This is different from `darkMode(false)`, which disables dark mode altogether. `themeSwitcher(false)` keeps dark mode active but hides the switcher. ### [​](https://filamentphp.com/docs/5.x/styling#forcing-dark-mode) Forcing dark mode If you want to force the panel to always use dark mode, regardless of the user’s preference, you can pass `isForced: true` to the `darkMode()` method. This also hides the theme switcher: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->darkMode(isForced: true); } ### [​](https://filamentphp.com/docs/5.x/styling#changing-the-default-theme-mode) Changing the default theme mode By default, Filament uses the user’s system theme as the default mode. For example, if the user’s computer is in dark mode, Filament will use dark mode by default. The system mode in Filament is reactive if the user changes their computer’s mode. If you want to change the default mode to force light or dark mode, you can use the `defaultThemeMode()` method, passing `ThemeMode::Light` or `ThemeMode::Dark`: use Filament\Enums\ThemeMode; use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->defaultThemeMode(ThemeMode::Light); } [​](https://filamentphp.com/docs/5.x/styling#adding-a-logo) Adding a logo ---------------------------------------------------------------------------- By default, Filament uses your app’s name to render a simple text-based logo. However, you can easily customize this. If you want to simply change the text that is used in the logo, you can use the `brandName()` method: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->brandName('Filament Demo'); } To render an image instead, you can pass a URL to the `brandLogo()` method: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->brandLogo(asset('images/logo.svg')); } Alternatively, you may directly pass HTML to the `brandLogo()` method to render an inline SVG element for example: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->brandLogo(fn () => view('filament.admin.logo')); } If you need a different logo to be used when the application is in dark mode, you can pass it to `darkModeBrandLogo()` in the same way. The logo height defaults to a sensible value, but it’s impossible to account for all possible aspect ratios. Therefore, you may customize the height of the rendered logo using the `brandLogoHeight()` method: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->brandLogo(fn () => view('filament.admin.logo')) ->brandLogoHeight('2rem'); } [​](https://filamentphp.com/docs/5.x/styling#adding-a-favicon) Adding a favicon ---------------------------------------------------------------------------------- To add a favicon, you can use the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) file, passing the public URL of the favicon: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->favicon(asset('images/favicon.png')); } [Multi-tenancy](https://filamentphp.com/docs/5.x/users/tenancy) [CSS hooks](https://filamentphp.com/docs/5.x/styling/css-hooks) ⌘I --- # Overview - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/resources#content-area) [​](https://filamentphp.com/docs/5.x/resources#introduction) Introduction ---------------------------------------------------------------------------- Resources are static classes that are used to build CRUD interfaces for your Eloquent models. They describe how administrators should be able to interact with data from your app using tables and forms. [​](https://filamentphp.com/docs/5.x/resources#creating-a-resource) Creating a resource ------------------------------------------------------------------------------------------ To create a resource for the `App\Models\Customer` model: php artisan make:filament-resource Customer This will create several files in the `app/Filament/Resources` directory: . +-- Customers | +-- CustomerResource.php | +-- Pages | | +-- CreateCustomer.php | | +-- EditCustomer.php | | +-- ListCustomers.php | +-- Schemas | | +-- CustomerForm.php | +-- Tables | | +-- CustomersTable.php Your new resource class lives in `CustomerResource.php`. The classes in the `Pages` directory are used to customize the pages in the app that interact with your resource. They’re all full-page [Livewire](https://livewire.laravel.com/) components that you can customize in any way you wish. The classes in the `Schemas` directory are used to define the content of the [forms](https://filamentphp.com/docs/5.x/forms) and [infolists](https://filamentphp.com/docs/5.x/infolists) for your resource. The classes in the `Tables` directory are used to build the table for your resource. Have you created a resource, but it’s not appearing in the navigation menu? If you have a [model policy](https://filamentphp.com/docs/5.x/resources#authorization) , make sure you return `true` from the `viewAny()` method. ### [​](https://filamentphp.com/docs/5.x/resources#simple-modal-resources) Simple (modal) resources Sometimes, your models are simple enough that you only want to manage records on one page, using modals to create, edit and delete records. To generate a simple resource with modals: php artisan make:filament-resource Customer --simple Your resource will have a “Manage” page, which is a List page with modals added. Additionally, your simple resource will have no `getRelations()` method, as [relation managers](https://filamentphp.com/docs/5.x/resources/managing-relationships) are only displayed on the Edit and View pages, which are not present in simple resources. Everything else is the same. ### [​](https://filamentphp.com/docs/5.x/resources#automatically-generating-forms-and-tables) Automatically generating forms and tables If you’d like to save time, Filament can automatically generate the [form](https://filamentphp.com/docs/5.x/resources#resource-forms) and [table](https://filamentphp.com/docs/5.x/resources#resource-tables) for you, based on your model’s database columns, using `--generate`: php artisan make:filament-resource Customer --generate ### [​](https://filamentphp.com/docs/5.x/resources#handling-soft-deletes) Handling soft-deletes By default, you will not be able to interact with deleted records in the app. If you’d like to add functionality to restore, force-delete and filter trashed records in your resource, use the `--soft-deletes` flag when generating the resource: php artisan make:filament-resource Customer --soft-deletes You can find out more about soft-deleting [here](https://filamentphp.com/docs/5.x/resources/deleting-records#handling-soft-deletes) . ### [​](https://filamentphp.com/docs/5.x/resources#generating-a-view-page) Generating a View page By default, only List, Create and Edit pages are generated for your resource. If you’d also like a [View page](https://filamentphp.com/docs/5.x/resources/viewing-records) , use the `--view` flag: php artisan make:filament-resource Customer --view ### [​](https://filamentphp.com/docs/5.x/resources#specifying-a-custom-model-namespace) Specifying a custom model namespace By default, Filament will assume that your model exists in the `App\Models` directory. You can pass a different namespace for the model using the `--model-namespace` flag: php artisan make:filament-resource Customer --model-namespace=Custom\\Path\\Models In this example, the model should exist at `Custom\Path\Models\Customer`. Please note the double backslashes `\\` in the command that are required. Now when [generating the resource](https://filamentphp.com/docs/5.x/resources#automatically-generating-forms-and-tables) , Filament will be able to locate the model and read the database schema. ### [​](https://filamentphp.com/docs/5.x/resources#generating-the-model-migration-and-factory-at-the-same-time) Generating the model, migration and factory at the same time If you’d like to save time when scaffolding your resources, Filament can also generate the model, migration and factory for the new resource at the same time using the `--model`, `--migration` and `--factory` flags in any combination: php artisan make:filament-resource Customer --model --migration --factory [​](https://filamentphp.com/docs/5.x/resources#record-titles) Record titles ------------------------------------------------------------------------------ A `$recordTitleAttribute` may be set for your resource, which is the name of the column on your model that can be used to identify it from others. For example, this could be a blog post’s `title` or a customer’s `name`: protected static ?string $recordTitleAttribute = 'name'; This is required for features like [global search](https://filamentphp.com/docs/5.x/resources/global-search) to work. You may specify the name of an [Eloquent accessor](https://laravel.com/docs/eloquent-mutators#defining-an-accessor) if just one column is inadequate at identifying a record. [​](https://filamentphp.com/docs/5.x/resources#resource-forms) Resource forms -------------------------------------------------------------------------------- Resource classes contain a `form()` method that is used to build the forms on the [Create](https://filamentphp.com/docs/5.x/resources/creating-records) and [Edit](https://filamentphp.com/docs/5.x/resources/editing-records) pages. By default, Filament creates a form schema file for you, which is referenced in the `form()` method. This is to keep your resource class clean and organized, otherwise it can get quite large: use App\Filament\Resources\Customers\Schemas\CustomerForm; use Filament\Schemas\Schema; public static function form(Schema $schema): Schema { return CustomerForm::configure($schema); } In the `CustomerForm` class, you can define the fields and layout of your form: use Filament\Forms\Components\TextInput; use Filament\Schemas\Schema; public static function configure(Schema $schema): Schema { return $schema ->components([\ TextInput::make('name')->required(),\ TextInput::make('email')->email()->required(),\ // ...\ ]); } The `components()` method is used to define the structure of your form. It is an array of [fields](https://filamentphp.com/docs/5.x/forms/overview#available-fields) and [layout components](https://filamentphp.com/docs/5.x/schemas/layouts#available-layout-components) , in the order they should appear in your form. Check out the Forms docs for a [guide](https://filamentphp.com/docs/5.x/forms) on how to build forms with Filament. If you would prefer to define the form directly in the resource class, you can do so and delete the form schema class altogether: use Filament\Forms\Components\TextInput; use Filament\Schemas\Schema; public static function form(Schema $schema): Schema { return $schema ->components([\ TextInput::make('name')->required(),\ TextInput::make('email')->email()->required(),\ // ...\ ]); } ### [​](https://filamentphp.com/docs/5.x/resources#hiding-components-based-on-the-current-operation) Hiding components based on the current operation The `hiddenOn()` method of form components allows you to dynamically hide fields based on the current page or action. In this example, we hide the `password` field on the `edit` page: use Filament\Forms\Components\TextInput; use Filament\Support\Enums\Operation; TextInput::make('password') ->password() ->required() ->hiddenOn(Operation::Edit), Alternatively, we have a `visibleOn()` shortcut method for only showing a field on one page or action: use Filament\Forms\Components\TextInput; use Filament\Support\Enums\Operation; TextInput::make('password') ->password() ->required() ->visibleOn(Operation::Create), [​](https://filamentphp.com/docs/5.x/resources#resource-tables) Resource tables ---------------------------------------------------------------------------------- Resource classes contain a `table()` method that is used to build the table on the [List page](https://filamentphp.com/docs/5.x/resources/listing-records) . By default, Filament creates a table file for you, which is referenced in the `table()` method. This is to keep your resource class clean and organized, otherwise it can get quite large: use App\Filament\Resources\Customers\Tables\CustomersTable; use Filament\Tables\Table; public static function table(Table $table): Table { return CustomersTable::configure($table); } In the `CustomersTable` class, you can define the columns, filters and actions of the table: use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteBulkAction; use Filament\Actions\EditAction; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Filters\Filter; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; public static function configure(Table $table): Table { return $table ->columns([\ TextColumn::make('name'),\ TextColumn::make('email'),\ // ...\ ]) ->filters([\ Filter::make('verified')\ ->query(fn (Builder $query): Builder => $query->whereNotNull('email_verified_at')),\ // ...\ ]) ->recordActions([\ EditAction::make(),\ ]) ->toolbarActions([\ BulkActionGroup::make([\ DeleteBulkAction::make(),\ ]),\ ]); } Check out the [tables](https://filamentphp.com/docs/5.x/tables) docs to find out how to add table columns, filters, actions and more. If you would prefer to define the table directly in the resource class, you can do so and delete the table class altogether: use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteBulkAction; use Filament\Actions\EditAction; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Filters\Filter; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; public static function table(Table $table): Table { return $table ->columns([\ TextColumn::make('name'),\ TextColumn::make('email'),\ // ...\ ]) ->filters([\ Filter::make('verified')\ ->query(fn (Builder $query): Builder => $query->whereNotNull('email_verified_at')),\ // ...\ ]) ->recordActions([\ EditAction::make(),\ ]) ->toolbarActions([\ BulkActionGroup::make([\ DeleteBulkAction::make(),\ ]),\ ]); } [​](https://filamentphp.com/docs/5.x/resources#customizing-the-model-label) Customizing the model label ---------------------------------------------------------------------------------------------------------- Each resource has a “model label” which is automatically generated from the model name. For example, an `App\Models\Customer` model will have a `customer` label. The label is used in several parts of the UI, and you may customize it using the `$modelLabel` property: protected static ?string $modelLabel = 'cliente'; Alternatively, you may use the `getModelLabel()` to define a dynamic label: public static function getModelLabel(): string { return __('filament/resources/customer.label'); } ### [​](https://filamentphp.com/docs/5.x/resources#customizing-the-plural-model-label) Customizing the plural model label Resources also have a “plural model label” which is automatically generated from the model label. For example, a `customer` label will be pluralized into `customers`. You may customize the plural version of the label using the `$pluralModelLabel` property: protected static ?string $pluralModelLabel = 'clientes'; Alternatively, you may set a dynamic plural label in the `getPluralModelLabel()` method: public static function getPluralModelLabel(): string { return __('filament/resources/customer.plural_label'); } ### [​](https://filamentphp.com/docs/5.x/resources#automatic-model-label-capitalization) Automatic model label capitalization By default, Filament will automatically capitalize each word in the model label, for some parts of the UI. For example, in page titles, the navigation menu, and the breadcrumbs. If you want to disable this behavior for a resource, you can set `$hasTitleCaseModelLabel` in the resource: protected static bool $hasTitleCaseModelLabel = false; [​](https://filamentphp.com/docs/5.x/resources#resource-navigation-items) Resource navigation items ------------------------------------------------------------------------------------------------------ Filament will automatically generate a navigation menu item for your resource using the [plural label](https://filamentphp.com/docs/5.x/resources#plural-label) . If you’d like to customize the navigation item label, you may use the `$navigationLabel` property: protected static ?string $navigationLabel = 'Mis Clientes'; Alternatively, you may set a dynamic navigation label in the `getNavigationLabel()` method: public static function getNavigationLabel(): string { return __('filament/resources/customer.navigation_label'); } ### [​](https://filamentphp.com/docs/5.x/resources#setting-a-resource-navigation-icon) Setting a resource navigation icon The `$navigationIcon` property supports the name of any Blade component. By default, [Heroicons](https://heroicons.com/) are installed. However, you may create your own custom icon components or install an alternative library if you wish. use BackedEnum; protected static string | BackedEnum | null $navigationIcon = 'heroicon-o-user-group'; Alternatively, you may set a dynamic navigation icon in the `getNavigationIcon()` method: use BackedEnum; use Illuminate\Contracts\Support\Htmlable; public static function getNavigationIcon(): string | BackedEnum | Htmlable | null { return 'heroicon-o-user-group'; } ### [​](https://filamentphp.com/docs/5.x/resources#sorting-resource-navigation-items) Sorting resource navigation items The `$navigationSort` property allows you to specify the order in which navigation items are listed: protected static ?int $navigationSort = 2; Alternatively, you may set a dynamic navigation item order in the `getNavigationSort()` method: public static function getNavigationSort(): ?int { return 2; } ### [​](https://filamentphp.com/docs/5.x/resources#grouping-resource-navigation-items) Grouping resource navigation items You may group navigation items by specifying a `$navigationGroup` property: use UnitEnum; protected static string | UnitEnum | null $navigationGroup = 'Shop'; Alternatively, you may use the `getNavigationGroup()` method to set a dynamic group label: public static function getNavigationGroup(): ?string { return __('filament/navigation.groups.shop'); } #### [​](https://filamentphp.com/docs/5.x/resources#grouping-resource-navigation-items-under-other-items) Grouping resource navigation items under other items You may group navigation items as children of other items by setting the `$navigationParentItem` property. You may reference the parent item either by its page or resource class, or by its label: use App\Filament\Resources\Products\ProductsResource; use UnitEnum; protected static ?string $navigationParentItem = ProductsResource::class; protected static string | UnitEnum | null $navigationGroup = 'Shop'; Alternatively, you may reference the parent by its label: use UnitEnum; protected static ?string $navigationParentItem = 'Products'; protected static string | UnitEnum | null $navigationGroup = 'Shop'; You may also use the `getNavigationParentItem()` method to determine the parent dynamically: use App\Filament\Resources\Products\ProductsResource; public static function getNavigationParentItem(): ?string { return ProductsResource::class; } Alternatively, you may return the parent’s label: public static function getNavigationParentItem(): ?string { return __('filament/navigation.groups.shop.items.products'); } The parent and child items must belong to the same navigation group. If the parent item has a navigation group, that group must also be defined on the child, otherwise the correct parent item cannot be identified. This applies whether you reference the parent by its class or by its label. If you’re reaching for a third level of navigation like this, you should consider using [clusters](https://filamentphp.com/docs/5.x/navigation/clusters) instead, which are a logical grouping of resources and [custom pages](https://filamentphp.com/docs/5.x/navigation/custom-pages) , which can share their own separate navigation. [​](https://filamentphp.com/docs/5.x/resources#generating-urls-to-resource-pages) Generating URLs to resource pages ---------------------------------------------------------------------------------------------------------------------- Filament provides a `getUrl()` static method on resource classes to generate URLs to resources and specific pages within them. Traditionally, you would need to construct the URL by hand or by using Laravel’s `route()` helper, but these methods depend on knowledge of the resource’s slug or route naming conventions. The `getUrl()` method, without any arguments, will generate a URL to the resource’s [List page](https://filamentphp.com/docs/5.x/resources/listing-records) : use App\Filament\Resources\Customers\CustomerResource; CustomerResource::getUrl(); // /admin/customers You may also generate URLs to specific pages within the resource. The name of each page is the array key in the `getPages()` array of the resource. For example, to generate a URL to the [Create page](https://filamentphp.com/docs/5.x/resources/creating-records) : use App\Filament\Resources\Customers\CustomerResource; CustomerResource::getUrl('create'); // /admin/customers/create Some pages in the `getPages()` method use URL parameters like `record`. To generate a URL to these pages and pass in a record, you should use the second argument: use App\Filament\Resources\Customers\CustomerResource; CustomerResource::getUrl('edit', ['record' => $customer]); // /admin/customers/edit/1 In this example, `$customer` can be an Eloquent model object, or an ID. ### [​](https://filamentphp.com/docs/5.x/resources#generating-urls-to-resource-modals) Generating URLs to resource modals This can be especially useful if you are using [simple resources](https://filamentphp.com/docs/5.x/resources#simple-modal-resources) with only one page. To generate a URL for an action in the resource’s table, you should pass the `tableAction` and `tableActionRecord` as URL parameters: use App\Filament\Resources\Customers\CustomerResource; use Filament\Actions\EditAction; CustomerResource::getUrl(parameters: [\ 'tableAction' => EditAction::getDefaultName(),\ 'tableActionRecord' => $customer,\ ]); // /admin/customers?tableAction=edit&tableActionRecord=1 Or if you want to generate a URL for an action on the page like a `CreateAction` in the header, you can pass it in to the `action` parameter: use App\Filament\Resources\Customers\CustomerResource; use Filament\Actions\CreateAction; CustomerResource::getUrl(parameters: [\ 'action' => CreateAction::getDefaultName(),\ ]); // /admin/customers?action=create ### [​](https://filamentphp.com/docs/5.x/resources#generating-urls-to-resources-in-other-panels) Generating URLs to resources in other panels If you have multiple panels in your app, `getUrl()` will generate a URL within the current panel. You can also indicate which panel the resource is associated with, by passing the panel ID to the `panel` argument: use App\Filament\Resources\Customers\CustomerResource; CustomerResource::getUrl(panel: 'marketing'); [​](https://filamentphp.com/docs/5.x/resources#customizing-the-resource-eloquent-query) Customizing the resource Eloquent query ---------------------------------------------------------------------------------------------------------------------------------- Within Filament, every query to your resource model will start with the `getEloquentQuery()` method. Because of this, it’s very easy to apply your own query constraints or [model scopes](https://laravel.com/docs/eloquent#query-scopes) that affect the entire resource: public static function getEloquentQuery(): Builder { return parent::getEloquentQuery()->where('is_active', true); } ### [​](https://filamentphp.com/docs/5.x/resources#disabling-global-scopes) Disabling global scopes By default, Filament will observe all global scopes that are registered to your model. However, this may not be ideal if you wish to access, for example, soft-deleted records. To overcome this, you may override the `getEloquentQuery()` method that Filament uses: public static function getEloquentQuery(): Builder { return parent::getEloquentQuery()->withoutGlobalScopes(); } Alternatively, you may remove specific global scopes: public static function getEloquentQuery(): Builder { return parent::getEloquentQuery()->withoutGlobalScopes([ActiveScope::class]); } More information about removing global scopes may be found in the [Laravel documentation](https://laravel.com/docs/eloquent#removing-global-scopes) . [​](https://filamentphp.com/docs/5.x/resources#customizing-the-resource-url) Customizing the resource URL ------------------------------------------------------------------------------------------------------------ By default, Filament will generate a URL based on the name of the resource. You can customize this by setting the `$slug` property on the resource: protected static ?string $slug = 'pending-orders'; [​](https://filamentphp.com/docs/5.x/resources#resource-sub-navigation) Resource sub-navigation -------------------------------------------------------------------------------------------------- Sub-navigation allows the user to navigate between different pages within a resource. Typically, all pages in the sub-navigation will be related to the same record in the resource. For example, in a Customer resource, you may have a sub-navigation with the following pages: * View customer, a [`ViewRecord` page](https://filamentphp.com/docs/5.x/resources/viewing-records) that provides a read-only view of the customer’s details. * Edit customer, an [`EditRecord` page](https://filamentphp.com/docs/5.x/resources/editing-records) that allows the user to edit the customer’s details. * Edit customer contact, an [`EditRecord` page](https://filamentphp.com/docs/5.x/resources/editing-records) that allows the user to edit the customer’s contact details. You can [learn how to create more than one Edit page](https://filamentphp.com/docs/5.x/resources/editing-records#creating-another-edit-page) . * Manage addresses, a [`ManageRelatedRecords` page](https://filamentphp.com/docs/5.x/resources/managing-relationships#relation-pages) that allows the user to manage the customer’s addresses. * Manage payments, a [`ManageRelatedRecords` page](https://filamentphp.com/docs/5.x/resources/managing-relationships#relation-pages) that allows the user to manage the customer’s payments. To add a sub-navigation to each “singular record” page in the resource, you can add the `getRecordSubNavigation()` method to the resource class: use Filament\Resources\Pages\Page; public static function getRecordSubNavigation(Page $page): array { return $page->generateNavigationItems([\ ViewCustomer::class,\ EditCustomer::class,\ EditCustomerContact::class,\ ManageCustomerAddresses::class,\ ManageCustomerPayments::class,\ ]); } Each item in the sub-navigation can be customized using the [same navigation methods as normal pages](https://filamentphp.com/docs/5.x/navigation) . If you’re looking to add sub-navigation to switch _between_ entire resources and [custom pages](https://filamentphp.com/docs/5.x/navigation/custom-pages) , you might be looking for [clusters](https://filamentphp.com/docs/5.x/navigation/clusters) , which are used to group these together. The `getRecordSubNavigation()` method is intended to construct a navigation between pages that relate to a particular record _inside_ a resource. ### [​](https://filamentphp.com/docs/5.x/resources#setting-the-sub-navigation-position-for-a-resource) Setting the sub-navigation position for a resource The sub-navigation is rendered at the start of the page by default. You may change the position for all pages in a resource by setting the `$subNavigationPosition` property on the resource. The value may be `SubNavigationPosition::Start`, `SubNavigationPosition::End`, or `SubNavigationPosition::Top` to render the sub-navigation as tabs: use Filament\Pages\Enums\SubNavigationPosition; protected static ?SubNavigationPosition $subNavigationPosition = SubNavigationPosition::End; The `SubNavigationPosition::Top` option renders the sub-navigation as tabs above the page content: [​](https://filamentphp.com/docs/5.x/resources#deleting-resource-pages) Deleting resource pages -------------------------------------------------------------------------------------------------- If you’d like to delete a page from your resource, you can just delete the page file from the `Pages` directory of your resource, and its entry in the `getPages()` method. For example, you may have a resource with records that may not be created by anyone. Delete the `Create` page file, and then remove it from `getPages()`: public static function getPages(): array { return [\ 'index' => ListCustomers::route('/'),\ 'edit' => EditCustomer::route('/{record}/edit'),\ ]; } Deleting a page will not delete any actions that link to that page. Any actions will open a modal instead of sending the user to the non-existent page. For instance, the `CreateAction` on the List page, the `EditAction` on the table or View page, or the `ViewAction` on the table or Edit page. If you want to remove those buttons, you must delete the actions as well. [​](https://filamentphp.com/docs/5.x/resources#security) Security -------------------------------------------------------------------- [​](https://filamentphp.com/docs/5.x/resources#authorization) Authorization ------------------------------------------------------------------------------ For authorization, Filament will observe any [model policies](https://laravel.com/docs/authorization#creating-policies) that are registered in your app. The following methods are used: * `viewAny()` is used to completely hide resources from the navigation menu, and prevents the user from accessing any pages. * `create()` is used to control [creating new records](https://filamentphp.com/docs/5.x/resources/creating-records) . * `update()` is used to control [editing a record](https://filamentphp.com/docs/5.x/resources/editing-records) . * `view()` is used to control [viewing a record](https://filamentphp.com/docs/5.x/resources/viewing-records) . * `delete()` is used to prevent a single record from being deleted. `deleteAny()` is used to prevent records from being bulk deleted. Filament uses the `deleteAny()` method because iterating through multiple records and checking the `delete()` policy is not very performant. When using a `DeleteBulkAction`, if you want to call the `delete()` method for each record anyway, you should use the `DeleteBulkAction::make()->authorizeIndividualRecords()` method. Any records that fail the authorization check will not be processed. * `forceDelete()` is used to prevent a single soft-deleted record from being force-deleted. `forceDeleteAny()` is used to prevent records from being bulk force-deleted. Filament uses the `forceDeleteAny()` method because iterating through multiple records and checking the `forceDelete()` policy is not very performant. When using a `ForceDeleteBulkAction`, if you want to call the `forceDelete()` method for each record anyway, you should use the `ForceDeleteBulkAction::make()->authorizeIndividualRecords()` method. Any records that fail the authorization check will not be processed. * `restore()` is used to prevent a single soft-deleted record from being restored. `restoreAny()` is used to prevent records from being bulk restored. Filament uses the `restoreAny()` method because iterating through multiple records and checking the `restore()` policy is not very performant. When using a `RestoreBulkAction`, if you want to call the `restore()` method for each record anyway, you should use the `RestoreBulkAction::make()->authorizeIndividualRecords()` method. Any records that fail the authorization check will not be processed. * `reorder()` is used to control [reordering records in a table](https://filamentphp.com/docs/5.x/resources/listing-records#reordering-records) . ### [​](https://filamentphp.com/docs/5.x/resources#skipping-authorization) Skipping authorization If you’d like to skip authorization for a resource, you may set the `$shouldSkipAuthorization` property to `true`: protected static bool $shouldSkipAuthorization = true; ### [​](https://filamentphp.com/docs/5.x/resources#protecting-model-attributes) Protecting model attributes Filament will expose all model attributes to JavaScript, except if they are `$hidden` on your model. This is Livewire’s behavior for model binding. We preserve this functionality to facilitate the dynamic addition and removal of form fields after they are initially loaded, while preserving the data they may need. While attributes may be visible in JavaScript, only those with a form field are actually editable by the user. This is not an issue with mass assignment. To remove certain attributes from JavaScript on the Edit and View pages, you may override [the `mutateFormDataBeforeFill()` method](https://filamentphp.com/docs/5.x/resources/editing-records#customizing-data-before-filling-the-form) : protected function mutateFormDataBeforeFill(array $data): array { unset($data['is_admin']); return $data; } In this example, we remove the `is_admin` attribute from JavaScript, as it’s not being used by the form. Adding a column to `$hidden` is required, not just recommended, when it contains binary data that is not valid UTF-8, such as a `geometry`, `point`, or `blob` column. Since Filament exposes model attributes to JavaScript, these values are sent to the browser as part of the Livewire request, but they cannot be serialized to JSON. This causes the page to fail to load, often with a blank screen and no error in the Laravel log.Adding such columns to [the `$hidden` array](https://laravel.com/docs/eloquent-serialization#hiding-attributes-from-json) on your model excludes them from its array and JSON representations, resolving the issue: protected $hidden = ['location']; If you need to work with the value, expose it through an [accessor](https://laravel.com/docs/eloquent-mutators#defining-an-accessor) instead of the raw column. [Getting started](https://filamentphp.com/docs/5.x/getting-started) [Listing records](https://filamentphp.com/docs/5.x/resources/listing-records) ⌘I --- # Overview - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/navigation#content-area) [​](https://filamentphp.com/docs/5.x/navigation#introduction) Introduction ----------------------------------------------------------------------------- By default, Filament will register navigation items for each of your [resources](https://filamentphp.com/docs/5.x/resources/overview) , [custom pages](https://filamentphp.com/docs/5.x/navigation/custom-pages) , and [clusters](https://filamentphp.com/docs/5.x/navigation/clusters) . These classes contain static properties and methods that you can override, to configure that navigation item. If you’re looking to add a second layer of navigation to your app, you can use [clusters](https://filamentphp.com/docs/5.x/navigation/clusters) . These are useful for grouping resources and pages together. [​](https://filamentphp.com/docs/5.x/navigation#customizing-a-navigation-item%E2%80%99s-label) Customizing a navigation item’s label --------------------------------------------------------------------------------------------------------------------------------------- By default, the navigation label is generated from the resource or page’s name. You may customize this using the `$navigationLabel` property: protected static ?string $navigationLabel = 'Custom Navigation Label'; Alternatively, you may override the `getNavigationLabel()` method: public static function getNavigationLabel(): string { return 'Custom Navigation Label'; } [​](https://filamentphp.com/docs/5.x/navigation#customizing-a-navigation-item%E2%80%99s-icon) Customizing a navigation item’s icon ------------------------------------------------------------------------------------------------------------------------------------- To customize a navigation item’s [icon](https://filamentphp.com/docs/5.x/styling/icons) , you may override the `$navigationIcon` property on the [resource](https://filamentphp.com/docs/5.x/resources/overview) or [page](https://filamentphp.com/docs/5.x/navigation/custom-pages) class: use BackedEnum; use Filament\Support\Icons\Heroicon; protected static string | BackedEnum | null $navigationIcon = Heroicon::OutlinedDocumentText; If you set `$navigationIcon = null` on all items within the same navigation group, those items will be joined with a vertical bar below the group label. ### [​](https://filamentphp.com/docs/5.x/navigation#switching-navigation-item-icon-when-it-is-active) Switching navigation item icon when it is active You may assign a navigation [icon](https://filamentphp.com/docs/5.x/styling/icons) which will only be used for active items using the `$activeNavigationIcon` property: use BackedEnum; use Filament\Support\Icons\Heroicon; protected static string | BackedEnum | null $activeNavigationIcon = Heroicon::OutlinedDocumentText; [​](https://filamentphp.com/docs/5.x/navigation#sorting-navigation-items) Sorting navigation items ----------------------------------------------------------------------------------------------------- By default, navigation items are sorted alphabetically. You may customize this using the `$navigationSort` property: protected static ?int $navigationSort = 3; Now, navigation items with a lower sort value will appear before those with a higher sort value - the order is ascending. [​](https://filamentphp.com/docs/5.x/navigation#adding-a-badge-to-a-navigation-item) Adding a badge to a navigation item --------------------------------------------------------------------------------------------------------------------------- To add a badge next to the navigation item, you can use the `getNavigationBadge()` method and return the content of the badge: public static function getNavigationBadge(): ?string { return static::getModel()::count(); } If a badge value is returned by `getNavigationBadge()`, it will display using the primary color by default. To style the badge contextually, return either `danger`, `gray`, `info`, `primary`, `success` or `warning` from the `getNavigationBadgeColor()` method: public static function getNavigationBadgeColor(): ?string { return static::getModel()::count() > 10 ? 'warning' : 'primary'; } A custom tooltip for the navigation badge can be set in `$navigationBadgeTooltip`: protected static ?string $navigationBadgeTooltip = 'The number of users'; Or it can be returned from `getNavigationBadgeTooltip()`: public static function getNavigationBadgeTooltip(): ?string { return 'The number of users'; } [​](https://filamentphp.com/docs/5.x/navigation#grouping-navigation-items) Grouping navigation items ------------------------------------------------------------------------------------------------------- You may group navigation items by specifying a `$navigationGroup` property on a [resource](https://filamentphp.com/docs/5.x/resources/overview) and [custom page](https://filamentphp.com/docs/5.x/navigation/custom-pages) : use UnitEnum; protected static string | UnitEnum | null $navigationGroup = 'Settings'; All items in the same navigation group will be displayed together under the same group label, “Settings” in this case. Ungrouped items will remain at the start of the navigation. ### [​](https://filamentphp.com/docs/5.x/navigation#grouping-navigation-items-under-other-items) Grouping navigation items under other items You may group navigation items as children of other items by setting the `$navigationParentItem` property. You may reference the parent item either by its page or resource class, or by its label: use App\Filament\Resources\Notifications\NotificationResource; use UnitEnum; protected static ?string $navigationParentItem = NotificationResource::class; protected static string | UnitEnum | null $navigationGroup = 'Settings'; Alternatively, you may reference the parent by its label: use UnitEnum; protected static ?string $navigationParentItem = 'Notifications'; protected static string | UnitEnum | null $navigationGroup = 'Settings'; You may also use the `getNavigationParentItem()` method to determine the parent dynamically: use App\Filament\Resources\Notifications\NotificationResource; public static function getNavigationParentItem(): ?string { return NotificationResource::class; } Alternatively, you may return the parent’s label: public static function getNavigationParentItem(): ?string { return __('filament/navigation.groups.settings.items.notifications'); } The parent and child items must belong to the same navigation group. If the parent item has a navigation group, that group must also be defined on the child, otherwise the correct parent item cannot be identified. This applies whether you reference the parent by its class or by its label. If you’re reaching for a third level of navigation like this, you should consider using [clusters](https://filamentphp.com/docs/5.x/navigation/clusters) instead, which are a logical grouping of resources and custom pages, which can share their own separate navigation. ### [​](https://filamentphp.com/docs/5.x/navigation#customizing-navigation-groups) Customizing navigation groups You may customize navigation groups by calling `navigationGroups()` in the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) , and passing `NavigationGroup` objects in order: use Filament\Navigation\NavigationGroup; use Filament\Panel; use Filament\Support\Icons\Heroicon; public function panel(Panel $panel): Panel { return $panel // ... ->navigationGroups([\ NavigationGroup::make()\ ->label('Shop')\ ->icon(Heroicon::OutlinedShoppingCart),\ NavigationGroup::make()\ ->label('Blog')\ ->icon(Heroicon::OutlinedPencil),\ NavigationGroup::make()\ ->label(fn (): string => __('navigation.settings'))\ ->icon(Heroicon::OutlinedCog6Tooth)\ ->collapsed(),\ ]); } In this example, we pass in a custom `icon()` for the groups, and make one `collapsed()` by default. #### [​](https://filamentphp.com/docs/5.x/navigation#ordering-navigation-groups) Ordering navigation groups By using `navigationGroups()`, you are defining a new order for the navigation groups. If you just want to reorder the groups and not define an entire `NavigationGroup` object, you may just pass the labels of the groups in the new order: $panel ->navigationGroups([\ 'Shop',\ 'Blog',\ 'Settings',\ ]) #### [​](https://filamentphp.com/docs/5.x/navigation#making-navigation-groups-not-collapsible) Making navigation groups not collapsible By default, navigation groups are collapsible. You may disable this behavior by calling `collapsible(false)` on the `NavigationGroup` object: use Filament\Navigation\NavigationGroup; use Filament\Support\Icons\Heroicon; NavigationGroup::make() ->label('Settings') ->icon(Heroicon::OutlinedCog6Tooth) ->collapsible(false); Or, you can do it globally for all groups in the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) : use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->collapsibleNavigationGroups(false); } #### [​](https://filamentphp.com/docs/5.x/navigation#adding-extra-html-attributes-to-navigation-groups) Adding extra HTML attributes to navigation groups You can pass extra HTML attributes to the navigation group, which will be merged onto the outer DOM element. Pass an array of attributes to the `extraSidebarAttributes()` or `extraTopbarAttributes()` method, where the key is the attribute name and the value is the attribute value: NavigationGroup::make() ->extraSidebarAttributes(['class' => 'featured-sidebar-group']), ->extraTopbarAttributes(['class' => 'featured-topbar-group']), The `extraSidebarAttributes()` will be applied to navigation group elements contained in the sidebar, and the `extraTopbarAttributes()` will only be applied to topbar navigation group dropdowns when using [top navigation](https://filamentphp.com/docs/5.x/navigation#using-top-navigation) . ### [​](https://filamentphp.com/docs/5.x/navigation#registering-navigation-groups-with-an-enum) Registering navigation groups with an enum You can use an enum class to register navigation groups, which allows you to control their labels, icons, and order in a single place, without needing to register them in the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) . To do this, you can create an enum class with cases for each group: enum NavigationGroup { case Shop; case Blog; case Settings; } The order that the cases are defined in will control the order of the navigation groups. To use an enum navigation group for a resource or custom page, you can set the `$navigationGroup` property to the enum case: protected static string | UnitEnum | null $navigationGroup = NavigationGroup::Shop; You can also implement the `HasLabel` interface on the enum class, to define a custom label for each group: use Filament\Support\Contracts\HasLabel; enum NavigationGroup implements HasLabel { case Shop; case Blog; case Settings; public function getLabel(): string { return match ($this) { self::Shop => __('navigation-groups.shop'), self::Blog => __('navigation-groups.blog'), self::Settings => __('navigation-groups.settings'), }; } } You can also implement the `HasIcon` interface on the enum class, to define a custom icon for each group: use BackedEnum; use Filament\Support\Contracts\HasIcon; use Filament\Support\Icons\Heroicon; use Illuminate\Contracts\Support\Htmlable; enum NavigationGroup implements HasIcon { case Shop; case Blog; case Settings; public function getIcon(): string | BackedEnum | Htmlable | null { return match ($this) { self::Shop => Heroicon::OutlinedShoppingCart, self::Blog => Heroicon::OutlinedPencil, self::Settings => Heroicon::OutlinedCog6Tooth, }; } } [​](https://filamentphp.com/docs/5.x/navigation#collapsible-sidebar-on-desktop) Collapsible sidebar on desktop ----------------------------------------------------------------------------------------------------------------- To make the sidebar collapsible on desktop as well as mobile, you can use the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) : use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->sidebarCollapsibleOnDesktop(); } By default, when you collapse the sidebar on desktop, the navigation icons still show. You can fully collapse the sidebar using the `sidebarFullyCollapsibleOnDesktop()` method: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->sidebarFullyCollapsibleOnDesktop(); } ### [​](https://filamentphp.com/docs/5.x/navigation#navigation-groups-in-a-collapsible-sidebar-on-desktop) Navigation groups in a collapsible sidebar on desktop This section only applies to `sidebarCollapsibleOnDesktop()`, not `sidebarFullyCollapsibleOnDesktop()`, since the fully collapsible UI just hides the entire sidebar instead of changing its design. When using a collapsible sidebar on desktop, you will also often be using [navigation groups](https://filamentphp.com/docs/5.x/navigation#grouping-navigation-items) . By default, the labels of each navigation group will be hidden when the sidebar is collapsed, since there is no space to display them. Even if the navigation group itself is [collapsible](https://filamentphp.com/docs/5.x/navigation#making-navigation-groups-not-collapsible) , all items will still be visible in the collapsed sidebar, since there is no group label to click on to expand the group. These issues can be solved, to achieve a very minimal sidebar design, by [passing an `icon()`](https://filamentphp.com/docs/5.x/navigation#customizing-navigation-groups) to the navigation group objects. When an icon is defined, the icon will be displayed in the collapsed sidebar instead of the items at all times. When the icon is clicked, a dropdown will open to the side of the icon, revealing the items in the group. When passing an icon to a navigation group, even if the items also have icons, the expanded sidebar UI will not show the item icons. This is to keep the navigation hierarchy clear, and the design minimal. However, the icons for the items will be shown in the collapsed sidebar’s dropdowns though, since the hierarchy is already clear from the fact that the dropdown is open. [​](https://filamentphp.com/docs/5.x/navigation#registering-custom-navigation-items) Registering custom navigation items --------------------------------------------------------------------------------------------------------------------------- To register new navigation items, you can use the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) : use Filament\Navigation\NavigationItem; use Filament\Pages\Dashboard; use Filament\Panel; use Filament\Support\Icons\Heroicon; use function Filament\Support\original_request; public function panel(Panel $panel): Panel { return $panel // ... ->navigationItems([\ NavigationItem::make('Analytics')\ ->url('https://filament.pirsch.io', shouldOpenInNewTab: true)\ ->icon(Heroicon::OutlinedPresentationChartLine)\ ->group('Reports')\ ->sort(3),\ NavigationItem::make('dashboard')\ ->label(fn (): string => __('filament-panels::pages/dashboard.title'))\ ->url(fn (): string => Dashboard::getUrl())\ ->isActiveWhen(fn () => original_request()->routeIs('filament.admin.pages.dashboard')),\ // ...\ ]); } [​](https://filamentphp.com/docs/5.x/navigation#conditionally-hiding-navigation-items) Conditionally hiding navigation items ------------------------------------------------------------------------------------------------------------------------------- You can also conditionally hide a navigation item by using the `visible()` or `hidden()` methods, passing in a condition to check: use Filament\Navigation\NavigationItem; NavigationItem::make('Analytics') ->visible(fn(): bool => auth()->user()->can('view-analytics')) // or ->hidden(fn(): bool => ! auth()->user()->can('view-analytics')), [​](https://filamentphp.com/docs/5.x/navigation#disabling-resource-or-page-navigation-items) Disabling resource or page navigation items ------------------------------------------------------------------------------------------------------------------------------------------- To prevent resources or pages from showing up in navigation, you may use: protected static bool $shouldRegisterNavigation = false; Or, you may override the `shouldRegisterNavigation()` method: public static function shouldRegisterNavigation(): bool { return false; } `shouldRegisterNavigation()` only hides the link from the sidebar — it does not prevent a user from typing the URL directly. To actually restrict access, use [resource authorization](https://filamentphp.com/docs/5.x/resources#authorization) or [page authorization](https://filamentphp.com/docs/5.x/navigation/custom-pages#authorization) . [​](https://filamentphp.com/docs/5.x/navigation#using-top-navigation) Using top navigation --------------------------------------------------------------------------------------------- By default, Filament will use a sidebar navigation. You may use a top navigation instead by using the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) : use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->topNavigation(); } [​](https://filamentphp.com/docs/5.x/navigation#customizing-the-width-of-the-sidebar) Customizing the width of the sidebar ----------------------------------------------------------------------------------------------------------------------------- You can customize the width of the sidebar by passing it to the `sidebarWidth()` method in the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) : use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->sidebarWidth('40rem'); } Additionally, if you are using the `sidebarCollapsibleOnDesktop()` method, you can customize width of the collapsed icons by using the `collapsedSidebarWidth()` method in the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) : use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->sidebarCollapsibleOnDesktop() ->collapsedSidebarWidth('9rem'); } [​](https://filamentphp.com/docs/5.x/navigation#advanced-navigation-customization) Advanced navigation customization ----------------------------------------------------------------------------------------------------------------------- The `navigation()` method can be called from the [configuration](https://filamentphp.com/docs/5.x/panel-configuration) . It allows you to build a custom navigation that overrides Filament’s automatically generated items. This API is designed to give you complete control over the navigation. ### [​](https://filamentphp.com/docs/5.x/navigation#registering-custom-navigation-items-2) Registering custom navigation items To register navigation items, call the `items()` method: use App\Filament\Pages\Settings; use App\Filament\Resources\Users\UserResource; use Filament\Navigation\NavigationBuilder; use Filament\Navigation\NavigationItem; use Filament\Pages\Dashboard; use Filament\Panel; use Filament\Support\Icons\Heroicon; use function Filament\Support\original_request; public function panel(Panel $panel): Panel { return $panel // ... ->navigation(function (NavigationBuilder $builder): NavigationBuilder { return $builder->items([\ NavigationItem::make('Dashboard')\ ->icon(Heroicon::OutlinedHome)\ ->isActiveWhen(fn (): bool => original_request()->routeIs('filament.admin.pages.dashboard'))\ ->url(fn (): string => Dashboard::getUrl()),\ ...UserResource::getNavigationItems(),\ ...Settings::getNavigationItems(),\ ]); }); } ### [​](https://filamentphp.com/docs/5.x/navigation#registering-custom-navigation-groups) Registering custom navigation groups If you want to register groups, you can call the `groups()` method: use App\Filament\Pages\HomePageSettings; use App\Filament\Resources\Categories\CategoryResource; use App\Filament\Resources\Pages\PageResource; use Filament\Navigation\NavigationBuilder; use Filament\Navigation\NavigationGroup; use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->navigation(function (NavigationBuilder $builder): NavigationBuilder { return $builder->groups([\ NavigationGroup::make('Website')\ ->items([\ ...PageResource::getNavigationItems(),\ ...CategoryResource::getNavigationItems(),\ ...HomePageSettings::getNavigationItems(),\ ]),\ ]); }); } ### [​](https://filamentphp.com/docs/5.x/navigation#disabling-navigation) Disabling navigation You may disable navigation entirely by passing `false` to the `navigation()` method: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->navigation(false); } Alternatively, you may pass a closure that returns a boolean to decide dynamically. Returning `false` hides the navigation, while returning `true` renders the default auto-discovered navigation items. This is useful for flows such as onboarding or setup wizards where the navigation should only appear once the user has reached a particular state: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->navigation(fn (): bool => auth()->user()->hasCompletedOnboarding()); } ### [​](https://filamentphp.com/docs/5.x/navigation#disabling-the-topbar) Disabling the topbar You may disable topbar entirely by passing `false` to the `topbar()` method: use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->topbar(false); } ### [​](https://filamentphp.com/docs/5.x/navigation#replacing-the-sidebar-and-topbar-livewire-components) Replacing the sidebar and topbar Livewire components You may completely replace the Livewire components that are used to render the sidebar and topbar, passing your own Livewire component class name into the `sidebarLivewireComponent()` or `topbarLivewireComponent()` method: use App\Livewire\Sidebar; use App\Livewire\Topbar; use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->sidebarLivewireComponent(Sidebar::class) ->topbarLivewireComponent(Topbar::class); } [​](https://filamentphp.com/docs/5.x/navigation#disabling-breadcrumbs) Disabling breadcrumbs ----------------------------------------------------------------------------------------------- The default layout will show breadcrumbs to indicate the location of the current page within the hierarchy of the app. You may disable breadcrumbs in your [configuration](https://filamentphp.com/docs/5.x/panel-configuration) : use Filament\Panel; public function panel(Panel $panel): Panel { return $panel // ... ->breadcrumbs(false); } [​](https://filamentphp.com/docs/5.x/navigation#reloading-the-sidebar-and-topbar) Reloading the sidebar and topbar --------------------------------------------------------------------------------------------------------------------- Once a page in the panel is loaded, the sidebar and topbar are not reloaded until you navigate away from the page, or until a menu item is clicked to trigger an action. You can manually reload these components to update them by dispatching a `refresh-sidebar` or `refresh-topbar` browser event. To dispatch an event from PHP, you can call the `$this->dispatch()` method from any Livewire component, such as a page class, relation manager class, or widget class: $this->dispatch('refresh-sidebar'); When your code does not live inside a Livewire component, such as when you have a custom action class, you can inject the `$livewire` argument into a closure function, and call `dispatch()` on that: use Filament\Actions\Action; use Livewire\Component; Action::make('create') ->action(function (Component $livewire) { // ... $livewire->dispatch('refresh-sidebar'); }) Alternatively, you can dispatch an event from JavaScript using the `$dispatch()` Alpine.js helper method, or the native browser `window.dispatchEvent()` method: window.dispatchEvent(new CustomEvent('refresh-sidebar')); [Panel configuration](https://filamentphp.com/docs/5.x/panel-configuration) [Custom pages](https://filamentphp.com/docs/5.x/navigation/custom-pages) ⌘I --- # Overview - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/filters#content-area) [​](https://filamentphp.com/docs/5.x/tables/filters#introduction) Introduction --------------------------------------------------------------------------------- Filters allow you to define certain constraints on your data, and allow users to scope it to find the information they need. You put them in the `$table->filters()` method. Filters may be created using the static `make()` method, passing its unique name. You should then pass a callback to `query()` which applies your filter’s scope: use Filament\Tables\Filters\Filter; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; public function table(Table $table): Table { return $table ->filters([\ Filter::make('is_featured')\ ->query(fn (Builder $query): Builder => $query->where('is_featured', true))\ // ...\ ]); } [​](https://filamentphp.com/docs/5.x/tables/filters#available-filters) Available filters ------------------------------------------------------------------------------------------- By default, using the `Filter::make()` method will render a checkbox form component. When the checkbox is on, the `query()` will be activated. * You can also [replace the checkbox with a toggle](https://filamentphp.com/docs/5.x/tables/filters#using-a-toggle-button-instead-of-a-checkbox) . * You may use a [select filter](https://filamentphp.com/docs/5.x/tables/filters/select) to allow users to select from a list of options, and filter using the selection. * You can use a [ternary filter](https://filamentphp.com/docs/5.x/tables/filters/ternary) to replace the checkbox with a select field to allow users to pick between 3 states - usually “true”, “false” and “blank”. This is useful for filtering boolean columns. * The [trashed filter](https://filamentphp.com/docs/5.x/tables/filters/ternary#filtering-soft-deletable-records) is a pre-built ternary filter that allows you to filter soft-deletable records. * Using a [query builder](https://filamentphp.com/docs/5.x/tables/filters/query-builder) , users can create complex sets of filters, with an advanced user interface for combining constraints. * You may build [custom filters](https://filamentphp.com/docs/5.x/tables/filters/custom) with other form fields, to do whatever you want. [​](https://filamentphp.com/docs/5.x/tables/filters#setting-a-label) Setting a label --------------------------------------------------------------------------------------- By default, the label of the filter is generated from the name of the filter. You may customize this using the `label()` method: use Filament\Tables\Filters\Filter; Filter::make('is_featured') ->label('Featured') Customizing the label in this way is useful if you wish to use a [translation string for localization](https://laravel.com/docs/localization#retrieving-translation-strings) : use Filament\Tables\Filters\Filter; Filter::make('is_featured') ->label(__('filters.is_featured')) [​](https://filamentphp.com/docs/5.x/tables/filters#customizing-the-filter-schema) Customizing the filter schema ------------------------------------------------------------------------------------------------------------------- By default, creating a filter with the `Filter` class will render a [checkbox form component](https://filamentphp.com/docs/5.x/forms/checkbox) . When the checkbox is checked, the `query()` function will be applied to the table’s query, scoping the records in the table. When the checkbox is unchecked, the `query()` function will be removed from the table’s query. Filters are built entirely on Filament’s form fields. They can render any combination of form fields, which users can then interact with to filter the table. ### [​](https://filamentphp.com/docs/5.x/tables/filters#using-a-toggle-button-instead-of-a-checkbox) Using a toggle button instead of a checkbox The simplest example of managing the form field that is used for a filter is to replace the [checkbox](https://filamentphp.com/docs/5.x/forms/checkbox) with a [toggle button](https://filamentphp.com/docs/5.x/forms/toggle) , using the `toggle()` method: use Filament\Tables\Filters\Filter; Filter::make('is_featured') ->toggle() ### [​](https://filamentphp.com/docs/5.x/tables/filters#customizing-the-built-in-filter-form-field) Customizing the built-in filter form field Whether you are using a checkbox, a [toggle](https://filamentphp.com/docs/5.x/tables/filters#using-a-toggle-button-instead-of-a-checkbox) or a [select](https://filamentphp.com/docs/5.x/tables/filters/select) , you can customize the built-in form field used for the filter, using the `modifyFormFieldUsing()` method. The method accepts a function with a `$field` parameter that gives you access to the form field object to customize: use Filament\Forms\Components\Checkbox; use Filament\Tables\Filters\Filter; Filter::make('is_featured') ->modifyFormFieldUsing(fn (Checkbox $field) => $field->inline(false)) [​](https://filamentphp.com/docs/5.x/tables/filters#applying-the-filter-by-default) Applying the filter by default --------------------------------------------------------------------------------------------------------------------- You may set a filter to be enabled by default, using the `default()` method: use Filament\Tables\Filters\Filter; Filter::make('is_featured') ->default() If you’re using a [select filter](https://filamentphp.com/docs/5.x/tables/filters/select) , [visit the “applying select filters by default” section](https://filamentphp.com/docs/5.x/tables/filters/select#applying-select-filters-by-default) . [​](https://filamentphp.com/docs/5.x/tables/filters#persisting-filters-in-the-user%E2%80%99s-session) Persisting filters in the user’s session ------------------------------------------------------------------------------------------------------------------------------------------------- To persist the table filters in the user’s session, use the `persistFiltersInSession()` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->persistFiltersInSession(); } [​](https://filamentphp.com/docs/5.x/tables/filters#live-filters) Live filters --------------------------------------------------------------------------------- By default, filter changes are deferred and do not affect the table, until the user clicks an “Apply” button. To disable this and make the filters “live” instead, use the `deferFilters(false)` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->deferFilters(false); } ### [​](https://filamentphp.com/docs/5.x/tables/filters#customizing-the-apply-filters-action) Customizing the apply filters action When deferring filters, you can customize the “Apply” button, using the `filtersApplyAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](https://filamentphp.com/docs/5.x/actions/overview) can be used: use Filament\Actions\Action; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->filtersApplyAction( fn (Action $action) => $action ->link() ->label('Save filters to table'), ); } [​](https://filamentphp.com/docs/5.x/tables/filters#deselecting-records-when-filters-change) Deselecting records when filters change --------------------------------------------------------------------------------------------------------------------------------------- By default, all records will be deselected when the filters change. Using the `deselectAllRecordsWhenFiltered(false)` method, you can disable this behavior: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->deselectAllRecordsWhenFiltered(false); } [​](https://filamentphp.com/docs/5.x/tables/filters#modifying-the-base-query) Modifying the base query --------------------------------------------------------------------------------------------------------- By default, modifications to the Eloquent query performed in the `query()` method will be applied inside a scoped `where()` clause. This is to ensure that the query does not clash with any other filters that may be applied, especially those that use `orWhere()`. However, the downside of this is that the `query()` method cannot be used to modify the query in other ways, such as removing global scopes, since the base query needs to be modified directly, not the scoped query. To modify the base query directly, you may use the `baseQuery()` method, passing a closure that receives the base query: use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; use Filament\Tables\Filters\TernaryFilter; TernaryFilter::make('trashed') // ... ->baseQuery(fn (Builder $query) => $query->withoutGlobalScopes([\ SoftDeletingScope::class,\ ])) [​](https://filamentphp.com/docs/5.x/tables/filters#excluding-filters-when-resolving-records) Excluding filters when resolving records ----------------------------------------------------------------------------------------------------------------------------------------- When a user interacts with a table record (e.g., clicking an action button), Filament resolves that record from the database. By default, all active filter conditions are applied, ensuring users cannot access records outside their filter scope. However, some filters like `TrashedFilter` modify global scopes rather than restricting access. When a record’s state changes after the user saw it in the table, you may still want the user to interact with it. You may mark a filter to be excluded when resolving records using the `excludeWhenResolvingRecord()` method: use Filament\Tables\Filters\Filter; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; Filter::make('trashed') ->query(fn (Builder $query) => $query->onlyTrashed()) ->baseQuery(fn (Builder $query) => $query->withoutGlobalScopes([\ SoftDeletingScope::class,\ ])) ->excludeWhenResolvingRecord() When `excludeWhenResolvingRecord()` is used: * The filter’s `query()` callback is not applied when resolving records * The filter’s `baseQuery()` callback is still applied when resolving records Do not use `excludeWhenResolvingRecord()` on filters that enforce authorization rules. For example, if you have a filter that restricts records by tenant or user ownership, those filters should remain enforced to prevent unauthorized access. [​](https://filamentphp.com/docs/5.x/tables/filters#customizing-the-filters-trigger-action) Customizing the filters trigger action ------------------------------------------------------------------------------------------------------------------------------------- To customize the filters trigger buttons, you may use the `filtersTriggerAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](https://filamentphp.com/docs/5.x/actions/overview) can be used: use Filament\Actions\Action; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->filtersTriggerAction( fn (Action $action) => $action ->button() ->label('Filter'), ); } [​](https://filamentphp.com/docs/5.x/tables/filters#customizing-the-remove-all-filters-action) Customizing the remove all filters action ------------------------------------------------------------------------------------------------------------------------------------------- To customize the action that removes all active filters from the indicator bar, you may use the `filtersRemoveAllAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](https://filamentphp.com/docs/5.x/actions/overview) can be used: use Filament\Actions\Action; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->filtersRemoveAllAction( fn (Action $action) => $action ->tooltip('Clear filters'), ); } [​](https://filamentphp.com/docs/5.x/tables/filters#filter-utility-injection) Filter utility injection --------------------------------------------------------------------------------------------------------- The vast majority of methods used to configure filters accept functions as parameters instead of hardcoded values: use App\Models\Author; use Filament\Tables\Filters\SelectFilter; SelectFilter::make('author') ->options(fn (): array => Author::query()->pluck('name', 'id')->all()) This alone unlocks many customization possibilities. The package is also able to inject many utilities to use inside these functions, as parameters. All customization methods that accept functions as arguments can inject utilities. These injected utilities require specific parameter names to be used. Otherwise, Filament doesn’t know what to inject. ### [​](https://filamentphp.com/docs/5.x/tables/filters#injecting-the-current-filter-instance) Injecting the current filter instance If you wish to access the current filter instance, define a `$filter` parameter: use Filament\Tables\Filters\BaseFilter; function (BaseFilter $filter) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/filters#injecting-the-current-livewire-component-instance) Injecting the current Livewire component instance If you wish to access the current Livewire component instance that the table belongs to, define a `$livewire` parameter: use Filament\Tables\Contracts\HasTable; function (HasTable $livewire) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/filters#injecting-the-current-table-instance) Injecting the current table instance If you wish to access the current table configuration instance that the filter belongs to, define a `$table` parameter: use Filament\Tables\Table; function (Table $table) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/filters#injecting-multiple-utilities) Injecting multiple utilities The parameters are injected dynamically using reflection, so you are able to combine multiple parameters in any order: use Filament\Tables\Contracts\HasTable; use Filament\Tables\Table; function (HasTable $livewire, Table $table) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/filters#injecting-dependencies-from-laravel%E2%80%99s-container) Injecting dependencies from Laravel’s container You may inject anything from Laravel’s container like normal, alongside utilities: use Filament\Tables\Table; use Illuminate\Http\Request; function (Request $request, Table $table) { // ... } [Custom columns](https://filamentphp.com/docs/5.x/tables/columns/custom-columns) [Select filters](https://filamentphp.com/docs/5.x/tables/filters/select) ⌘I --- # Select filters - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/filters/select#content-area) [​](https://filamentphp.com/docs/5.x/tables/filters/select#introduction) Introduction ---------------------------------------------------------------------------------------- Often, you will want to use a [select field](https://filamentphp.com/docs/5.x/forms/select) instead of a checkbox. This is especially true when you want to filter a column based on a set of pre-defined options that the user can choose from. To do this, you can create a filter using the `SelectFilter` class: use Filament\Tables\Filters\SelectFilter; SelectFilter::make('status') ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) The `options()` that are passed to the filter are the same as those that are passed to the [select field](https://filamentphp.com/docs/5.x/forms/select) . `options()` is a UI affordance, not an authorization boundary. The list constrains what the dropdown displays, but the submitted value is not checked against it before the filter runs. A user tampering with the Livewire request can submit any value to the filter’s state — `apply()` will pass it straight into `whereIn`/`where` on the query.If you are using `options()` to hide certain values from a group of users (for example, hiding `archived` from non-admins), scope the table query itself instead — for example with [`modifyQueryUsing()`](https://filamentphp.com/docs/5.x/resources/listing-records#customizing-the-eloquent-query) or a global scope on the resource — so the restricted rows are never reachable regardless of what the filter submits. [​](https://filamentphp.com/docs/5.x/tables/filters/select#customizing-the-column-used-by-a-select-filter) Customizing the column used by a select filter ------------------------------------------------------------------------------------------------------------------------------------------------------------ Select filters do not require a custom `query()` method. The column name used to scope the query is the name of the filter. To customize this, you may use the `attribute()` method: use Filament\Tables\Filters\SelectFilter; SelectFilter::make('status') ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) ->attribute('status_id') [​](https://filamentphp.com/docs/5.x/tables/filters/select#multi-select-filters) Multi-select filters -------------------------------------------------------------------------------------------------------- These allow the user to [select multiple options](https://filamentphp.com/docs/5.x/forms/select#multi-select) to apply the filter to their table. For example, a status filter may present the user with a few status options to pick from and filter the table using. When the user selects multiple options, the table will be filtered to show records that match any of the selected options. You can enable this behavior using the `multiple()` method: use Filament\Tables\Filters\SelectFilter; SelectFilter::make('status') ->multiple() ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) [​](https://filamentphp.com/docs/5.x/tables/filters/select#relationship-select-filters) Relationship select filters ---------------------------------------------------------------------------------------------------------------------- Select filters are also able to automatically populate themselves based on a relationship. For example, if your table has a `author` relationship with a `name` column, you may use `relationship()` to filter the records belonging to an author: use Filament\Tables\Filters\SelectFilter; SelectFilter::make('author') ->relationship('author', 'name') ### [​](https://filamentphp.com/docs/5.x/tables/filters/select#preloading-the-select-filter-relationship-options) Preloading the select filter relationship options If you’d like to populate the searchable options from the database when the page is loaded, instead of when the user searches, you can use the `preload()` method: use Filament\Tables\Filters\SelectFilter; SelectFilter::make('author') ->relationship('author', 'name') ->searchable() ->preload() ### [​](https://filamentphp.com/docs/5.x/tables/filters/select#filtering-empty-relationships) Filtering empty relationships By default, upon selecting an option, all records that have an empty relationship will be excluded from the results. If you want to introduce an additional “None” option for the user to select, which will include all records that do not have a relationship, you can use the `hasEmptyOption()` argument of the `relationship()` method: use Filament\Tables\Filters\SelectFilter; SelectFilter::make('author') ->relationship('author', 'name', hasEmptyOption: true) You can rename the “None” option using the `emptyRelationshipOptionLabel()` method: use Filament\Tables\Filters\SelectFilter; SelectFilter::make('author') ->relationship('author', 'name', hasEmptyOption: true) ->emptyRelationshipOptionLabel('No author') ### [​](https://filamentphp.com/docs/5.x/tables/filters/select#customizing-the-select-filter-relationship-query) Customizing the select filter relationship query You may customize the database query that retrieves options using the third parameter of the `relationship()` method: use Filament\Tables\Filters\SelectFilter; use Illuminate\Database\Eloquent\Builder; SelectFilter::make('author') ->relationship('author', 'name', fn (Builder $query) => $query->withTrashed()) ### [​](https://filamentphp.com/docs/5.x/tables/filters/select#searching-select-filter-options) Searching select filter options You may enable a search input to allow easier access to many options, using the `searchable()` method: use Filament\Tables\Filters\SelectFilter; SelectFilter::make('author') ->relationship('author', 'name') ->searchable() [​](https://filamentphp.com/docs/5.x/tables/filters/select#disable-placeholder-selection) Disable placeholder selection -------------------------------------------------------------------------------------------------------------------------- You can remove the placeholder (null option), which disables the filter so all options are applied, using the `selectablePlaceholder()` method: use Filament\Tables\Filters\SelectFilter; SelectFilter::make('status') ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) ->default('draft') ->selectablePlaceholder(false) [​](https://filamentphp.com/docs/5.x/tables/filters/select#applying-select-filters-by-default) Applying select filters by default ------------------------------------------------------------------------------------------------------------------------------------ You may set a select filter to be enabled by default, using the `default()` method. If using a single select filter, the `default()` method accepts a single option value. If using a `multiple()` select filter, the `default()` method accepts an array of option values: use Filament\Tables\Filters\SelectFilter; SelectFilter::make('status') ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) ->default('draft') SelectFilter::make('status') ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) ->multiple() ->default(['draft', 'reviewing']) [Overview](https://filamentphp.com/docs/5.x/tables/filters/overview) [Ternary filters](https://filamentphp.com/docs/5.x/tables/filters/ternary) ⌘I --- # Select column - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/columns/select#content-area) [​](https://filamentphp.com/docs/5.x/tables/columns/select#introduction) Introduction ---------------------------------------------------------------------------------------- The select column allows you to render a select field inside the table, which can be used to update that database record without needing to open a new page or a modal. You must pass options to the column: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('status') ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) [​](https://filamentphp.com/docs/5.x/tables/columns/select#enabling-the-javascript-select) Enabling the JavaScript select ---------------------------------------------------------------------------------------------------------------------------- By default, Filament uses the native HTML5 select. You may enable a more customizable JavaScript select using the `native(false)` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('status') ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) ->native(false) [​](https://filamentphp.com/docs/5.x/tables/columns/select#searching-options) Searching options -------------------------------------------------------------------------------------------------- You may enable a search input to allow easier access to many options, using the `searchableOptions()` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->label('Author') ->options(User::query()->pluck('name', 'id')) ->searchableOptions() Optionally, you may pass a boolean value to control if the input should be searchable or not: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->label('Author') ->options(User::query()->pluck('name', 'id')) ->searchableOptions(FeatureFlag::active()) ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#returning-custom-search-results) Returning custom search results If you have lots of options and want to populate them based on a database search or other external data source, you can use the `getOptionsSearchResultsUsing()` and `getOptionLabelUsing()` methods instead of `options()`. The `getOptionsSearchResultsUsing()` method accepts a callback that returns search results in `$key => $value` format. The current user’s search is available as `$search`, and you should use that to filter your results. The `getOptionLabelUsing()` method accepts a callback that transforms the selected option `$value` into a label. This is used when the form is first loaded when the user has not made a search yet. Otherwise, the label used to display the currently selected option would not be available. Both `getOptionsSearchResultsUsing()` and `getOptionLabelUsing()` must be used on the select if you want to provide custom search results: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->searchableOptions() ->getOptionsSearchResultsUsing(fn (string $search): array => User::query() ->where('name', 'like', "%{$search}%") ->limit(50) ->pluck('name', 'id') ->all()) ->getOptionLabelUsing(fn ($value): ?string => User::find($value)?->name), `getOptionLabelUsing()` is crucial, since it provides Filament with the label of the selected option, so it doesn’t need to execute a full search to find it. If an option is not valid, it should return `null`. ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#setting-a-custom-loading-message) Setting a custom loading message When you’re using a searchable select or multi-select, you may want to display a custom message while the options are loading. You can do this using the `optionsLoadingMessage()` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'name') ->searchableOptions() ->optionsLoadingMessage('Loading authors...') ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#setting-a-custom-no-search-results-message) Setting a custom no search results message When you’re using a searchable select or multi-select, you may want to display a custom message when no search results are found. You can do this using the `noOptionsSearchResultsMessage()` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'name') ->searchableOptions() ->noOptionsSearchResultsMessage('No authors found.') ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#setting-a-custom-search-prompt) Setting a custom search prompt When you’re using a searchable select or multi-select, you may want to display a custom message when the user has not yet entered a search term. You can do this using the `optionsSearchPrompt()` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'name') ->searchableOptions(['name', 'email']) ->optionsSearchPrompt('Search authors by their name or email address') ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#setting-a-custom-searching-message) Setting a custom searching message When you’re using a searchable select or multi-select, you may want to display a custom message while the search results are being loaded. You can do this using the `optionsSearchingMessage()` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'name') ->searchableOptions() ->optionsSearchingMessage('Searching authors...') ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#tweaking-the-search-debounce) Tweaking the search debounce By default, Filament will wait 1000 milliseconds (1 second) before searching for options when the user types in a searchable select or multi-select. It will also wait 1000 milliseconds between searches, if the user is continuously typing into the search input. You can change this using the `optionsSearchDebounce()` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'name') ->searchableOptions() ->optionsSearchDebounce(500) Ensure that you are not lowering the debounce too much, as this may cause the select to become slow and unresponsive due to a high number of network requests to retrieve options from server. [​](https://filamentphp.com/docs/5.x/tables/columns/select#integrating-with-an-eloquent-relationship) Integrating with an Eloquent relationship -------------------------------------------------------------------------------------------------------------------------------------------------- You may employ the `optionsRelationship()` method of the `SelectColumn` to configure a `BelongsTo` relationship to automatically retrieve options from. The `titleAttribute` is the name of a column that will be used to generate a label for each option: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'name') ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#searching-relationship-options-across-multiple-columns) Searching relationship options across multiple columns By default, if the select is also searchable, Filament will return search results for the relationship based on the title column of the relationship. If you’d like to search across multiple columns, you can pass an array of columns to the `searchableOptions()` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'name') ->searchableOptions(['name', 'email']) ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#preloading-relationship-options) Preloading relationship options If you’d like to populate the searchable options from the database when the page is loaded, instead of when the user searches, you can use the `preloadOptions()` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'name') ->searchableOptions() ->preloadOptions() Optionally, you may pass a boolean value to control if the input should be preloaded or not: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'name') ->searchableOptions() ->preload(FeatureFlag::active()) ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#excluding-the-current-record) Excluding the current record When working with recursive relationships, you will likely want to remove the current record from the set of results. This can be easily be done using the `ignoreRecord` argument: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('parent_id') ->optionsRelationship(name: 'parent', titleAttribute: 'name', ignoreRecord: true) ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#customizing-the-relationship-query) Customizing the relationship query You may customize the database query that retrieves options using the third parameter of the `optionsRelationship()` method: use Filament\Tables\Columns\SelectColumn; use Illuminate\Database\Eloquent\Builder; SelectColumn::make('author_id') ->optionsRelationship( name: 'author', titleAttribute: 'name', modifyQueryUsing: fn (Builder $query) => $query->withTrashed(), ) ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#customizing-the-relationship-option-labels) Customizing the relationship option labels If you’d like to customize the label of each option, maybe to be more descriptive, or to concatenate a first and last name, you could use a virtual column in your database migration: $table->string('full_name')->virtualAs('concat(first_name, \' \', last_name)'); use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'full_name') Alternatively, you can use the `getOptionLabelFromRecordUsing()` method to transform an option’s Eloquent model into a label: use Filament\Tables\Columns\SelectColumn; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; SelectColumn::make('author_id') ->optionsRelationship( name: 'author', modifyQueryUsing: fn (Builder $query) => $query->orderBy('first_name')->orderBy('last_name'), ) ->getOptionLabelFromRecordUsing(fn (Model $record) => "{$record->first_name} {$record->last_name}") ->searchableOptions(['first_name', 'last_name']) ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#remembering-options) Remembering options By default, when using `optionsRelationship()`, Filament will remember the options for the duration of the table page to improve performance. This means that the options function will only run once per table page instead of once per cell. You can disable this behavior using the `rememberOptions(false)` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'name') ->rememberOptions(false) When options are remembered, any record-specific options or disabled options will not work correctly, as the same options will be used for all records in the table. If you need record-specific options or disabled options, you should disable option remembering. [​](https://filamentphp.com/docs/5.x/tables/columns/select#allowing-html-in-the-option-labels) Allowing HTML in the option labels ------------------------------------------------------------------------------------------------------------------------------------ By default, Filament will escape any HTML in the option labels. If you’d like to allow HTML, you can use the `allowOptionsHtml()` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('technology') ->options([\ 'tailwind' => 'Tailwind',\ 'alpine' => 'Alpine',\ 'laravel' => 'Laravel',\ 'livewire' => 'Livewire',\ ]) ->searchableOptions() ->allowOptionsHtml() Be aware that you will need to ensure that the HTML is safe to render, otherwise your application will be vulnerable to XSS attacks. Optionally, you may pass a boolean value to control if the input should allow HTML or not: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('technology') ->options([\ 'tailwind' => 'Tailwind',\ 'alpine' => 'Alpine',\ 'laravel' => 'Laravel',\ 'livewire' => 'Livewire',\ ]) ->searchableOptions() ->allowOptionsHtml(FeatureFlag::active()) [​](https://filamentphp.com/docs/5.x/tables/columns/select#wrap-or-truncate-option-labels) Wrap or truncate option labels ---------------------------------------------------------------------------------------------------------------------------- When using the JavaScript select, labels that exceed the width of the select element will wrap onto multiple lines by default. Alternatively, you may choose to truncate overflowing labels. use Filament\Tables\Columns\SelectColumn; SelectColumn::make('truncate') ->wrapOptionLabels(false) [​](https://filamentphp.com/docs/5.x/tables/columns/select#disable-placeholder-selection) Disable placeholder selection -------------------------------------------------------------------------------------------------------------------------- You can prevent the placeholder (null option) from being selected using the `selectablePlaceholder(false)` method: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('status') ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) ->selectablePlaceholder(false) [​](https://filamentphp.com/docs/5.x/tables/columns/select#disabling-specific-options) Disabling specific options -------------------------------------------------------------------------------------------------------------------- You can disable specific options using the `disableOptionWhen()` method. It accepts a closure, in which you can check if the option with a specific `$value` should be disabled: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('status') ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) ->default('draft') ->disableOptionWhen(fn (string $value): bool => $value === 'published') [​](https://filamentphp.com/docs/5.x/tables/columns/select#limiting-the-number-of-options) Limiting the number of options ---------------------------------------------------------------------------------------------------------------------------- You can limit the number of options that are displayed in a searchable select or multi-select using the `optionsLimit()` method. The default is 50: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->optionsRelationship(name: 'author', titleAttribute: 'name') ->searchableOptions() ->optionsLimit(20) Ensure that you are not raising the limit too high, as this may cause the select to become slow and unresponsive due to high in-browser memory usage. [​](https://filamentphp.com/docs/5.x/tables/columns/select#validation) Validation ------------------------------------------------------------------------------------ You can validate the input by passing any [Laravel validation rules](https://laravel.com/docs/validation#available-validation-rules) in an array: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('status') ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) ->rules(['required']) ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#valid-options-validation-in-rule) Valid options validation (`in` rule) The `in` rule ensures that users cannot select an option that is not in the list of options. This is an important rule for data integrity purposes, so Filament applies it by default to all select fields. Since there are many ways for a select field to populate its options, and in many cases the options are not all loaded into the select by default and require searching to retrieve them, Filament uses the presence of a valid “option label” to determine whether the selected value exists. It also checks if that option is [disabled](https://filamentphp.com/docs/5.x/tables/columns/select#disabling-specific-options) or not. If you are using a custom search query to retrieve options, you should ensure that the `getOptionLabelUsing()` method is defined, so that Filament can validate the selected value against the available options: use Filament\Tables\Columns\SelectColumn; SelectColumn::make('author_id') ->searchableOptions() ->getOptionsSearchResultsUsing(fn (string $search): array => Author::query() ->where('name', 'like', "%{$search}%") ->limit(50) ->pluck('name', 'id') ->all()) ->getOptionLabelUsing(fn (string $value): ?string => Author::find($value)?->name), The `getOptionLabelUsing()` method should return `null` if the option is not valid, to allow Filament to determine that the selected value is not in the list of options. If the option is valid, it should return the label of the option. If you are using the `optionsRelationship()` method, the `getOptionLabelUsing()` method will be automatically defined for you, so you don’t need to worry about it. [​](https://filamentphp.com/docs/5.x/tables/columns/select#lifecycle-hooks) Lifecycle hooks ---------------------------------------------------------------------------------------------- Hooks may be used to execute code at various points within the select’s lifecycle: SelectColumn::make() ->beforeStateUpdated(function ($record, $state) { // Runs before the state is saved to the database. }) ->afterStateUpdated(function ($record, $state) { // Runs after the state is saved to the database. }) [​](https://filamentphp.com/docs/5.x/tables/columns/select#security) Security -------------------------------------------------------------------------------- ### [​](https://filamentphp.com/docs/5.x/tables/columns/select#authorization) Authorization The select column does not automatically check Laravel Model Policies before saving changes. When a user updates a value via the select column, Filament checks whether the column is `disabled()` but does not run any `update` policy gate check. This means that if a user can see a record in the table and the column is not disabled, they can update that column’s value regardless of any `update` policy you have defined. If you need to restrict who can edit this column, you should use the `disabled()` method to conditionally prevent editing based on your own authorization logic, for example `disabled(fn ($record) => $record->user_id !== auth()->id())`. Alternatively, consider using a full edit page or modal action where Filament’s resource authorization is enforced. [Color column](https://filamentphp.com/docs/5.x/tables/columns/color) [Toggle column](https://filamentphp.com/docs/5.x/tables/columns/toggle) ⌘I --- # Toggle column - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/columns/toggle#content-area) [​](https://filamentphp.com/docs/5.x/tables/columns/toggle#introduction) Introduction ---------------------------------------------------------------------------------------- The toggle column allows you to render a toggle button inside the table, which can be used to update that database record without needing to open a new page or a modal: use Filament\Tables\Columns\ToggleColumn; ToggleColumn::make('is_admin') [​](https://filamentphp.com/docs/5.x/tables/columns/toggle#lifecycle-hooks) Lifecycle hooks ---------------------------------------------------------------------------------------------- Hooks may be used to execute code at various points within the toggle’s lifecycle: ToggleColumn::make() ->beforeStateUpdated(function ($record, $state) { // Runs before the state is saved to the database. }) ->afterStateUpdated(function ($record, $state) { // Runs after the state is saved to the database. }) [​](https://filamentphp.com/docs/5.x/tables/columns/toggle#security) Security -------------------------------------------------------------------------------- ### [​](https://filamentphp.com/docs/5.x/tables/columns/toggle#authorization) Authorization The toggle column does not automatically check Laravel Model Policies before saving changes. When a user updates a value via the toggle column, Filament checks whether the column is `disabled()` but does not run any `update` policy gate check. This means that if a user can see a record in the table and the column is not disabled, they can update that column’s value regardless of any `update` policy you have defined. If you need to restrict who can edit this column, you should use the `disabled()` method to conditionally prevent editing based on your own authorization logic, for example `disabled(fn ($record) => $record->user_id !== auth()->id())`. Alternatively, consider using a full edit page or modal action where Filament’s resource authorization is enforced. [Select column](https://filamentphp.com/docs/5.x/tables/columns/select) [Text input column](https://filamentphp.com/docs/5.x/tables/columns/text-input) ⌘I --- # Icon column - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/columns/icon#content-area) [​](https://filamentphp.com/docs/5.x/tables/columns/icon#introduction) Introduction -------------------------------------------------------------------------------------- Icon columns render an [icon](https://filamentphp.com/docs/5.x/styling/icons) representing the state of the column: use Filament\Tables\Columns\IconColumn; use Filament\Support\Icons\Heroicon; IconColumn::make('status') ->icon(fn (string $state): Heroicon => match ($state) { 'draft' => Heroicon::OutlinedPencil, 'reviewing' => Heroicon::OutlinedClock, 'published' => Heroicon::OutlinedCheckCircle, }) [​](https://filamentphp.com/docs/5.x/tables/columns/icon#customizing-the-color) Customizing the color -------------------------------------------------------------------------------------------------------- You may change the [color](https://filamentphp.com/docs/5.x/styling/colors) of the icon, using the `color()` method: use Filament\Tables\Columns\IconColumn; IconColumn::make('status') ->color('success') By passing a function to `color()`, you can customize the color based on the state of the column: use Filament\Tables\Columns\IconColumn; IconColumn::make('status') ->color(fn (string $state): string => match ($state) { 'draft' => 'info', 'reviewing' => 'warning', 'published' => 'success', default => 'gray', }) [​](https://filamentphp.com/docs/5.x/tables/columns/icon#customizing-the-size) Customizing the size ------------------------------------------------------------------------------------------------------ The default icon size is `IconSize::Large`, but you may customize the size to be either `IconSize::ExtraSmall`, `IconSize::Small`, `IconSize::Medium`, `IconSize::ExtraLarge` or `IconSize::TwoExtraLarge`: use Filament\Tables\Columns\IconColumn; use Filament\Support\Enums\IconSize; IconColumn::make('status') ->size(IconSize::Medium) [​](https://filamentphp.com/docs/5.x/tables/columns/icon#handling-booleans) Handling booleans ------------------------------------------------------------------------------------------------ Icon columns can display a check or “X” icon based on the state of the column, either true or false, using the `boolean()` method: use Filament\Tables\Columns\IconColumn; IconColumn::make('is_featured') ->boolean() > If this attribute in the model class is already cast as a `bool` or `boolean`, Filament is able to detect this, and you do not need to use `boolean()` manually. Optionally, you may pass a boolean value to control if the icon should be boolean or not: use Filament\Tables\Columns\IconColumn; IconColumn::make('is_featured') ->boolean(FeatureFlag::active()) ### [​](https://filamentphp.com/docs/5.x/tables/columns/icon#customizing-the-boolean-icons) Customizing the boolean icons You may customize the [icon](https://filamentphp.com/docs/5.x/styling/icons) representing each state: use Filament\Tables\Columns\IconColumn; use Filament\Support\Icons\Heroicon; IconColumn::make('is_featured') ->boolean() ->trueIcon(Heroicon::OutlinedCheckBadge) ->falseIcon(Heroicon::OutlinedXMark) ### [​](https://filamentphp.com/docs/5.x/tables/columns/icon#customizing-the-boolean-colors) Customizing the boolean colors You may customize the icon [color](https://filamentphp.com/docs/5.x/styling/colors) representing each state: use Filament\Tables\Columns\IconColumn; IconColumn::make('is_featured') ->boolean() ->trueColor('info') ->falseColor('warning') [​](https://filamentphp.com/docs/5.x/tables/columns/icon#wrapping-multiple-icons) Wrapping multiple icons ------------------------------------------------------------------------------------------------------------ When displaying multiple icons, they can be set to wrap if they can’t fit on one line, using `wrap()`: use Filament\Tables\Columns\IconColumn; IconColumn::make('icon') ->wrap() The “width” for wrapping is affected by the column label, so you may need to use a shorter or hidden label to wrap more tightly. [Text column](https://filamentphp.com/docs/5.x/tables/columns/text) [Image column](https://filamentphp.com/docs/5.x/tables/columns/image) ⌘I --- # Custom columns - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/columns/custom-columns#content-area) [​](https://filamentphp.com/docs/5.x/tables/columns/custom-columns#introduction) Introduction ------------------------------------------------------------------------------------------------ You may create your own custom column classes and views, which you can reuse across your project, and even release as a plugin to the community. To create a custom column class and view, you may use the following command: php artisan make:filament-table-column AudioPlayerColumn This will create the following component class: use Filament\Tables\Columns\Column; class AudioPlayerColumn extends Column { protected string $view = 'filament.tables.columns.audio-player-column'; } It will also create a view file at `resources/views/filament/tables/columns/audio-player-column.blade.php`. Filament table columns are **not** Livewire components. Defining public properties and methods on a table column class will not make them accessible in the Blade view. [​](https://filamentphp.com/docs/5.x/tables/columns/custom-columns#accessing-the-state-of-the-column-in-the-blade-view) Accessing the state of the column in the Blade view ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Inside the Blade view, you may access the [state](https://filamentphp.com/docs/5.x/tables/columns/overview#column-content-state) of the column using the `$getState()` function:
{{ $getState() }}
[​](https://filamentphp.com/docs/5.x/tables/columns/custom-columns#accessing-the-eloquent-record-in-the-blade-view) Accessing the Eloquent record in the Blade view ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- Inside the Blade view, you may access the current table row’s Eloquent record using the `$record` variable:
{{ $record->name }}
[​](https://filamentphp.com/docs/5.x/tables/columns/custom-columns#accessing-the-current-livewire-component-instance-in-the-blade-view) Accessing the current Livewire component instance in the Blade view -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Inside the Blade view, you may access the current Livewire component instance using `$this`: @php use Filament\Resources\Users\RelationManagers\ConferencesRelationManager; @endphp
@if ($this instanceof ConferencesRelationManager) You are editing the conferences of a user. @endif
[​](https://filamentphp.com/docs/5.x/tables/columns/custom-columns#accessing-the-current-column-instance-in-the-blade-view) Accessing the current column instance in the Blade view -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Inside the Blade view, you may access the current column instance using `$column`. You can call public methods on this object to access other information that may not be available in variables:
@if ($column->isLabelHidden()) This is a new conference. @endif
[​](https://filamentphp.com/docs/5.x/tables/columns/custom-columns#adding-a-configuration-method-to-a-custom-column-class) Adding a configuration method to a custom column class ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ You may add a public method to the custom column class that accepts a configuration value, stores it in a protected property, and returns it again from another public method: use Filament\Tables\Columns\Column; class AudioPlayerColumn extends Column { protected string $view = 'filament.tables.columns.audio-player-column'; protected ?float $speed = null; public function speed(?float $speed): static { $this->speed = $speed; return $this; } public function getSpeed(): ?float { return $this->speed; } } Now, in the Blade view for the custom column, you may access the speed using the `$getSpeed()` function:
{{ $getSpeed() }}
Any public method that you define on the custom column class can be accessed in the Blade view as a variable function in this way. To pass the configuration value to the custom column class, you may use the public method: use App\Filament\Tables\Columns\AudioPlayerColumn; AudioPlayerColumn::make('recording') ->speed(0.5) [​](https://filamentphp.com/docs/5.x/tables/columns/custom-columns#allowing-utility-injection-in-a-custom-column-configuration-method) Allowing utility injection in a custom column configuration method ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ [Utility injection](https://filamentphp.com/docs/5.x/tables/columns/overview#column-utility-injection) is a powerful feature of Filament that allows users to configure a component using functions that can access various utilities. You can allow utility injection by ensuring that the parameter type and property type of the configuration allows the user to pass a `Closure`. In the getter method, you should pass the configuration value to the `$this->evaluate()` method, which will inject utilities into the user’s function if they pass one, or return the value if it is static: use Closure; use Filament\Tables\Columns\Column; class AudioPlayerColumn extends Column { protected string $view = 'filament.tables.columns.audio-player-column'; protected float | Closure | null $speed = null; public function speed(float | Closure | null $speed): static { $this->speed = $speed; return $this; } public function getSpeed(): ?float { return $this->evaluate($this->speed); } } Now, you can pass a static value or a function to the `speed()` method, and [inject any utility](https://filamentphp.com/docs/5.x/tables/columns/overview#component-utility-injection) as a parameter: use App\Filament\Tables\Columns\AudioPlayerColumn; AudioPlayerColumn::make('recording') ->speed(fn (Conference $record): float => $record->isGlobal() ? 1 : 0.5) [Checkbox column](https://filamentphp.com/docs/5.x/tables/columns/checkbox) [Overview](https://filamentphp.com/docs/5.x/tables/filters/overview) ⌘I --- # Custom filters - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/filters/custom#content-area) [​](https://filamentphp.com/docs/5.x/tables/filters/custom#custom-filter-schemas) Custom filter schemas ---------------------------------------------------------------------------------------------------------- You may use [schema components](https://filamentphp.com/docs/5.x/schemas) to create custom filters. The data from the custom filter schema is available in the `$data` array of the `query()` callback: use Filament\Forms\Components\DatePicker; use Filament\Tables\Filters\Filter; use Illuminate\Database\Eloquent\Builder; Filter::make('created_at') ->schema([\ DatePicker::make('created_from'),\ DatePicker::make('created_until'),\ ]) ->query(function (Builder $query, array $data): Builder { return $query ->when( $data['created_from'], fn (Builder $query, $date): Builder => $query->whereDate('created_at', '>=', $date), ) ->when( $data['created_until'], fn (Builder $query, $date): Builder => $query->whereDate('created_at', '<=', $date), ); }) ### [​](https://filamentphp.com/docs/5.x/tables/filters/custom#setting-default-values-for-custom-filter-fields) Setting default values for custom filter fields To customize the default value of a field in a custom filter schema, you may use the `default()` method: use Filament\Forms\Components\DatePicker; use Filament\Tables\Filters\Filter; Filter::make('created_at') ->schema([\ DatePicker::make('created_from'),\ DatePicker::make('created_until')\ ->default(now()),\ ]) [​](https://filamentphp.com/docs/5.x/tables/filters/custom#active-indicators) Active indicators -------------------------------------------------------------------------------------------------- When a filter is active, an indicator is displayed above the table content to signal that the table query has been scoped. By default, the label of the filter is used as the indicator. You can override this using the `indicator()` method: use Filament\Tables\Filters\Filter; Filter::make('is_admin') ->label('Administrators only?') ->indicator('Administrators') If you are using a [custom filter schema](https://filamentphp.com/docs/5.x/tables/filters/custom#custom-filter-schemas) , you should use [`indicateUsing()`](https://filamentphp.com/docs/5.x/tables/filters/custom#custom-active-indicators) to display an active indicator. Please note: if you do not have an indicator for your filter, then the badge-count of how many filters are active in the table will not include that filter. ### [​](https://filamentphp.com/docs/5.x/tables/filters/custom#custom-active-indicators) Custom active indicators Not all indicators are simple, so you may need to use `indicateUsing()` to customize which indicators should be shown at any time. For example, if you have a custom date filter, you may create a custom indicator that formats the selected date: use Carbon\Carbon; use Filament\Forms\Components\DatePicker; use Filament\Tables\Filters\Filter; Filter::make('created_at') ->schema([DatePicker::make('date')]) // ... ->indicateUsing(function (array $data): ?string { if (! $data['date']) { return null; } return 'Created at ' . Carbon::parse($data['date'])->toFormattedDateString(); }) ### [​](https://filamentphp.com/docs/5.x/tables/filters/custom#multiple-active-indicators) Multiple active indicators You may even render multiple indicators at once, by returning an array of `Indicator` objects. If you have different fields associated with different indicators, you should set the field using the `removeField()` method on the `Indicator` object to ensure that the correct field is reset when the filter is removed: use Carbon\Carbon; use Filament\Forms\Components\DatePicker; use Filament\Tables\Filters\Filter; use Filament\Tables\Filters\Indicator; Filter::make('created_at') ->schema([\ DatePicker::make('from'),\ DatePicker::make('until'),\ ]) // ... ->indicateUsing(function (array $data): array { $indicators = []; if ($data['from'] ?? null) { $indicators[] = Indicator::make('Created from ' . Carbon::parse($data['from'])->toFormattedDateString()) ->removeField('from'); } if ($data['until'] ?? null) { $indicators[] = Indicator::make('Created until ' . Carbon::parse($data['until'])->toFormattedDateString()) ->removeField('until'); } return $indicators; }) ### [​](https://filamentphp.com/docs/5.x/tables/filters/custom#preventing-indicators-from-being-removed) Preventing indicators from being removed You can prevent users from removing an indicator using `removable(false)` on an `Indicator` object: use Carbon\Carbon; use Filament\Tables\Filters\Indicator; Indicator::make('Created from ' . Carbon::parse($data['from'])->toFormattedDateString()) ->removable(false) [Query builder](https://filamentphp.com/docs/5.x/tables/filters/query-builder) [Filter layout](https://filamentphp.com/docs/5.x/tables/filters/layout) ⌘I --- # Filter layout - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/filters/layout#content-area) [​](https://filamentphp.com/docs/5.x/tables/filters/layout#positioning-filters-into-grid-columns) Positioning filters into grid columns ------------------------------------------------------------------------------------------------------------------------------------------ To change the number of columns that filters may occupy, you may use the `filtersFormColumns()` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->filtersFormColumns(3); } [​](https://filamentphp.com/docs/5.x/tables/filters/layout#controlling-the-width-of-the-filters-dropdown) Controlling the width of the filters dropdown ---------------------------------------------------------------------------------------------------------------------------------------------------------- To customize the dropdown width, you may use the `filtersFormWidth()` method, and specify a width - `ExtraSmall`, `Small`, `Medium`, `Large`, `ExtraLarge`, `TwoExtraLarge`, `ThreeExtraLarge`, `FourExtraLarge`, `FiveExtraLarge`, `SixExtraLarge` or `SevenExtraLarge`. By default, the width is `ExtraSmall`: use Filament\Support\Enums\Width; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->filtersFormWidth(Width::FourExtraLarge); } [​](https://filamentphp.com/docs/5.x/tables/filters/layout#controlling-the-maximum-height-of-the-filters-dropdown) Controlling the maximum height of the filters dropdown ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To add a maximum height to the filters’ dropdown content, so that they scroll, you may use the `filtersFormMaxHeight()` method, passing a [CSS length](https://developer.mozilla.org/en-US/docs/Web/CSS/length) : use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->filtersFormMaxHeight('400px'); } [​](https://filamentphp.com/docs/5.x/tables/filters/layout#displaying-filters-in-a-modal) Displaying filters in a modal -------------------------------------------------------------------------------------------------------------------------- To render the filters in a modal instead of in a dropdown, you may use: use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ], layout: FiltersLayout::Modal); } You may use the [trigger action API](https://filamentphp.com/docs/5.x/tables/filters/overview#customizing-the-filters-trigger-action) to [customize the modal](https://filamentphp.com/docs/5.x/actions/modals) , including [using a `slideOver()`](https://filamentphp.com/docs/5.x/actions/modals#using-a-slide-over-instead-of-a-modal) . [​](https://filamentphp.com/docs/5.x/tables/filters/layout#displaying-filters-above-the-table-content) Displaying filters above the table content ---------------------------------------------------------------------------------------------------------------------------------------------------- To render the filters above the table content instead of in a dropdown, you may use: use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ], layout: FiltersLayout::AboveContent); } ### [​](https://filamentphp.com/docs/5.x/tables/filters/layout#allowing-filters-above-the-table-content-to-be-collapsed) Allowing filters above the table content to be collapsed To allow the filters above the table content to be collapsed, you may use: use Filament\Tables\Enums\FiltersLayout; public function table(Table $table): Table { return $table ->filters([\ // ...\ ], layout: FiltersLayout::AboveContentCollapsible); } [​](https://filamentphp.com/docs/5.x/tables/filters/layout#displaying-filters-below-the-table-content) Displaying filters below the table content ---------------------------------------------------------------------------------------------------------------------------------------------------- To render the filters below the table content instead of in a dropdown, you may use: use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ], layout: FiltersLayout::BelowContent); } [​](https://filamentphp.com/docs/5.x/tables/filters/layout#displaying-filters-to-the-left-or-right-of-the-table-content) Displaying filters to the left or right of the table content ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- To render the filters to the left (before) or right (after) of the table content instead of in a dropdown, you may use: use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ], layout: FiltersLayout::BeforeContent); // or `FiltersLayout::AfterContent` } ### [​](https://filamentphp.com/docs/5.x/tables/filters/layout#allowing-filters-to-be-collapsible-when-displayed-to-the-left-or-right-of-the-table-content) Allowing filters to be collapsible when displayed to the left or right of the table content To allow the filters to be collapsible when displayed to the left or right of the table content, you may use: use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ], layout: FiltersLayout::BeforeContentCollapsible); // or `FiltersLayout::AfterContentCollapsible` } [​](https://filamentphp.com/docs/5.x/tables/filters/layout#hiding-the-filter-indicators) Hiding the filter indicators ------------------------------------------------------------------------------------------------------------------------ To hide the active filters indicators above the table, you may use `hiddenFilterIndicators()`: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->hiddenFilterIndicators(); } [​](https://filamentphp.com/docs/5.x/tables/filters/layout#customizing-the-filter-form-schema) Customizing the filter form schema ------------------------------------------------------------------------------------------------------------------------------------ You may customize the [form schema](https://filamentphp.com/docs/5.x/schemas/layouts) of the entire filter form at once, in order to rearrange filters into your desired layout, and use any of the [layout components](https://filamentphp.com/docs/5.x/schemas/layouts) available to forms. To do this, use the `filterFormSchema()` method, passing a closure function that receives the array of defined `$filters` that you can insert: use Filament\Schemas\Components\Section; use Filament\Tables\Filters\Filter; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ Filter::make('is_featured'),\ Filter::make('published_at'),\ Filter::make('author'),\ ]) ->filtersFormColumns(2) ->filtersFormSchema(fn (array $filters): array => [\ Section::make('Visibility')\ ->description('These filters affect the visibility of the records in the table.')\ ->schema([\ $filters['is_featured'],\ $filters['published_at'],\ ])\ ->columns(2)\ ->columnSpanFull(),\ $filters['author'],\ ]); } In this example, we have put two of the filters inside a [section](https://filamentphp.com/docs/5.x/schemas/sections) component, and used the `columns()` method to specify that the section should have two columns. We have also used the `columnSpanFull()` method to specify that the section should span the full width of the filter form, which is also 2 columns wide. We have inserted each filter into the form schema by using the filter’s name as the key in the `$filters` array. [​](https://filamentphp.com/docs/5.x/tables/filters/layout#displaying-the-reset-action-in-the-footer) Displaying the reset action in the footer -------------------------------------------------------------------------------------------------------------------------------------------------- By default, the reset action appears in the header of the filters form. You may move it to the footer, next to the apply action, using the `filtersResetActionPosition()` method: use Filament\Tables\Enums\FiltersResetActionPosition; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->filtersResetActionPosition(FiltersResetActionPosition::Footer); } [Custom filters](https://filamentphp.com/docs/5.x/tables/filters/custom) [Actions](https://filamentphp.com/docs/5.x/tables/actions) ⌘I --- # Text column - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/columns/text#content-area) [​](https://filamentphp.com/docs/5.x/tables/columns/text#introduction) Introduction -------------------------------------------------------------------------------------- Text columns display simple text: use Filament\Tables\Columns\TextColumn; TextColumn::make('title') [​](https://filamentphp.com/docs/5.x/tables/columns/text#customizing-the-color) Customizing the color -------------------------------------------------------------------------------------------------------- You may set a [color](https://filamentphp.com/docs/5.x/styling/colors) for the text: use Filament\Tables\Columns\TextColumn; TextColumn::make('status') ->color('primary') [​](https://filamentphp.com/docs/5.x/tables/columns/text#adding-an-icon) Adding an icon ------------------------------------------------------------------------------------------ Text columns may also have an [icon](https://filamentphp.com/docs/5.x/styling/icons) : use Filament\Tables\Columns\TextColumn; use Filament\Support\Icons\Heroicon; TextColumn::make('email') ->icon(Heroicon::Envelope) You may set the position of an icon using `iconPosition()`: use Filament\Tables\Columns\TextColumn; use Filament\Support\Enums\IconPosition; use Filament\Support\Icons\Heroicon; TextColumn::make('email') ->icon(Heroicon::Envelope) ->iconPosition(IconPosition::After) // `IconPosition::Before` or `IconPosition::After` The icon color defaults to the text color, but you may customize the icon [color](https://filamentphp.com/docs/5.x/styling/colors) separately using `iconColor()`: use Filament\Tables\Columns\TextColumn; use Filament\Support\Icons\Heroicon; TextColumn::make('email') ->icon(Heroicon::Envelope) ->iconColor('primary') [​](https://filamentphp.com/docs/5.x/tables/columns/text#displaying-as-a-%E2%80%9Cbadge%E2%80%9D) Displaying as a “badge” ---------------------------------------------------------------------------------------------------------------------------- By default, text is quite plain and has no background color. You can make it appear as a “badge” instead using the `badge()` method. A great use case for this is with statuses, where may want to display a badge with a [color](https://filamentphp.com/docs/5.x/tables/columns/text#customizing-the-color) that matches the status: use Filament\Tables\Columns\TextColumn; TextColumn::make('status') ->badge() ->color(fn (string $state): string => match ($state) { 'draft' => 'gray', 'reviewing' => 'warning', 'published' => 'success', 'rejected' => 'danger', }) You may add other things to the badge, like an [icon](https://filamentphp.com/docs/5.x/tables/columns/text#adding-an-icon) . Optionally, you may pass a boolean value to control if the text should be in a badge or not: use Filament\Tables\Columns\TextColumn; TextColumn::make('status') ->badge(FeatureFlag::active()) [​](https://filamentphp.com/docs/5.x/tables/columns/text#formatting) Formatting ---------------------------------------------------------------------------------- When using a text column, you may want the actual outputted text in the UI to differ from the raw [state](https://filamentphp.com/docs/5.x/tables/columns/overview#column-content-state) of the column, which is often automatically retrieved from an Eloquent model. Formatting the state allows you to preserve the integrity of the raw data while also allowing it to be presented in a more user-friendly way. To format the state of a text column without changing the state itself, you can use the `formatStateUsing()` method. This method accepts a function that takes the state as an argument and returns the formatted state: use Filament\Tables\Columns\TextColumn; TextColumn::make('status') ->formatStateUsing(fn (string $state): string => __("statuses.{$state}")) In this case, the `status` column in the database might contain values like `draft`, `reviewing`, `published`, or `rejected`, but the formatted state will be the translated version of these values. ### [​](https://filamentphp.com/docs/5.x/tables/columns/text#date-formatting) Date formatting Instead of passing a function to `formatStateUsing()`, you may use the `date()`, `dateTime()`, and `time()` methods to format the column’s state using [PHP date formatting tokens](https://www.php.net/manual/en/datetime.format.php) : use Filament\Tables\Columns\TextColumn; TextColumn::make('created_at') ->date() TextColumn::make('created_at') ->dateTime() TextColumn::make('created_at') ->time() You may customize the date format by passing a custom format string to the `date()`, `dateTime()`, or `time()` method. You may use any [PHP date formatting tokens](https://www.php.net/manual/en/datetime.format.php) : use Filament\Tables\Columns\TextColumn; TextColumn::make('created_at') ->date('M j, Y') TextColumn::make('created_at') ->dateTime('M j, Y H:i:s') TextColumn::make('created_at') ->time('H:i:s') #### [​](https://filamentphp.com/docs/5.x/tables/columns/text#date-formatting-using-carbon-macro-formats) Date formatting using Carbon macro formats You may use also the `isoDate()`, `isoDateTime()`, and `isoTime()` methods to format the column’s state using [Carbon’s macro-formats](https://carbon.nesbot.com/docs/#available-macro-formats) : use Filament\Tables\Columns\TextColumn; TextColumn::make('created_at') ->isoDate() TextColumn::make('created_at') ->isoDateTime() TextColumn::make('created_at') ->isoTime() You may customize the date format by passing a custom macro format string to the `isoDate()`, `isoDateTime()`, or `isoTime()` method. You may use any [Carbon’s macro-formats](https://carbon.nesbot.com/docs/#available-macro-formats) : use Filament\Tables\Columns\TextColumn; TextColumn::make('created_at') ->isoDate('L') TextColumn::make('created_at') ->isoDateTime('LLL') TextColumn::make('created_at') ->isoTime('LT') #### [​](https://filamentphp.com/docs/5.x/tables/columns/text#relative-date-formatting) Relative date formatting You may use the `since()` method to format the column’s state using [Carbon’s `diffForHumans()`](https://carbon.nesbot.com/docs/#api-humandiff) : use Filament\Tables\Columns\TextColumn; TextColumn::make('created_at') ->since() #### [​](https://filamentphp.com/docs/5.x/tables/columns/text#displaying-a-formatting-date-in-a-tooltip) Displaying a formatting date in a tooltip Additionally, you can use the `dateTooltip()`, `dateTimeTooltip()`, `timeTooltip()`, `isoDateTooltip()`, `isoDateTimeTooltip()`, `isoTime()`, `isoTimeTooltip()`, or `sinceTooltip()` method to display a formatted date in a [tooltip](https://filamentphp.com/docs/5.x/tables/columns/overview#adding-a-tooltip-to-an-column) , often to provide extra information: use Filament\Tables\Columns\TextColumn; TextColumn::make('created_at') ->since() ->dateTooltip() // Accepts a custom PHP date formatting string TextColumn::make('created_at') ->since() ->dateTimeTooltip() // Accepts a custom PHP date formatting string TextColumn::make('created_at') ->since() ->timeTooltip() // Accepts a custom PHP date formatting string TextColumn::make('created_at') ->since() ->isoDateTooltip() // Accepts a custom Carbon macro format string TextColumn::make('created_at') ->since() ->isoDateTimeTooltip() // Accepts a custom Carbon macro format string TextColumn::make('created_at') ->since() ->isoTimeTooltip() // Accepts a custom Carbon macro format string TextColumn::make('created_at') ->dateTime() ->sinceTooltip() #### [​](https://filamentphp.com/docs/5.x/tables/columns/text#setting-the-timezone-for-date-formatting) Setting the timezone for date formatting Each of the date formatting methods listed above also accepts a `timezone` argument, which allows you to convert the time set in the state to a different timezone: use Filament\Tables\Columns\TextColumn; TextColumn::make('created_at') ->dateTime(timezone: 'America/New_York') You can also pass a timezone to the `timezone()` method of the column to apply a timezone to all date-time formatting methods at once: use Filament\Tables\Columns\TextColumn; TextColumn::make('created_at') ->timezone('America/New_York') ->dateTime() If you do not pass a `timezone()` to the column, it will use Filament’s default timezone. You can set Filament’s default timezone using the `FilamentTimezone::set()` method in the `boot()` method of a service provider such as `AppServiceProvider`: use Filament\Support\Facades\FilamentTimezone; public function boot(): void { FilamentTimezone::set('America/New_York'); } This is useful if you want to set a default timezone for all text columns in your application. It is also used in other places where timezones are used in Filament. Filament’s default timezone will only apply when the column stores a time. If the column stores a date only (`date()` instead of `dateTime()`), the timezone will not be applied. This is to prevent timezone shifts when storing dates without times. ### [​](https://filamentphp.com/docs/5.x/tables/columns/text#number-formatting) Number formatting Instead of passing a function to `formatStateUsing()`, you can use the `numeric()` method to format a column as a number: use Filament\Tables\Columns\TextColumn; TextColumn::make('stock') ->numeric() If you would like to customize the number of decimal places used to format the number with, you can use the `decimalPlaces` argument: use Filament\Tables\Columns\TextColumn; TextColumn::make('stock') ->numeric(decimalPlaces: 0) By default, your app’s locale will be used to format the number suitably. If you would like to customize the locale used, you can pass it to the `locale` argument: use Filament\Tables\Columns\TextColumn; TextColumn::make('stock') ->numeric(locale: 'nl') ### [​](https://filamentphp.com/docs/5.x/tables/columns/text#money-formatting) Money formatting Instead of passing a function to `formatStateUsing()`, you can use the `money()` method to easily format amounts of money, in any currency: use Filament\Tables\Columns\TextColumn; TextColumn::make('price') ->money('EUR') There is also a `divideBy` argument for `money()` that allows you to divide the original value by a number before formatting it. This could be useful if your database stores the price in cents, for example: use Filament\Tables\Columns\TextColumn; TextColumn::make('price') ->money('EUR', divideBy: 100) By default, your app’s locale will be used to format the money suitably. If you would like to customize the locale used, you can pass it to the `locale` argument: use Filament\Tables\Columns\TextColumn; TextColumn::make('price') ->money('EUR', locale: 'nl') If you would like to customize the number of decimal places used to format the number with, you can use the `decimalPlaces` argument: use Filament\Tables\Columns\TextColumn; TextColumn::make('price') ->money('EUR', decimalPlaces: 3) ### [​](https://filamentphp.com/docs/5.x/tables/columns/text#rendering-markdown) Rendering Markdown If your column value is Markdown, you may render it using `markdown()`: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->markdown() Optionally, you may pass a boolean value to control if the text should be rendered as Markdown or not: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->markdown(FeatureFlag::active()) ### [​](https://filamentphp.com/docs/5.x/tables/columns/text#rendering-html) Rendering HTML If your column value is HTML, you may render it using `html()`: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->html() Optionally, you may pass a boolean value to control if the text should be rendered as HTML or not: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->html(FeatureFlag::active()) Filament’s built-in HTML sanitizer permits inline `style` attributes in order to support rich text formatting features such as font colors, text highlighting, and image sizing. This means that CSS properties like `background: url(...)` or `position: fixed` will not be stripped from sanitized HTML. If your content comes from untrusted users, you should consider restricting the default configuration. See the [security documentation](https://filamentphp.com/docs/5.x/advanced/security#customizing-the-sanitizer) for details on how to customize the sanitizer. #### [​](https://filamentphp.com/docs/5.x/tables/columns/text#rendering-raw-html-without-sanitization) Rendering raw HTML without sanitization If you use this method, then the HTML will be sanitized to remove any potentially unsafe content before it is rendered. If you’d like to opt out of this behavior, you can wrap the HTML in an `HtmlString` object by formatting it: use Filament\Tables\Columns\TextColumn; use Illuminate\Support\HtmlString; TextColumn::make('description') ->formatStateUsing(fn (string $state): HtmlString => new HtmlString($state)) Be cautious when rendering raw HTML, as it may contain malicious content, which can lead to security vulnerabilities in your app such as cross-site scripting (XSS) attacks. Always ensure that the HTML you are rendering is safe before using this method. Alternatively, you can return a `view()` object from the `formatStateUsing()` method, which will also not be sanitized: use Filament\Tables\Columns\TextColumn; use Illuminate\Contracts\View\View; TextColumn::make('description') ->formatStateUsing(fn (string $state): View => view( 'filament.tables.columns.description-column-content', ['state' => $state], )) [​](https://filamentphp.com/docs/5.x/tables/columns/text#displaying-a-description) Displaying a description -------------------------------------------------------------------------------------------------------------- Descriptions may be used to easily render additional text above or below the column contents. You can display a description below the contents of a text column using the `description()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->description(fn (Post $record): string => $record->description) By default, the description is displayed below the main text, but you can move it using `'above'` as the second parameter: use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->description(fn (Post $record): string => $record->description, position: 'above') [​](https://filamentphp.com/docs/5.x/tables/columns/text#listing-multiple-values) Listing multiple values ------------------------------------------------------------------------------------------------------------ Multiple values can be rendered in a text column if its [state](https://filamentphp.com/docs/5.x/tables/columns/overview#column-content-state) is an array. This can happen if you are using an `array` cast on an Eloquent attribute, an Eloquent relationship with multiple results, or if you have passed an array to the [`state()` method](https://filamentphp.com/docs/5.x/tables/columns/overview#setting-the-state-of-an-column) . If there are multiple values inside your text column, they will be comma-separated. You may use the `listWithLineBreaks()` method to display them on new lines instead: use Filament\Tables\Columns\TextColumn; TextColumn::make('authors.name') ->listWithLineBreaks() Optionally, you may pass a boolean value to control if the text should have line breaks between each item or not: use Filament\Tables\Columns\TextColumn; TextColumn::make('authors.name') ->listWithLineBreaks(FeatureFlag::active()) ### [​](https://filamentphp.com/docs/5.x/tables/columns/text#adding-bullet-points-to-the-list) Adding bullet points to the list You may add a bullet point to each list item using the `bulleted()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('authors.name') ->bulleted() Optionally, you may pass a boolean value to control if the text should have bullet points or not: use Filament\Tables\Columns\TextColumn; TextColumn::make('authors.name') ->bulleted(FeatureFlag::active()) ### [​](https://filamentphp.com/docs/5.x/tables/columns/text#limiting-the-number-of-values-in-the-list) Limiting the number of values in the list You can limit the number of values in the list using the `limitList()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('authors.name') ->listWithLineBreaks() ->limitList(3) #### [​](https://filamentphp.com/docs/5.x/tables/columns/text#expanding-the-limited-list) Expanding the limited list You can allow the limited items to be expanded and collapsed, using the `expandableLimitedList()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('authors.name') ->listWithLineBreaks() ->limitList(3) ->expandableLimitedList() This is only a feature for `listWithLineBreaks()` or `bulleted()`, where each item is on its own line. Optionally, you may pass a boolean value to control if the text should be expandable or not: use Filament\Tables\Columns\TextColumn; TextColumn::make('authors.name') ->listWithLineBreaks() ->limitList(3) ->expandableLimitedList(FeatureFlag::active()) ### [​](https://filamentphp.com/docs/5.x/tables/columns/text#splitting-a-single-value-into-multiple-list-items) Splitting a single value into multiple list items If you want to “explode” a text string from your model into multiple list items, you can do so with the `separator()` method. This is useful for displaying comma-separated tags [as badges](https://filamentphp.com/docs/5.x/tables/columns/text#displaying-as-a-badge) , for example: use Filament\Tables\Columns\TextColumn; TextColumn::make('tags') ->badge() ->separator(',') [​](https://filamentphp.com/docs/5.x/tables/columns/text#customizing-the-text-size) Customizing the text size ---------------------------------------------------------------------------------------------------------------- Text columns have small font size by default, but you may change this to `TextSize::ExtraSmall`, `TextSize::Medium`, or `TextSize::Large`. For instance, you may make the text larger using `size(TextSize::Large)`: use Filament\Tables\Columns\TextColumn; use Filament\Support\Enums\TextSize; TextColumn::make('title') ->size(TextSize::Large) [​](https://filamentphp.com/docs/5.x/tables/columns/text#customizing-the-font-weight) Customizing the font weight -------------------------------------------------------------------------------------------------------------------- Text columns have regular font weight by default, but you may change this to any of the following options: `FontWeight::Thin`, `FontWeight::ExtraLight`, `FontWeight::Light`, `FontWeight::Medium`, `FontWeight::SemiBold`, `FontWeight::Bold`, `FontWeight::ExtraBold` or `FontWeight::Black`. For instance, you may make the font bold using `weight(FontWeight::Bold)`: use Filament\Tables\Columns\TextColumn; use Filament\Support\Enums\FontWeight; TextColumn::make('title') ->weight(FontWeight::Bold) [​](https://filamentphp.com/docs/5.x/tables/columns/text#customizing-the-font-family) Customizing the font family -------------------------------------------------------------------------------------------------------------------- You can change the text font family to any of the following options: `FontFamily::Sans`, `FontFamily::Serif` or `FontFamily::Mono`. For instance, you may make the font monospaced using `fontFamily(FontFamily::Mono)`: use Filament\Support\Enums\FontFamily; use Filament\Tables\Columns\TextColumn; TextColumn::make('email') ->fontFamily(FontFamily::Mono) [​](https://filamentphp.com/docs/5.x/tables/columns/text#handling-long-text) Handling long text -------------------------------------------------------------------------------------------------- ### [​](https://filamentphp.com/docs/5.x/tables/columns/text#limiting-text-length) Limiting text length You may `limit()` the length of the column’s value: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->limit(50) By default, when text is truncated, an ellipsis (`...`) is appended to the end of the text. You may customize this by passing a custom string to the `end` argument: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->limit(50, end: ' (more)') You may also reuse the value that is being passed to `limit()` in a function, by getting it using the `getCharacterLimit()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->limit(50) ->tooltip(function (TextColumn $column): ?string { $state = $column->getState(); if (strlen($state) <= $column->getCharacterLimit()) { return null; } // Only render the tooltip if the column contents exceeds the length limit. return $state; }) ### [​](https://filamentphp.com/docs/5.x/tables/columns/text#limiting-word-count) Limiting word count You may limit the number of `words()` displayed in the column: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->words(10) By default, when text is truncated, an ellipsis (`...`) is appended to the end of the text. You may customize this by passing a custom string to the `end` argument: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->words(10, end: ' (more)') ### [​](https://filamentphp.com/docs/5.x/tables/columns/text#allowing-text-wrapping) Allowing text wrapping By default, text will not wrap to the next line if it exceeds the width of the container. You can enable this behavior using the `wrap()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->wrap() Optionally, you may pass a boolean value to control if the text should wrap or not: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->wrap(FeatureFlag::active()) #### [​](https://filamentphp.com/docs/5.x/tables/columns/text#limiting-text-to-a-specific-number-of-lines) Limiting text to a specific number of lines You may want to limit text to a specific number of lines instead of limiting it to a fixed length. Clamping text to a number of lines is useful in responsive interfaces where you want to ensure a consistent experience across all screen sizes. This can be achieved using the `lineClamp()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('description') ->wrap() ->lineClamp(2) [​](https://filamentphp.com/docs/5.x/tables/columns/text#allowing-the-text-to-be-copied-to-the-clipboard) Allowing the text to be copied to the clipboard ------------------------------------------------------------------------------------------------------------------------------------------------------------ You may make the text copyable, such that clicking on the column copies the text to the clipboard, and optionally specify a custom confirmation message and duration in milliseconds: use Filament\Tables\Columns\TextColumn; TextColumn::make('email') ->copyable() ->copyMessage('Email address copied') ->copyMessageDuration(1500) Optionally, you may pass a boolean value to control if the text should be copyable or not: use Filament\Tables\Columns\TextColumn; TextColumn::make('email') ->copyable(FeatureFlag::active()) This feature only works when SSL is enabled for the app. [Overview](https://filamentphp.com/docs/5.x/tables/columns/overview) [Icon column](https://filamentphp.com/docs/5.x/tables/columns/icon) ⌘I --- # Overview - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/columns/overview#content-area) [​](https://filamentphp.com/docs/5.x/tables/columns/overview#introduction) Introduction ------------------------------------------------------------------------------------------ Column classes can be found in the `Filament\Tables\Columns` namespace. They reside within the `$table->columns()` method. Filament includes a number of columns built-in: * [Text column](https://filamentphp.com/docs/5.x/tables/columns/text) * [Icon column](https://filamentphp.com/docs/5.x/tables/columns/icon) * [Image column](https://filamentphp.com/docs/5.x/tables/columns/image) * [Color column](https://filamentphp.com/docs/5.x/tables/columns/color) Editable columns allow the user to update data in the database without leaving the table: * [Select column](https://filamentphp.com/docs/5.x/tables/columns/select) * [Toggle column](https://filamentphp.com/docs/5.x/tables/columns/toggle) * [Text input column](https://filamentphp.com/docs/5.x/tables/columns/text-input) * [Checkbox column](https://filamentphp.com/docs/5.x/tables/columns/checkbox) You may also [create your own custom columns](https://filamentphp.com/docs/5.x/tables/columns/custom-columns) to display data however you wish. Columns may be created using the static `make()` method, passing its unique name. Usually, the name of a column corresponds to the name of an attribute on an Eloquent model. You may use “dot notation” to access attributes within relationships: use Filament\Tables\Columns\TextColumn; TextColumn::make('title') TextColumn::make('author.name') [​](https://filamentphp.com/docs/5.x/tables/columns/overview#column-content-state) Column content (state) ------------------------------------------------------------------------------------------------------------ Columns may feel a bit magic at first, but they’re designed to be simple to use and optimized to display data from an Eloquent record. Despite this, they’re flexible and you can display data from any source, not just an Eloquent record attribute. The data that a column displays is called its “state”. When using a [panel resource](https://filamentphp.com/docs/5.x/resources/overview) , the table is aware of the records it is displaying. This means that the state of the column is set based on the value of the attribute on the record. For example, if the column is used in the table of a `PostResource`, then the `title` attribute value of the current post will be displayed. use Filament\Tables\Columns\TextColumn; TextColumn::make('title') If you want to access the value stored in a relationship, you can use “dot notation”. The name of the relationship that you would like to access data from comes first, followed by a dot, and then the name of the attribute: use Filament\Tables\Columns\TextColumn; TextColumn::make('author.name') You can also use “dot notation” to access values within a JSON / array column on an Eloquent model. The name of the attribute comes first, followed by a dot, and then the key of the JSON object you want to read from: use Filament\Tables\Columns\TextColumn; TextColumn::make('meta.title') ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#setting-the-state-of-a-column) Setting the state of a column You can pass your own state to a column by using the `state()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->state('Hello, world!') ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#setting-the-default-state-of-a-column) Setting the default state of a column When a column is empty (its state is `null`), you can use the `default()` method to define alternative state to use instead. This method will treat the default state as if it were real, so columns like [image](https://filamentphp.com/docs/5.x/tables/columns/image) or [color](https://filamentphp.com/docs/5.x/tables/columns/color) will display the default image or color. use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->default('Untitled') #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#adding-placeholder-text-if-a-column-is-empty) Adding placeholder text if a column is empty Sometimes you may want to display placeholder text for columns with an empty state, which is styled as a lighter gray text. This differs from the [default value](https://filamentphp.com/docs/5.x/tables/columns/overview#setting-the-default-state-of-an-column) , as the placeholder is always text and not treated as if it were real state. use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->placeholder('Untitled') ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#displaying-data-from-relationships) Displaying data from relationships You may use “dot notation” 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') #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#counting-relationships) 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](https://laravel.com/docs/eloquent-relationships#counting-related-models) for storing the result. If you’d like to scope the relationship before counting, you can pass an array to the method, where the key is the relationship name and the value is the function to scope the Eloquent query with: use Filament\Tables\Columns\TextColumn; use Illuminate\Database\Eloquent\Builder; TextColumn::make('users_count')->counts([\ 'users' => fn (Builder $query) => $query->where('is_active', true),\ ]) #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#determining-relationship-existence) 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](https://laravel.com/docs/eloquent-relationships#other-aggregate-functions) for storing the result. If you’d like to scope the relationship before checking existence, you can pass an array to the method, where the key is the relationship name and the value is the function to scope the Eloquent query with: use Filament\Tables\Columns\TextColumn; use Illuminate\Database\Eloquent\Builder; TextColumn::make('users_exists')->exists([\ 'users' => fn (Builder $query) => $query->where('is_active', true),\ ]) #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#aggregating-relationships) Aggregating relationships Filament provides several methods for aggregating a relationship field, including `avg()`, `max()`, `min()` and `sum()`. For instance, if 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](https://laravel.com/docs/eloquent-relationships#other-aggregate-functions) for storing the result. If you’d like to scope the relationship before aggregating, you can pass an array to the method, where the key is the relationship name and the value is the function to scope the Eloquent query with: use Filament\Tables\Columns\TextColumn; use Illuminate\Database\Eloquent\Builder; TextColumn::make('users_avg_age')->avg([\ 'users' => fn (Builder $query) => $query->where('is_active', true),\ ], 'age') [​](https://filamentphp.com/docs/5.x/tables/columns/overview#setting-a-column%E2%80%99s-label) Setting a column’s 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('name') ->label('Full name') Customizing the label in this way is useful if you wish to use a [translation string for localization](https://laravel.com/docs/localization#retrieving-translation-strings) : use Filament\Tables\Columns\TextColumn; TextColumn::make('name') ->label(__('columns.name')) [​](https://filamentphp.com/docs/5.x/tables/columns/overview#sorting) 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('name') ->sortable() Using the name of the column, Filament will apply an `orderBy()` clause to the Eloquent query. This is useful for simple cases where the column name matches the database column name. It can also handle [relationships](https://filamentphp.com/docs/5.x/tables/columns/overview#displaying-data-from-relationships) . However, many columns are not as simple. The [state](https://filamentphp.com/docs/5.x/tables/columns/overview#column-content-state) of the column might be customized, or using an [Eloquent accessor](https://laravel.com/docs/eloquent-mutators#accessors-and-mutators) . In this case, you may need to customize the sorting behavior. You can pass an array of real database columns in the table to sort the column with: use Filament\Tables\Columns\TextColumn; TextColumn::make('full_name') ->sortable(['first_name', 'last_name']) In this instance, the `full_name` column is not a real column in the database, but the `first_name` and `last_name` columns are. When the `full_name` column is sorted, Filament will sort the table by the `first_name` and `last_name` columns. The reason why two columns are passed is that if two records have the same `first_name`, the `last_name` will be used to sort them. If your use case doesn’t require this, you can pass only one column in the array if you wish. You may also directly interact with the Eloquent query to customize how sorting is applied for that column: 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); }) ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#sorting-by-default) Sorting by default You may choose to sort a table by default if no other sort is applied. You can use the `defaultSort()` method for this: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->defaultSort('stock', direction: 'desc'); } The second parameter is optional and defaults to `'asc'`. If you pass the name of a table column as the first parameter, Filament will use that column’s sorting behavior (custom sorting columns or query function). However, if you need to sort by a column that doesn’t exist in the table or in the database, you should pass a query function instead: use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->defaultSort(function (Builder $query): Builder { return $query->orderBy('stock'); }); } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#persisting-the-sort-in-the-user%E2%80%99s-session) Persisting the sort in the user’s session To persist the sorting in the user’s session, use the `persistSortInSession()` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->persistSortInSession(); } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#setting-a-default-sort-option-label) Setting a default sort option label To set a default sort option label, use the `defaultSortOptionLabel()` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->defaultSortOptionLabel('Date'); } [​](https://filamentphp.com/docs/5.x/tables/columns/overview#disabling-default-primary-key-sorting) Disabling default primary key sorting -------------------------------------------------------------------------------------------------------------------------------------------- By default, Filament will automatically add a primary key sort to the table query to ensure that the order of records is consistent. The primary key will be sorted in the same direction as the other sort column. If your table doesn’t have a primary key, or you wish to disable this behavior, you can use the `defaultKeySort(false)` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->defaultKeySort(false); } [​](https://filamentphp.com/docs/5.x/tables/columns/overview#searching) Searching ------------------------------------------------------------------------------------ Columns may be searchable by using the text input field 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('name') ->searchable() By default, Filament will apply a `where` clause to the Eloquent query, searching for the column name. This is useful for simple cases where the column name matches the database column name. It can also handle [relationships](https://filamentphp.com/docs/5.x/tables/columns/overview#displaying-data-from-relationships) . However, many columns are not as simple. The [state](https://filamentphp.com/docs/5.x/tables/columns/overview#column-content-state) of the column might be customized, or using an [Eloquent accessor](https://laravel.com/docs/eloquent-mutators#accessors-and-mutators) . In this case, you may need to customize the search behavior. You can pass an array of real database columns in the table to search the column with: use Filament\Tables\Columns\TextColumn; TextColumn::make('full_name') ->searchable(['first_name', 'last_name']) In this instance, the `full_name` column is not a real column in the database, but the `first_name` and `last_name` columns are. When the `full_name` column is searched, Filament will search the table by the `first_name` and `last_name` columns. You may also directly interact with the Eloquent query to customize how searching is applied for that column: 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}%") ->orWhere('last_name', 'like', "%{$search}%"); }) ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#adding-extra-searchable-columns-to-the-table) Adding extra searchable columns to the table You may allow the table to search with extra columns that aren’t present in the table by passing an array of column names to the `searchable()` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->searchable(['id']); } You may use dot notation to search within relationships: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->searchable(['id', 'author.id']); } You may also pass custom functions to search using: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->searchable([\ 'id',\ 'author.id',\ function (Builder $query, string $search): Builder {\ if (! is_numeric($search)) {\ return $query;\ }\ \ return $query->whereYear('published_at', $search);\ },\ ]); } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#customizing-the-table-search-field-placeholder) Customizing the table search field placeholder You may customize the placeholder in the search field using the `searchPlaceholder()` method on the `$table`: use Filament\Tables\Table; public static function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->searchPlaceholder('Search (ID, Name)'); } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#searching-individually) Searching individually You can choose to enable a per-column search input field using the `isIndividual` parameter: use Filament\Tables\Columns\TextColumn; TextColumn::make('name') ->searchable(isIndividual: true) If you use the `isIndividual` parameter, you may still search that column using the main “global” search input field for the entire table. To disable that functionality while still preserving the individual search functionality, you need the `isGlobal` parameter: use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->searchable(isIndividual: true, isGlobal: false) ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#customizing-the-table-search-debounce) Customizing the table search debounce You may customize the debounce time in all table search fields using the `searchDebounce()` method on the `$table`. By default, it is set to `500ms`: use Filament\Tables\Table; public static function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->searchDebounce('750ms'); } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#searching-when-the-input-is-blurred) Searching when the input is blurred Instead of automatically reloading the table contents while the user is typing their search, which is affected by the [debounce](https://filamentphp.com/docs/5.x/tables/columns/overview#customizing-the-table-search-debounce) of the search field, you may change the behavior so that the table is only searched when the user blurs the input (tabs or clicks out of it), using the `searchOnBlur()` method: use Filament\Tables\Table; public static function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->searchOnBlur(); } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#persisting-the-search-in-the-user%E2%80%99s-session) Persisting the search in the user’s session To persist the table or individual column search in the user’s session, use the `persistSearchInSession()` or `persistColumnSearchInSession()` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->persistSearchInSession() ->persistColumnSearchesInSession(); } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#disabling-search-term-splitting) Disabling search term splitting By default, the table search will split the search term into individual words and search for each word separately. This allows for more flexible search queries. However, it can have a negative impact on performance when large datasets are involved. You can disable this behavior using the `splitSearchTerms(false)` method on the table: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->splitSearchTerms(false); } You can also use the `splitIndividualSearchTerms()` method on a column to override the table’s setting for that column’s [individual search](https://filamentphp.com/docs/5.x/tables/columns/overview#searching-individually) : use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->searchable(isIndividual: true) ->splitIndividualSearchTerms(false) This method only affects the column’s individual search. Search term splitting for the table’s global search is controlled by the table’s `splitSearchTerms()` method. [​](https://filamentphp.com/docs/5.x/tables/columns/overview#clickable-cell-content) Clickable cell content -------------------------------------------------------------------------------------------------------------- When a cell is clicked, you may open a URL or trigger an “action”. ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#opening-urls) Opening URLs To open a URL, you may use the `url()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->url(fn (Post $record): string => route('posts.edit', ['post' => $record])) You can also pick a URL for the entire row to open, not just a singular column. Please see the [Record URLs section](https://filamentphp.com/docs/5.x/tables/overview#record-urls-clickable-rows) .When using a record URL and a column URL, the column URL will override the record URL for those cells only. 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() If you are passing user-controlled data to the `url()` method, you should validate that the URL does not use a dangerous scheme such as `javascript:` or `data:`. Failing to do so could expose your application to XSS attacks. The simplest way to guard against this is to wrap the value in Filament’s [`Str::sanitizeUrl()`](https://filamentphp.com/docs/5.x/advanced/security#validating-user-input) helper, which returns `null` for any URL that does not use `http`/`https` (or a relative path). ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#triggering-actions) Triggering actions To run a function when a cell is clicked, you may use the `action()` method. Each method accepts a `$record` parameter which you may use to customize the behavior of the action: use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->action(function (Post $record): void { $this->dispatch('open-post-edit-modal', post: $record->getKey()); }) #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#action-modals) Action modals You may open [action modals](https://filamentphp.com/docs/5.x/actions#modals) by passing in an `Action` object to the `action()` method: use Filament\Actions\Action; use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->action( Action::make('select') ->requiresConfirmation() ->action(function (Post $record): void { $this->dispatch('select-post', post: $record->getKey()); }), ) Action objects passed into the `action()` method must have a unique name to distinguish it from other actions within the table. #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#preventing-cells-from-being-clicked) Preventing cells from being clicked You may prevent a cell from being clicked by using the `disabledClick()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->disabledClick() If [row URLs](https://filamentphp.com/docs/5.x/tables/overview#record-urls-clickable-rows) are enabled, the cell will not be clickable. [​](https://filamentphp.com/docs/5.x/tables/columns/overview#adding-a-tooltip-to-a-column) Adding a tooltip to a column -------------------------------------------------------------------------------------------------------------------------- You may specify a tooltip to display when you hover over a cell: use Filament\Tables\Columns\TextColumn; TextColumn::make('title') ->tooltip('Title') [​](https://filamentphp.com/docs/5.x/tables/columns/overview#adding-a-header-tooltip-to-a-column) Adding a header tooltip to a column ---------------------------------------------------------------------------------------------------------------------------------------- You may specify a tooltip to display when you hover over the column header: use Filament\Tables\Columns\TextColumn; TextColumn::make('sku') ->headerTooltip('Stock Keeping Unit') [​](https://filamentphp.com/docs/5.x/tables/columns/overview#aligning-column-content) Aligning column content ---------------------------------------------------------------------------------------------------------------- ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#horizontally-aligning-column-content) Horizontally aligning column content You may align the content of an column to the start (left in left-to-right interfaces, right in right-to-left interfaces), center, or end (right in left-to-right interfaces, left in right-to-left interfaces) using the `alignStart()`, `alignCenter()` or `alignEnd()` methods: use Filament\Tables\Columns\TextColumn; TextColumn::make('email') ->alignStart() // This is the default alignment. TextColumn::make('email') ->alignCenter() TextColumn::make('email') ->alignEnd() Alternatively, you may pass an `Alignment` enum to the `alignment()` method: use Filament\Support\Enums\Alignment; use Filament\Tables\Columns\TextColumn; TextColumn::make('email') ->label('Email address') ->alignment(Alignment::End) ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#vertically-aligning-column-content) Vertically aligning column content You may align the content of a column to the start, center, or end using the `verticallyAlignStart()`, `verticallyAlignCenter()` or `verticallyAlignEnd()` methods: use Filament\Tables\Columns\TextColumn; TextColumn::make('name') ->verticallyAlignStart() TextColumn::make('name') ->verticallyAlignCenter() // This is the default alignment. TextColumn::make('name') ->verticallyAlignEnd() Alternatively, you may pass a `VerticalAlignment` enum to the `verticalAlignment()` method: use Filament\Support\Enums\VerticalAlignment; use Filament\Tables\Columns\TextColumn; TextColumn::make('name') ->verticalAlignment(VerticalAlignment::Start) [​](https://filamentphp.com/docs/5.x/tables/columns/overview#allowing-column-headers-to-wrap) Allowing column headers to wrap -------------------------------------------------------------------------------------------------------------------------------- By default, column headers will not wrap onto multiple lines if they need more space. You may allow them to wrap using the `wrapHeader()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('name') ->wrapHeader() Optionally, you may pass a boolean value to control if the header should wrap: use Filament\Tables\Columns\TextColumn; TextColumn::make('name') ->wrapHeader(FeatureFlag::active()) [​](https://filamentphp.com/docs/5.x/tables/columns/overview#controlling-the-width-of-columns) Controlling the width of columns ---------------------------------------------------------------------------------------------------------------------------------- By default, columns will take up as much space as they need. You may allow some columns to consume more space than others by using the `grow()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('name') ->grow() Alternatively, you can define a width for the column, which is passed to the header cell using the `style` attribute, so you can use any valid CSS value: use Filament\Tables\Columns\IconColumn; IconColumn::make('is_paid') ->label('Paid') ->boolean() ->width('1%') [​](https://filamentphp.com/docs/5.x/tables/columns/overview#grouping-columns) Grouping columns -------------------------------------------------------------------------------------------------- You group multiple columns together underneath a single heading using a `ColumnGroup` object: use Filament\Tables\Columns\ColumnGroup; use Filament\Tables\Columns\IconColumn; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ TextColumn::make('title'),\ TextColumn::make('slug'),\ ColumnGroup::make('Visibility', [\ TextColumn::make('status'),\ IconColumn::make('is_featured'),\ ]),\ TextColumn::make('author.name'),\ ]); } The first argument is the label of the group, and the second is an array of column objects that belong to that group. You can also control the group header [alignment](https://filamentphp.com/docs/5.x/tables/columns/overview#horizontally-aligning-column-content) and [wrapping](https://filamentphp.com/docs/5.x/tables/columns/overview#allowing-column-headers-to-wrap) on the `ColumnGroup` object. To improve the multi-line fluency of the API, you can chain the `columns()` onto the object instead of passing it as the second argument: use Filament\Support\Enums\Alignment; use Filament\Tables\Columns\ColumnGroup; ColumnGroup::make('Website visibility') ->columns([\ // ...\ ]) ->alignCenter() ->wrapHeader() [​](https://filamentphp.com/docs/5.x/tables/columns/overview#hiding-columns) Hiding columns ---------------------------------------------------------------------------------------------- You may hide a column by using the `hidden()` or `visible()` method: use Filament\Tables\Columns\TextColumn; TextColumn::make('email') ->hidden() TextColumn::make('email') ->visible() To hide a column conditionally, you may pass a boolean value to either method: use Filament\Tables\Columns\TextColumn; TextColumn::make('role') ->hidden(FeatureFlag::active()) TextColumn::make('role') ->visible(FeatureFlag::active()) ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#allowing-users-to-manage-columns) Allowing users to manage columns #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#toggling-column-visibility) 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('email') ->toggleable() ##### Making toggleable columns hidden by default By default, toggleable columns are visible. To make them hidden instead: use Filament\Tables\Columns\TextColumn; TextColumn::make('id') ->toggleable(isToggledHiddenByDefault: true) #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#reordering-columns) Reordering columns You may allow columns to be reordered in the table using the `reorderableColumns()` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->reorderableColumns(); } #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#live-column-manager) Live column manager By default, column manager changes (toggling and reordering columns) are deferred and do not affect the table, until the user clicks an “Apply” button. To disable this and make the filters “live” instead, use the `deferColumnManager(false)` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->reorderableColumns() ->deferColumnManager(false); } #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#displaying-the-column-manager-in-a-modal) Displaying the column manager in a modal To render the column manager in a modal instead of in a dropdown, you may use the `columnManagerLayout()` method: use Filament\Tables\Enums\ColumnManagerLayout; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->columnManagerLayout(ColumnManagerLayout::Modal); } You may use the [trigger action API](https://filamentphp.com/docs/5.x/tables/columns/overview#customizing-the-column-manager-trigger-action) to [customize the modal](https://filamentphp.com/docs/5.x/actions/modals) , including [using a `slideOver()`](https://filamentphp.com/docs/5.x/actions/modals#using-a-slide-over-instead-of-a-modal) . #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#customizing-the-column-manager-trigger-action) Customizing the column manager trigger action To customize the column manager trigger button, you may use the `columnManagerTriggerAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](https://filamentphp.com/docs/5.x/actions/overview) can be used: use Filament\Actions\Action; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->columnManagerTriggerAction( fn (Action $action) => $action ->button() ->label('Column Manager'), ); } #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#displaying-the-reset-action-in-the-footer) Displaying the reset action in the footer By default, the reset action appears in the header of the column manager. You may move it to the footer, next to the apply action, using the `columnManagerResetActionPosition()` method: use Filament\Tables\Enums\ColumnManagerResetActionPosition; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->columnManagerResetActionPosition(ColumnManagerResetActionPosition::Footer); } #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#disabling-column-persistence-in-the-user%E2%80%99s-session) Disabling column persistence in the user’s session By default, Filament persists the table’s columns by storing them in the user’s session. To prevent persisting the columns in the user’s session, use the `persistColumnsInSession(false)` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->persistColumnsInSession(false); } #### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#changing-the-number-of-display-columns-in-the-column-manager) Changing the number of display columns in the column manager By default, the column manager displays its options in a single column. You can increase this to multiple columns using the `columnManagerColumns()` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->columns([\ // ...\ ]) ->columnManagerColumns(2); } [​](https://filamentphp.com/docs/5.x/tables/columns/overview#adding-extra-html-attributes-to-a-column-content) Adding extra HTML attributes to a column content ------------------------------------------------------------------------------------------------------------------------------------------------------------------ You can pass extra HTML attributes to the column content via the `extraAttributes()` method, which will be merged onto its outer HTML element. The attributes should be represented by an array, where the key is the attribute name and the value is the attribute value: use Filament\Tables\Columns\TextColumn; TextColumn::make('slug') ->extraAttributes(['class' => 'slug-column']) By default, calling `extraAttributes()` multiple times will overwrite the previous attributes. If you wish to merge the attributes instead, you can pass `merge: true` to the method. ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#adding-extra-html-attributes-to-the-cell) Adding extra HTML attributes to the cell You can also pass extra HTML attributes to the table cell which surrounds the content of the column: use Filament\Tables\Columns\TextColumn; TextColumn::make('slug') ->extraCellAttributes(['class' => 'slug-cell']) By default, calling `extraCellAttributes()` multiple times will overwrite the previous attributes. If you wish to merge the attributes instead, you can pass `merge: true` to the method. ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#adding-extra-attributes-to-the-header-cell) Adding extra attributes to the header cell You can pass extra HTML attributes to the table header cell which surrounds the content of the column: use Filament\Tables\Columns\TextColumn; TextColumn::make('slug') ->extraHeaderAttributes(['class' => 'slug-header-cell']) By default, calling `extraHeaderAttributes()` multiple times will overwrite the previous attributes. If you wish to merge the attributes instead, you can pass `merge: true` to the method. [​](https://filamentphp.com/docs/5.x/tables/columns/overview#column-utility-injection) Column utility injection ------------------------------------------------------------------------------------------------------------------ The vast majority of methods used to configure columns accept functions as parameters instead of hardcoded values: use App\Models\User; use Filament\Tables\Columns\TextColumn; TextColumn::make('email') ->placeholder(fn (User $record): string => "No email for {$record->name}") TextColumn::make('role') ->badge(fn (User $record): bool => $record->role === 'admin') TextColumn::make('name') ->extraAttributes(fn (User $record): array => ['class' => "{$record->getKey()}-name-column"]) This alone unlocks many customization possibilities. The package is also able to inject many utilities to use inside these functions, as parameters. All customization methods that accept functions as arguments can inject utilities. These injected utilities require specific parameter names to be used. Otherwise, Filament doesn’t know what to inject. ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#injecting-the-current-state-of-the-column) Injecting the current state of the column If you wish to access the current [value (state)](https://filamentphp.com/docs/5.x/tables/columns/overview#column-content-state) of the column, define a `$state` parameter: function ($state) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#injecting-the-current-eloquent-record) Injecting the current Eloquent record You may retrieve the Eloquent record for the current schema using a `$record` parameter: use Illuminate\Database\Eloquent\Model; function (?Model $record) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#injecting-the-row-loop) Injecting the row loop To access the [row loop](https://laravel.com/docs/blade#the-loop-variable) object for the current table row, define a `$rowLoop` parameter: function (stdClass $rowLoop) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#injecting-the-current-livewire-component-instance) Injecting the current Livewire component instance If you wish to access the current Livewire component instance, define a `$livewire` parameter: use Livewire\Component; function (Component $livewire) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#injecting-the-current-column-instance) Injecting the current column instance If you wish to access the current component instance, define a `$component` parameter: use Filament\Tables\Columns\Column; function (Column $component) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#injecting-the-current-table-instance) Injecting the current table instance If you wish to access the current table instance, define a `$table` parameter: use Filament\Tables\Table; function (Table $table) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#injecting-multiple-utilities) Injecting multiple utilities The parameters are injected dynamically using reflection, so you’re able to combine multiple parameters in any order: use App\Models\User; use Livewire\Component as Livewire; function (Livewire $livewire, mixed $state, User $record) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/columns/overview#injecting-dependencies-from-laravel%E2%80%99s-container) Injecting dependencies from Laravel’s container You may inject anything from Laravel’s container like normal, alongside utilities: use App\Models\User; use Illuminate\Http\Request; function (Request $request, User $record) { // ... } [​](https://filamentphp.com/docs/5.x/tables/columns/overview#global-settings) Global settings ------------------------------------------------------------------------------------------------ If you wish to change the default behavior 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 `TextColumn` columns [`toggleable()`](https://filamentphp.com/docs/5.x/tables/columns/overview#toggling-column-visibility) , you can do it like so: use Filament\Tables\Columns\TextColumn; TextColumn::configureUsing(function (TextColumn $column): void { $column->toggleable(); }); Of course, you’re still able to overwrite this on each column individually: use Filament\Tables\Columns\TextColumn; TextColumn::make('name') ->toggleable(false) [Overview](https://filamentphp.com/docs/5.x/tables/overview) [Text column](https://filamentphp.com/docs/5.x/tables/columns/text) ⌘I --- # Ternary filters - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/filters/ternary#content-area) [​](https://filamentphp.com/docs/5.x/tables/filters/ternary#introduction) Introduction ----------------------------------------------------------------------------------------- Ternary filters allow you to easily create a select filter which has three states - usually true, false and blank. To filter a column named `is_featured` to be `true` or `false`, you may use the ternary filter: use Filament\Tables\Filters\TernaryFilter; TernaryFilter::make('is_featured') [​](https://filamentphp.com/docs/5.x/tables/filters/ternary#using-a-ternary-filter-with-a-nullable-column) Using a ternary filter with a nullable column ----------------------------------------------------------------------------------------------------------------------------------------------------------- Another common pattern is to use a nullable column. For example, when filtering verified and unverified users using the `email_verified_at` column, unverified users have a null timestamp in this column. To apply that logic, you may use the `nullable()` method: use Filament\Tables\Filters\TernaryFilter; TernaryFilter::make('email_verified_at') ->nullable() [​](https://filamentphp.com/docs/5.x/tables/filters/ternary#customizing-the-column-used-by-a-ternary-filter) Customizing the column used by a ternary filter --------------------------------------------------------------------------------------------------------------------------------------------------------------- The column name used to scope the query is the name of the filter. To customize this, you may use the `attribute()` method: use Filament\Tables\Filters\TernaryFilter; TernaryFilter::make('verified') ->nullable() ->attribute('status_id') [​](https://filamentphp.com/docs/5.x/tables/filters/ternary#customizing-the-ternary-filter-option-labels) Customizing the ternary filter option labels --------------------------------------------------------------------------------------------------------------------------------------------------------- You may customize the labels used for each state of the ternary filter. The true option label can be customized using the `trueLabel()` method. The false option label can be customized using the `falseLabel()` method. The blank (default) option label can be customized using the `placeholder()` method: use Illuminate\Database\Eloquent\Builder; use Filament\Tables\Filters\TernaryFilter; TernaryFilter::make('email_verified_at') ->label('Email verification') ->nullable() ->placeholder('All users') ->trueLabel('Verified users') ->falseLabel('Not verified users') [​](https://filamentphp.com/docs/5.x/tables/filters/ternary#customizing-how-a-ternary-filter-modifies-the-query) Customizing how a ternary filter modifies the query ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- You may customize how the query changes for each state of the ternary filter, use the `queries()` method: use Illuminate\Database\Eloquent\Builder; use Filament\Tables\Filters\TernaryFilter; TernaryFilter::make('email_verified_at') ->label('Email verification') ->placeholder('All users') ->trueLabel('Verified users') ->falseLabel('Not verified users') ->queries( true: fn (Builder $query) => $query->whereNotNull('email_verified_at'), false: fn (Builder $query) => $query->whereNull('email_verified_at'), blank: fn (Builder $query) => $query, // In this example, we do not want to filter the query when it is blank. ) [​](https://filamentphp.com/docs/5.x/tables/filters/ternary#filtering-soft-deletable-records) Filtering soft-deletable records --------------------------------------------------------------------------------------------------------------------------------- The `TrashedFilter` can be used to filter soft-deleted records. It is a type of ternary filter that is built-in to Filament. You can use it like so: use Filament\Tables\Filters\TrashedFilter; TrashedFilter::make() [Select filters](https://filamentphp.com/docs/5.x/tables/filters/select) [Query builder](https://filamentphp.com/docs/5.x/tables/filters/query-builder) ⌘I --- # Query builder - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/filters/query-builder#content-area) [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#introduction) Introduction ----------------------------------------------------------------------------------------------- The query builder allows you to define a complex set of conditions to filter the data in your table. It is able to handle unlimited nesting of conditions, which you can group together with “and” and “or” operations. To use it, you need to define a set of “constraints” that will be used to filter the data. Filament includes some built-in constraints, that follow common data types, but you can also define your own custom constraints. You can add a query builder to any table using the `QueryBuilder` filter: use Filament\Tables\Filters\QueryBuilder; use Filament\QueryBuilder\Constraints\BooleanConstraint; use Filament\QueryBuilder\Constraints\DateConstraint; use Filament\QueryBuilder\Constraints\NumberConstraint; use Filament\QueryBuilder\Constraints\RelationshipConstraint; use Filament\QueryBuilder\Constraints\RelationshipConstraint\Operators\IsRelatedToOperator; use Filament\QueryBuilder\Constraints\SelectConstraint; use Filament\QueryBuilder\Constraints\TextConstraint; QueryBuilder::make() ->constraints([\ TextConstraint::make('name'),\ BooleanConstraint::make('is_visible'),\ NumberConstraint::make('stock'),\ SelectConstraint::make('status')\ ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ])\ ->multiple(),\ DateConstraint::make('created_at'),\ RelationshipConstraint::make('categories')\ ->multiple()\ ->selectable(\ IsRelatedToOperator::make()\ ->titleAttribute('name')\ ->searchable()\ ->multiple(),\ ),\ NumberConstraint::make('reviews.rating')\ ->integer(),\ ]) When deeply nesting the query builder, you might need to increase the amount of space that the filters can consume. One way of doing this is to [position the filters above the table content](https://filamentphp.com/docs/5.x/tables/filters/layout#displaying-filters-above-the-table-content) : use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Filters\QueryBuilder; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ QueryBuilder::make()\ ->constraints([\ // ...\ ]),\ ], layout: FiltersLayout::AboveContent); } [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#limiting-the-size-of-the-rule-tree) Limiting the size of the rule tree ------------------------------------------------------------------------------------------------------------------------------------------- The set of rules a user builds is stored in the Livewire component’s state and submitted with each request. To protect against a request that contains an excessively large or deeply-nested set of rules consuming too much server memory or CPU, you can limit how many rules and how deeply nested they can be. By default, no limits are applied. You can set them using the `maxRules()` and `maxNestingDepth()` methods: use Filament\Tables\Filters\QueryBuilder; QueryBuilder::make() ->maxRules(100) ->maxNestingDepth(10) ->constraints([\ // ...\ ]) Both methods also accept a function to compute the value dynamically: use Filament\Tables\Filters\QueryBuilder; QueryBuilder::make() ->maxRules(fn (): int => auth()->user()->isAdmin() ? 200 : 50) ->constraints([\ // ...\ ]) The `maxRules()` limit counts individual conditions only. “OR” groups are structural containers, so they do not count towards the limit themselves — nesting is bounded separately by `maxNestingDepth()`. When a limit is set, the UI enforces it: once the maximum number of rules is reached, the “add rule” and clone buttons are disabled with a tooltip explaining why, and the “OR” grouping option is hidden once the maximum nesting depth is reached. As a safeguard against a tampered request that bypasses the UI, a submitted rule tree that still exceeds either limit is safely ignored, applying no constraints instead of filtering the table. Since these limits are the same for every query builder, you will usually want to apply them globally rather than repeating them on each filter. You can do this using `configureUsing()` in the `boot()` method of a service provider, so that every query builder in your app is bounded: use Filament\Tables\Filters\QueryBuilder; QueryBuilder::configureUsing(function (QueryBuilder $queryBuilder): void { $queryBuilder ->maxRules(100) ->maxNestingDepth(10); }); [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#available-constraints) Available constraints ----------------------------------------------------------------------------------------------------------------- Filament ships with many different constraints that you can use out of the box. You can also [create your own custom constraints](https://filamentphp.com/docs/5.x/tables/filters/query-builder#creating-custom-constraints) : * [Text constraint](https://filamentphp.com/docs/5.x/tables/filters/query-builder#text-constraints) * [Boolean constraint](https://filamentphp.com/docs/5.x/tables/filters/query-builder#boolean-constraints) * [Number constraint](https://filamentphp.com/docs/5.x/tables/filters/query-builder#number-constraints) * [Date constraint](https://filamentphp.com/docs/5.x/tables/filters/query-builder#date-constraints) * [Select constraint](https://filamentphp.com/docs/5.x/tables/filters/query-builder#select-constraints) * [Relationship constraint](https://filamentphp.com/docs/5.x/tables/filters/query-builder#relationship-constraints) ### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#text-constraints) Text constraints Text constraints allow you to filter text fields. They can be used to filter any text field, including via relationships. use Filament\QueryBuilder\Constraints\TextConstraint; TextConstraint::make('name') // Filter the `name` column TextConstraint::make('creator.name') // Filter the `name` column on the `creator` relationship using dot syntax By default, the following operators are available: * Contains - filters a column to contain the search term * Does not contain - filters a column to not contain the search term * Starts with - filters a column to start with the search term * Does not start with - filters a column to not start with the search term * Ends with - filters a column to end with the search term * Does not end with - filters a column to not end with the search term * Equals - filters a column to equal the search term * Does not equal - filters a column to not equal the search term * Is filled - filters a column to not be empty * Is blank - filters a column to be empty ### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#boolean-constraints) Boolean constraints Boolean constraints allow you to filter boolean fields. They can be used to filter any boolean field, including via relationships. use Filament\QueryBuilder\Constraints\BooleanConstraint; BooleanConstraint::make('is_visible') // Filter the `is_visible` column BooleanConstraint::make('creator.is_admin') // Filter the `is_admin` column on the `creator` relationship using dot syntax By default, the following operators are available: * Is true - filters a column to be `true` * Is false - filters a column to be `false` ### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#number-constraints) Number constraints Number constraints allow you to filter numeric fields. They can be used to filter any numeric field, including via relationships. use Filament\QueryBuilder\Constraints\NumberConstraint; NumberConstraint::make('stock') // Filter the `stock` column NumberConstraint::make('orders.item_count') // Filter the `item_count` column on the `orders` relationship using dot syntax By default, the following operators are available: * Is minimum - filters a column to be greater than or equal to the search number * Is less than - filters a column to be less than the search number * Is maximum - filters a column to be less than or equal to the search number * Is greater than - filters a column to be greater than the search number * Equals - filters a column to equal the search number * Does not equal - filters a column to not equal the search number * Is filled - filters a column to not be empty * Is blank - filters a column to be empty When using relationship column with a number constraint, users also have the ability to “aggregate” related records. This means that they can filter the column to be the sum, average, minimum or maximum of all the related records at once. #### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#integer-constraints) Integer constraints By default, number constraints will allow decimal values. If you’d like to only allow integer values, you can use the `integer()` method: use Filament\QueryBuilder\Constraints\NumberConstraint; NumberConstraint::make('stock') ->integer() ### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#date-constraints) Date constraints Date constraints allow you to filter date fields. They can be used to filter any date field, including via relationships. use Filament\QueryBuilder\Constraints\DateConstraint; DateConstraint::make('created_at') // Filter the `created_at` column DateConstraint::make('creator.created_at') // Filter the `created_at` column on the `creator` relationship using dot syntax By default, the following operators are available: * Is after - filters a column to be after the search date * Is not after - filters a column to not be after the search date, or to be the same date * Is before - filters a column to be before the search date * Is not before - filters a column to not be before the search date, or to be the same date * Is date - filters a column to be the same date as the search date * Is not date - filters a column to not be the same date as the search date * Is month - filters a column to be in the same month as the selected month * Is not month - filters a column to not be in the same month as the selected month * Is year - filters a column to be in the same year as the searched year * Is not year - filters a column to not be in the same year as the searched year #### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#datetime-constraints) Datetime constraints By default, date constraints only filter by date. If you have a datetime column and want to enable time-based filtering, you can use the `time()` method: use Filament\QueryBuilder\Constraints\DateConstraint; DateConstraint::make('published_at') ->time() ### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#select-constraints) Select constraints Select constraints allow you to filter fields using a select field. They can be used to filter any field, including via relationships. use Filament\QueryBuilder\Constraints\SelectConstraint; SelectConstraint::make('status') // Filter the `status` column ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) SelectConstraint::make('creator.department') // Filter the `department` column on the `creator` relationship using dot syntax ->options([\ 'sales' => 'Sales',\ 'marketing' => 'Marketing',\ 'engineering' => 'Engineering',\ 'purchasing' => 'Purchasing',\ ]) `options()` is a UI affordance, not an authorization boundary. The list constrains what the dropdown displays, but the submitted value is not checked against it before the constraint runs. Query-builder rules are stored in Livewire state and can be tampered with — a crafted request can submit any value into the constraint’s `settings`, and `IsOperator::apply()` passes it straight into `whereIn`/`where` on the query.If you are using `options()` to hide certain values from a group of users (for example, hiding `archived` from non-admins), scope the underlying query itself — for example with [`modifyRelationshipQueryUsing()`](https://filamentphp.com/docs/5.x/tables/filters/query-builder#scoping-relationships) on the constraint, a [`modifyQueryUsing()`](https://filamentphp.com/docs/5.x/resources/listing-records#customizing-the-eloquent-query) on the resource, or a global scope on the model — so the restricted rows are never reachable regardless of what the constraint submits. #### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#searchable-select-constraints) Searchable select constraints By default, select constraints will not allow the user to search the options. If you’d like to allow the user to search the options, you can use the `searchable()` method: use Filament\QueryBuilder\Constraints\SelectConstraint; SelectConstraint::make('status') ->searchable() ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) #### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#multi-select-constraints) Multi-select constraints By default, select constraints will only allow the user to select a single option. If you’d like to allow the user to select multiple options, you can use the `multiple()` method: use Filament\QueryBuilder\Constraints\SelectConstraint; SelectConstraint::make('status') ->multiple() ->options([\ 'draft' => 'Draft',\ 'reviewing' => 'Reviewing',\ 'published' => 'Published',\ ]) When the user selects multiple options, the table will be filtered to show records that match any of the selected options. ### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#relationship-constraints) Relationship constraints Relationship constraints allow you to filter fields using data about a relationship: use Filament\QueryBuilder\Constraints\RelationshipConstraint; use Filament\QueryBuilder\Constraints\RelationshipConstraint\Operators\IsRelatedToOperator; RelationshipConstraint::make('creator') // Filter the `creator` relationship ->selectable( IsRelatedToOperator::make() ->titleAttribute('name') ->searchable() ->multiple(), ) The `IsRelatedToOperator` is used to configure the “Is / Contains” and “Is not / Does not contain” operators. It provides a select field which allows the user to filter the relationship by which records are attached to it. The `titleAttribute()` method is used to specify which attribute should be used to identify each related record in the list. The `searchable()` method makes the list searchable. The `multiple()` method allows the user to select multiple related records, and if they do, the table will be filtered to show records that match any of the selected related records. #### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#multiple-relationships) Multiple relationships By default, relationship constraints only include operators that are appropriate for filtering a singular relationship, like a `BelongsTo`. If you have a relationship such as a `HasMany` or `BelongsToMany`, you may wish to mark the constraint as `multiple()`: use Filament\QueryBuilder\Constraints\RelationshipConstraint; RelationshipConstraint::make('categories') ->multiple() This will add the following operators to the constraint: * Has minimum - filters a column to have at least the specified number of related records * Has less than - filters a column to have less than the specified number of related records * Has maximum - filters a column to have at most the specified number of related records * Has more than - filters a column to have more than the specified number of related records * Has - filters a column to have the specified number of related records * Does not have - filters a column to not have the specified number of related records #### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#empty-relationship-constraints) Empty relationship constraints The `RelationshipConstraint` does not support [`nullable()`](https://filamentphp.com/docs/5.x/tables/filters/query-builder#nullable-constraints) in the same way as other constraints. If the relationship is `multiple()`, then the constraint will show an option to filter out “empty” relationships. This means that the relationship has no related records. If your relationship is singular, then you can use the `emptyable()` method to show an option to filter out “empty” relationships: use Filament\QueryBuilder\Constraints\RelationshipConstraint; RelationshipConstraint::make('creator') ->emptyable() If you have a `multiple()` relationship that must always have at least 1 related record, then you can use the `emptyable(false)` method to hide the option to filter out “empty” relationships: use Filament\QueryBuilder\Constraints\RelationshipConstraint; RelationshipConstraint::make('categories') ->emptyable(false) #### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#nullable-constraints) Nullable constraints By default, constraints will not show an option to filter `null` values. If you’d like to show an option to filter `null` values, you can use the `nullable()` method: use Filament\QueryBuilder\Constraints\TextConstraint; TextConstraint::make('name') ->nullable() Now, the following operators are also available: * Is filled - filters a column to not be empty * Is blank - filters a column to be empty [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#scoping-relationships) Scoping relationships ----------------------------------------------------------------------------------------------------------------- When you use a relationship constraint, you can scope the relationship to filter the related records using the `modifyRelationshipQueryUsing()` method: use Filament\QueryBuilder\Constraints\TextConstraint; use Illuminate\Database\Eloquent\Builder; TextConstraint::make('creator.name') ->label('Admin creator name') ->modifyRelationshipQueryUsing(fn (Builder $query) => $query->where('is_admin', true)) [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#customizing-the-constraint-icon) Customizing the constraint icon ------------------------------------------------------------------------------------------------------------------------------------- Each constraint type has a default [icon](https://filamentphp.com/docs/5.x/styling/icons) , which is displayed next to the label in the picker. You can customize the icon for a constraint by passing its name to the `icon()` method: use Filament\QueryBuilder\Constraints\TextConstraint; TextConstraint::make('author.name') ->icon('heroicon-m-user') [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#overriding-the-default-operators) Overriding the default operators --------------------------------------------------------------------------------------------------------------------------------------- Each constraint type has a set of default operators, which you can customize by using the `operators()`method: use Filament\QueryBuilder\Constraints\Operators\IsFilledOperator; use Filament\QueryBuilder\Constraints\TextConstraint; TextConstraint::make('author.name') ->operators([\ IsFilledOperator::make(),\ ]) This will remove all operators, and register the `EqualsOperator`. If you’d like to add an operator to the end of the list, use `pushOperators()` instead: use Filament\QueryBuilder\Constraints\Operators\IsFilledOperator; use Filament\QueryBuilder\Constraints\TextConstraint; TextConstraint::make('author.name') ->pushOperators([\ IsFilledOperator::class,\ ]) If you’d like to add an operator to the start of the list, use `unshiftOperators()` instead: use Filament\QueryBuilder\Constraints\Operators\IsFilledOperator; use Filament\QueryBuilder\Constraints\TextConstraint; TextConstraint::make('author.name') ->unshiftOperators([\ IsFilledOperator::class,\ ]) [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#creating-custom-constraints) Creating custom constraints ----------------------------------------------------------------------------------------------------------------------------- Custom constraints can be created “inline” with other constraints using the `Constraint::make()` method. You should also pass an [icon](https://filamentphp.com/docs/5.x/tables/filters/query-builder#customizing-the-constraint-icon) to the `icon()` method: use Filament\QueryBuilder\Constraints\Constraint; Constraint::make('subscribed') ->icon('heroicon-m-bell') ->operators([\ // ...\ ]), If you want to customize the label of the constraint, you can use the `label()` method: use Filament\QueryBuilder\Constraints\Constraint; Constraint::make('subscribed') ->label('Subscribed to updates') ->icon('heroicon-m-bell') ->operators([\ // ...\ ]), Now, you must [define operators](https://filamentphp.com/docs/5.x/tables/filters/query-builder#creating-custom-operators) for the constraint. These are options that you can pick from to filter the column. If the column is [nullable](https://filamentphp.com/docs/5.x/tables/filters/query-builder#nullable-constraints) , you can also register that built-in operator for your custom constraint: use Filament\QueryBuilder\Constraints\Constraint; use Filament\QueryBuilder\Constraints\Operators\IsFilledOperator; Constraint::make('subscribed') ->label('Subscribed to updates') ->icon('heroicon-m-bell') ->operators([\ // ...\ IsFilledOperator::class,\ ]), ### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#creating-custom-operators) Creating custom operators Custom operators can be created using the `Operator::make()` method: use Filament\QueryBuilder\Constraints\Operators\Operator; Operator::make('subscribed') ->label(fn (bool $isInverse): string => $isInverse ? 'Not subscribed' : 'Subscribed') ->summary(fn (bool $isInverse): string => $isInverse ? 'You are not subscribed' : 'You are subscribed') ->baseQuery(fn (Builder $query, bool $isInverse) => $query->{$isInverse ? 'whereDoesntHave' : 'whereHas'}( 'subscriptions.user', fn (Builder $query) => $query->whereKey(auth()->user()), )), In this example, the operator is able to filter records based on whether or not the authenticated user is subscribed to the record. A subscription is recorded in the `subscriptions` relationship of the table. The `baseQuery()` method is used to define the query that will be used to filter the records. The `$isInverse` argument is `false` when the “Subscribed” option is selected, and `true` when the “Not subscribed” option is selected. The function is applied to the base query of the table, where `whereHas()` can be used. If your function does not need to be applied to the base query of the table, like when you are using a simple `where()` or `whereIn()`, you can use the `query()` method instead, which has the bonus of being able to be used inside nested “OR” groups. The `label()` method is used to render the options in the operator select. Two options are registered for each operator, one for when the operator is not inverted, and one for when it is inverted. The `summary()` method is used in the header of the constraint when it is applied to the query, to provide an overview of the active constraint. [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#customizing-the-constraint-picker) Customizing the constraint picker ----------------------------------------------------------------------------------------------------------------------------------------- ### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#changing-the-number-of-columns-in-the-constraint-picker) Changing the number of columns in the constraint picker The constraint picker has only 1 column. You may customize it by passing a number of columns to `constraintPickerColumns()`: use Filament\Tables\Filters\QueryBuilder; QueryBuilder::make() ->constraintPickerColumns(2) ->constraints([\ // ...\ ]) This method can be used in a couple of different ways: * You can pass an integer like `constraintPickerColumns(2)`. This integer is the number of columns used on the `lg` breakpoint and higher. All smaller devices will have just 1 column. * You can pass an array, where the key is the breakpoint and the value is the number of columns. For example, `constraintPickerColumns(['md' => 2, 'xl' => 4])` will create a 2 column layout on medium devices, and a 4 column layout on extra large devices. The default breakpoint for smaller devices uses 1 column, unless you use a `default` array key. Breakpoints (`sm`, `md`, `lg`, `xl`, `2xl`) are defined by Tailwind, and can be found in the [Tailwind documentation](https://tailwindcss.com/docs/responsive-design#overview) . ### [​](https://filamentphp.com/docs/5.x/tables/filters/query-builder#increasing-the-width-of-the-constraint-picker) Increasing the width of the constraint picker When you [increase the number of columns](https://filamentphp.com/docs/5.x/tables/filters/query-builder#changing-the-number-of-columns-in-the-constraint-picker) , the width of the dropdown should increase incrementally to handle the additional columns. If you’d like more control, you can manually set a maximum width for the dropdown using the `constraintPickerWidth()` method. Options correspond to [Tailwind’s max-width scale](https://tailwindcss.com/docs/max-width) . The options are `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`, `4xl`, `5xl`, `6xl`, `7xl`: use Filament\Tables\Filters\QueryBuilder; QueryBuilder::make() ->constraintPickerColumns(3) ->constraintPickerWidth('2xl') ->constraints([\ // ...\ ]) [Ternary filters](https://filamentphp.com/docs/5.x/tables/filters/ternary) [Custom filters](https://filamentphp.com/docs/5.x/tables/filters/custom) ⌘I --- # Overview - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/filters/overview#content-area) [​](https://filamentphp.com/docs/5.x/tables/filters/overview#introduction) Introduction ------------------------------------------------------------------------------------------ Filters allow you to define certain constraints on your data, and allow users to scope it to find the information they need. You put them in the `$table->filters()` method. Filters may be created using the static `make()` method, passing its unique name. You should then pass a callback to `query()` which applies your filter’s scope: use Filament\Tables\Filters\Filter; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; public function table(Table $table): Table { return $table ->filters([\ Filter::make('is_featured')\ ->query(fn (Builder $query): Builder => $query->where('is_featured', true))\ // ...\ ]); } [​](https://filamentphp.com/docs/5.x/tables/filters/overview#available-filters) Available filters ---------------------------------------------------------------------------------------------------- By default, using the `Filter::make()` method will render a checkbox form component. When the checkbox is on, the `query()` will be activated. * You can also [replace the checkbox with a toggle](https://filamentphp.com/docs/5.x/tables/filters/overview#using-a-toggle-button-instead-of-a-checkbox) . * You may use a [select filter](https://filamentphp.com/docs/5.x/tables/filters/select) to allow users to select from a list of options, and filter using the selection. * You can use a [ternary filter](https://filamentphp.com/docs/5.x/tables/filters/ternary) to replace the checkbox with a select field to allow users to pick between 3 states - usually “true”, “false” and “blank”. This is useful for filtering boolean columns. * The [trashed filter](https://filamentphp.com/docs/5.x/tables/filters/ternary#filtering-soft-deletable-records) is a pre-built ternary filter that allows you to filter soft-deletable records. * Using a [query builder](https://filamentphp.com/docs/5.x/tables/filters/query-builder) , users can create complex sets of filters, with an advanced user interface for combining constraints. * You may build [custom filters](https://filamentphp.com/docs/5.x/tables/filters/custom) with other form fields, to do whatever you want. [​](https://filamentphp.com/docs/5.x/tables/filters/overview#setting-a-label) Setting a label ------------------------------------------------------------------------------------------------ By default, the label of the filter is generated from the name of the filter. You may customize this using the `label()` method: use Filament\Tables\Filters\Filter; Filter::make('is_featured') ->label('Featured') Customizing the label in this way is useful if you wish to use a [translation string for localization](https://laravel.com/docs/localization#retrieving-translation-strings) : use Filament\Tables\Filters\Filter; Filter::make('is_featured') ->label(__('filters.is_featured')) [​](https://filamentphp.com/docs/5.x/tables/filters/overview#customizing-the-filter-schema) Customizing the filter schema ---------------------------------------------------------------------------------------------------------------------------- By default, creating a filter with the `Filter` class will render a [checkbox form component](https://filamentphp.com/docs/5.x/forms/checkbox) . When the checkbox is checked, the `query()` function will be applied to the table’s query, scoping the records in the table. When the checkbox is unchecked, the `query()` function will be removed from the table’s query. Filters are built entirely on Filament’s form fields. They can render any combination of form fields, which users can then interact with to filter the table. ### [​](https://filamentphp.com/docs/5.x/tables/filters/overview#using-a-toggle-button-instead-of-a-checkbox) Using a toggle button instead of a checkbox The simplest example of managing the form field that is used for a filter is to replace the [checkbox](https://filamentphp.com/docs/5.x/forms/checkbox) with a [toggle button](https://filamentphp.com/docs/5.x/forms/toggle) , using the `toggle()` method: use Filament\Tables\Filters\Filter; Filter::make('is_featured') ->toggle() ### [​](https://filamentphp.com/docs/5.x/tables/filters/overview#customizing-the-built-in-filter-form-field) Customizing the built-in filter form field Whether you are using a checkbox, a [toggle](https://filamentphp.com/docs/5.x/tables/filters/overview#using-a-toggle-button-instead-of-a-checkbox) or a [select](https://filamentphp.com/docs/5.x/tables/filters/select) , you can customize the built-in form field used for the filter, using the `modifyFormFieldUsing()` method. The method accepts a function with a `$field` parameter that gives you access to the form field object to customize: use Filament\Forms\Components\Checkbox; use Filament\Tables\Filters\Filter; Filter::make('is_featured') ->modifyFormFieldUsing(fn (Checkbox $field) => $field->inline(false)) [​](https://filamentphp.com/docs/5.x/tables/filters/overview#applying-the-filter-by-default) Applying the filter by default ------------------------------------------------------------------------------------------------------------------------------ You may set a filter to be enabled by default, using the `default()` method: use Filament\Tables\Filters\Filter; Filter::make('is_featured') ->default() If you’re using a [select filter](https://filamentphp.com/docs/5.x/tables/filters/select) , [visit the “applying select filters by default” section](https://filamentphp.com/docs/5.x/tables/filters/select#applying-select-filters-by-default) . [​](https://filamentphp.com/docs/5.x/tables/filters/overview#persisting-filters-in-the-user%E2%80%99s-session) Persisting filters in the user’s session ---------------------------------------------------------------------------------------------------------------------------------------------------------- To persist the table filters in the user’s session, use the `persistFiltersInSession()` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->persistFiltersInSession(); } [​](https://filamentphp.com/docs/5.x/tables/filters/overview#live-filters) Live filters ------------------------------------------------------------------------------------------ By default, filter changes are deferred and do not affect the table, until the user clicks an “Apply” button. To disable this and make the filters “live” instead, use the `deferFilters(false)` method: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->deferFilters(false); } ### [​](https://filamentphp.com/docs/5.x/tables/filters/overview#customizing-the-apply-filters-action) Customizing the apply filters action When deferring filters, you can customize the “Apply” button, using the `filtersApplyAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](https://filamentphp.com/docs/5.x/actions/overview) can be used: use Filament\Actions\Action; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->filtersApplyAction( fn (Action $action) => $action ->link() ->label('Save filters to table'), ); } [​](https://filamentphp.com/docs/5.x/tables/filters/overview#deselecting-records-when-filters-change) Deselecting records when filters change ------------------------------------------------------------------------------------------------------------------------------------------------ By default, all records will be deselected when the filters change. Using the `deselectAllRecordsWhenFiltered(false)` method, you can disable this behavior: use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->deselectAllRecordsWhenFiltered(false); } [​](https://filamentphp.com/docs/5.x/tables/filters/overview#modifying-the-base-query) Modifying the base query ------------------------------------------------------------------------------------------------------------------ By default, modifications to the Eloquent query performed in the `query()` method will be applied inside a scoped `where()` clause. This is to ensure that the query does not clash with any other filters that may be applied, especially those that use `orWhere()`. However, the downside of this is that the `query()` method cannot be used to modify the query in other ways, such as removing global scopes, since the base query needs to be modified directly, not the scoped query. To modify the base query directly, you may use the `baseQuery()` method, passing a closure that receives the base query: use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; use Filament\Tables\Filters\TernaryFilter; TernaryFilter::make('trashed') // ... ->baseQuery(fn (Builder $query) => $query->withoutGlobalScopes([\ SoftDeletingScope::class,\ ])) [​](https://filamentphp.com/docs/5.x/tables/filters/overview#excluding-filters-when-resolving-records) Excluding filters when resolving records -------------------------------------------------------------------------------------------------------------------------------------------------- When a user interacts with a table record (e.g., clicking an action button), Filament resolves that record from the database. By default, all active filter conditions are applied, ensuring users cannot access records outside their filter scope. However, some filters like `TrashedFilter` modify global scopes rather than restricting access. When a record’s state changes after the user saw it in the table, you may still want the user to interact with it. You may mark a filter to be excluded when resolving records using the `excludeWhenResolvingRecord()` method: use Filament\Tables\Filters\Filter; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\SoftDeletingScope; Filter::make('trashed') ->query(fn (Builder $query) => $query->onlyTrashed()) ->baseQuery(fn (Builder $query) => $query->withoutGlobalScopes([\ SoftDeletingScope::class,\ ])) ->excludeWhenResolvingRecord() When `excludeWhenResolvingRecord()` is used: * The filter’s `query()` callback is not applied when resolving records * The filter’s `baseQuery()` callback is still applied when resolving records Do not use `excludeWhenResolvingRecord()` on filters that enforce authorization rules. For example, if you have a filter that restricts records by tenant or user ownership, those filters should remain enforced to prevent unauthorized access. [​](https://filamentphp.com/docs/5.x/tables/filters/overview#customizing-the-filters-trigger-action) Customizing the filters trigger action ---------------------------------------------------------------------------------------------------------------------------------------------- To customize the filters trigger buttons, you may use the `filtersTriggerAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](https://filamentphp.com/docs/5.x/actions/overview) can be used: use Filament\Actions\Action; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->filtersTriggerAction( fn (Action $action) => $action ->button() ->label('Filter'), ); } [​](https://filamentphp.com/docs/5.x/tables/filters/overview#customizing-the-remove-all-filters-action) Customizing the remove all filters action ---------------------------------------------------------------------------------------------------------------------------------------------------- To customize the action that removes all active filters from the indicator bar, you may use the `filtersRemoveAllAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](https://filamentphp.com/docs/5.x/actions/overview) can be used: use Filament\Actions\Action; use Filament\Tables\Table; public function table(Table $table): Table { return $table ->filters([\ // ...\ ]) ->filtersRemoveAllAction( fn (Action $action) => $action ->tooltip('Clear filters'), ); } [​](https://filamentphp.com/docs/5.x/tables/filters/overview#filter-utility-injection) Filter utility injection ------------------------------------------------------------------------------------------------------------------ The vast majority of methods used to configure filters accept functions as parameters instead of hardcoded values: use App\Models\Author; use Filament\Tables\Filters\SelectFilter; SelectFilter::make('author') ->options(fn (): array => Author::query()->pluck('name', 'id')->all()) This alone unlocks many customization possibilities. The package is also able to inject many utilities to use inside these functions, as parameters. All customization methods that accept functions as arguments can inject utilities. These injected utilities require specific parameter names to be used. Otherwise, Filament doesn’t know what to inject. ### [​](https://filamentphp.com/docs/5.x/tables/filters/overview#injecting-the-current-filter-instance) Injecting the current filter instance If you wish to access the current filter instance, define a `$filter` parameter: use Filament\Tables\Filters\BaseFilter; function (BaseFilter $filter) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/filters/overview#injecting-the-current-livewire-component-instance) Injecting the current Livewire component instance If you wish to access the current Livewire component instance that the table belongs to, define a `$livewire` parameter: use Filament\Tables\Contracts\HasTable; function (HasTable $livewire) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/filters/overview#injecting-the-current-table-instance) Injecting the current table instance If you wish to access the current table configuration instance that the filter belongs to, define a `$table` parameter: use Filament\Tables\Table; function (Table $table) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/filters/overview#injecting-multiple-utilities) Injecting multiple utilities The parameters are injected dynamically using reflection, so you are able to combine multiple parameters in any order: use Filament\Tables\Contracts\HasTable; use Filament\Tables\Table; function (HasTable $livewire, Table $table) { // ... } ### [​](https://filamentphp.com/docs/5.x/tables/filters/overview#injecting-dependencies-from-laravel%E2%80%99s-container) Injecting dependencies from Laravel’s container You may inject anything from Laravel’s container like normal, alongside utilities: use Filament\Tables\Table; use Illuminate\Http\Request; function (Request $request, Table $table) { // ... } [Custom columns](https://filamentphp.com/docs/5.x/tables/columns/custom-columns) [Select filters](https://filamentphp.com/docs/5.x/tables/filters/select) ⌘I --- # Image column - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/columns/image#content-area) [​](https://filamentphp.com/docs/5.x/tables/columns/image#introduction) Introduction --------------------------------------------------------------------------------------- Tables can render images, based on the path in the state of the column: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('avatar') In this case, the `avatar` state could contain `users/avatars/4281246003439.jpg`, which is relative to the root directory of the storage disk. The storage disk is defined in the [configuration file](https://filamentphp.com/docs/5.x/introduction/installation#publishing-configuration) , `local` by default. You can also set the `FILESYSTEM_DISK` environment variable to change this. Alternatively, the state could contain an absolute URL to an image, such as `https://example.com/images/avatar.jpg`. [​](https://filamentphp.com/docs/5.x/tables/columns/image#setting-the-alt-text) Setting the alt text ------------------------------------------------------------------------------------------------------- You should set descriptive alt text on your images so that screen reader users understand what each image shows. Use the `alt()` method: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('avatar') ->alt('User avatar') If you do not set any alt text, the image is rendered with an empty `alt` attribute, which marks it as decorative for assistive technology. When an image [links to a URL](https://filamentphp.com/docs/5.x/tables/columns/overview#opening-urls) , its alt text becomes the accessible name of the link. Always set meaningful `alt()` text on linked images, otherwise screen reader users will encounter a link with no name. [​](https://filamentphp.com/docs/5.x/tables/columns/image#managing-the-image-disk) Managing the image disk ------------------------------------------------------------------------------------------------------------- The default storage disk is defined in the [configuration file](https://filamentphp.com/docs/5.x/introduction/installation#publishing-configuration) , `local` by default. You can also set the `FILESYSTEM_DISK` environment variable to change this. If you want to deviate from the default disk, you may pass a custom disk name to the `disk()` method: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('header_image') ->disk('s3') [​](https://filamentphp.com/docs/5.x/tables/columns/image#public-images) Public images ----------------------------------------------------------------------------------------- By default, Filament will generate temporary URLs to images in the filesystem, unless the [disk](https://filamentphp.com/docs/5.x/tables/columns/image#managing-the-image-disk) is set to `public`. If your images are stored in a public disk, you can set the `visibility()` to `public`: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('header_image') ->visibility('public') [​](https://filamentphp.com/docs/5.x/tables/columns/image#customizing-the-size) Customizing the size ------------------------------------------------------------------------------------------------------- You may customize the image size by passing a `imageWidth()` and `imageHeight()`, or both with `imageSize()`: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('header_image') ->imageWidth(200) ImageColumn::make('header_image') ->imageHeight(50) ImageColumn::make('avatar') ->imageSize(40) ### [​](https://filamentphp.com/docs/5.x/tables/columns/image#square-images) Square images You may display the image using a 1:1 aspect ratio: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('avatar') ->imageHeight(40) ->square() Optionally, you may pass a boolean value to control if the image should be square or not: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('avatar') ->imageHeight(40) ->square(FeatureFlag::active()) [​](https://filamentphp.com/docs/5.x/tables/columns/image#circular-images) Circular images --------------------------------------------------------------------------------------------- You may make the image fully rounded, which is useful for rendering avatars: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('avatar') ->imageHeight(40) ->circular() Optionally, you may pass a boolean value to control if the image should be circular or not: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('avatar') ->imageHeight(40) ->circular(FeatureFlag::active()) [​](https://filamentphp.com/docs/5.x/tables/columns/image#adding-a-default-image-url) Adding a default image URL ------------------------------------------------------------------------------------------------------------------- You can display a placeholder image if one doesn’t exist yet, by passing a URL to the `defaultImageUrl()` method: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('header_image') ->defaultImageUrl(url('storage/posts/header-images/default.jpg')) [​](https://filamentphp.com/docs/5.x/tables/columns/image#stacking-images) Stacking images --------------------------------------------------------------------------------------------- You may display multiple images as a stack of overlapping images by using `stacked()`: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('colleagues.avatar') ->imageHeight(40) ->circular() ->stacked() Optionally, you may pass a boolean value to control if the images should be stacked or not: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('colleagues.avatar') ->imageHeight(40) ->circular() ->stacked(FeatureFlag::active()) ### [​](https://filamentphp.com/docs/5.x/tables/columns/image#customizing-the-stacked-ring-width) Customizing the stacked ring width The default ring width is `3`, but you may customize it to be from `0` to `8`: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('colleagues.avatar') ->imageHeight(40) ->circular() ->stacked() ->ring(5) ### [​](https://filamentphp.com/docs/5.x/tables/columns/image#customizing-the-stacked-overlap) Customizing the stacked overlap The default overlap is `4`, but you may customize it to be from `0` to `8`: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('colleagues.avatar') ->imageHeight(40) ->circular() ->stacked() ->overlap(2) [​](https://filamentphp.com/docs/5.x/tables/columns/image#setting-a-limit) Setting a limit --------------------------------------------------------------------------------------------- You may limit the maximum number of images you want to display by passing `limit()`: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('colleagues.avatar') ->imageHeight(40) ->circular() ->stacked() ->limit(3) ### [​](https://filamentphp.com/docs/5.x/tables/columns/image#showing-the-remaining-images-count) Showing the remaining images count When you set a limit you may also display the count of remaining images by passing `limitedRemainingText()`. use Filament\Tables\Columns\ImageColumn; ImageColumn::make('colleagues.avatar') ->imageHeight(40) ->circular() ->stacked() ->limit(3) ->limitedRemainingText() Optionally, you may pass a boolean value to control if the remaining text should be displayed or not: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('colleagues.avatar') ->imageHeight(40) ->circular() ->stacked() ->limit(3) ->limitedRemainingText(FeatureFlag::active()) #### [​](https://filamentphp.com/docs/5.x/tables/columns/image#customizing-the-limited-remaining-text-size) Customizing the limited remaining text size By default, the size of the remaining text is `TextSize::Small`. You can customize this to be `TextSize::ExtraSmall`, `TextSize::Medium` or `TextSize::Large` using the `size` parameter: use Filament\Tables\Columns\ImageColumn; use Filament\Support\Enums\TextSize; ImageColumn::make('colleagues.avatar') ->imageHeight(40) ->circular() ->stacked() ->limit(3) ->limitedRemainingText(size: TextSize::Large) [​](https://filamentphp.com/docs/5.x/tables/columns/image#prevent-file-existence-checks) Prevent file existence checks ------------------------------------------------------------------------------------------------------------------------- When the schema is loaded, it will automatically detect whether the images exist to prevent errors for missing files. This is all done on the backend. When using remote storage with many images, this can be time-consuming. You can use the `checkFileExistence(false)` method to disable this feature: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('attachment') ->checkFileExistence(false) [​](https://filamentphp.com/docs/5.x/tables/columns/image#wrapping-multiple-images) Wrapping multiple images --------------------------------------------------------------------------------------------------------------- Images can be set to wrap if they can’t fit on one line, by setting `wrap()`: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('colleagues.avatar') ->circular() ->stacked() ->wrap() The “width” for wrapping is affected by the column label, so you may need to use a shorter or hidden label to wrap more tightly. [​](https://filamentphp.com/docs/5.x/tables/columns/image#adding-extra-html-attributes-to-the-image) Adding extra HTML attributes to the image ------------------------------------------------------------------------------------------------------------------------------------------------- You can pass extra HTML attributes to the `` element via the `extraImgAttributes()` method. The attributes should be represented by an array, where the key is the attribute name and the value is the attribute value: use Filament\Tables\Columns\ImageColumn; ImageColumn::make('logo') ->extraImgAttributes([\ 'alt' => 'Logo',\ 'loading' => 'lazy',\ ]) By default, calling `extraImgAttributes()` multiple times will overwrite the previous attributes. If you wish to merge the attributes instead, you can pass `merge: true` to the method. [Icon column](https://filamentphp.com/docs/5.x/tables/columns/icon) [Color column](https://filamentphp.com/docs/5.x/tables/columns/color) ⌘I --- # Color column - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/columns/color#content-area) [​](https://filamentphp.com/docs/5.x/tables/columns/color#introduction) Introduction --------------------------------------------------------------------------------------- The color column allows you to show the color preview from a CSS color definition, typically entered using the [color picker field](https://filamentphp.com/docs/5.x/forms/color-picker) , in one of the supported formats (HEX, HSL, RGB, RGBA). use Filament\Tables\Columns\ColorColumn; ColorColumn::make('color') [​](https://filamentphp.com/docs/5.x/tables/columns/color#allowing-the-color-to-be-copied-to-the-clipboard) Allowing the color to be copied to the clipboard --------------------------------------------------------------------------------------------------------------------------------------------------------------- You may make the color copyable, such that clicking on the preview copies the CSS value to the clipboard, and optionally specify a custom confirmation message and duration in milliseconds. This feature only works when SSL is enabled for the app. use Filament\Tables\Columns\ColorColumn; ColorColumn::make('color') ->copyable() ->copyMessage('Copied!') ->copyMessageDuration(1500) Optionally, you may pass a boolean value to control if the text should be copyable or not: use Filament\Tables\Columns\ColorColumn; ColorColumn::make('color') ->copyable(FeatureFlag::active()) [​](https://filamentphp.com/docs/5.x/tables/columns/color#wrapping-multiple-color-blocks) Wrapping multiple color blocks --------------------------------------------------------------------------------------------------------------------------- Color blocks can be set to wrap if they can’t fit on one line, by setting `wrap()`: use Filament\Tables\Columns\ColorColumn; ColorColumn::make('color') ->wrap() The “width” for wrapping is affected by the column label, so you may need to use a shorter or hidden label to wrap more tightly. [Image column](https://filamentphp.com/docs/5.x/tables/columns/image) [Select column](https://filamentphp.com/docs/5.x/tables/columns/select) ⌘I --- # Text input column - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/columns/text-input#content-area) [​](https://filamentphp.com/docs/5.x/tables/columns/text-input#introduction) Introduction -------------------------------------------------------------------------------------------- The text input column allows you to render a text input inside the table, which can be used to update that database record without needing to open a new page or a modal: use Filament\Tables\Columns\TextInputColumn; TextInputColumn::make('email') [​](https://filamentphp.com/docs/5.x/tables/columns/text-input#validation) Validation ---------------------------------------------------------------------------------------- You can validate the input by passing any [Laravel validation rules](https://laravel.com/docs/validation#available-validation-rules) in an array: use Filament\Tables\Columns\TextInputColumn; TextInputColumn::make('name') ->rules(['required', 'max:255']) [​](https://filamentphp.com/docs/5.x/tables/columns/text-input#customizing-the-html-input-type) Customizing the HTML input type ---------------------------------------------------------------------------------------------------------------------------------- You may use the `type()` method to pass a custom [HTML input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types) : use Filament\Tables\Columns\TextInputColumn; TextInputColumn::make('background_color')->type('color') [​](https://filamentphp.com/docs/5.x/tables/columns/text-input#setting-the-html-input-mode) Setting the HTML input mode -------------------------------------------------------------------------------------------------------------------------- You may use the `inputMode()` method to set the [HTML inputmode attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode) , which hints at the type of keyboard to show on mobile. For numeric inputs, use `inputMode('decimal')` for decimal values or `inputMode('numeric')` for integers: use Filament\Tables\Columns\TextInputColumn; TextInputColumn::make('quantity') ->type('number') ->inputMode('decimal') [​](https://filamentphp.com/docs/5.x/tables/columns/text-input#setting-the-numeric-step) Setting the numeric step -------------------------------------------------------------------------------------------------------------------- When using `type('number')`, you may use the `step()` method to set the [HTML step attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number#step) . Use `step('any')` for decimal values or `step('1')` for integers: use Filament\Tables\Columns\TextInputColumn; TextInputColumn::make('quantity') ->type('number') ->inputMode('decimal') ->step('1') [​](https://filamentphp.com/docs/5.x/tables/columns/text-input#lifecycle-hooks) Lifecycle hooks -------------------------------------------------------------------------------------------------- Hooks may be used to execute code at various points within the input’s lifecycle: TextInputColumn::make() ->beforeStateUpdated(function ($record, $state) { // Runs before the state is saved to the database. }) ->afterStateUpdated(function ($record, $state) { // Runs after the state is saved to the database. }) [​](https://filamentphp.com/docs/5.x/tables/columns/text-input#adding-affix-text-aside-the-field) Adding affix text aside the field -------------------------------------------------------------------------------------------------------------------------------------- You may place text before and after the input using the `prefix()` and `suffix()` methods: use Filament\Tables\Columns\TextInputColumn; TextInputColumn::make('domain') ->prefix('https://') ->suffix('.com') ### [​](https://filamentphp.com/docs/5.x/tables/columns/text-input#using-icons-as-affixes) Using icons as affixes You may place an [icon](https://filamentphp.com/docs/5.x/styling/icons) before and after the input using the `prefixIcon()` and `suffixIcon()` methods: use Filament\Tables\Columns\TextInputColumn; use Filament\Support\Icons\Heroicon; TextInputColumn::make('domain') ->prefixIcon(Heroicon::GlobeAlt) ->suffixIcon(Heroicon::CheckCircle) #### [​](https://filamentphp.com/docs/5.x/tables/columns/text-input#setting-the-affix-icon%E2%80%99s-color) Setting the affix icon’s color Affix icons are gray by default, but you may set a different color using the `prefixIconColor()` and `suffixIconColor()` methods: use Filament\Tables\Columns\TextInputColumn; use Filament\Support\Icons\Heroicon; TextInputColumn::make('status') ->suffixIcon(Heroicon::CheckCircle) ->suffixIconColor('success') [​](https://filamentphp.com/docs/5.x/tables/columns/text-input#security) Security ------------------------------------------------------------------------------------ ### [​](https://filamentphp.com/docs/5.x/tables/columns/text-input#authorization) Authorization The text input column does not automatically check Laravel Model Policies before saving changes. When a user updates a value via the text input column, Filament checks whether the column is `disabled()` but does not run any `update` policy gate check. This means that if a user can see a record in the table and the column is not disabled, they can update that column’s value regardless of any `update` policy you have defined. If you need to restrict who can edit this column, you should use the `disabled()` method to conditionally prevent editing based on your own authorization logic, for example `disabled(fn ($record) => $record->user_id !== auth()->id())`. Alternatively, consider using a full edit page or modal action where Filament’s resource authorization is enforced. [Toggle column](https://filamentphp.com/docs/5.x/tables/columns/toggle) [Checkbox column](https://filamentphp.com/docs/5.x/tables/columns/checkbox) ⌘I --- # Checkbox column - Filament > Documentation Index > ------------------- > > Fetch the complete documentation index at: [/docs/llms.txt](https://filamentphp.com/docs/llms.txt) > > Use this file to discover all available pages before exploring further. [Skip to main content](https://filamentphp.com/docs/5.x/tables/columns/checkbox#content-area) [​](https://filamentphp.com/docs/5.x/tables/columns/checkbox#introduction) Introduction ------------------------------------------------------------------------------------------ The checkbox column allows you to render a checkbox inside the table, which can be used to update that database record without needing to open a new page or a modal: use Filament\Tables\Columns\CheckboxColumn; CheckboxColumn::make('is_admin') [​](https://filamentphp.com/docs/5.x/tables/columns/checkbox#lifecycle-hooks) Lifecycle hooks ------------------------------------------------------------------------------------------------ Hooks may be used to execute code at various points within the checkbox’s lifecycle: CheckboxColumn::make() ->beforeStateUpdated(function ($record, $state) { // Runs before the state is saved to the database. }) ->afterStateUpdated(function ($record, $state) { // Runs after the state is saved to the database. }) [​](https://filamentphp.com/docs/5.x/tables/columns/checkbox#security) Security ---------------------------------------------------------------------------------- ### [​](https://filamentphp.com/docs/5.x/tables/columns/checkbox#authorization) Authorization The checkbox column does not automatically check Laravel Model Policies before saving changes. When a user updates a value via the checkbox column, Filament checks whether the column is `disabled()` but does not run any `update` policy gate check. This means that if a user can see a record in the table and the column is not disabled, they can update that column’s value regardless of any `update` policy you have defined. If you need to restrict who can edit this column, you should use the `disabled()` method to conditionally prevent editing based on your own authorization logic, for example `disabled(fn ($record) => $record->user_id !== auth()->id())`. Alternatively, consider using a full edit page or modal action where Filament’s resource authorization is enforced. [Text input column](https://filamentphp.com/docs/5.x/tables/columns/text-input) [Custom columns](https://filamentphp.com/docs/5.x/tables/columns/custom-columns) ⌘I ---