2026.06.11 (Qui)

✨ Resumo do GPT-5.5  

Registro da troca dos cards de busca montados por strings em JavaScript por um card Liquid compartilhado, para que data, categorias, visualizações e layout do overlay sigam as mesmas regras das listagens normais.

Os resultados de busca pareciam antigos.

Na home e nas páginas de categoria, os cards de posts já estavam mais organizados. Abaixo do título apareciam a data, os badges de categoria e a contagem de visualizações na mesma linha de metadados.

Mas, ao abrir a busca, aparecia uma UI antiga.

Ela mostrava só título e resumo. Não dava para ver de imediato quando o post tinha sido escrito. Também não havia categoria nem visualizações. O mesmo post tinha contexto nas listagens normais, mas perdia esse contexto na busca.

A causa era que os resultados de busca ainda eram renderizados com uma string HTML separada em JavaScript.

Renderização por string JavaScript deixava a busca antiga

A busca em si continua sendo feita pelo Lunr.

Em um blog estático com Jekyll, faz sentido criar um search store no build e consultá-lo com JavaScript no navegador.

O problema era que o JavaScript também construía o card do resultado.

As listagens normais eram renderizadas por _includes/archive-single.html, enquanto os resultados de busca eram montados como strings em assets/js/lunr/lunr-en.js.

A estrutura era mais ou menos esta:

Regular listing
-> Liquid include
-> archive__item
-> date, category, views

Search results
-> Lunr JS
-> hand-built HTML string
-> title and excerpt only

Esse era o problema.

Se eu adicionasse badges de categoria à listagem normal, a busca não mudava. Se ajustasse a regra da data, a busca não mudava. Se mexesse nos metadados de visualizações, a busca continuava igual.

O mesmo card estava sendo mantido em dois lugares.

Separei o card de post em um include compartilhado

Em vez de aumentar o JavaScript da busca, fiz ele criar menos HTML.

Criei includes compartilhados para o card.

_includes/archive-item-card.html
_includes/archive-item-meta-row.html
_includes/archive-item-categories.html

archive-item-card.html recebe um documento e renderiza a mesma estrutura usada nas listagens de arquivo.

list__item
archive__item
archive__item-title
archive__item-meta-row
archive__item-excerpt

archive-item-meta-row.html agrupa data, visualizações e categorias em uma linha. Data e visualizações continuam usando page__meta.html, e categorias ficam em archive-item-categories.html.

Depois, _includes/archive-single.html virou um wrapper fino.

{% include archive-item-card.html document=post type=include.type context="archive" %}

Agora listagens normais e resultados de busca usam o HTML gerado pelo mesmo include.

Guardei o HTML completo do card no store do Lunr

O Lunr continua fazendo a busca.

Mas o JavaScript não monta mais o HTML do card.

Durante o build do Jekyll, assets/js/lunr/lunr-store.js renderiza o include de card para cada documento e guarda o resultado no campo html.

title
excerpt
categories
tags
lang
locale
html
url
teaser

O JavaScript de busca agora pega entry.html e insere no DOM.

Antes, ele misturava links de título, imagem teaser, corte de resumo e montagem de string HTML.

var renderSearchResult = function (entry) {
  return entry.html || '';
};

O JS de busca fica responsável por buscar, filtrar por locale, mostrar a contagem de resultados e inserir os resultados.

Visualizações na busca são exibidas, não registradas

Faltava decidir se a busca também deveria mostrar visualizações.

No começo pensei em esconder. A busca poderia ficar barulhenta, e havia o timing de preencher dados em DOM inserido dinamicamente.

Mas, se o card precisava seguir a listagem normal, deixar só as visualizações de fora também ficava estranho.

Então os resultados de busca mostram visualizações. O que fica separado é exibição e registro.

Search result exposure is not a visit.
The view count in search results is display-only.
Actual visit tracking belongs only to the currently opened page.

Os elementos de visualização do blog têm data-page-view-path. O alvo real de registro é o elemento da página atual com data-page-view-track="true".

Cards de busca têm apenas data-page-view-path; eles não têm data-page-view-track="true".

Assim, aparecer em resultados de busca não aumenta as visualizações do post.

Só mostra o número.

Reapliquei visualizações aos resultados dinâmicos

Os resultados de busca não existem no DOM quando a página carrega.

Eles são inseridos depois que o usuário digita. Se o script de visualizações captura elementos apenas uma vez no carregamento, as visualizações dentro da busca nunca são preenchidas.

Por isso também alterei assets/js/custom/visitor-stats.js.

