Illustration de l'article sur le mode sombre Shopware sans FOUC
Conversão e UX

Modo escuro no Shopware 6.7: porque todas as montras precisam dele em 2026 (e como o implementar sem flash branco)

Em 2026, o modo escuro já não é uma funcionalidade «para programadores». Os estudos de utilização mostram que 60 % a 80 % dos utilizadores ativam o modo escuro no sistema operativo pelo menos durante parte do dia: o iOS muda automaticamente à noite, o macOS e o Windows têm as suas definições de luminosidade automática, e os utilizadores avançados deixam-no sempre ligado para reduzir o cansaço visual. Uma loja sem modo escuro deixou de corresponder às expectativas de UX de 2026 e envia aos visitantes um flash branco agressivo a cada carregamento de página, particularmente penoso à noite e em telemóvel.

O Shopware 6.7 não oferece modo escuro nativo na montra. Esta ausência não é inocente: uma implementação limpa obriga a tratar vários temas técnicos (anti-FOUC, persistência entre dispositivos, compatibilidade com o Bootstrap, sincronização com outros componentes) que raramente ficam bem feitos sem um plugin dedicado. Este guia detalha como implementar um modo escuro completo e rápido no Shopware 6.7, com as armadilhas técnicas a evitar.

Porque é que o modo escuro se tornou um padrão de UX em 2026

Três forças fizeram do modo escuro uma expectativa em vez de um bónus.

O uso no sistema operativo generalizou-se. Desde o iOS 13 (2019) e o macOS Mojave (2018), o modo escuro de sistema passou de nicho a mainstream. As estatísticas de 2025 indicam que 80 % dos utilizadores de iOS e 65 % dos de Android ativaram o modo escuro pelo menos ocasionalmente, e 35 % mantêm-no sempre ligado. Em computador é um pouco menos (40 % a 50 %), mas em crescimento constante.

O cansaço visual é um tema de saúde reconhecido. Vários estudos, nomeadamente os publicados pela American Academy of Ophthalmology, documentaram o impacto do branco luminoso noturno na qualidade do sono e na fadiga ocular. O modo escuro já não é uma preferência estética: é uma prática de conforto integrada nas rotinas digitais dos utilizadores sensíveis a estes temas.

As expectativas de UX alinharam-se. As grandes plataformas (X, Reddit, GitHub, Notion, Linear, Slack, Discord) oferecem todas um modo escuro cuidado. Os utilizadores habituam-se a poder passar a escuro em qualquer interface e percecionam negativamente os sites que não acompanham. Para uma loja online, é um sinal de qualidade subtil mas real, sobretudo nos segmentos tecnológico, criativo e jovem, onde o modo escuro é quase uma norma tribal.

O atraso do Shopware neste ponto não é crítico em absoluto (a plataforma continua sólida nos fundamentos), mas deixa as lojas sem uma funcionalidade que os comerciantes modernos esperam. Colmatar essa lacuna com limpeza é ganhar em três eixos: conforto do utilizador, sinal de qualidade percebida e reconhecimento junto das audiências sensíveis à UX moderna.

A armadilha do flash branco (FOUC): porque é eliminatória em UX

FOUC significa «Flash of Unstyled Content». Aplicado ao modo escuro, é o breve flash branco visível antes de o JavaScript do modo escuro executar e aplicar o tema. Para um visitante com o sistema em escuro, esse flash dura tipicamente 100 a 400 milissegundos no primeiro carregamento de página: precisamente o tempo que um humano precisa para perceber a incoerência visual.

Porque é eliminatório:

Cognitivamente, o flash sinaliza um erro. O cérebro humano interpreta as mudanças visuais bruscas como anomalias. Uma página que arranca em branco e passa a escuro parece avariada, mesmo que o resultado final esteja certo. É o contrário do que se procura numa UX premium.

Em telemóvel, é fisicamente desagradável. Em uso noturno, precisamente quando o modo escuro é mais útil, o flash de 300 ms a plena luminosidade branca é sentido como uma agressão visual. Os utilizadores percecionam o site como «pouco sério» e fecham muitas vezes o separador sem razão consciente.

Do lado dos Core Web Vitals, degrada o LCP percebido. O LCP mede o momento em que o maior elemento visível é renderizado. Se o seu LCP está em 1,8 s mas o flash branco dura mais 300 ms, o utilizador perceciona na realidade 2,1 s de carregamento, e a sua impressão de qualidade do site degrada-se.

A causa técnica do FOUC é conhecida: a maioria dos plugins de modo escuro aplica o tema via JavaScript em DOMContentLoaded, um evento que dispara depois do primeiro paint do navegador. A ordem é: (1) o HTML é renderizado em modo claro por omissão, (2) o navegador faz o primeiro paint, (3) o DOMContentLoaded dispara, (4) o JS aplica o tema escuro, (5) o navegador volta a pintar. Entre 2 e 5 está o flash branco.

