Introdução

A versão beta do Filament v4 chegou com uma série de atualizações poderosas e úteis. Está mais rápido, mais fácil de usar e oferece mais controle na criação de aplicações. Neste artigo, destacamos as novidades e como essas mudanças podem melhorar seu fluxo de trabalho!

Para atualizar seu app para o Filament v4 beta, leia o guia de atualização. Para instalar o Filament v4 em um novo app, acesse o guia de instalação.

Você está visualizando os recursos do Filament 4.x, que está atualmente em beta e ainda não é uma versão estável. Mudanças que quebram compatibilidade podem ser introduzidas durante o período beta. Informe qualquer problema encontrado no GitHub.

Procurando a versão estável atual? Acesse a documentação da versão 3.x.

Geral

Desempenho

O desempenho de renderização e interação no Filament melhorou significativamente, especialmente em tabelas grandes. Internamente, muitos templates Blade foram otimizados para reduzir o número de views renderizadas. Ao usar objetos PHP existentes para gerar o HTML em vez de incluir novos arquivos, o Filament v4 diminui o número de arquivos carregados, melhorando o desempenho. O tamanho dos templates Blade também foi reduzido, agrupando classes do Tailwind CSS em classes dedicadas, usadas nos templates. Isso reduz o HTML necessário, tornando o carregamento de páginas mais rápido e a resposta menor.

Filament v4 agora usa Tailwind CSS v4

O Tailwind CSS v4 é uma atualização importante, focada em desempenho, flexibilidade e padrões modernos da web. Conta com um sistema de configuração reformulado, personalização aprimorada e builds mais rápidas, facilitando a criação de um sistema de design personalizado em escala.
Para conhecer os recursos mais recentes e notas de versão, acesse o blog do Tailwind CSS.

O Tailwind CSS v4 modernizou seu sistema de cores ao migrar de rgb para oklch, usando a gama de cores mais ampla P3 para cores mais vivas e precisas, além das limitações do sRGB.

Como o Filament v4 é baseado no Tailwind v4, ele também adota o oklch para seu sistema de temas.

Títulos semânticos e sistemas de cores dinâmicos

Com a atualização para a versão 4, algumas melhorias de acessibilidade foram implementadas:

  • Os níveis de título agora são gerados dinamicamente, mantendo uma estrutura HTML semântica adequada e melhorando a acessibilidade.
  • Paletas de cores são geradas com mais precisão a partir de uma cor base.
  • As cores do texto são calculadas dinamicamente com base na cor de fundo dos elementos, garantindo melhor contraste e legibilidade.

Autenticação

Autenticação multifator (MFA)

Agora no Filament v4, além da autenticação padrão por e-mail/senha, a Autenticação Multifator (MFA) adiciona uma camada extra de segurança ao login.

O Filament oferece suporte a dois métodos de MFA integrados:

Precisa de mais opções de MFA? É possível registrar provedores personalizados para ampliar os recursos de autenticação do Filament.

Heroicons

O Filament inclui o conjunto de ícones Heroicons, permitindo o uso de ícones sem instalar nada extra.
A nova classe enum Heroicon oferece autocomplete na IDE, facilitando a busca pelo ícone certo — sem mais strings!

Cada ícone está disponível nas variantes sólida e contornada (Heroicon::Star vs. Heroicon::OutlinedStar). O Filament escolhe automaticamente o tamanho ideal (16px, 20px ou 24px) conforme o contexto.

Definindo um fuso horário padrão com FilamentTimezone

A nova facade FilamentTimezone permite definir um fuso horário padrão globalmente via método FilamentTimezone::set(), facilitando a padronização do fuso horário em todos os componentes.
Isso afeta diversos componentes de uma vez, como DateTimePicker, TextColumn e TextEntry.

Formatos "ISO"

Datas e horários agora suportam formatação usando os padrões "ISO" nos componentes TextColumn e TextEntry.

Resources

Nested Resources

Relation Managers e Relation pages facilitam a exibição e o gerenciamento de registros relacionados dentro de um resource.
Por exemplo, em um CourseResource, você pode usar um relation manager ou uma página para gerenciar as aulas pertencentes a um curso. Isso permite criar e editar aulas diretamente a partir de uma tabela usando modais.

Mas se as aulas forem mais complexas, os modais podem não ser suficientes. Nesse caso, você pode dar às aulas seu próprio resource com páginas completas de criação e edição — isso é chamado de nested resource.

Organização das classes no resource

