Resumo
Se o seu site Discourse parecer um HTML simples e sem estilo quando acessado por meio de um link no aplicativo do Facebook no iPhone — sem CSS, sem JavaScript, sem funcionalidade — a causa é a detecção de robôs do Discourse identificando incorretamente o navegador integrado do Facebook como um bot.
A correção é uma alteração de uma linha via console do Rails.
O sintoma
Usuários que clicam em links para o seu site Discourse a partir do aplicativo do Facebook no iPhone veem uma página HTML simplificada e sem estilo — essencialmente o layout de crawler/noscript. Nenhum JavaScript é executado, então recursos como grades de imagens, lightboxes e players de mídia não funcionam. Os mesmos links funcionam corretamente no Safari, Chrome e no navegador integrado do Facebook no Android e iPad.
A causa
O navegador integrado do Facebook no iPhone se identifica com uma string de user agent contendo a palavra facebook, por exemplo:
Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15
(KHTML, like Gecko) Mobile/23D8133 Safari/604.1 MetaIAB Facebook
A detecção de robôs do Discourse (CrawlerDetection) verifica os user agents contra a configuração do site crawler_user_agents, cujo valor padrão inclui facebook:
rss|bot|spider|crawler|facebook|archive|wayback|ping|...
Isso faz com que o Discourse sirva ao navegador integrado do Facebook o layout estático do crawler em vez do aplicativo Ember completo — mesmo sendo um navegador real sendo usado por uma pessoa real.
Você pode confirmar que isso está acontecendo verificando seu log de acesso do nginx para solicitações desse navegador e notando que o tamanho da carga de resposta é dramaticamente menor que o normal (geralmente ~5KB vs ~35KB para uma página de tópico completa).
A correção
Adicione MetaIAB à configuração do site crawler_check_bypass_agents. Essa configuração foi projetada especificamente para isentar user agents do tratamento de robôs, mesmo quando correspondem à lista de robôs.
Observação: crawler_check_bypass_agents é uma configuração de site oculta e não aparece na interface administrativa padrão. O console do Rails é necessário.
Via o console do Rails
SiteSetting.crawler_check_bypass_agents = "MetaIAB"
Se a configuração já tiver um valor (por exemplo, cubot), anexe com um separador de pipe:
SiteSetting.crawler_check_bypass_agents = "cubot|MetaIAB"
A alteração entra em vigor imediatamente — nenhuma reinicialização é necessária.
Por que isso funciona
O método CrawlerDetection.crawler? usa três configurações em combinação:
non_crawler_user_agents— se o UA corresponder a esta lista, ele pode ser um navegador realcrawler_user_agents— se também corresponder a esta lista, é tratado como um robôcrawler_check_bypass_agents— se corresponder a esta lista, é isento do tratamento de robôs, independentemente
O UA do navegador integrado do Facebook contém Safari, que corresponde a non_crawler_user_agents. Também contém facebook, que corresponde a crawler_user_agents. Adicionar MetaIAB — uma string exclusiva do UA do navegador integrado do Facebook — a crawler_check_bypass_agents faz com que o Discourse sirva o aplicativo completo a ele.
Por que Android e iPad não são afetados
- Android: O navegador integrado do Facebook no Android envia um user agent diferente que não contém
facebook, então ele passa pela detecção de robôs sem problemas. - iPad: O navegador integrado do Facebook no iPad também ativa o layout do crawler, mas como o iPad reporta uma
window.innerWidthampla (~1180px), o Discourse serve o layout de desktop, que acaba sendo renderizado adequadamente. A viewport estreita do iPhone (~414px) ativa o layout móvel, que no modo crawler é completamente não funcional.
Nota adicional: inundação do meta-webindexer
Separadamente, o indexador da web do Facebook (meta-webindexer/1.1) pode enviar um volume muito alto de solicitações ao seu site — potencialmente milhares por hora — todas direcionadas à página inicial. Diferentemente do meta-externalagent (que lida com pré-visualizações de links OG e deve permanecer desbloqueado), o meta-webindexer parece não ter nenhum propósito útil para a maioria das instalações do Discourse.
Se você observar esse tráfego em seus logs, pode bloqueá-lo no nível do nginx adicionando-o à sua configuração de bloqueio de bots:
"~*meta-webindexer" 1;
O meta-externalagent deve permanecer permitido, pois é responsável por extrair metadados OG quando links são compartilhados no Facebook.