Em vez de fixar document.querySelectorAll("[data-page-view-path]") no topo do arquivo, ele passa a buscar esses elementos de novo sempre que renderiza visualizações.

Também cacheei o payload de analytics.

latestAnalyticsPayload

Depois que os resultados são renderizados, o script de busca dispara hyuk:search-results-rendered.

O visitor stats escuta esse evento e, se já tiver payload, reaplica visualizações ao novo DOM.

Ele não chama a API de novo.

Se cada mudança no input chamasse a API de visualizações, a busca interferiria no contador. Resultados de busca mudam com frequência, então a rede não deve seguir cada tecla.

O fluxo ficou assim:

Page load
-> receive analytics payload once
-> render views for existing listing/current page

Search results render
-> dispatch event
-> reuse cached payload for newly inserted DOM

Assim a busca não contamina o contador.

Metadados multilíngues seguem cada locale

Depois do trabalho multilíngue do blog, o site tem páginas e collections por locale, como /en/, /ja/ e /zh-Hans/. A busca não pode misturar esses locales.

O search store inclui lang e locale, e o HTML do card usa o locale do documento para os rótulos de metadados. Em inglês aparece Views, em japonês 閲覧数, e em português Visualizações.

Categorias seguem a mesma regra.

O prefixo de locale não deve aparecer como badge de categoria, então archive-item-categories.html ignora esse segmento e mostra apenas as categorias reais.

Restaurei sidebar e largura maior no overlay de busca

Alinhar o card não bastava.

Ao abrir a busca, a largura dos resultados ainda ficava estranha. Mesmo usando o mesmo HTML das listagens normais, o layout não aproveitava o espaço à direita.

Havia outro problema maior: ao abrir a busca, as categorias laterais desapareciam.

O overlay de busca não é uma camada sobre o corpo existente. Ao abrir a busca, .initial-content é escondido e uma área separada #site-search é exibida.

Isso faz a sidebar da página normal desaparecer também. Mesmo com card compartilhado, a busca ainda parece outra tela se a estrutura ao redor for diferente.

Por isso incluí a sidebar dentro de _includes/search/search_form.html.

<div class="search-content__inner-wrap">
  {% include sidebar.html %}
  <div class="archive search-content__archive">
    ...
  </div>
</div>

Também envolvi a área de resultados com archive search-content__archive, para que os resultados sigam o layout de arquivo.

Depois removi o CSS que estreitava os cards.

O Minimal Mistakes tinha esta regra de busca:

.search-content .archive__item {
  @include breakpoint($large) {
    width: 75%;
  }

  @include breakpoint($x-large) {
    width: 50%;
  }
}

A aparência antiga não vinha só do HTML. Em telas grandes, o próprio card era reduzido pela metade.

No SCSS customizado, os cards de busca voltaram a usar largura total.

.search-content .archive__item {
  width: 100%;
}

Ainda havia um detalhe.

O archive normal reserva espaço à direita com padding-inline-end para a sidebar direita. O overlay de busca não tem essa sidebar. Manter esse padding deixa os resultados estreitos de novo.

Então removi esse padding só no archive do overlay de busca.

.search-content .search-content__archive {
  padding-inline-end: 0;
}

As regras de renderização do card são compartilhadas com as listagens normais; o layout do overlay é ajustado para a tela de busca.

Conferi desktop e mobile

Rodei build e checks de sintaxe.

bundle exec jekyll build
node --check _site/assets/js/lunr/lunr-store.js
node --check _site/assets/js/lunr/lunr-en.js
node --check _site/assets/js/custom/visitor-stats.js

O search store gerado contém page__views e data-page-view-path.

O HTML do card de busca não contém data-page-view-track="true", o que evita misturar exposição em busca com registro de visita.

Depois abri a busca em páginas de vários locales e testei consultas como:

References
Keymory
Daily review

Os cards mostraram data, categoria e visualizações na mesma linha de metadados das listagens normais. Os rótulos seguiram cada locale: Views, 閲覧数, Visualizações e os demais.

Dentro dos resultados não havia data-page-view-track="true". Nas páginas de post, o elemento de tracking da página atual continuou aparecendo uma única vez.

O overlay de busca também voltou a ter sidebar. Em desktop de 1280px, a sidebar tinha 22 itens, e o card de resultado chegou a cerca de 974px de largura.

Em mobile de 390px, a sidebar ficou empilhada acima, e o card usou 345px para título, metadados e resumo.

Não houve erros no console do navegador.

Deixe um comentário