As classes dos resources agora são geradas dentro de seus próprios namespaces dedicados, tornando sua base de código mais organizada.

Dicas de organização de código

Também adicionamos recomendações mais detalhadas sobre como manter seu código Filament limpo e sustentável na v4. Aqui estão algumas das dicas:

  • Use classes de schema e tabela para separar definições grandes de form() e table() em arquivos próprios. Isso evita métodos sobrecarregados e melhora a legibilidade.
  • Crie classes de componente dedicadas quando entradas de formulário, colunas de tabela, filtros ou ações se tornarem complexas. Isso mantém cada parte do código focada e reutilizável.
  • Organize os componentes por tipo e propósito, como inputs de formulário em Schemas/Components e ações de tabela em Actions.

Preservar dados ao criar outro registro

Por padrão, a ação Salvar e criar outro limpa o formulário após o envio.
Se quiser manter certos valores, agora você pode usar o método preserveFormDataWhenCreatingAnother() na classe da página de criação e retornar apenas os dados que deseja preservar.

Ao usar a ação de criação, você também pode aplicar o método preserveFormDataWhenCreatingAnother().

Personalização do conteúdo da página

Antes do Filament v4, não havia uma forma prática de personalizar layouts de página no painel. Agora, cada página possui seu próprio schema, que define sua estrutura e conteúdo.

Você pode sobrescrever o schema padrão da página usando o método content() para controlar completamente o layout.
Isso permite adicionar, remover ou reordenar componentes do schema, como tabelas, abas e elementos personalizados.

Redirecionamento após criar um resource

Agora é possível configurar o comportamento padrão de redirecionamento após a criação de um resource.
Usando a configuração do painel, você pode definir se o usuário será redirecionado para a página de índice, visualização ou edição após criar um registro.

Isso se aplica globalmente a todos os resources do painel.

Desativar divisão de termos na busca

A nova propriedade $shouldSplitGlobalSearchTerms permite desativar a divisão dos termos de busca global em palavras individuais, o que pode melhorar a performance da busca em grandes volumes de dados.

Relation managers

Personalização da tab

As páginas de Edição e Visualização agora suportam personalização completa da tab (aba) principal de conteúdo.
Ao sobrescrever o método getContentTabComponent(), é possível usar todas as opções de personalização de tabs, incluindo alteração de label, ícone ou até mesmo comportamentos personalizados.

Antes, apenas o ícone era personalizável — agora, toda a tab (aba) pode ser configurada.

Navegação

Sidebar / Topbar

A Sidebar e a Topbar agora são componentes Livewire, permitindo atualizações dinâmicas.
Se for necessário atualizá-las — por exemplo, após mudança de configuração ou permissão —, você pode disparar um evento do navegador refresh-sidebar ou refresh-topbar para recarregá-las.

Schemas

Schemas são a base da abordagem de UI orientada por servidor do Filament.
Eles permitem construir interfaces diretamente em PHP usando objetos de configuração estruturados — sem precisar escrever HTML ou JavaScript manualmente.

Esses schemas definem a aparência e o comportamento da interface, representando componentes como campos de formulário, campos de infolist, componentes de layout e componentes do próprio schema.

Todo componente de UI do Filament — seja um campo de formulário, lista ou elementos estáticos como texto ou botões — é configurado por meio de um schema.
Os componentes são modulares, aninháveis e reutilizáveis, o que torna as interfaces consistentes e fáceis de manter.

Um schema é representado por um objeto Filament\Schemas\Schema, e você pode passar um array de componentes para ele no método components().

Para ver a lista completa de componentes disponíveis, consulte a documentação de Schemas.

Tabs verticais

Tabs ajudam a organizar schemas longos ou complexos, agrupando componentes em seções separadas.
Isso reduz a poluição visual e torna os formulários mais fáceis de navegar.

Agora é possível usar um layout de tabs verticais com o método vertical().

Container queries

Além dos breakpoints tradicionais baseados no tamanho da janela, agora você pode usar container queries para criar layouts responsivos com base no tamanho do container pai.

Formulários

Rich editor

O Rich editor agora utiliza o Tiptap, um framework moderno e altamente extensível para edição de texto open source.

Armazenamento em HTML ou JSON

Por padrão, o editor armazena o conteúdo como HTML. Se preferir armazenar como JSON, é possível usar o método json().

Blocos personalizados

Blocos personalizados são elementos que os usuários podem arrastar e soltar no rich editor.
Você pode definir esses blocos com o método customBlocks().

Tags dinâmicas