A solução é igualmente conhecida: injetar um script inline minimalista diretamente no head, que lê o cookie de preferência (síncrono, umas 10 linhas de JS) e coloca o atributo data-bs-theme no elemento raiz da página antes do primeiro paint. Mas esta solução raramente é bem implementada no Shopware porque exige alterar o layout de base Twig com um script inline, coisa que poucos programadores fazem naturalmente.

Arquitetura de um modo escuro limpo no Shopware 6.7

Um modo escuro completo e rápido assenta em cinco componentes que têm de trabalhar juntos.

Uma convenção CSS suportada pelo tema. O Bootstrap 5.3 introduziu data-bs-theme="dark" como convenção padrão, e a maioria dos temas Shopware 6.7+ baseados em Bootstrap segue essa convenção. Temas mais antigos ou à medida podem usar uma classe .dark em html ou body. Antes de tudo, confirme que convenção o seu tema usa, porque é isso que determina onde o modo escuro será aplicado.

Um script anti-FOUC no início do head. Este script lê a preferência do visitante (cookie ou deteção do navegador) e aplica o atributo data-bs-theme antes do primeiro paint. É o único componente não negociável de uma implementação limpa.

Um interruptor no cabeçalho. Botão ou switch que o utilizador pode acionar para alternar entre Auto (segue o navegador), Claro (forçado) e Escuro (forçado). O padrão de 3 estados tornou-se norma em 2026: não só claro e escuro, mas também auto, para respeitar a escolha do sistema sem obrigar a clicar de cada vez.

Persistência por cookie. Para que a escolha se mantenha entre sessões, é preciso um cookie de navegador (tipicamente 1 ano de duração, SameSite=Lax). Sem cookie, o visitante volta sempre ao modo Auto a cada visita, o que anula o interesse de o ter regulado à mão.

Persistência de cliente para quem tem sessão iniciada. Para os clientes que entram na conta Shopware, a preferência deve ficar guardada do lado do servidor (custom field do cliente) para ser recuperada em qualquer dispositivo. Sem isso, um cliente que regula o modo escuro no telemóvel chega ao computador e volta a encontrar o modo claro por omissão.

A orquestração: no login, sincroniza-se o cookie com o custom field do cliente (o cookie é escrito com o valor guardado, se existir). A cada mudança pelo interruptor, atualiza-se o cookie e escreve-se no custom field se o utilizador estiver autenticado. O resultado é um modo escuro «entre dispositivos» que acompanha o cliente para todo o lado.

Implementação passo a passo na montra do Shopware 6.7

A implementação segue cinco etapas ordenadas.

Etapa 1: confirmar a convenção CSS do tema. Inspecione theme/Resources/app/storefront/src/scss/ para ver se o tema usa [data-bs-theme="dark"] ou outra convenção. Se o Bootstrap 5.3+ estiver em uso, como acontece nos temas Shopware 6.6+, deve encontrar regras dark com essa convenção. Caso contrário, terá de acrescentar os seus próprios estilos escuros sob o seletor que escolher.

Etapa 2: acrescentar o script anti-FOUC no layout de base. Faça override de base.html.twig no tema para acrescentar, no bloco correspondente ao head, um script inline que lê o cookie df-dark-mode e aplica o atributo. O script deve ficar o mais acima possível no head, idealmente antes de qualquer outro script ou folha de estilos, para executar antes do primeiro paint.

Etapa 3: criar o componente do interruptor. Um componente Twig simples, dark-mode-toggle.html.twig, com um botão que percorre os 3 estados. Inclua-o no bloco base_header_actions_wishlist do layout de base, ou noutro bloco conforme o design. O interruptor deve mostrar um ícone representativo do estado atual (lua para escuro, sol para claro, meia-lua ou ícone composto para auto).

Etapa 4: implementar a lógica JavaScript. Um plugin JS de montra (dark-mode-toggle.plugin.js) que: (a) escuta os cliques no interruptor, (b) calcula o novo estado, (c) escreve o cookie, (d) atualiza o atributo data-bs-theme, (e) emite um evento personalizado df-dark-mode-changed para que outros componentes reajam, (f) se o utilizador estiver autenticado, envia um POST para uma rota Shopware que atualiza o custom field.

Etapa 5: plugin PHP para o custom field e a rota AJAX. Um plugin Shopware 6.7 normal que: (a) cria na instalação o custom field df_dark_mode_preference na entidade customer (tipo Select com 3 opções), (b) expõe uma rota AJAX /df-dark-mode/save que valida o modo recebido e escreve o custom field, (c) escuta o CustomerLoginEvent para sincronizar o cookie no login, (d) remove o custom field na desinstalação.