As tags dinâmicas permitem inserir "variáveis" — como {{ name }} ou {{ today }} — no conteúdo.
Essas tags são substituídas por valores dinâmicos na hora da renderização, sendo úteis para personalizar mensagens ou exibir datas por exemplo.

Para ativar, use o método mergeTags().
O usuário pode digitar {{ ou usar o botão na barra de ferramentas para acessar o painel com as tags disponíveis.

Estendendo o rich editor

Você pode estender o editor criando plugins personalizados.
Eles permitem adicionar suas próprias extensões do TipTap, botões e comportamentos personalizados.

Slider

O componente Slider permite que o usuário selecione um ou mais valores numéricos arrastando um controle sobre uma barra — ideal para intervalos, notas ou porcentagens.

Editor de código

O Code editor permite que o usuário escreva e edite código diretamente na interface.
Suporta linguagens como HTML, CSS, JavaScript, PHP e JSON.

Repeaters em formato de tabela

Os repeaters em tabela exibem os itens de um repeater no formato de tabela.
Você configura as colunas com o método table() e objetos TableColumn, que mapeiam os campos do schema do repeater.

Cada coluna pode ser personalizada com:

  • hiddenHeaderLabel(): esconde a label visualmente, mantendo acessível.
  • markAsRequired(): exibe um asterisco vermelho em campos obrigatórios.
  • wrapHeader(): permite quebra de linha em labels longas.
  • alignment(): alinha o título da coluna (start, center, end).
  • width(): define uma largura fixa.

Selecionar opções via tabela em modal

O componente ModalTableSelect permite selecionar registros a partir de uma tabela em modal — ideal para relacionamentos com muitos dados e que exigem busca e filtros avançados.

Usando JavaScript para reduzir requisições

hiddenJs() e visibleJs()

Você pode ocultar/exibir campos com os métodos hidden() ou visible(), mas isso recarrega o schema — gerando requisição no backend.

Para evitar isso, use hiddenJs() ou visibleJs(), que utilizam expressões JavaScript no cliente, sem recarregar a página.

JsContent

Você pode definir dinamicamente conteúdos de texto (como label() ou belowContent()) usando JsContent.
Isso permite reagir a valores de outros campos, usando $state e $get.

afterStateUpdatedJs()

Usar $set() dentro de afterStateUpdated() atualiza o estado de outro campo, mas ainda envia uma requisição ao servidor.
Com afterStateUpdatedJs(), tudo acontece no lado do cliente, sem requisição de rede.

Você pode usar $state, $get() e $set() no contexto JavaScript.

Agrupando campos visualmente

O componente FusedGroup permite combinar visualmente vários campos em um único grupo compacto.
Ideal para inputs de texto, selects, date-time pickers e color pickers.

Conteúdo extra nos campos

Campos possuem vários slots para inserir conteúdo personalizado.
Eles aceitam texto, componentes de schema, ações ou grupos de ações.

Slots disponíveis:

  • aboveLabel(), beforeLabel(), afterLabel(), belowLabel()
  • aboveContent(), beforeContent(), afterContent(), belowContent()
  • aboveErrorMessage(), belowErrorMessage()

Renderização parcial

Por padrão, usar live() em um campo faz o schema inteiro ser renderizado novamente ao mudar de valor.

Agora o Filament oferece opções mais eficientes:

  • partiallyRenderComponentsAfterStateUpdated(): renderiza apenas campos selecionados.
  • partiallyRenderAfterStateUpdated(): renderiza só o próprio campo.
  • skipRenderAfterStateUpdated(): não renderiza nada.

Tipagem aprimorada do estado dos campos

O estado dos campos agora é convertido automaticamente para o tipo correto.
Por exemplo, ao usar um campo Select vinculado a um enum, ele retorna uma instância da enum — e não apenas uma string — mesmo com $state ou $get().

Isso melhora a consistência e reduz a necessidade de conversões manuais.

Infolists

Code entry

O Code entry permite exibir trechos de código com destaque de sintaxe em uma infolist.
Ele usa o Phiki para destacar o código no servidor.

Tabelas

Tabelas com custom data

As tabelas do Filament geralmente usam modelos Eloquent, mas isso nem sempre é ideal. Quando os dados não estão no banco de dados — ou vêm de fontes externas — é possível usar custom data como fonte de dados.

Você agora pode passar um array para o método records(). Você ainda poderá usar recursos como colunas, ordenação, busca, paginação e ações.

Você também pode buscar dados de APIs externas usando o cliente HTTP do Laravel.

Ao usar APIs, implemente autenticação, tratamento de erros e limites de requisições.

Relacionamentos vazios com filtros select

Use o método hasEmptyOption() para adicionar uma opção “Nenhum” que filtra registros sem relação. Personalize o texto com emptyRelationshipOptionLabel().

Cabeçalhos em tabelas vazias

Agora as tabelas exibem os cabeçalhos mesmo sem registros. Isso melhora a experiência do usuário, principalmente com buscas ou filtros ativos.

Melhorias em Bulk actions

Confira a seção de bulk actions mais abaixo.


Actions

Unified Actions

Actions agora funcionam em formulários, tabelas, infolists e ações genéricas com uma única estrutura, usando o namespace Filament\Actions.

Actions na barra de ferramentas

Tabelas agora possuem uma área de actions na toolbar, configurável com o método toolbarActions(). Útil para ações como “criar” ou facilitar o uso de bulk actions.

Bulk actions

Melhor performance

Use chunkSelectedRecords() para processar os registros em lotes, evitando alto consumo de memória.

Autorizações individuais

Com authorizeIndividualRecords(), você pode validar permissões por registro. Apenas os autorizados entram em $records.

Notificações

Exiba notificações após bulk actions:

  • successNotificationTitle() — tudo processado com sucesso.
  • failureNotificationTitle() — falhas em parte ou todos os registros.

Use $successCount e $failureCount para mensagens dinâmicas.

Actions pré-definidas

Bulk actions pré-prontas não exigem que todos os modelos sejam carregados, o que melhora o desempenho.

Registros desmarcados

Agora o Filament rastreia registros desmarcados ao usar “Selecionar todos”, reduzindo o número de IDs armazenados.

Limites de uso (rate limiting)

Com rateLimit(), limite quantas vezes uma action pode ser executada por IP/minuto.

Mensagens de autorização

Mensagens de permissão agora aparecem em tooltips e notificações.

Importação de dados

Relacionamentos

É possível importar relações BelongsToMany em ações de importação.

Exportação de dados

Estilo em colunas XLSX

Personalize células no Excel com makeXlsxRow() e makeXlsxHeaderRow().

Writer personalizado

Configure o OpenSpout XLSX writer com:

  • getXlsxWriterOptions() — opções de exportação;
  • configureXlsxWriterBeforeClosing() — ajustes finais antes de fechar o arquivo.

Tooltips em botões desabilitados

Agora você pode mostrar tooltips em botões desativados.

Testes de ações

Testar ações ficou mais simples. Veja a documentação de testes.


Widgets

Chart collapsible

Basta definir $isCollapsible = true na classe do widget para tornar charts collapsible.

Filtros personalizados

Use HasFiltersSchema e defina filtersSchema() para criar filtros com componentes de schema em chart widgets. Os valores ficam disponíveis via $this->filters.


Dashboard

Widgets agora suportam o sistema de grid responsivo.


Multi-tenancy

O suporte a multi-tenancy aplica escopos e eventos automaticamente.

Validações unique e exists

Use scopedUnique() e scopedExists() para respeitar escopos de tenant durante a validação.


Configuração do Painel

Fonte local Inter

A fonte Inter agora é carregada localmente. Você pode trocar a fonte com font().

Posição da subnavegação

Configure com subNavigationPosition():

  • Start (início)
  • End (fim)
  • Top (abas)

Modo strict authorization

Com strictAuthorization(), o painel exigirá policies explícitas para cada permissão, lançando exceções se algo estiver ausente.

Verificação de troca de e-mail

Com emailChangeVerification(), o novo e-mail precisa ser verificado em até 60 minutos. O antigo também recebe um link para cancelar a mudança.

Notificações de erro

Personalize como erros aparecem:

  • errorNotifications(false) desativa globalmente.
  • registerErrorNotification(título, corpo) define mensagem padrão.
  • Use statusCode para mensagens por código HTTP.
  • Controle por página com $hasErrorNotifications.

Conclusão

O Filament v4 Beta traz melhorias profundas para performance, organização e experiência de uso.
É o momento ideal para explorar, testar e enviar seu feedback.

Para atualizar seu projeto, siga o guia de upgrade. Para novos projetos, veja o guia de instalação.

Agradecimento especial a Dan Harrin pelo trabalho incrível no Filament v4!

Este artigo foi escrito por Leandro Ferreira, com contribuições de André Domingues e revisão de Dan Harrin e Alex Six.