A implementação à mão leva meio dia a um programador Shopware experiente, mais algumas horas de testes. É exequível. Mas é também tipicamente o género de funcionalidade que se desenvolve uma vez e se instala em várias lojas, daí o interesse de um plugin dedicado.

É o que faz o nosso plugin DataFirefly Dark Mode: interruptor de 3 estados no cabeçalho, anti-FOUC garantido por script inline, persistência por cookie para os visitantes e custom field para os clientes autenticados, sincronização no login, evento JS para integrações de terceiros, snippets multilingues FR/EN/DE incluídos (as chaves em português acrescentam-se no gestor de snippets do Shopware). Instalação em 3 minutos, configuração por omissão testada.

A persistência é o tema em que a maioria dos plugins de modo escuro faz compromissos que degradam a experiência.

Só cookie. O mais simples: um cookie guarda a preferência durante 1 ano. Vantagens: zero impacto na base de dados, funciona sem login, imediato. Limite: a preferência fica presa a um dispositivo e a um navegador. Um cliente que muda de dispositivo ou navega em privado perde a definição.

Só custom field do cliente. A preferência fica guardada na entidade customer do lado do servidor. Vantagens: recuperada em todos os dispositivos do cliente, duradoura. Limite: só funciona para clientes autenticados e exige um pedido ao servidor para ler o valor, logo é inutilizável para o anti-FOUC, que tem de ser síncrono do lado do navegador.

Abordagem híbrida (a boa). Cookie para o anti-FOUC e a persistência de navegador do lado do cliente, mais custom field para os utilizadores autenticados. Na mudança de preferência, escreve-se nos dois. No login, sincroniza-se o cookie com o valor do custom field. Este desenho híbrido combina as vantagens de ambos e elimina os respetivos limites.

O detalhe técnico que faz toda a diferença: a sincronização no login. Sem ela, um cliente que entra num dispositivo novo verá o modo por omissão em vez de recuperar a definição anterior. Com ela, a experiência é coerente em todos os dispositivos. É um detalhe invisível quando funciona bem, mas imediatamente percetível quando falta.

Sincronizar o modo escuro com os outros componentes da página

Com o modo escuro no ar, alguns componentes de terceiros precisam de saber que tema está aplicado para se adaptarem. Os casos mais frequentes: gráficos Recharts ou Chart.js, iframes externas (calendário, vídeo incorporado, formulário de terceiros), widgets de chat em direto, leitores de áudio e vídeo. Sem sincronização, esses componentes ficam em modo claro sobre fundo escuro, com contrastes desagradáveis que partem a coerência visual.

A solução limpa: um evento JavaScript personalizado emitido em document a cada mudança de tema. O padrão usa um evento chamado df-dark-mode-changed com um payload que expõe a preferência bruta (auto/light/dark) e o tema efetivamente aplicado (light/dark, calculado depois de resolver o modo auto).

Os componentes interessados escutam o evento com document.addEventListener e adaptam a renderização: um gráfico Recharts volta a desenhar-se com uma paleta adequada, uma iframe externa recebe um postMessage para mudar de tema, um leitor de vídeo troca as suas sobreposições.

Esta mecânica é limpa porque desacopla os componentes: o plugin de modo escuro não precisa de conhecer os componentes de terceiros, nem o inverso. O evento serve de interface neutra. O custo de implementação do lado do plugin é mínimo (um dispatchEvent a cada mudança), mas o benefício nas integrações é grande.

Conclusão: um investimento moderado, um sinal de qualidade forte

O modo escuro no Shopware 6.7 não é tecnicamente muito complexo em si. Mas combina vários detalhes (anti-FOUC, persistência entre dispositivos, compatibilidade com o Bootstrap, evento de sincronização) que têm de estar todos bem feitos para a experiência ficar limpa. Um modo escuro mal feito degrada a UX em vez de a melhorar: flash branco, preferência perdida entre dispositivos, conflitos com o tema, contrastes partidos nos componentes de terceiros.

O investimento compensa porque sinaliza aos visitantes que a loja segue os padrões de UX de 2026, e porque beneficia de forma particularmente marcada as audiências sensíveis à UX (segmentos tecnológico, criativo, utilizadores avançados). O custo é moderado (meio dia de desenvolvimento na versão manual, 49 € num plugin dedicado), o benefício é duradouro.

Para ir mais longe nos temas relacionados, percorra as categorias Conversão e UX e Desempenho e Core Web Vitals. E para um modo escuro Shopware 6.7 pronto a instalar, com anti-FOUC garantido, persistência híbrida e evento de sincronização nativo, o plugin DataFirefly Dark Mode implementa tudo o que está neste artigo em poucos minutos de instalação.

Para passar à ação: a nossa seleção de plugins Shopware para o design e a personalização.

Continuar a ler

Artigos relacionados