<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blogging on kenji.blog</title><link>http://kenji.blog/pt/categories/blogging/</link><description>Recent content in Blogging on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>pt</language><copyright>kenjinote</copyright><lastBuildDate>Sun, 13 Sep 2026 02:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/pt/categories/blogging/index.xml" rel="self" type="application/rss+xml"/><item><title>Introdução ao Gerador de Sites Estáticos com Hugo (Guia de Migração do WordPress)</title><link>http://kenji.blog/pt/p/hugo-static-site-generator-wordpress-migration/</link><pubDate>Sun, 13 Sep 2026 02:00:00 +0900</pubDate><guid>http://kenji.blog/pt/p/hugo-static-site-generator-wordpress-migration/</guid><description>&lt;img src="http://kenji.blog/p/hugo-static-site-generator-wordpress-migration/img/eyecatch.jpg" alt="Featured image of post Introdução ao Gerador de Sites Estáticos com Hugo (Guia de Migração do WordPress)" />&lt;p>No desenvolvimento web moderno e no gerenciamento de blogs, a velocidade de carregamento, segurança e capacidade de manutenção de um site tornaram-se fatores cruciais. O &amp;ldquo;WordPress&amp;rdquo;, que há muito ostenta uma participação de mercado esmagadora como base para blogs e sites corporativos, é apreciado por muitos usuários devido ao seu ecossistema flexível de plugins e painel de administração intuitivo. No entanto, por envolver comunicação com banco de dados e geração dinâmica de páginas no lado do servidor (processamento via PHP), ele também enfrenta desafios como vulnerabilidade a picos repentinos de tráfego e latência de exibição.&lt;/p>
&lt;p>Por isso, nos últimos anos, os &amp;ldquo;Geradores de Sites Estáticos&amp;rdquo; (SSG: Static Site Generator) têm se popularizado rapidamente. Neste artigo, vamos nos aprofundar no &amp;ldquo;&lt;strong>Hugo&lt;/strong>&amp;rdquo;, que se destaca entre muitos SSGs por ser desenvolvido na linguagem Go e conhecido por sua velocidade de build impressionante. Vamos explicar detalhadamente desde a comparação da arquitetura técnica com CMS dinâmicos (Sistemas de Gerenciamento de Conteúdo) como o WordPress, até os procedimentos específicos de migração, avaliação de desempenho usando modelos matemáticos, e a estrutura de diretórios e ordem de busca de templates específicas do Hugo.&lt;/p>
&lt;hr>
&lt;h2 id="1-diferenças-técnicas-entre-cms-dinâmico-wordpress-e-gerador-de-sites-estáticos-hugo">1. Diferenças técnicas entre CMS dinâmico (WordPress) e gerador de sites estáticos (Hugo)
&lt;/h2>&lt;p>Quando se trata do mecanismo de entrega de um site, o WordPress e o Hugo adotam abordagens fundamentalmente diferentes.&lt;/p>
&lt;h3 id="11-arquitetura-do-wordpress-geração-dinâmica">1.1 Arquitetura do WordPress (Geração Dinâmica)
&lt;/h3>&lt;p>O WordPress é um exemplo clássico de CMS dinâmico que monta páginas no lado do servidor a cada requisição. Quando um usuário (navegador) acessa uma página, o servidor web (Apache, Nginx, etc.) executa scripts PHP e emite consultas a um banco de dados relacional como MySQL (ou MariaDB). Ele combina o conteúdo recuperado do banco de dados (dados do artigo, categorias, tags, configurações do site, etc.) com arquivos de template, gera o HTML final e o retorna ao cliente.&lt;/p>
&lt;p>Este mecanismo tem a vantagem de poder gerar conteúdo diferente em tempo real para cada visitante (ex: carrinhos de sites de e-commerce, páginas exclusivas para usuários logados), mas consome muitos recursos do servidor a menos que um mecanismo de cache (proxy reverso, plugins, etc.) seja projetado adequadamente.&lt;/p>
&lt;h3 id="12-arquitetura-do-hugo-geração-prévia-no-build">1.2 Arquitetura do Hugo (Geração Prévia no Build)
&lt;/h3>&lt;p>Por outro lado, como o nome &amp;ldquo;Gerador de Sites Estáticos&amp;rdquo; sugere, o Hugo gera o conteúdo no momento do &amp;ldquo;build&amp;rdquo; e não no momento da &amp;ldquo;requisição&amp;rdquo;. O conteúdo é mantido não em um banco de dados, mas como &amp;ldquo;arquivos Markdown&amp;rdquo; locais versionados pelo Git ou ferramentas similares.
Quando o desenvolvedor executa o comando (&lt;code>hugo&lt;/code>), o Hugo lê os arquivos Markdown, injeta os dados nos templates HTML especificados (arquivos de layout) e gera uma coleção final e pura de arquivos HTML/CSS/JS.&lt;/p>
&lt;p>O conjunto de arquivos gerados (ativos estáticos) pode ser entregue simplesmente colocando-os em um &amp;ldquo;ambiente de hospedagem estática&amp;rdquo; como Amazon S3, Cloudflare Pages, Netlify, Vercel ou até mesmo em um servidor Nginx simples. Como nem banco de dados nem linguagens do lado do servidor (como PHP) são necessários, os riscos de segurança (como injeção de SQL ou vulnerabilidades do PHP) caem drasticamente, e a velocidade de entrega é acelerada ao extremo através do cache nos nós de borda de uma CDN (Content Delivery Network).&lt;/p>
&lt;p>Abaixo, a diferença entre as arquiteturas é mostrada em um diagrama Mermaid.&lt;/p>
&lt;pre class="mermaid">
flowchart TD
subgraph WordPress[&amp;#34;CMS Dinâmico (WordPress)&amp;#34;]
direction TB
Req1[&amp;#34;Requisição do Usuário&amp;#34;] --&amp;gt; WebServer1[&amp;#34;Servidor Web (Nginx/Apache)&amp;#34;]
WebServer1 --&amp;gt; PHP[&amp;#34;Processamento PHP&amp;#34;]
PHP &amp;lt;--&amp;gt; DB[&amp;#34;Banco de Dados (MySQL)&amp;#34;]
PHP --&amp;gt; HTML1[&amp;#34;Geração de HTML&amp;#34;]
HTML1 --&amp;gt; Res1[&amp;#34;Retorno da Resposta&amp;#34;]
end
subgraph Hugo[&amp;#34;Gerador de Sites Estáticos (Hugo)&amp;#34;]
direction TB
Dev[&amp;#34;Desenvolvedor / CI・CD&amp;#34;] --&amp;gt; HugoBuild[&amp;#34;Processo de Build do Hugo&amp;#34;]
Markdown[&amp;#34;Arquivos Markdown&amp;#34;] --&amp;gt; HugoBuild
Templates[&amp;#34;Templates (HTML)&amp;#34;] --&amp;gt; HugoBuild
HugoBuild --&amp;gt; StaticFiles[&amp;#34;Arquivos Estáticos (HTML/CSS/JS)&amp;#34;]
StaticFiles --&amp;gt; CDN[&amp;#34;CDN / Hospedagem Estática&amp;#34;]
Req2[&amp;#34;Requisição do Usuário&amp;#34;] --&amp;gt; CDN
CDN --&amp;gt; Res2[&amp;#34;Retorno Imediato da Resposta&amp;#34;]
end
&lt;/pre>
&lt;hr>
&lt;h2 id="2-avaliação-de-desempenho-através-de-modelos-matemáticos">2. Avaliação de desempenho através de modelos matemáticos
&lt;/h2>&lt;p>Um dos maiores benefícios de migrar do WordPress para o Hugo é a melhoria do desempenho (velocidade de exibição). Para entender isso quantitativamente, vamos representá-lo usando um modelo matemático simples.&lt;/p>
&lt;p>O tempo para concluir o carregamento da página (Load Time: $T_{load}$) é dividido principalmente no tempo de resposta do servidor (TTFB: Time To First Byte) e no tempo de renderização/aquisição de recursos pelo navegador ($T_{render}$).&lt;/p>
$$ T_{load} = T_{ttfb} + T_{render} $$&lt;p>No caso de um CMS dinâmico (WordPress), o $T_{ttfb}$ é a soma dos seguintes elementos: latência da rede ($T_{network}$), tempo de execução de scripts no lado do servidor ($T_{php}$) e tempo de processamento de consultas ao banco de dados ($T_{db}$).&lt;/p>
$$ T_{ttfb\_wp} = T_{network} + T_{php} + T_{db} $$&lt;p>Em situações de pico de acessos (alta carga), $T_{php}$ e $T_{db}$ aumentam de forma não linear, e o sistema inteiro pode se tornar um gargalo. Expresso em uma fórmula, pode-se observar a seguinte deterioração no tempo de resposta em relação ao número de requisições ($N$) (onde $k$ é o coeficiente de sobrecarga de processamento).&lt;/p>
$$ T_{php}(N) \approx O(N^k), \quad T_{db}(N) \approx O(N^k) \quad \text{where } k > 1 $$&lt;p>Por outro lado, na arquitetura que combina um gerador de sites estáticos (Hugo) e uma CDN, o processamento dinâmico no lado do servidor (PHP ou consultas ao banco de dados) não existe. Como o conteúdo fica em cache em servidores de borda distribuídos globalmente, o $T_{ttfb}$ depende puramente da latência de rede do cliente para o servidor de borda mais próximo ($T_{edge}$).&lt;/p>
$$ T_{ttfb\_hugo} = T_{edge} $$&lt;p>Devido a isso, a relação $T_{edge} \ll (T_{network} + T_{php} + T_{db})$ se estabelece, e o TTFB é drasticamente reduzido para apenas alguns a dezenas de milissegundos. Além disso, mesmo que o número de requisições $N$ aumente, o tempo de resposta permanece quase constante ($O(1)$) devido à capacidade de balanceamento de carga dos servidores de borda.&lt;/p>
$$ \lim_{N \to \infty} T_{ttfb\_hugo}(N) \approx \text{Constant} $$&lt;p>Esta é a base matemática que comprova que o Hugo (site estático) é extremamente robusto contra picos de tráfego (como quando um conteúdo viraliza).&lt;/p>
&lt;hr>
&lt;h2 id="3-estrutura-básica-e-princípios-de-funcionamento-do-hugo">3. Estrutura Básica e Princípios de Funcionamento do Hugo
&lt;/h2>&lt;p>Para dominar o Hugo, é essencial entender sua estrutura única de diretórios e os conceitos de &amp;ldquo;Front Matter&amp;rdquo; e &amp;ldquo;Template Lookup Order&amp;rdquo; (Ordem de Busca de Templates).&lt;/p>
&lt;h3 id="31-explicação-detalhada-da-estrutura-de-diretórios">3.1 Explicação Detalhada da Estrutura de Diretórios
&lt;/h3>&lt;p>Ao criar um novo projeto Hugo (&lt;code>hugo new site mysite&lt;/code>), a seguinte estrutura de diretórios é gerada:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">mysite/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── archetypes/ # Templates para criação de novos conteúdos (modelos de Front Matter)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── assets/ # Arquivos processados pelo Hugo Pipes (SCSS/Sass, JavaScript, etc.)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── content/ # O conteúdo real do site (arquivos Markdown). Substitui o banco de dados.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── data/ # Dados externos e configurações usados em todo o site (JSON, TOML, YAML, CSV, etc.)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── layouts/ # Templates HTML que determinam o visual do site (usa Go html/template)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── public/ # Local onde os arquivos estáticos gerados são colocados após a execução do comando de build
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── static/ # Arquivos estáticos publicados como estão (imagens, favicon, robots.txt, etc.)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">├── themes/ # Diretório de temas (criados por você ou de terceiros)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">└── hugo.toml # Arquivo de configuração global do site (antigamente config.toml era o padrão)
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>No WordPress, o conteúdo é armazenado na tabela &lt;code>wp_posts&lt;/code> do MySQL, mas no Hugo, tudo é gerenciado como arquivos de texto (principalmente Markdown) dentro do diretório &lt;code>content/&lt;/code>. Isso facilita o controle de versão (Git) do conteúdo.&lt;/p>
&lt;h3 id="32-gerenciamento-de-conteúdo-markdown-e-front-matter">3.2 Gerenciamento de Conteúdo: Markdown e Front Matter
&lt;/h3>&lt;p>Cada arquivo de artigo do Hugo possui um bloco de metadados no topo chamado de &amp;ldquo;Front Matter&amp;rdquo;, seguido pelo corpo do texto (Markdown). O Front Matter pode ser escrito em TOML, YAML ou JSON, mas o YAML é amplamente utilizado.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">title&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Entendendo as Taxonomias do Hugo&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">date&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="ld">2026-09-13T10:00:00&lt;/span>&lt;span class="m">+09&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="m">00&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">draft&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">false&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">categories&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;Explicação Técnica&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">tags&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;Hugo&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;Go&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">aliases&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;/old-category/hugo-taxonomy/&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="l">A partir daqui é o corpo do texto. Escrito em **Markdown**.&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="l">Vou explicar os recursos poderosos do Hugo...&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>O que merece atenção aqui é a chave &lt;code>aliases&lt;/code>. Ao migrar do WordPress, a alteração dos permalinks (URLs) pode ser muito prejudicial para o SEO. Usando a funcionalidade de alias do Hugo, basta especificar a URL antiga, e o Hugo gera automaticamente o HTML para redirecionamento (redirecionamento via meta refresh). Isso é muito útil, pois elimina a necessidade de configurações de redirecionamento no lado do servidor (como .htaccess).&lt;/p>
&lt;h3 id="33-ordem-de-busca-de-templates-template-lookup-order">3.3 Ordem de Busca de Templates (Template Lookup Order)
&lt;/h3>&lt;p>Um dos recursos poderosos do Hugo é o seu mecanismo flexível de busca de templates (Template Lookup Order). Ao renderizar uma página específica, o Hugo procura por diretórios e nomes de arquivos em uma ordem particular para encontrar o template ideal.&lt;/p>
&lt;p>Por exemplo, ao renderizar um único artigo (Single Page) como &lt;code>content/post/hello-world.md&lt;/code>, o Hugo geralmente procura os arquivos de layout na seguinte ordem:&lt;/p>
&lt;ol>
&lt;li>&lt;code>layouts/post/single.html&lt;/code>&lt;/li>
&lt;li>&lt;code>layouts/post/list.html&lt;/code> (Não é um erro, mas normalmente é para listas)&lt;/li>
&lt;li>&lt;code>layouts/_default/single.html&lt;/code>&lt;/li>
&lt;li>&lt;code>themes/&amp;lt;NOME_DO_TEMA&amp;gt;/layouts/post/single.html&lt;/code>&lt;/li>
&lt;li>&lt;code>themes/&amp;lt;NOME_DO_TEMA&amp;gt;/layouts/_default/single.html&lt;/code>&lt;/li>
&lt;/ol>
&lt;p>Os desenvolvedores podem &lt;strong>sobrescrever (override)&lt;/strong> os templates do tema simplesmente criando um arquivo com o mesmo nome no diretório &lt;code>layouts/&lt;/code> do próprio projeto, sem precisar modificar diretamente o código-fonte do tema. Isso permite que você aplique personalizações únicas sem impedir atualizações do tema base.&lt;/p>
&lt;h3 id="34-taxonomia-taxonomy">3.4 Taxonomia (Taxonomy)
&lt;/h3>&lt;p>O sistema de classificação do Hugo, equivalente às &amp;ldquo;categorias&amp;rdquo; e &amp;ldquo;tags&amp;rdquo; do WordPress, é chamado de &amp;ldquo;Taxonomia&amp;rdquo; (Taxonomy).
Por padrão, o Hugo suporta as taxonomias &lt;code>categories&lt;/code> e &lt;code>tags&lt;/code>, mas ao editar o &lt;code>hugo.toml&lt;/code>, você pode adicionar livremente taxonomias customizadas (por exemplo, &lt;code>series&lt;/code>, &lt;code>authors&lt;/code>, etc.).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Exemplo de hugo.toml&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">taxonomies&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">category&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;categories&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">tag&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;tags&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">series&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;series&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">author&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;authors&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Isso torna possível organizar e listar conteúdos com base em diversos eixos.&lt;/p>
&lt;hr>
&lt;h2 id="4-processo-de-migração-do-wordpress-para-o-hugo-migração">4. Processo de Migração do WordPress para o Hugo (Migração)
&lt;/h2>&lt;p>A chave para o sucesso na migração do WordPress para o Hugo é como converter o conteúdo dinâmico no banco de dados em arquivos estáticos limpos (Markdown + Front Matter), mantendo a estrutura de URL existente.&lt;/p>
&lt;p>O fluxo geral do pipeline de migração é mostrado abaixo.&lt;/p>
&lt;pre class="mermaid">
flowchart LR
WPDB[&amp;#34;Banco de Dados WP&amp;#34;] --&amp;gt;|Plugin| Exporter[&amp;#34;Ferramenta de Exportação&amp;#34;]
Exporter --&amp;gt;| Extrai Texto, \nMeta, Imagens | ZipFile[&amp;#34;Zip / Pasta&amp;#34;]
ZipFile --&amp;gt;|Descompactar| MarkdownFiles[&amp;#34;Arquivos Markdown \n(content/)&amp;#34;]
ZipFile --&amp;gt;|Descompactar| ImageFiles[&amp;#34;Imagens \n(static/wp-content/)&amp;#34;]
MarkdownFiles --&amp;gt; Formatting[&amp;#34;Revisão e Formatação \n(Ajustar Shortcodes)&amp;#34;]
Formatting --&amp;gt; Git[&amp;#34;Commit no Git&amp;#34;]
&lt;/pre>
&lt;h3 id="41-extração-de-dados-e-conversão-para-markdown">4.1 Extração de dados e conversão para Markdown
&lt;/h3>&lt;p>Para exportar dados do WordPress para uso no Hugo, a forma mais fácil e confiável é usar plugins dedicados. Apresentamos abaixo algumas das abordagens mais comuns.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Uso do plugin Jekyll Exporter&lt;/strong>
Como o Hugo tem uma estrutura de dados muito semelhante ao Jekyll, que também é um SSG, usar o plugin &amp;ldquo;Jekyll Exporter&amp;rdquo; para WordPress é uma abordagem comum. Ao instalar e executar este plugin, todos os posts e páginas estáticas são convertidos em arquivos Markdown com Front Matter, e podem ser baixados como um arquivo ZIP junto com os arquivos de imagem.&lt;/li>
&lt;li>&lt;strong>Criação de scripts próprios usando a API do WordPress&lt;/strong>
Consiste em bater na REST API do WordPress (&lt;code>/wp-json/wp/v2/posts&lt;/code>) com Python, Node.js, etc., analisar os dados JSON e criar um script que gere arquivos Markdown por conta própria. É eficaz para sites que utilizam intensivamente campos personalizados complexos (como ACF) que não podem ser completamente suportados por plugins.&lt;/li>
&lt;li>&lt;strong>Utilização da ferramenta wp2hugo&lt;/strong>
Também existe a abordagem de usar ferramentas CLI escritas em Go, entre outras linguagens, para converter diretamente o arquivo XML de exportação do WordPress (WXR) para o formato do Hugo.&lt;/li>
&lt;/ol>
&lt;h3 id="42-manutenção-da-estrutura-de-permalinks-url">4.2 Manutenção da estrutura de Permalinks (URL)
&lt;/h3>&lt;p>Para manter a autoridade de SEO, é extremamente importante preservar as URLs da era do WordPress exatamente como eram. Se você configurou seus permalinks no WordPress como &lt;code>https://example.com/2026/09/13/meu-post/&lt;/code>, deverá especificar a estrutura dos permalinks no &lt;code>hugo.toml&lt;/code> do Hugo.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">permalinks&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">post&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;/:year/:month/:day/:slug/&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Alternativamente, você pode especificar o parâmetro &lt;code>url&lt;/code> diretamente no Front Matter de cada artigo para forçar e fixar a URL.
Além disso, para as páginas cujas URLs mudarem, configure redirecionamentos usando os &lt;code>aliases&lt;/code> mencionados anteriormente.&lt;/p>
&lt;h3 id="43-conversão-de-shortcodes">4.3 Conversão de Shortcodes
&lt;/h3>&lt;p>Os shortcodes específicos do WordPress (ex: &lt;code>[gallery]&lt;/code>, &lt;code>[caption]&lt;/code>, ou códigos próprios de diversos plugins) muitas vezes permanecem como strings não renderizadas durante a exportação, então é necessário lidar com eles.
Estes podem ser excluídos em lote usando scripts de substituição (sed ou Python), ou podem ser migrados usando a poderosa funcionalidade de &lt;strong>shortcodes personalizados&lt;/strong> do Hugo (criando layouts próprios em &lt;code>layouts/shortcodes/&lt;/code>) para que sejam renderizados corretamente no lado do Hugo.&lt;/p>
&lt;hr>
&lt;h2 id="5-ferramentas-cli-do-hugo-build-e-deploy">5. Ferramentas CLI do Hugo, Build e Deploy
&lt;/h2>&lt;p>Uma vez concluído o trabalho de migração, finalmente usaremos o Hugo para buildar o site e publicá-lo para o mundo. Fornecido como um binário da linguagem Go, o Hugo tem uma velocidade impressionante que conclui o build em apenas alguns segundos, mesmo para sites com milhares ou dezenas de milhares de páginas.&lt;/p>
&lt;h3 id="51-iniciando-o-servidor-de-desenvolvimento-local">5.1 Iniciando o servidor de desenvolvimento local
&lt;/h3>&lt;p>Ao escrever artigos ou ajustar o design, você deve iniciar o servidor local.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Comando para iniciar o servidor de desenvolvimento (use -D para incluir rascunhos)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hugo server -D
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Ao executar este comando, o site estará disponível para visualização em &lt;code>http://localhost:1313/&lt;/code>. O Hugo possui uma poderosa funcionalidade &amp;ldquo;LiveReload&amp;rdquo; integrada, onde, no momento em que você edita e salva um arquivo Markdown, template ou CSS, a tela do navegador é atualizada automaticamente em alta velocidade. Graças a isso, a experiência de escrita e desenvolvimento se torna muito mais agradável do que o painel administrativo do WordPress.&lt;/p>
&lt;h3 id="52-build-de-produção-e-otimização-de-desempenho">5.2 Build de produção e otimização de desempenho
&lt;/h3>&lt;p>Para gerar os arquivos estáticos para deploy no ambiente de produção, basta digitar &lt;code>hugo&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Execução do build de produção. A opção --minify minifica HTML/CSS/JS&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hugo --minify
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Com este comando, todos os arquivos do site serão exportados para o diretório &lt;code>public/&lt;/code>. Ao adicionar a opção &lt;code>--minify&lt;/code>, quebras de linha e espaços desnecessários são removidos, e o tamanho do arquivo é ainda mais reduzido. Isso contribui diretamente para a redução da latência da rede ($T_{network}$) no modelo matemático mencionado anteriormente.&lt;/p>
&lt;h3 id="53-automação-de-deploy-cicd">5.3 Automação de deploy (CI/CD)
&lt;/h3>&lt;p>Gerar os arquivos estáticos em um PC local a cada vez e fazer upload via FTP é ineficiente. Na operação moderna de SSG, a melhor prática é construir um ambiente CI/CD que realize build e deploy automaticamente, usando um push para um repositório Git (como GitHub) como gatilho.&lt;/p>
&lt;p>Por exemplo, a forma básica de uma configuração (arquivo YAML) para fazer o deploy para o Cloudflare Pages ou GitHub Pages usando o GitHub Actions é a seguinte:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="c"># Exemplo de .github/workflows/hugo.yml&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Deploy Hugo site to GitHub Pages&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">push&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">branches&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;main&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">workflow_dispatch&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">permissions&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">contents&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">read&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">pages&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">write&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">id-token&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">write&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">jobs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">build&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ubuntu-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">steps&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Checkout&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/checkout@v3&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">submodules&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">recursive&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Se os temas forem gerenciados como submódulos&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">fetch-depth&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Setup Hugo&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">peaceiris/actions-hugo@v2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">hugo-version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;latest&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">extended&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Build&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">hugo --minify&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Upload artifact&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/upload-pages-artifact@v2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">path&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">./public&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">deploy&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">environment&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">github-pages&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">url&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ steps.deployment.outputs.page_url }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ubuntu-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">needs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">build&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">steps&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Deploy to GitHub Pages&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">id&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">deployment&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/deploy-pages@v2&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Com essa configuração, a simples ação de &amp;ldquo;escrever um artigo em Markdown e fazer o Push para o GitHub&amp;rdquo; completa um pipeline automatizado que publica o site atualizado no ambiente de produção em apenas alguns minutos.&lt;/p>
&lt;hr>
&lt;h2 id="6-vantagens-operacionais-e-de-seo-após-a-migração">6. Vantagens operacionais e de SEO após a migração
&lt;/h2>&lt;p>Operadores de sites que concluem a migração do WordPress para o Hugo frequentemente sentem os seguintes três benefícios notáveis:&lt;/p>
&lt;h3 id="61-melhoria-drástica-na-velocidade-do-site-e-no-core-web-vitals">6.1 Melhoria drástica na velocidade do site e no Core Web Vitals
&lt;/h3>&lt;p>Como resultado da eliminação de consultas ao banco de dados e da renderização no lado do servidor, o tempo de carregamento da página é reduzido para milissegundos. Isso está diretamente ligado a uma melhora significativa nas pontuações do &amp;ldquo;Core Web Vitals&amp;rdquo; (LCP, FID/INP, CLS), que é um fator de ranqueamento do Google. É esperado que a taxa de rejeição dos usuários diminua e a avaliação de SEO melhore.&lt;/p>
&lt;h3 id="62-libertação-das-ameaças-de-segurança">6.2 Libertação das ameaças de segurança
&lt;/h3>&lt;p>Por ser o WordPress tão amplamente usado em todo o mundo, ele é sempre um alvo de ataques. Os riscos de invasões tirando vantagem das vulnerabilidades dos plugins e logins invadidos por força bruta estão sempre presentes.
No entanto, os sites estáticos gerados pelo Hugo não possuem banco de dados, nem ambiente PHP, nem sequer uma tela de administração (formulário de login). Não há espaço para hackers invadirem o servidor e reescreverem o banco de dados, e o risco de segurança se aproxima do zero.&lt;/p>
&lt;h3 id="63-operação-livre-de-manutenção">6.3 Operação livre de manutenção
&lt;/h3>&lt;p>Na operação do WordPress, são necessários constantes trabalhos de manutenção, como atualizações da plataforma principal, atualizações de plugins e acompanhamento da versão do PHP. É preciso ter sempre o temor de que o site possa quebrar devido a problemas de compatibilidade.
No caso do Hugo, as atualizações da própria ferramenta só precisam ser feitas quando necessário, e como o código do site é um conjunto de arquivos de texto independentes, há uma tremenda sensação de segurança de que ele &amp;ldquo;não quebra mesmo se deixado como está&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="7-conclusão">7. Conclusão
&lt;/h2>&lt;p>Neste artigo, explicamos em detalhes sobre a migração de um CMS dinâmico como o WordPress para o &amp;ldquo;Hugo&amp;rdquo;, um poderoso gerador de sites estáticos baseado na linguagem Go, abrangendo desde as diferenças na arquitetura técnica, comprovação de desempenho por meio de modelos matemáticos, até os procedimentos de migração práticos.&lt;/p>
&lt;p>Embora a migração para um gerador de sites estáticos requeira um custo de aprendizado inicial (operações no Git, sintaxe do Markdown, execução de comandos CLI pelo terminal, compreensão das especificações do motor de templates, etc.), ela traz retornos de &amp;ldquo;velocidade de exibição avassaladora&amp;rdquo;, &amp;ldquo;segurança sólida&amp;rdquo; e ser &amp;ldquo;livre de manutenção&amp;rdquo;, que mais do que compensam esse custo.&lt;/p>
&lt;p>Se o seu site não necessita de mudanças de design frequentes ou processos dinâmicos complexos (funcionalidades exclusivas para membros, recursos avançados de e-commerce, etc.) e seu principal objetivo é a divulgação de informações (blogs, mídias, sites corporativos), a migração para o Hugo será, sem dúvida, um dos investimentos técnicos mais eficientes. Esperamos que você use este artigo como referência para dar o primeiro passo rumo à operação de sites de próxima geração com o Hugo.&lt;/p></description></item><item><title>Blog Técnico em Markdown: Configurações de Editor para Dobrar a Velocidade de Escrita</title><link>http://kenji.blog/pt/p/markdown-editor-setup-for-tech-blogs/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/pt/p/markdown-editor-setup-for-tech-blogs/</guid><description>&lt;img src="http://kenji.blog/p/markdown-editor-setup-for-tech-blogs/img/eyecatch.jpg" alt="Featured image of post Blog Técnico em Markdown: Configurações de Editor para Dobrar a Velocidade de Escrita" />&lt;p>Para continuar escrevendo um blog técnico, a otimização do ambiente de escrita é essencial. Neste artigo, vamos nos aprofundar nas configurações avançadas de editor para melhorar drasticamente a velocidade de escrita de blogs técnicos usando Markdown. Explicaremos tudo de forma abrangente, desde a customização extrema do Visual Studio Code (VS Code) e do Neovim, o uso de snippets, a introdução do textlint (uma ferramenta de verificação gramatical) e a automação através de pipelines de CI/CD, até as técnicas de escrita mais avançadas utilizando LLMs, como o GitHub Copilot.&lt;/p>
&lt;h2 id="1-modelo-matemático-para-aumento-da-velocidade-de-escrita">1. Modelo matemático para aumento da velocidade de escrita
&lt;/h2>&lt;p>Vamos primeiro modelar com uma fórmula simples o quanto a otimização das configurações do editor afeta o tempo de escrita. Seja $T_{total}$ o tempo total de digitação para escrever um artigo de blog.&lt;/p>
$$
T_{total} = T_{think} + T_{type} + T_{format} + T_{review}
$$&lt;p>Aqui, $T_{think}$ é o tempo de pensamento, $T_{type}$ é o tempo de digitação, $T_{format}$ é o tempo de ajuste de formatação (como Markdown) e $T_{review}$ é o tempo de revisão e correção.&lt;/p>
&lt;p>O tempo $T_{saved}$ reduzido pela customização do editor (como a introdução de snippets e configurações de Linter) pode ser expresso da seguinte forma, usando o número de ocorrências $N$ de um determinado padrão (por exemplo, shortcodes do Hugo ou tabelas em Markdown), o tempo necessário para entrada manual $t_{manual}$ e o tempo necessário com automação, como snippets, $t_{snippet}$.&lt;/p>
$$
T_{saved} = \sum_{i=1}^{k} N_i \times (t_{manual, i} - t_{snippet, i}) + T_{review\_saved}
$$&lt;p>Além disso, ao introduzir formatadores automáticos e ferramentas de Lint, o tempo de verificação visual humana $T_{review}$ é consideravelmente reduzido. Maximizar este $T_{saved}$ é exatamente o objetivo deste artigo.&lt;/p>
&lt;h2 id="2-configuração-definitiva-do-visual-studio-code-vs-code">2. Configuração definitiva do Visual Studio Code (VS Code)
&lt;/h2>&lt;p>O VS Code é um dos editores mais populares atualmente e possui um ecossistema de extensões poderoso para escrever em Markdown.&lt;/p>
&lt;h3 id="extensões-recomendadas">Extensões recomendadas
&lt;/h3>&lt;p>Para acelerar a escrita, recomendamos fortemente a instalação das seguintes extensões.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Markdown All in One&lt;/strong>: Possui todos os recursos básicos necessários para escrever em Markdown, como atalhos para negrito e itálico, continuação automática de listas e geração automática de índice (TOC).&lt;/li>
&lt;li>&lt;strong>markdownlint&lt;/strong>: Alerta em tempo real sobre erros de sintaxe ou violações de estilo no Markdown.&lt;/li>
&lt;li>&lt;strong>vscode-textlint&lt;/strong>: Aplica um conjunto de regras para documentos técnicos, prevenindo inconsistências ortográficas e erros gramaticais.&lt;/li>
&lt;/ol>
&lt;h3 id="configuração-de-snippets-personalizados-para-o-hugo-markdownjson">Configuração de snippets personalizados para o Hugo (&lt;code>markdown.json&lt;/code>)
&lt;/h3>&lt;p>Se você estiver usando um gerador de sites estáticos como Hugo ou Docusaurus para o seu blog técnico, precisará digitar frequentemente o Frontmatter e shortcodes personalizados. Com o recurso de snippets do VS Code, é possível expandi-los instantaneamente.&lt;/p>
&lt;p>Selecione &lt;code>Preferences: Configure User Snippets&lt;/code> na Command Palette e adicione as seguintes configurações ao &lt;code>markdown.json&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;Hugo Frontmatter&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;prefix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;frontmatter&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;body&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;---&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;title: \&amp;#34;${1:Título}\&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;slug: \&amp;#34;${2:slug-name}\&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;date: \&amp;#34;$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE T$CURRENT_HOUR:$CURRENT_MINUTE:$CURRENT_SECOND+09:00\&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;image: \&amp;#34;img/eyecatch.jpg\&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;math: true&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;mermaid: true&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;categories: [\&amp;#34;${3:Category}\&amp;#34;]&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;tags: [\&amp;#34;${4:Tag1}\&amp;#34;, \&amp;#34;${5:Tag2}\&amp;#34;]&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;---&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;${0}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Expande o YAML Frontmatter para o Hugo&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;Hugo Figure Shortcode&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;prefix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;hfig&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;body&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;{{&amp;lt; figure src=\&amp;#34;${1:image.jpg}\&amp;#34; title=\&amp;#34;${2:Título da imagem}\&amp;#34; &amp;gt;}}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Shortcode Figure do Hugo&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;Markdown Table&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;prefix&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;mtable&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;body&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;| ${1:Header 1} | ${2:Header 2} | ${3:Header 3} |&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;| :--- | :---: | ---: |&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;| ${4:Row 1} | ${5:Data} | ${6:Data} |&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;| ${7:Row 2} | ${8:Data} | ${9:Data} |&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;$0&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Gera uma tabela Markdown de 3 colunas&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Com essa configuração, basta digitar &lt;code>frontmatter&lt;/code> e pressionar a tecla Tab para que o YAML Frontmatter, incluindo a hora atual, seja instantaneamente expandido, acelerando drasticamente o início da escrita.&lt;/p>
&lt;h3 id="assistência-de-escrita-utilizando-o-github-copilot">Assistência de escrita utilizando o GitHub Copilot
&lt;/h3>&lt;p>Se você tiver o GitHub Copilot ativado no VS Code, o preenchimento de IA baseado no contexto também funcionará no Markdown. Especialmente no caso de blogs técnicos, a IA pode antecipar e sugerir &amp;ldquo;a estrutura a ser explicada a seguir&amp;rdquo; ou &amp;ldquo;blocos de código relacionados&amp;rdquo;, reduzindo consideravelmente o tempo de digitação $T_{type}$.&lt;/p>
&lt;h2 id="3-customização-extrema-no-neovim">3. Customização extrema no Neovim
&lt;/h2>&lt;p>Embora a interface gráfica do VS Code seja excelente, para os entusiastas de terminal e Vimmers, o Neovim é a escolha definitiva, pois permite concluir tudo sem tirar as mãos do teclado.&lt;/p>
&lt;h3 id="arquitetura-lsp-do-neovim">Arquitetura LSP do Neovim
&lt;/h3>&lt;p>A arquitetura do LSP (Language Server Protocol) e do Linter no Neovim para o ambiente Markdown é a seguinte.&lt;/p>
&lt;pre class="mermaid">
classDiagram
class Neovim {
+&amp;#34;Buffer de Texto&amp;#34;
+&amp;#34;Mapeamento de Teclas&amp;#34;
}
class nvim_lspconfig {
+&amp;#34;marksman (LSP de Markdown)&amp;#34;
}
class null_ls_or_none_ls {
+&amp;#34;markdownlint&amp;#34;
+&amp;#34;textlint&amp;#34;
}
class LuaSnip {
+&amp;#34;Snippets Dinâmicos&amp;#34;
}
class CMP {
+&amp;#34;Mecanismo de Autocompletar&amp;#34;
}
Neovim --&amp;gt; nvim_lspconfig : &amp;#34;Fornece recursos semânticos&amp;#34;
Neovim --&amp;gt; null_ls_or_none_ls : &amp;#34;Diagnósticos e Formatação&amp;#34;
Neovim --&amp;gt; CMP : &amp;#34;Solicitação de Autocompletar&amp;#34;
CMP --&amp;gt; nvim_lspconfig : &amp;#34;Fonte LSP&amp;#34;
CMP --&amp;gt; LuaSnip : &amp;#34;Fonte de Snippets&amp;#34;
&lt;/pre>
&lt;h3 id="expansão-avançada-de-snippets-usando-o-luasnip">Expansão avançada de snippets usando o LuaSnip
&lt;/h3>&lt;p>Ainda mais poderoso que os snippets em JSON do VS Code é o plugin &lt;code>LuaSnip&lt;/code> do Neovim. Você pode calcular e expandir o conteúdo do snippet de forma dinâmica usando a lógica do Lua.&lt;/p>
&lt;p>Abaixo está um exemplo de configuração do LuaSnip que obtém dinamicamente a data e hora atuais para expandir o Frontmatter do Hugo.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-lua" data-lang="lua">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="n">ls&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">require&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;luasnip&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="n">s&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ls.snippet&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="n">t&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ls.text_node&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ls.insert_node&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="n">f&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ls.function_node&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">-- Função para obter a hora atual em JST&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">local&lt;/span> &lt;span class="kr">function&lt;/span> &lt;span class="nf">get_current_date_jst&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">return&lt;/span> &lt;span class="n">os.date&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;!%Y-%m-%dT%H:%M:%S&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">..&lt;/span> &lt;span class="s2">&amp;#34;+09:00&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">end&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ls.add_snippets&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;markdown&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">s&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;frontmatter&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;---&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;title: &lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Title&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;slug: &lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;slug-name&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;date: &lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kr">function&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="kr">return&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="n">get_current_date_jst&lt;/span>&lt;span class="p">()}&lt;/span> &lt;span class="kr">end&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{}),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;image: &lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">img/eyecatch.jpg&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;math: true&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;mermaid: true&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;categories: [&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Category&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">]&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;tags: [&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Tag&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\&amp;#34;&lt;/span>&lt;span class="s2">]&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;---&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">s&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;mtable&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34;| &amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Header 1&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34; | &amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Header 2&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34; |&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;|---|---|&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;| &amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Cell 1&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34; | &amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span> &lt;span class="n">i&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Cell 2&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="n">t&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s2">&amp;#34; |&amp;#34;&lt;/span>&lt;span class="p">}),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Dessa forma, aproveitando o poder de uma linguagem de programação (Lua), é possível criar snippets insanos que não apenas inserem strings fixas, mas também incorporam valores de retorno de funções ou aumentam/diminuem dinamicamente o número de colunas de uma tabela com base na quantidade de caracteres inseridos.&lt;/p>
&lt;h2 id="4-análise-estática-equilibrando-qualidade-e-velocidade-de-escrita-textlint-e-expressões-regulares">4. Análise estática equilibrando qualidade e velocidade de escrita (textlint e expressões regulares)
&lt;/h2>&lt;p>Para garantir a qualidade do blog, é necessário prevenir erros de digitação, omissões e inconsistências ortográficas. Fazer isso manualmente faria o $T_{review}$ aumentar explosivamente, portanto, vamos introduzir a análise estática com o &lt;code>textlint&lt;/code>.&lt;/p>
&lt;h3 id="introdução-do-textlint-e-conjuntos-de-regras">Introdução do textlint e conjuntos de regras
&lt;/h3>&lt;p>Instale o textlint em um ambiente Node.js.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npm install -D textlint textlint-rule-preset-ja-technical-writing textlint-rule-prh textlint-filter-rule-comments
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Crie um arquivo &lt;code>.textlintrc.json&lt;/code> na raiz do projeto e configure da seguinte maneira.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;filters&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;comments&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rules&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;preset-ja-technical-writing&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;ja-no-mixed-period&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;periodMark&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;。&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;sentence-length&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;max&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">100&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;prh&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;rulePaths&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;./prh.yml&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Crie um arquivo &lt;code>prh.yml&lt;/code> para definir inconsistências na grafia de termos técnicos. Por exemplo, unifique &amp;ldquo;Javascript&amp;rdquo; e &amp;ldquo;JavaScript&amp;rdquo;.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">rules&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">expected&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;JavaScript&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">pattern&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Javascript&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">expected&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;サーバー&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">pattern&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;サーバ&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">expected&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;インターフェース&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">pattern&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;インターフェイス&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Com isso, inconsistências ortográficas serão alertadas em tempo real sempre que você digitar texto no editor, reduzindo o tempo de revisão a quase zero.&lt;/p>
&lt;h3 id="substituição-em-lote-e-padrões-estruturados-usando-expressões-regulares">Substituição em lote e padrões estruturados usando expressões regulares
&lt;/h3>&lt;p>A substituição em lote com expressões regulares é útil ao migrar artigos existentes para Markdown ou ao trazer textos de fontes externas.&lt;/p>
&lt;p>Por exemplo, a expressão regular para converter a tag HTML &lt;code>&amp;lt;b&amp;gt;negrito&amp;lt;/b&amp;gt;&lt;/code> para Markdown &lt;code>**negrito**&lt;/code>:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Padrão de pesquisa&lt;/strong>: &lt;code>&amp;lt;b&amp;gt;(.*?)&amp;lt;/b&amp;gt;&lt;/code>&lt;/li>
&lt;li>&lt;strong>Padrão de substituição&lt;/strong>: &lt;code>**$1**&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Para consolidar quebras de linha consecutivas desnecessárias em apenas uma:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Padrão de pesquisa&lt;/strong>: &lt;code>\n{3,}&lt;/code>&lt;/li>
&lt;li>&lt;strong>Padrão de substituição&lt;/strong>: &lt;code>\n\n&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Ao executar esses padrões utilizando o recurso de pesquisa e substituição do VS Code (modo de expressão regular) ou o comando &lt;code>%s&lt;/code> do Neovim (&lt;code>:%s/&amp;lt;b&amp;gt;\(.*?\)&amp;lt;\/b&amp;gt;/**\1**/g&lt;/code>), é possível unificar a formatação em um instante.&lt;/p>
&lt;h3 id="verificação-automática-através-de-pipelines-de-cicd">Verificação automática através de pipelines de CI/CD
&lt;/h3>&lt;p>Além disso, criaremos um pipeline de CI usando o GitHub Actions, para que o textlint seja executado automaticamente sempre que fizermos push de um artigo do blog. Isso previne preventivamente a implantação de artigos que violem as regras.&lt;/p>
&lt;pre class="mermaid">
flowchart TD
A[&amp;#34;Autor&amp;#34;] --&amp;gt;|Push de alterações| B[&amp;#34;Repositório do GitHub&amp;#34;]
B --&amp;gt; C{&amp;#34;GitHub Actions Acionado&amp;#34;}
C --&amp;gt; D[&amp;#34;Checkout do Repositório&amp;#34;]
D --&amp;gt; E[&amp;#34;Configuração do Node.js&amp;#34;]
E --&amp;gt; F[&amp;#34;npm install&amp;#34;]
F --&amp;gt; G[&amp;#34;Executar textlint&amp;#34;]
G --&amp;gt;|Passou| H[&amp;#34;Construir Site Hugo&amp;#34;]
G --&amp;gt;|Falhou| I[&amp;#34;Relatar Erro no PR/Commit&amp;#34;]
H --&amp;gt; J[&amp;#34;Implantar em Hospedagem (Vercel/Netlify)&amp;#34;]
&lt;/pre>
&lt;h2 id="5-técnicas-de-escrita-em-markdown-na-era-dos-llms">5. Técnicas de escrita em Markdown na era dos LLMs
&lt;/h2>&lt;p>Na escrita de blogs técnicos de hoje, o uso de LLMs (Large Language Models) é inevitável. Ao aproveitar ferramentas de IA integradas ao editor, a velocidade de escrita dobra ainda mais.&lt;/p>
&lt;h3 id="engenharia-de-prompt-dentro-do-editor">Engenharia de prompt dentro do editor
&lt;/h3>&lt;p>Você pode enviar os seguintes tipos de prompts sem sair do editor, utilizando o GitHub Copilot Chat no VS Code, ou o &lt;code>ChatGPT.nvim&lt;/code> e &lt;code>Copilot.vim&lt;/code> no Neovim.&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;Crie um esboço em estrutura hierárquica Markdown, voltado para iniciantes, sobre os seguintes elementos técnicos: Docker, Kubernetes, CI/CD&amp;rdquo;&lt;/p>
&lt;/blockquote>
&lt;p>Em seguida, os cabeçalhos e marcadores em Markdown são gerados instantaneamente. Precisamos apenas adicionar conteúdo a essa estrutura.&lt;/p>
&lt;p>Além disso, descrições complexas de diagramas Mermaid ou fórmulas (LaTeX) também podem ter sua sintaxe precisa gerada dando instruções à IA. Por exemplo, a base dos layouts das fórmulas e diagramas deste artigo também foi acelerada pela escrita em par com um LLM.&lt;/p>
&lt;h2 id="6-conclusão">6. Conclusão
&lt;/h2>&lt;p>Explicamos sobre as configurações de editor que dobram a velocidade de escrita ao escrever blogs técnicos em Markdown.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Conscientização do modelo matemático&lt;/strong>: Erradicar tarefas repetitivas para maximizar o $T_{saved}$.&lt;/li>
&lt;li>&lt;strong>Utilização do VS Code&lt;/strong>: Omitir a digitação manual com extensões e snippets no &lt;code>markdown.json&lt;/code>.&lt;/li>
&lt;li>&lt;strong>Customização extrema no Neovim&lt;/strong>: Snippets dinâmicos com o &lt;code>LuaSnip&lt;/code> e uso completo do teclado.&lt;/li>
&lt;li>&lt;strong>textlint e análise estática&lt;/strong>: Integração do Linter local e CI/CD para reduzir o tempo de correção para perto de zero.&lt;/li>
&lt;li>&lt;strong>Integração de LLMs&lt;/strong>: Fazer a IA gerar a estrutura do Markdown e o código de diagramas diretamente dentro do editor.&lt;/li>
&lt;/ol>
&lt;p>Ao incorporar essas configurações no seu próprio ambiente, o &amp;ldquo;tédio&amp;rdquo; de escrever deve desaparecer, e a quantidade e qualidade da sua produção técnica melhorarão drasticamente. Que tal começar registrando apenas um pequeno snippet?&lt;/p></description></item><item><title>Como evitar a 'falta de ideias' em artigos técnicos! Métodos eficientes de input e geração de ideias</title><link>http://kenji.blog/pt/p/tech-blog-idea-generation-and-input-strategy/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/pt/p/tech-blog-idea-generation-and-input-strategy/</guid><description>&lt;img src="http://kenji.blog/p/tech-blog-idea-generation-and-input-strategy/img/eyecatch.jpg" alt="Featured image of post Como evitar a 'falta de ideias' em artigos técnicos! Métodos eficientes de input e geração de ideias" />&lt;p>Ao gerenciar um blog técnico como engenheiro ou pesquisador, há uma barreira que você quase certamente enfrentará: a &amp;ldquo;falta de ideias&amp;rdquo;. Mesmo que você consiga escrever os primeiros artigos sem problemas, não é incomum ser atormentado por dúvidas como &amp;ldquo;Não sei sobre o que escrever a seguir&amp;rdquo; ou &amp;ldquo;Falta uma quantidade esmagadora de &amp;lsquo;inputs&amp;rsquo; para poder gerar &amp;lsquo;outputs&amp;rsquo;&amp;rdquo; à medida que você continua. A escrita de blogs técnicos depende muito não apenas da habilidade de escrever, mas também do design de um sistema de coleta de conhecimentos diários, sua organização e a combinação deles para criar novos valores.&lt;/p>
&lt;p>Neste artigo, explicarei detalhadamente e de forma bastante técnica sobre um &lt;strong>pipeline sistematizado de input e output&lt;/strong> para gerar ideias para artigos técnicos de forma quase permanente. Começaremos com um mecanismo que extrai automaticamente tópicos de tendência usando APIs de fontes internacionais de alta qualidade, como Hacker News e Lobsters, sendo executados regularmente através do GitHub Actions. Em seguida, sistematizaremos as informações coletadas como conhecimento usando o método Zettelkasten com Obsidian e construiremos um sistema avançado de Gestão de Conhecimento Pessoal (PKM - Personal Knowledge Management) que possibilita buscas semânticas combinando a API Embeddings da OpenAI com o Pinecone (um banco de dados vetorial).&lt;/p>
&lt;p>Além disso, para compensar as limitações da memória humana, nos aprofundaremos no processo de transformar o conhecimento retido em novas ideias através da &amp;ldquo;Criatividade Combinatória&amp;rdquo; (Combinatorial Creativity). Isso é feito aplicando a Repetição Espaçada (Spaced Repetition) com base na curva de esquecimento de Ebbinghaus usando o Anki, juntamente com modelos matemáticos concretos e exemplos de implementação em scripts Python.&lt;/p>
&lt;h2 id="1-a-entropia-da-informação-e-o-mecanismo-da-falta-de-ideias">1. A Entropia da Informação e o Mecanismo da &amp;ldquo;Falta de Ideias&amp;rdquo;
&lt;/h2>&lt;p>Por que sofremos com a &amp;ldquo;falta de ideias&amp;rdquo;? Do ponto de vista da teoria da informação, pode-se dizer que a &amp;ldquo;quantidade de informação&amp;rdquo; no sistema de conhecimento que possuímos está esgotada ou homogeneizada.&lt;/p>
&lt;p>A entropia da informação $H(X)$, proposta por Claude Shannon, representa a incerteza (ou o grau de surpresa) da informação obtida de uma fonte.&lt;/p>
$$ H(X) = - \sum_{i=1}^{n} P(x_i) \log_2 P(x_i) $$&lt;p>Aqui, $X$ é a variável aleatória dos tópicos obtidos da fonte de informação e $P(x_i)$ é a probabilidade de encontrar o tópico $x_i$. Se você costuma visitar apenas sites semelhantes (por exemplo, apenas determinados sites de notícias locais ou documentação da mesma pilha de tecnologias), um $P(x_i)$ específico se torna extremamente alto, resultando em uma diminuição da entropia geral do sistema, $H(X)$. Um estado de baixa entropia significa que não há &amp;ldquo;novas descobertas (surpresas)&amp;rdquo;, e essa é a causa raiz da &amp;ldquo;falta de ideias&amp;rdquo;.&lt;/p>
&lt;p>Para manter uma entropia alta, é necessário introduzir intencionalmente fontes de informação com as quais você não tem contato usual como ruído, para nivelar a distribuição de probabilidade de encontrar tópicos desconhecidos. Essa é a principal razão para automatizar os inputs de diversas fontes.&lt;/p>
&lt;h2 id="2-construção-de-um-pipeline-automatizado-de-coleta-de-informações-hacker-news--lobsters-api">2. Construção de um Pipeline Automatizado de Coleta de Informações: Hacker News &amp;amp; Lobsters API
&lt;/h2>&lt;p>Para obter inputs de alta qualidade, é eficaz extrair informações sobre tendências de boas comunidades de engenharia, que têm pouco ruído. O Hacker News (operado pela Y Combinator) e o Lobsters são os lugares ideais por apresentarem discussões técnicas profundas. No entanto, visitar esses sites diariamente toma tempo e consome recursos cognitivos.&lt;/p>
&lt;p>Portanto, criaremos um script usando Python para extrair automaticamente artigos com uma pontuação acima de um limite definido das APIs dessas plataformas.&lt;/p>
&lt;h3 id="script-em-python-para-extrair-artigos-em-alta">Script em Python para Extrair Artigos em Alta
&lt;/h3>&lt;p>O script abaixo busca artigos que atendem a certos critérios usando a API do Firebase do Hacker News e os feeds JSON do Lobsters, gerando arquivos Markdown.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">requests&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">json&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">datetime&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">datetime&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">os&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Configurações&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">HN_TOPSTORIES_URL&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://hacker-news.firebaseio.com/v0/topstories.json&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">HN_ITEM_URL&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://hacker-news.firebaseio.com/v0/item/&lt;/span>&lt;span class="si">{}&lt;/span>&lt;span class="s2">.json&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">LOBSTERS_URL&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;https://lobste.rs/hottest.json&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">MIN_HN_SCORE&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">100&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">MIN_LOBSTERS_SCORE&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">10&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">OUTPUT_DIR&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;./daily_inputs&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">get_hacker_news_trends&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Obtém as principais histórias com pontuação alta do Hacker News&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Fetching Hacker News top stories...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">HN_TOPSTORIES_URL&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">status_code&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">200&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">story_ids&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">json&lt;/span>&lt;span class="p">()[:&lt;/span>&lt;span class="mi">30&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="c1"># Limita ao top 30&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">trending_stories&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">story_id&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">story_ids&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">item_resp&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">HN_ITEM_URL&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">format&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">story_id&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">item_resp&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">status_code&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">200&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">item&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">item_resp&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">json&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">item&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="n">item&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;score&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;gt;=&lt;/span> &lt;span class="n">MIN_HN_SCORE&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">trending_stories&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;title&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">item&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;title&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">item&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;https://news.ycombinator.com/item?id=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">story_id&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;score&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">item&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;score&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;source&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Hacker News&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">trending_stories&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">get_lobsters_trends&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Obtém as histórias mais populares do Lobsters&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Fetching Lobsters hottest stories...&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">requests&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">LOBSTERS_URL&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">status_code&lt;/span> &lt;span class="o">!=&lt;/span> &lt;span class="mi">200&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">items&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">json&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">trending_stories&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">item&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">items&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">item&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;score&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;gt;=&lt;/span> &lt;span class="n">MIN_LOBSTERS_SCORE&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">trending_stories&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;title&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">item&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;title&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">item&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">item&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;comments_url&amp;#34;&lt;/span>&lt;span class="p">)),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;score&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">item&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;score&amp;#34;&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;source&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Lobsters&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">trending_stories&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">save_to_markdown&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">stories&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Salva as histórias obtidas em um arquivo Markdown&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">path&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">exists&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">OUTPUT_DIR&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">makedirs&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">OUTPUT_DIR&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">today_str&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">datetime&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">now&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">strftime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;%Y-%m-&lt;/span>&lt;span class="si">%d&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">filepath&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">path&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">join&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">OUTPUT_DIR&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;trends_&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">today_str&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">.md&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">with&lt;/span> &lt;span class="nb">open&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">filepath&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;w&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">encoding&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;utf-8&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;# Daily Tech Trends: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">today_str&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="se">\n\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">story&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">stories&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;## [&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">story&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;title&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">](&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">story&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;url&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">)&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;- **Source**: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">story&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;source&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;- **Score**: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">story&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;score&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">f&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;- **Notes**: (Adicione suas reflexões aqui)&lt;/span>&lt;span class="se">\n\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Saved &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">stories&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> stories to &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">filepath&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">hn_stories&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">get_hacker_news_trends&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lobsters_stories&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">get_lobsters_trends&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">all_stories&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">hn_stories&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">lobsters_stories&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Ordena por pontuação de forma decrescente&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">all_stories&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sort&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">key&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="k">lambda&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">x&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;score&amp;#34;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">reverse&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">save_to_markdown&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">all_stories&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Este script oferece mais valor do que um simples leitor de RSS. Ao filtrar as pontuações, é possível extrair apenas os tópicos técnicos que realmente estão chamando a atenção da comunidade (sinal alto e pouco ruído).&lt;/p>
&lt;h2 id="3-agendamento-e-automação-com-github-actions">3. Agendamento e Automação com GitHub Actions
&lt;/h2>&lt;p>Executar manualmente o script em Python todos os dias é tedioso. O princípio básico da automação é reduzir a intervenção humana ao máximo. Usando o recurso Cron do GitHub Actions, construiremos um mecanismo para executar o script em um horário especificado todos os dias, fazendo commit automaticamente dos resultados no repositório.&lt;/p>
&lt;p>Crie o arquivo &lt;code>.github/workflows/daily_trends.yml&lt;/code> na raiz do projeto e adicione o seguinte:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Daily Tech Trends Scraper&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">schedule&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">cron&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;0 0 * * *&amp;#39;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Executa diariamente às 0:00 UTC&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">workflow_dispatch&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Permite execução manual&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">jobs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">scrape-and-commit&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">ubuntu-latest&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">steps&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Checkout Repository&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/checkout@v3&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Setup Python&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">actions/setup-python@v4&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">python-version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;3.10&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Install Dependencies&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> python -m pip install --upgrade pip
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> pip install requests
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> &lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Run Scraper Script&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">python scripts/fetch_trends.py&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Commit and Push Changes&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">|&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git config --local user.email &amp;#34;action@github.com&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git config --local user.name &amp;#34;GitHub Action&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git add daily_inputs/
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git commit -m &amp;#34;Auto-update daily tech trends [skip ci]&amp;#34; || echo &amp;#34;No changes to commit&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git push&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Com isso, ao abrir o Obsidian todas as manhãs, você terá um ambiente onde os tópicos importantes do dia são adicionados automaticamente como arquivos Markdown na sua caixa de entrada (&lt;code>daily_inputs/&lt;/code>).&lt;/p>
&lt;h2 id="4-rede-de-conhecimento-usando-zettelkasten-e-obsidian">4. Rede de Conhecimento usando Zettelkasten e Obsidian
&lt;/h2>&lt;p>As informações coletadas automaticamente ainda são apenas &amp;ldquo;dados&amp;rdquo;. Um processo é necessário para sublimá-los em &amp;ldquo;conhecimento&amp;rdquo;. É aqui que entram o método Zettelkasten e o Obsidian.&lt;/p>
&lt;p>O Zettelkasten é um método de anotações desenvolvido pelo sociólogo alemão Niklas Luhmann. Em vez de classificar as anotações em pastas hierárquicas, cada nota é mantida pequena (atômica) e interligada umas às outras através de links, formando uma rede de conhecimentos que se assemelha aos circuitos neurais do cérebro.&lt;/p>
&lt;p>O Zettelkasten consiste principalmente em 3 tipos de anotações:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Fleeting Notes (Notas Temporárias)&lt;/strong>: Utilizadas para registrar ideias ou informações que surgem no momento. Os arquivos Markdown com informações de tendências gerados automaticamente pertencem a esta categoria.&lt;/li>
&lt;li>&lt;strong>Literature Notes (Notas de Leitura)&lt;/strong>: Resumos que você escreveu com suas próprias palavras após a leitura de artigos ou livros.&lt;/li>
&lt;li>&lt;strong>Permanent Notes (Notas Permanentes)&lt;/strong>: Reflexões completas sobre um único tópico. Essas notas são a semente direta para artigos de blogs.&lt;/li>
&lt;/ol>
&lt;p>Usando o recurso de backlinks (&lt;code>[[Nome da Nota]]&lt;/code>) do Obsidian, por exemplo, ao linkar uma anotação sobre a &amp;ldquo;Ownership no Rust&amp;rdquo; com outra sobre a &amp;ldquo;História do Garbage Collection&amp;rdquo;, é possível descobrir conexões de ideias completamente inesperadas.&lt;/p>
&lt;h2 id="5-busca-semântica-usando-banco-de-dados-vetorial-pinecone-e-openai-embeddings">5. Busca Semântica usando Banco de Dados Vetorial (Pinecone) e OpenAI Embeddings
&lt;/h2>&lt;p>Quando o número de anotações chega a centenas ou milhares, torna-se difícil encontrar a nota desejada apenas através de pesquisas por palavras-chave (pesquisa de texto completo). Se você pensar &amp;ldquo;Não consigo me lembrar da palavra-chave, mas quero buscar uma anotação conceitualmente semelhante&amp;rdquo;, a busca semântica, que aproveita os Embeddings de um modelo de linguagem de grande escala (LLM), mostrará sua eficácia.&lt;/p>
&lt;p>Usando os modelos &lt;code>text-embedding-ada-002&lt;/code> ou &lt;code>text-embedding-3-small&lt;/code> da OpenAI, cada anotação Markdown do Obsidian é convertida em vetores multidimensionais (conjuntos numéricos contendo de centenas a milhares de dimensões). Nesse espaço vetorial, sentenças com significados próximos também têm distâncias físicas reduzidas.&lt;/p>
&lt;p>Para medir a similaridade entre os vetores, é amplamente utilizada a Similaridade de Cosseno (Cosine Similarity).&lt;/p>
$$ \text{similarity} = \cos(\theta) = \frac{\mathbf{A} \cdot \mathbf{B}}{\|\mathbf{A}\| \|\mathbf{B}\|} = \frac{\sum_{i=1}^{n} A_i B_i}{\sqrt{\sum_{i=1}^{n} A_i^2} \sqrt{\sum_{i=1}^{n} B_i^2}} $$&lt;p>$\mathbf{A}$ e $\mathbf{B}$ são o vetor da string de consulta e o vetor da anotação, respectivamente. Para calcular isso rapidamente, usamos bancos de dados vetoriais como Pinecone ou Qdrant.&lt;/p>
&lt;h3 id="exemplo-de-implementação-de-busca-semântica">Exemplo de Implementação de Busca Semântica
&lt;/h3>&lt;p>Abaixo está um trecho de código em Python que varre o diretório de notas do Obsidian, usa a API da OpenAI para vetorizá-las e insere ou atualiza (upsert) essas informações no Pinecone.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;span class="lnt">83
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">os&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">glob&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">openai&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">OpenAI&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">pinecone&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Pinecone&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">ServerlessSpec&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Configuração das chaves de API (obtidas das variáveis de ambiente)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">OPENAI_API_KEY&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">getenv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;OPENAI_API_KEY&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">PINECONE_API_KEY&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">getenv&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;PINECONE_API_KEY&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">client&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">OpenAI&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">api_key&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">OPENAI_API_KEY&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">pc&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Pinecone&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">api_key&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">PINECONE_API_KEY&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">INDEX_NAME&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;obsidian-notes&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">OBSIDIAN_DIR&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;/path/to/obsidian/vault/PermanentNotes&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">init_pinecone&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Inicialização do índice Pinecone&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">INDEX_NAME&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">pc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">list_indexes&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">names&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">create_index&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">INDEX_NAME&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">dimension&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1536&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="c1"># Número de dimensões do text-embedding-3-small / ada-002&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">metric&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;cosine&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">spec&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">ServerlessSpec&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">cloud&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;aws&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">region&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;us-east-1&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">pc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Index&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">INDEX_NAME&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">get_embedding&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Vetoriza texto usando a API da OpenAI&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">client&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">embeddings&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">create&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">input&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">text&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;text-embedding-3-small&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">embedding&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">sync_notes_to_pinecone&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">index&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Lê os arquivos Markdown, os vetoriza e salva no Pinecone&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">md_files&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">glob&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">glob&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">path&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">join&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">OBSIDIAN_DIR&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;*.md&amp;#34;&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vectors&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">filepath&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">md_files&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">filename&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">os&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">path&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">basename&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">filepath&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">with&lt;/span> &lt;span class="nb">open&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">filepath&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;r&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">encoding&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;utf-8&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">content&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">f&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">read&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Processa apenas se o conteúdo da nota não estiver vazio&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">content&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">strip&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Embedding note: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">filename&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">embedding&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">get_embedding&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">content&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Formato do Pinecone (id, vetor, metadados)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vectors&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;id&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">filename&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;values&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">embedding&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;metadata&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="s2">&amp;#34;text&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">content&lt;/span>&lt;span class="p">[:&lt;/span>&lt;span class="mi">500&lt;/span>&lt;span class="p">]}&lt;/span> &lt;span class="c1"># Texto parcial para exibição nos resultados de busca&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Faz o Upsert usando processamento em lote&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">vectors&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">index&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">upsert&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">vectors&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">vectors&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Successfully upserted &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="nb">len&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">vectors&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> notes.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">search_similar_ideas&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">index&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">query_text&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">top_k&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;Pesquisa notas semelhantes à consulta para uso na geração de ideias&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">query_embedding&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">get_embedding&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">query_text&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">results&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">index&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">query&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vector&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">query_embedding&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">top_k&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">top_k&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">include_metadata&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">--- Search Results for: &amp;#39;&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">query_text&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#39; ---&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="k">match&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">results&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;matches&amp;#34;&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Score: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">match&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;score&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.4f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> | Note: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">match&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;id&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;Preview: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">match&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;metadata&amp;#39;&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="s1">&amp;#39;text&amp;#39;&lt;/span>&lt;span class="p">][:&lt;/span>&lt;span class="mi">100&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">...&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">idx&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">init_pinecone&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Na primeira execução, chame sync_notes_to_pinecone(idx) para construir o banco de dados&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sync_notes_to_pinecone&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">idx&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Busca de ideias para o blog&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">search_similar_ideas&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">idx&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s2">&amp;#34;Aceleração de inferência de aprendizado de máquina no navegador usando WebAssembly&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Com este sistema, ao questionar &amp;ldquo;Quero escrever sobre &amp;lsquo;WebAssembly&amp;rsquo;, que estava em alta no Hacker News desta semana, mas será que já escrevi notas relacionadas no passado?&amp;rdquo;, a IA pode extrair instantaneamente Notas Permanentes do passado que tenham relação semântica. Assim, é possível estruturar artigos de maneira profunda, aproveitando ao máximo todos os seus conhecimentos anteriores.&lt;/p>
&lt;h2 id="6-curva-de-esquecimento-de-ebbinghaus-e-repetição-espaçada-com-anki">6. Curva de Esquecimento de Ebbinghaus e Repetição Espaçada com Anki
&lt;/h2>&lt;p>Não importa quão bom seja o conhecimento que você anote, se a informação não for fixada em seu próprio cérebro, será difícil conectar fluentemente vários conceitos enquanto você estiver escrevendo. Aqui, a &amp;ldquo;Curva de Esquecimento de Ebbinghaus&amp;rdquo;, um modelo matemático do mecanismo da memória humana, entra em jogo.&lt;/p>
&lt;p>A curva de esquecimento pode ser aproximada pela seguinte equação:&lt;/p>
$$ R = e^{-\frac{t}{S}} $$&lt;p>Onde,&lt;/p>
&lt;ul>
&lt;li>$R$ é a taxa de retenção da memória (Retrievability, num intervalo de 0 a 1)&lt;/li>
&lt;li>$t$ é o tempo decorrido desde a aprendizagem&lt;/li>
&lt;li>$S$ é a estabilidade ou a força da memória (Stability)&lt;/li>
&lt;/ul>
&lt;p>Logo após assimilar um novo conceito, $S$ é pequeno, e a medida que o tempo $t$ passa, $R$ cai rapidamente (esquecimento). No entanto, quando você revisa (Recall) exatamente no momento em que está prestes a esquecer, a velocidade da perda da informação até o próximo esquecimento diminui ($S$ aumenta) consolidando-se então na memória de longo prazo.&lt;/p>
&lt;p>&amp;ldquo;Anki&amp;rdquo; é um software que usa algoritmos (como o SuperMemo 2) para calcular automaticamente este tempo ideal de revisão e o apresenta por meio de flashcards.&lt;/p>
&lt;p>Uma abordagem poderosa para gerar conteúdo em um blog técnico é &lt;strong>transformar o conteúdo das Notas Permanentes do Obsidian em flashcards no Anki&lt;/strong>.
Por exemplo, você pode adicionar perguntas fundamentais sobre engenharia ao Anki, como &amp;ldquo;Quais são os 3 elementos do Teorema CAP?&amp;rdquo; ou &amp;ldquo;Por que os índices B-Tree têm capacidade de pesquisa O(log N)?&amp;rdquo;, e os revisar diariamente. Quando o conhecimento for indexado ao seu cérebro como memória de longo prazo, tomando banho ou andando, informações se juntam inconscientemente resultando em um momento de inspiração (momento eureka) em que pensará: &amp;ldquo;Ah, agora sou capaz de escrever um artigo sobre algoritmos de consenso para sistemas distribuídos&amp;rdquo;.&lt;/p>
&lt;h2 id="7-criatividade-combinatória-combinatorial-creativity">7. Criatividade Combinatória (Combinatorial Creativity)
&lt;/h2>&lt;p>Com o pipeline utilizado até agora, alcançamos os objetivos de termos: &amp;ldquo;diversidade em obtenção de informações&amp;rdquo;, &amp;ldquo;busca com inteligência artificial e sistematização usando o método Zettelkasten&amp;rdquo; e &amp;ldquo;fortalecimento da memória de longo prazo utilizando o aplicativo Anki&amp;rdquo;. O último passo consiste na chamada &amp;ldquo;Criatividade Combinatória&amp;rdquo; (Combinatorial Creativity) para fundir esses recursos em ideias para artigos completamente novas.&lt;/p>
&lt;p>Acredita-se que inovar e ser criativo não surge a partir do nada, mas sim, de novas combinações de informações preexistentes. A citação de Steve Jobs, &amp;ldquo;Creativity is just connecting things.&amp;rdquo; (A criatividade consiste apenas em conectar as coisas.), é famosa.&lt;/p>
&lt;p>Os padrões para formar matrizes com relação à produção de textos para blogs consistem geralmente nas seguintes ideias:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>[Tecnologia Antiga] × [Novo Paradigma]&lt;/strong>: Ex. &amp;ldquo;Aprendendo sobre os antipadrões do design moderno de microsserviços com a arquitetura do COBOL&amp;rdquo;&lt;/li>
&lt;li>&lt;strong>[Front-end] × [Conceitos do Back-end]&lt;/strong>: Ex. &amp;ldquo;Compreendendo os algoritmos de atualização do DOM virtual do React sob a perspectiva dos níveis de isolamento de transação em bancos de dados&amp;rdquo;&lt;/li>
&lt;li>&lt;strong>[Fórmulas Abstratas de Matemática / Teoria] × [Implementações Concretas]&lt;/strong>: Ex. &amp;ldquo;Usando a Teoria dos Grafos para interpretar a otimização do escalonamento de Pods no Kubernetes&amp;rdquo;&lt;/li>
&lt;/ol>
&lt;p>Para gerar essas combinações intencionalmente, utilize o mecanismo de busca semântica Pinecone configurado anteriormente para extrair um conceito aleatório A e um conceito B e, em seguida, envie um prompt para uma IA (como o ChatGPT): &amp;ldquo;Proponha 5 títulos e estruturas para blogs técnicos combinando estes 2 conceitos&amp;rdquo;. Dessa forma, você poderá gerar um número infinito de ideias de artigos inovadores, com perspectivas que você talvez nunca pensasse sozinho.&lt;/p>
&lt;h2 id="8-arquitetura-geral-do-sistema">8. Arquitetura Geral do Sistema
&lt;/h2>&lt;p>O processo que exploramos até agora visando evitar a &amp;ldquo;falta de ideias&amp;rdquo; na criação de publicações técnicas foi detalhado no fluxograma Mermaid abaixo, abrangendo desde a &amp;ldquo;coleta de informações até a criação de ideias&amp;rdquo; em uma arquitetura completa:&lt;/p>
&lt;pre class="mermaid">
flowchart TD
A[&amp;#34;Hacker News / Lobsters API&amp;#34;] --&amp;gt;|Script de extração em Python| B[&amp;#34;Dados de tendências brutos&amp;#34;]
C[&amp;#34;GitHub Actions (Cron)&amp;#34;] --&amp;gt;|Agendamento de execução regular| A
B --&amp;gt;|Conversão para o formato Markdown| D[&amp;#34;Daily Inputs (Fleeting Notes)&amp;#34;]
D --&amp;gt;|Trabalho manual de leitura e resumo| E[&amp;#34;Obsidian Zettelkasten&amp;#34;]
E --&amp;gt;|Criação de Notas Permanentes| F[&amp;#34;Permanent Notes&amp;#34;]
F --&amp;gt;|Processo de sincronização automática| G[&amp;#34;OpenAI Embeddings API&amp;#34;]
G --&amp;gt;|Conversão em vetores| H[&amp;#34;Pinecone Vector Database&amp;#34;]
H --&amp;gt;|Busca Semântica| I[&amp;#34;Descoberta e extração de conhecimento relevante&amp;#34;]
F --&amp;gt;|Criação de Flashcards| J[&amp;#34;Anki (Spaced Repetition)&amp;#34;]
J --&amp;gt;|Inspiração da memória de longo prazo| K[&amp;#34;Combinatorial Creativity&amp;#34;]
I --&amp;gt; K
K --&amp;gt;|Criação de Estruturas e Roteiros| L[&amp;#34;Blog Post Draft (Escrita do Artigo)&amp;#34;]
&lt;/pre>
&lt;p>A principal característica deste sistema é que &lt;strong>&amp;ldquo;As funções intelectuais que exigem esforço manual (resumir, interpretar e escrever)&amp;rdquo; e as &amp;ldquo;tarefas que devem ser deixadas para a máquina (buscas, coletas e agendamento de repetições espaçadas)&amp;rdquo; estão completamente separadas&lt;/strong>. Esse fator possibilita ao escritor focar naquilo que agrega mais valor: &amp;ldquo;pensar&amp;rdquo; e &amp;ldquo;combinar&amp;rdquo;.&lt;/p>
&lt;h2 id="9-modelo-de-transição-de-estado-da-ideia-à-publicação">9. Modelo de Transição de Estado: Da Ideia à Publicação
&lt;/h2>&lt;p>O ciclo de vida das ideias acumuladas no Zettelkasten, desde sua concepção até se tornarem artigos finais em um blog, pode ser representado no diagrama de transição de estado a seguir. Neste modelo, usaremos as ferramentas apropriadas de acordo com o estado em que nos encontramos:&lt;/p>
&lt;pre class="mermaid">
stateDiagram-v2
[*] --&amp;gt; Capture[&amp;#34;Idea Capture (Captura de Ideias)&amp;#34;]
Capture[&amp;#34;Idea Capture (Captura de Ideias)&amp;#34;] --&amp;gt; Fleeting[&amp;#34;Fleeting Notes (Notas Temporárias)&amp;#34;]
Fleeting[&amp;#34;Fleeting Notes (Notas Temporárias)&amp;#34;] --&amp;gt; Permanent[&amp;#34;Permanent Notes (Notas Permanentes)&amp;#34;]
Permanent[&amp;#34;Permanent Notes (Notas Permanentes)&amp;#34;] --&amp;gt; Brainstorming[&amp;#34;Brainstorming (Busca Semântica por IA)&amp;#34;]
Permanent[&amp;#34;Permanent Notes (Notas Permanentes)&amp;#34;] --&amp;gt; Memorization[&amp;#34;Memorization (Revisão no Anki)&amp;#34;]
Memorization[&amp;#34;Memorization (Revisão no Anki)&amp;#34;] --&amp;gt; Brainstorming[&amp;#34;Brainstorming (Busca Semântica por IA)&amp;#34;]
Brainstorming[&amp;#34;Brainstorming (Busca Semântica por IA)&amp;#34;] --&amp;gt; Outlining[&amp;#34;Outlining (Criação de Índice e Estrutura)&amp;#34;]
Outlining[&amp;#34;Outlining (Criação de Índice e Estrutura)&amp;#34;] --&amp;gt; Drafting[&amp;#34;Drafting (Redação de Rascunho)&amp;#34;]
Drafting[&amp;#34;Drafting (Redação de Rascunho)&amp;#34;] --&amp;gt; Review[&amp;#34;Review &amp;amp; Edit (Revisão e Edição)&amp;#34;]
Review[&amp;#34;Review &amp;amp; Edit (Revisão e Edição)&amp;#34;] --&amp;gt; Published[&amp;#34;Published (Publicação no Blog)&amp;#34;]
Published[&amp;#34;Published (Publicação no Blog)&amp;#34;] --&amp;gt; [*]
&lt;/pre>
&lt;p>Estar ciente desse fluxo de trabalho o ajudará a descobrir claramente: &amp;ldquo;Em qual fase estou travado agora?&amp;rdquo;. Se você não conseguir ter novas ideias, você pode sempre voltar para a fase &amp;ldquo;Capture&amp;rdquo; ou &amp;ldquo;Permanent&amp;rdquo; e verificar se o seu pipeline de input está funcionando perfeitamente.&lt;/p>
&lt;h2 id="conclusão-escrever-é-um-sistema">Conclusão: Escrever é um &amp;ldquo;Sistema&amp;rdquo;
&lt;/h2>&lt;p>A &amp;ldquo;falta de ideias para o blog técnico&amp;rdquo; não se deve à falta de habilidade individual ou perda de motivação, mas sim é o &lt;strong>resultado inevitável da falta da construção de um sistema de circulação do conhecimento&lt;/strong>.&lt;/p>
&lt;p>Conforme apresentado neste artigo:&lt;/p>
&lt;ol>
&lt;li>Utilização de &lt;strong>APIs e automação&lt;/strong> para assegurar um input de alta qualidade e com pouco ruído&lt;/li>
&lt;li>Transformação do conhecimento em uma rede usando o método Zettelkasten no &lt;strong>Obsidian&lt;/strong>&lt;/li>
&lt;li>Busca semântica de nossos próprios ativos utilizando &lt;strong>OpenAI e Pinecone&lt;/strong>&lt;/li>
&lt;li>Fortalecimento da indexação mental explorando a curva de esquecimento de Ebbinghaus com o &lt;strong>Anki&lt;/strong>&lt;/li>
&lt;li>&lt;strong>Criatividade combinatória&lt;/strong> para entrelaçar conceitos já existentes&lt;/li>
&lt;/ol>
&lt;p>Ao construir um pipeline abrangente que combina esses elementos, em vez de esgotar as ideias para o blog, você pode criar um estado onde, quanto mais você escreve, mais as novas ideias se multiplicam por si sementes.&lt;/p>
&lt;p>Você não precisa construir tudo perfeitamente desde o início. Comece criando um script simples que consulta a API do Hacker News e adquirindo o hábito de fazer anotações em Markdown dos artigos que lhe interessam. Esperamos que seu blog técnico se torne uma excelente fonte de ideias inovadoras para a próxima geração.&lt;/p></description></item><item><title>Como hospedar um blog Hugo grátis e super rápido no Cloudflare Pages ou GitHub Pages</title><link>http://kenji.blog/pt/p/hugo-hosting-cloudflare-vs-github-pages/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/pt/p/hugo-hosting-cloudflare-vs-github-pages/</guid><description>&lt;img src="http://kenji.blog/p/hugo-hosting-cloudflare-vs-github-pages/img/eyecatch.jpg" alt="Featured image of post Como hospedar um blog Hugo grátis e super rápido no Cloudflare Pages ou GitHub Pages" />&lt;p>Ao gerenciar um site ou blog, a velocidade de carregamento (desempenho), os custos operacionais e a segurança são fatores extremamente importantes. No passado, a combinação de um CMS dinâmico (Content Management System) como o WordPress e um servidor de hospedagem era predominante, mas hoje a arquitetura chamada &amp;ldquo;Jamstack&amp;rdquo; está atraindo muita atenção. Entre as opções, combinando o &amp;ldquo;Hugo&amp;rdquo; - um gerador de sites estáticos (SSG) ultrarrápido escrito em Go - com serviços de hospedagem modernos como o Cloudflare Pages e o GitHub Pages, é possível construir um ambiente de blog &lt;strong>totalmente gratuito e incrivelmente rápido&lt;/strong>.&lt;/p>
&lt;p>Neste artigo, explicaremos a fundo, sob uma perspectiva técnica, as etapas específicas para publicar um site estático usando Hugo no Cloudflare Pages ou GitHub Pages, as diferenças na arquitetura de cada plataforma, a construção de CI/CD (Integração Contínua/Implantação Contínua) usando o GitHub Actions, a otimização de DNS, estratégias de cache e até a introdução de análises de acesso que respeitam a privacidade.&lt;/p>
&lt;hr>
&lt;h2 id="1-o-básico-sobre-geradores-de-sites-estáticos-ssg-e-jamstack">1. O Básico sobre Geradores de Sites Estáticos (SSG) e Jamstack
&lt;/h2>&lt;h3 id="11-por-que-sites-estáticos">1.1 Por que sites estáticos?
&lt;/h3>&lt;p>Sistemas de CMS dinâmicos tradicionais (ex: WordPress) enviam consultas a um banco de dados (como MySQL) e geram o HTML dinamicamente no lado do servidor (como PHP) para cada solicitação do usuário. Embora esse método seja altamente flexível, ele possui baixa tolerância a picos repentinos de tráfego (ou seja, quando algo viraliza ou ataques DDoS) e frequentemente exige uma arquitetura de infraestrutura complexa, como colocar servidores de cache (Redis ou Varnish) na frente.&lt;/p>
&lt;p>Por outro lado, geradores de sites estáticos (SSG) que adotam a arquitetura Jamstack (JavaScript, APIs e Markup) geram antecipadamente (no momento do build) todos os arquivos HTML, CSS e JavaScript. Para as solicitações do usuário, o servidor web (ou CDN) simplesmente retorna os arquivos estáticos já gerados, o que permite alcançar uma velocidade impressionante e segurança robusta.&lt;/p>
&lt;h3 id="12-a-vantagem-do-hugo">1.2 A Vantagem do Hugo
&lt;/h3>&lt;p>Há várias opções de SSG, como Next.js, Gatsby, Jekyll e Astro, mas a maior característica do Hugo é a sua &lt;strong>velocidade de compilação&lt;/strong>. Beneficiando-se do processamento simultâneo fornecido pela linguagem Go, a compilação é concluída em apenas alguns segundos, mesmo para sites com milhares a dezenas de milhares de páginas. Isso reduz drasticamente o tempo de espera no pipeline de CI/CD e está diretamente ligado à melhoria da experiência do desenvolvedor (DX: Developer Experience).&lt;/p>
&lt;hr>
&lt;h2 id="2-comparação-da-arquitetura-dos-serviços-de-hospedagem">2. Comparação da Arquitetura dos Serviços de Hospedagem
&lt;/h2>&lt;p>A próxima questão é onde hospedar os arquivos estáticos gerados pelo Hugo. Opções típicas incluem o Cloudflare Pages, o GitHub Pages e o Netlify, mas a arquitetura de rede por trás de cada um deles difere.&lt;/p>
&lt;h3 id="21-cdn-e-computação-de-borda-edge-computing">2.1 CDN e Computação de Borda (Edge Computing)
&lt;/h3>&lt;p>Todas essas plataformas utilizam uma CDN (Content Delivery Network) distribuída globalmente para entregar conteúdo. No entanto, além do simples armazenamento em cache de arquivos estáticos, o fator de diferenciação é se elas podem executar roteamento de solicitações e reescrita de cabeçalhos no PoP (Point of Presence) mais próximo do usuário, usando a &amp;ldquo;computação de borda&amp;rdquo;.&lt;/p>
&lt;pre class="mermaid">
graph TD
A[&amp;#34;Usuário (Tóquio)&amp;#34;] --&amp;gt;|Baixa Latência| B[&amp;#34;Nó de Borda (NRT)&amp;#34;]
C[&amp;#34;Usuário (Nova York)&amp;#34;] --&amp;gt;|Baixa Latência| D[&amp;#34;Nó de Borda (EWR)&amp;#34;]
E[&amp;#34;Usuário (Londres)&amp;#34;] --&amp;gt;|Baixa Latência| F[&amp;#34;Nó de Borda (LHR)&amp;#34;]
B --&amp;gt; G[&amp;#34;Armazenamento de Origem / Object Store&amp;#34;]
D --&amp;gt; G
F --&amp;gt; G
&lt;/pre>
&lt;h3 id="22-github-pages">2.2 GitHub Pages
&lt;/h3>&lt;p>O GitHub Pages é um serviço que permite publicar arquivos HTML, CSS e JavaScript diretamente de um repositório GitHub. Por trás dele, são utilizadas CDNs como o Fastly, entregando um desempenho adequado. Contudo, possui recursos de infraestrutura pura mais limitados, havendo restrições quanto à personalização de cabeçalhos (ex: configuração de &lt;code>Cache-Control&lt;/code> ou cabeçalhos de segurança), além de que as configurações de redirecionamento dependem de atualizações meta do HTML ou de plugins do Jekyll.&lt;/p>
&lt;h3 id="23-cloudflare-pages">2.3 Cloudflare Pages
&lt;/h3>&lt;p>O Cloudflare Pages é um serviço de hospedagem de sites estáticos construído na maior rede Anycast do mundo (presente em mais de 275 cidades), orgulhosamente fornecida pela Cloudflare.
Ele permite ajustes de desempenho esmagadores, como o suporte padrão ao HTTP/3 (QUIC), otimização de imagens e a integração de funções de borda (Cloudflare Workers). Além disso, não há cobrança por largura de banda, o que significa que pode ser operado gratuitamente independentemente de quão repentinamente o tráfego aumentar, sendo esta uma grande vantagem.&lt;/p>
&lt;h3 id="24-netlify">2.4 Netlify
&lt;/h3>&lt;p>O Netlify é um pioneiro no modelo Jamstack, fornecendo uma DX tudo-em-um que integra funcionalidades de formulário, autenticação (Identity), funções serverless (sem servidor), entre outras. Porém, caso a largura de banda ultrapasse a cota gratuita (100 GB por mês), são geradas cobranças baseadas no consumo que podem ser altas, de modo que é necessário ter cuidado com o controle de custos em blogs que utilizam muitas imagens e vídeos.&lt;/p>
&lt;hr>
&lt;h2 id="3-cálculo-teórico-de-desempenho-e-latência-modelo-matemático-com-latex">3. Cálculo Teórico de Desempenho e Latência (Modelo Matemático com LaTeX)
&lt;/h2>&lt;p>Ao avaliar o desempenho web, a redução da latência (Latency) é o indicador mais importante. Vamos modelar o quanto a latência pode ser reduzida utilizando uma CDN (Borda) em comparação ao acesso direto ao servidor de origem.&lt;/p>
&lt;p>Definiremos a probabilidade da requisição do usuário atingir o cache como a &amp;ldquo;Taxa de Acertos de Cache&amp;rdquo; (Cache Hit Ratio), denotada por $C$, onde $0 \le C \le 1$.
Seja a latência até o servidor de origem $L_{origin}$, e a latência até o nó de borda mais próximo $L_{edge}$.&lt;/p>
&lt;p>A nova latência média $L_{new}$ é calculada como o seguinte valor esperado:&lt;/p>
$$ L_{new} = C \times L_{edge} + (1 - C) \times (L_{edge} + L_{origin}) $$&lt;p>Simplificando esta fórmula, temos:&lt;/p>
$$ L_{new} = L_{edge} + (1 - C) \times L_{origin} $$&lt;p>Por exemplo, se um usuário em Tóquio acessar um servidor de origem localizado na costa leste dos Estados Unidos (Nova York), levando em conta a distância física da fibra óptica e o atraso de processamento nos roteadores, $L_{origin}$ será de aproximadamente 200 ms. Por outro lado, utilizando uma CDN como a Cloudflare, é possível conectar-se ao nó de borda de Tóquio, reduzindo $L_{edge}$ para cerca de 10 ms.&lt;/p>
&lt;p>Supondo uma taxa de acertos de cache $C = 0.95$ (95%),&lt;/p>
$$ L_{new} = 10 + (1 - 0.95) \times 200 = 10 + 0.05 \times 200 = 10 + 10 = 20 \text{ ms} $$&lt;p>Dessa forma, com a introdução da CDN, torna-se possível reduzir drasticamente (em cerca de 90%) a latência média, de 210 ms para 20 ms.&lt;/p>
&lt;hr>
&lt;h2 id="4-construção-de-um-pipeline-cicd-com-github-actions">4. Construção de um Pipeline CI/CD com GitHub Actions
&lt;/h2>&lt;p>Para automatizar o processo de atualização de um blog Hugo, construiremos um pipeline CI/CD utilizando o GitHub Actions. Com isso, basta escrever artigos em Markdown localmente e dar um &lt;code>git push&lt;/code> para que o processo de compilação execute automaticamente e o site seja implantado no Cloudflare Pages ou GitHub Pages.&lt;/p>
&lt;p>O diagrama de sequência a seguir mostra todo o fluxo, desde o envio do artigo (Push) até sua entrega aos usuários.&lt;/p>
&lt;pre class="mermaid">
sequenceDiagram
participant U as &amp;#34;Usuário (Autor)&amp;#34;
participant G as &amp;#34;Repositório GitHub&amp;#34;
participant A as &amp;#34;GitHub Actions&amp;#34;
participant C as &amp;#34;Cloudflare Pages&amp;#34;
participant V as &amp;#34;Visitante&amp;#34;
U-&amp;gt;&amp;gt;G: &amp;#34;git push origin main&amp;#34;
G-&amp;gt;&amp;gt;A: &amp;#34;Acionar Evento Push&amp;#34;
A-&amp;gt;&amp;gt;A: &amp;#34;Checkout e Configurar Hugo&amp;#34;
A-&amp;gt;&amp;gt;A: &amp;#34;hugo --minify (Build)&amp;#34;
A-&amp;gt;&amp;gt;C: &amp;#34;Implantar no Cloudflare Pages (Upload Direto)&amp;#34;
C--&amp;gt;&amp;gt;A: &amp;#34;URL de Implantação (Sucesso)&amp;#34;
V-&amp;gt;&amp;gt;C: &amp;#34;Solicitar Página Web&amp;#34;
C--&amp;gt;&amp;gt;V: &amp;#34;Retornar HTML em Cache (Borda)&amp;#34;
&lt;/pre>
&lt;h3 id="41-configuração-de-implantação-para-o-cloudflare-pages-upload-direto">4.1 Configuração de Implantação para o Cloudflare Pages (Upload Direto)
&lt;/h3>&lt;p>O Cloudflare Pages possui dois métodos: vincular um repositório GitHub para que a compilação ocorra na infraestrutura da Cloudflare, ou fazer o &amp;ldquo;Direct Upload&amp;rdquo; (Upload Direto) dos arquivos estáticos previamente compilados com o GitHub Actions. Se você deseja controlar a versão do Hugo com mais rigor e vincular o processo a outras tarefas (testes e otimização de imagens), é recomendável o método de compilação no GitHub Actions e Upload Direto.&lt;/p>
&lt;p>Abaixo, um exemplo prático do arquivo &lt;code>.github/workflows/deploy.yml&lt;/code> para implantação no Cloudflare Pages.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Deploy Hugo site to Cloudflare Pages&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">push&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">branches&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;main&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">workflow_dispatch&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">jobs&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">build-and-deploy&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">runs-on&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;ubuntu-latest&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">steps&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Checkout repository&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;actions/checkout@v4&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">submodules&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;recursive&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">fetch-depth&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="m">0&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Setup Hugo&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;peaceiris/actions-hugo@v3&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">hugo-version&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;0.125.0&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">extended&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="kc">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Build Hugo Site&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">run&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;hugo --minify --gc&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">env&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">HUGO_ENVIRONMENT&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;production&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;Deploy to Cloudflare Pages&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">uses&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;cloudflare/pages-action@v1&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">with&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">apiToken&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ secrets.CLOUDFLARE_API_TOKEN }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">accountId&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ secrets.CLOUDFLARE_ACCOUNT_ID }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">projectName&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;your-project-name&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">directory&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;public&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">gitHubToken&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">${{ secrets.GITHUB_TOKEN }}&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">branch&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;main&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Neste pipeline, utilizamos a opção &lt;code>--minify&lt;/code> para minificar HTML/CSS/JS e &lt;code>--gc&lt;/code> para remover arquivos desnecessários. Esses são os fundamentos da otimização de desempenho.&lt;/p>
&lt;hr>
&lt;h2 id="5-mergulho-profundo-nas-configurações-de-dns-domínios-personalizados-e-registros-cname--alias">5. Mergulho Profundo nas Configurações de DNS: Domínios Personalizados e Registros CNAME / ALIAS
&lt;/h2>&lt;p>Ao utilizar um domínio personalizado (ex: &lt;code>kenji.blog&lt;/code>), a configuração adequada do DNS (Domain Name System) é essencial.&lt;/p>
&lt;h3 id="51-restrições-dos-registros-cname-e-zone-apex">5.1 Restrições dos Registros CNAME e Zone Apex
&lt;/h3>&lt;p>Normalmente, para apontar um subdomínio (ex: &lt;code>www.kenji.blog&lt;/code>) para um serviço externo, usa-se um registro &lt;code>CNAME&lt;/code>. Contudo, devido à especificação do DNS (RFC 1034), não é possível definir um registro &lt;code>CNAME&lt;/code> no domínio raiz (também conhecido como Zone Apex ou naked domain, ex: &lt;code>kenji.blog&lt;/code>). Isso ocorre porque o Zone Apex deve, obrigatoriamente, conter um registro SOA (Start of Authority), registros NS (Name Server) ou MX (Mail Exchange), e há uma regra de que o CNAME não pode coexistir com outros registros de recurso.&lt;/p>
&lt;h3 id="52-a-solução-alias--aname--cname-flattening">5.2 A Solução: ALIAS / ANAME / CNAME Flattening
&lt;/h3>&lt;p>Para resolver esse problema, os provedores de DNS modernos oferecem suas próprias extensões:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Registros ALIAS / ANAME&lt;/strong>: O servidor DNS realiza dinamicamente a resolução de nomes no lado do servidor e retorna os registros A finais (endereços IP) para o cliente. Serviços como o Amazon Route 53 suportam isso.&lt;/li>
&lt;li>&lt;strong>CNAME Flattening&lt;/strong>: Um recurso fornecido pela Cloudflare. Ele atua como se um CNAME fosse configurado para a Zone Apex, mas o servidor DNS autoritativo da Cloudflare retorna de forma transparente para o cliente o conjunto de endereços IP (registros A e AAAA) que foram resolvidos automaticamente.&lt;/li>
&lt;/ul>
&lt;p>Ao utilizar o Cloudflare Pages, delegar os servidores de nomes (nameservers) do seu domínio para a Cloudflare e aproveitar este &amp;ldquo;CNAME Flattening&amp;rdquo; é a configuração mais perfeita e de maior desempenho.&lt;/p>
&lt;hr>
&lt;h2 id="6-estratégias-de-cache-e-controle-de-cabeçalhos-http">6. Estratégias de Cache e Controle de Cabeçalhos HTTP
&lt;/h2>&lt;p>Outro pilar na aceleração de sites estáticos é a &amp;ldquo;Estratégia de Cache&amp;rdquo;. Com o Cloudflare Pages, utilizando o arquivo gerado (arquivo &lt;code>_headers&lt;/code>), é possível ter um controle preciso dos cabeçalhos HTTP de resposta.&lt;/p>
&lt;h3 id="61-cache-de-borda-edge-cache-vs-cache-do-navegador-browser-cache">6.1 Cache de Borda (Edge Cache) vs Cache do Navegador (Browser Cache)
&lt;/h3>&lt;p>O cache é amplamente dividido em dois tipos: o &amp;ldquo;Edge Cache&amp;rdquo; mantido pelo lado da CDN e o &amp;ldquo;Browser Cache&amp;rdquo; armazenado no navegador do usuário.&lt;/p>
&lt;p>Para os arquivos estáticos (como imagens, CSS e JS que contêm hashes no nome do arquivo), o ideal é que eles sejam mantidos no cache do navegador por longos períodos. Por outro lado, para arquivos HTML, a fim de que as atualizações sejam refletidas imediatamente, a prática comum é ter um tempo de cache de navegador muito curto (ou até mesmo desativado), lidando com essas requisições por meio do edge cache.&lt;/p>
&lt;p>Exemplo de configuração do arquivo &lt;code>_headers&lt;/code> no Cloudflare Pages:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;span class="lnt">8
&lt;/span>&lt;span class="lnt">9
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"># Arquivos HTML não usarão o cache do navegador e serão validados sempre
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/*.html
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Cache-Control: public, max-age=0, must-revalidate
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># Arquivos de recursos (CSS/JS/Imagens) ficarão no cache do navegador por 1 ano
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/assets/*
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Cache-Control: public, max-age=31536000, immutable
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">/img/*
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> Cache-Control: public, max-age=31536000, immutable
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="62-fórmula-para-cálculo-de-redução-dos-custos-com-largura-de-banda">6.2 Fórmula para Cálculo de Redução dos Custos com Largura de Banda
&lt;/h3>&lt;p>Ao configurar cabeçalhos de cache apropriados, o volume de transferência de dados do servidor (borda) pode ser drasticamente reduzido. O custo mensal com largura de banda $Cost$ pode ser expresso pelo seguinte modelo, dependendo do volume de transferência $B_i$ de cada recurso, da taxa de acertos do cache $C_i$ e do preço unitário da largura de banda $R$:&lt;/p>
$$ Cost = \sum_{i=1}^{n} \left( B_i \times (1 - C_i) \times R \right) $$&lt;p>Como a taxa de transferência de saída da Cloudflare é gratuita ($R = 0$), o custo monetário direto é $0$. Porém, ao utilizar outras infraestruturas simultaneamente como o GitHub Pages, ou usar serviços como o AWS S3 como backend, maximizar essa taxa de acertos de cache $C_i$ se torna o pilar para a redução dos custos da infraestrutura.&lt;/p>
&lt;hr>
&lt;h2 id="7-análise-de-acesso-que-equilibra-privacidade-e-desempenho">7. Análise de Acesso que Equilibra Privacidade e Desempenho
&lt;/h2>&lt;p>Ao gerir um blog, a análise de acesso (Web Analytics) é essencial para saber quantos usuários o estão visitando. O Google Analytics (GA4) foi o padrão da indústria por muito tempo, mas com a recente tendência voltada para a proteção de privacidade (GDPR, CCPA) e a depreciação dos cookies de terceiros, o cenário está mudando.&lt;/p>
&lt;h3 id="71-impacto-no-desempenho-da-web">7.1 Impacto no Desempenho da Web
&lt;/h3>&lt;p>A adoção do Google Analytics (especificamente o &lt;code>gtag.js&lt;/code> e o Google Tag Manager) resulta no carregamento e execução de inúmeros scripts externos, prejudicando o desempenho (especialmente o tempo de TTFB e o tempo de bloqueio da thread principal).&lt;/p>
&lt;p>Vamos tentar dividir e considerar o tempo de carregamento de um site da seguinte maneira:&lt;/p>
&lt;pre class="mermaid">
pie title Repartição Típica do Tempo de Carregamento do Site
&amp;#34;TTFB (Time to First Byte)&amp;#34; : 15
&amp;#34;Download de Conteúdo (HTML/CSS)&amp;#34; : 20
&amp;#34;DOM Parsing &amp;amp; Renderização&amp;#34; : 45
&amp;#34;Analytics &amp;amp; JS de Terceiros&amp;#34; : 20
&lt;/pre>
&lt;p>Não é raro que ferramentas analíticas JS de terceiros representem entre cerca de 20% a 30% do tempo total de carregamento.&lt;/p>
&lt;h3 id="72-implementando-o-cloudflare-web-analytics">7.2 Implementando o Cloudflare Web Analytics
&lt;/h3>&lt;p>Assim, ferramentas de análises de acesso que colocam a privacidade em primeiro lugar e não utilizam cookies (Cookieless), como o Cloudflare Web Analytics e o Plausible Analytics, vêm chamando a atenção.&lt;/p>
&lt;p>O Cloudflare Web Analytics funciona apenas com a incorporação de um snippet de JavaScript extremamente leve e, como não emite cookies, evita a necessidade de colocar os incômodos banners de consentimento de cookies (Cookie Consent Banner).&lt;/p>
&lt;p>A implementação no Hugo também é muito simples. Basta adicionar o snippet fornecido nos arquivos &lt;code>layouts/partials/head.html&lt;/code> ou &lt;code>layouts/partials/analytics.html&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">{{ if eq hugo.Environment &amp;#34;production&amp;#34; }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- Cloudflare Web Analytics --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">defer&lt;/span> &lt;span class="na">src&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#39;https://static.cloudflareinsights.com/beacon.min.js&amp;#39;&lt;/span> &lt;span class="na">data-cf-beacon&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#39;{&amp;#34;token&amp;#34;: &amp;#34;YOUR_CLOUDFLARE_BEACON_TOKEN&amp;#34;}&amp;#39;&lt;/span>&lt;span class="p">&amp;gt;&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- End Cloudflare Web Analytics --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Adicionando o atributo &lt;code>defer&lt;/code>, o script é carregado de forma assíncrona sem bloquear a análise (parsing) do HTML e executado após a construção do DOM. Dessa forma, é possível minimizar os impactos na velocidade de renderização inicial (LCP: Largest Contentful Paint e FCP: First Contentful Paint).&lt;/p>
&lt;hr>
&lt;h2 id="8-conclusão-e-melhores-práticas">8. Conclusão e Melhores Práticas
&lt;/h2>&lt;p>Na operação de sites estáticos usando o Hugo, a adoção de plataformas de hospedagem modernas como o Cloudflare Pages e o GitHub Pages possui vantagens esmagadoras em termos de relação custo-benefício, velocidade de exibição e segurança.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Compilação Extremamente Rápida&lt;/strong>: Aproveitar a velocidade do Hugo para minimizar o tempo de execução do pipeline de CI/CD (GitHub Actions).&lt;/li>
&lt;li>&lt;strong>Distribuição na Borda&lt;/strong>: Usar a rede de borda da Cloudflare para entregar conteúdo a usuários em todo o mundo com latência de milissegundos.&lt;/li>
&lt;li>&lt;strong>Configuração Apropriada de DNS&lt;/strong>: Aproveitar o CNAME Flattening para operar a Zone Apex (seu domínio personalizado) de forma segura e rápida.&lt;/li>
&lt;li>&lt;strong>Otimização de Estratégias de Cache&lt;/strong>: Usar o arquivo &lt;code>_headers&lt;/code> para separar adequadamente o cache de navegador do cache de borda, dependendo do tipo de recurso.&lt;/li>
&lt;li>&lt;strong>Analytics Mais Leves&lt;/strong>: Implementar opções como o Cloudflare Web Analytics, que respeitam a privacidade enquanto não comprometem o desempenho.&lt;/li>
&lt;/ol>
&lt;p>Combinando tudo isso, é possível construir de forma gratuita um sistema de blog escalável e robusto, capaz de suportar tráfegos de larga escala (de milhões de pageviews mensais). Se você está considerando iniciar um blog de tecnologia, um site corporativo ou um portfólio, por favor não hesite em testar essa configuração composta por Jamstack, Hugo e Cloudflare Pages.&lt;/p></description></item><item><title>Estratégia para reescrever artigos técnicos antigos usando o Google Search Console</title><link>http://kenji.blog/pt/p/google-search-console-rewrite-strategy/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/pt/p/google-search-console-rewrite-strategy/</guid><description>&lt;img src="http://kenji.blog/p/google-search-console-rewrite-strategy/img/eyecatch.jpg" alt="Featured image of post Estratégia para reescrever artigos técnicos antigos usando o Google Search Console" />&lt;h2 id="1-introdução-a-importância-da-reescrita-e-uma-abordagem-baseada-em-dados-em-blogs-técnicos">1. Introdução: A importância da reescrita e uma abordagem baseada em dados em blogs técnicos
&lt;/h2>&lt;p>Ao gerenciar um blog técnico ou mídia própria voltada para desenvolvedores, a &amp;ldquo;reescrita de artigos antigos&amp;rdquo; é tão ou mais importante do que a escrita contínua de novos artigos. Especialmente em tópicos técnicos e de TI, as informações se tornam obsoletas rapidamente, e não é incomum que trechos de código ou especificações de API escritos há alguns anos sejam agora descontinuados (Deprecated). No entanto, atualizar cegamente artigos antigos não maximizará o tráfego (visitas) dos motores de busca.&lt;/p>
&lt;p>Neste artigo, explicarei uma estratégia avançada para identificar quais artigos técnicos devem ser reescritos e melhorar drasticamente as classificações de pesquisa e taxas de cliques (CTR). Para isso, usaremos dados do &lt;strong>Google Search Console (doravante GSC)&lt;/strong> e do &lt;strong>Google Analytics 4 (GA4)&lt;/strong>, adotando uma abordagem matemática e baseada em dados.&lt;/p>
&lt;p>Especificamente, explicarei de forma abrangente desde como usar Python e BigQuery para integrar os dados do GSC e GA4 e encontrar &amp;ldquo;artigos de perda de oportunidade&amp;rdquo; com uma CTR baixa em relação ao número de impressões, até como identificar palavras-chave ausentes nos cabeçalhos H2 e H3 usando a análise TF-IDF de Processamento de Linguagem Natural (PNL) para preencher eficientemente as lacunas de conteúdo.&lt;/p>
&lt;hr>
&lt;h2 id="2-análise-da-lacuna-entre-ctr-esperada-e-ctr-real-introdução-ao-modelo-matemático">2. Análise da lacuna entre CTR esperada e CTR real (Introdução ao modelo matemático)
&lt;/h2>&lt;p>Um dos indicadores mais básicos em SEO é a &amp;ldquo;taxa de cliques (CTR) em relação à classificação de pesquisa&amp;rdquo;. Geralmente, a CTR para a primeira posição é de cerca de 25-30%, a segunda posição é de cerca de 15%, e diminui acentuadamente a partir daí. Essa relação entre classificação e CTR pode ser modelada como uma distribuição seguindo a Lei de Potência (Power Law).&lt;/p>
&lt;p>Sabe-se que a taxa de cliques esperada $CTR(r)$ para a classificação $r$ pode ser aproximada pela seguinte fórmula:&lt;/p>
$$
CTR(r) = a \cdot r^{-b}
$$&lt;p>Aqui, $a$ representa a CTR esperada para a primeira posição (por exemplo, $0.30$ para 30%) e $b$ é o parâmetro de decaimento (geralmente entre $1.0$ e $1.5$).&lt;/p>
&lt;p>A abordagem mais eficaz para selecionar artigos para reescrever é &lt;strong>encontrar artigos (palavras-chave) onde a &amp;ldquo;CTR real&amp;rdquo; está significativamente abaixo dessa &amp;ldquo;CTR esperada&amp;rdquo;&lt;/strong>. Por exemplo, se a classificação da pesquisa for a 3ª posição (CTR esperada de cerca de 10%), mas a CTR real for de apenas 2%, é muito provável que haja uma incompatibilidade entre a intenção de pesquisa e o título ou descrição, ou que os cliques estejam sendo perdidos por fatores da concorrência, como rich snippets.&lt;/p>
&lt;p>O gráfico a seguir ilustra a divergência entre a CTR esperada e a CTR real em um blog técnico.&lt;/p>
&lt;pre class="mermaid">
xychart-beta
title CTR Esperada vs CTR Real por Posição
x-axis [&amp;#34;1&amp;#34;, &amp;#34;2&amp;#34;, &amp;#34;3&amp;#34;, &amp;#34;4&amp;#34;, &amp;#34;5&amp;#34;, &amp;#34;6&amp;#34;, &amp;#34;7&amp;#34;, &amp;#34;8&amp;#34;, &amp;#34;9&amp;#34;, &amp;#34;10&amp;#34;]
y-axis &amp;#34;CTR (%)&amp;#34; 0 --&amp;gt; 35
line [30.5, 15.2, 10.1, 7.5, 5.2, 4.1, 3.2, 2.5, 2.0, 1.5]
bar [32.1, 14.0, 8.5, 4.0, 5.0, 2.1, 1.5, 1.0, 1.2, 0.5]
&lt;/pre>
&lt;p>(※ A linha representa a CTR esperada e o gráfico de barras mostra a CTR real. Pode-se observar que os valores estão notavelmente abaixo nas posições 4 e 8.)&lt;/p>
&lt;hr>
&lt;h2 id="3-extração-automática-de-dados-de-desempenho-de-pesquisa-usando-a-api-do-gsc-python">3. Extração automática de dados de desempenho de pesquisa usando a API do GSC (Python)
&lt;/h2>&lt;p>Embora seja possível baixar CSVs da interface web do GSC para análise, a melhor abordagem para grandes blogs ou para realizar análises contínuas é construir um sistema que extraia automaticamente os dados usando Python e a API do GSC.&lt;/p>
&lt;p>Abaixo está um snippet de código em Python usando &lt;code>google-api-python-client&lt;/code> para obter dados de desempenho por página e por consulta (cliques, impressões, CTR, posição média) num período específico.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">google.oauth2&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">service_account&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">googleapiclient.discovery&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">get_gsc_data&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">key_path&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">site_url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">start_date&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">end_date&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Carregamento de credenciais e construção do cliente de API&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">credentials&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">service_account&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Credentials&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_service_account_file&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">key_path&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">scopes&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;https://www.googleapis.com/auth/webmasters.readonly&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">service&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">build&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;searchconsole&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;v1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">credentials&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">credentials&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Configuração do payload da requisição de API (especificando página e consulta como dimensões)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">request&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;startDate&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">start_date&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;endDate&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">end_date&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;dimensions&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;page&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;query&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;rowLimit&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">25000&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Execução da API&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">service&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">searchanalytics&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">query&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">siteUrl&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">site_url&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">body&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">request&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">execute&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Extração de dados da resposta e conversão para Pandas DataFrame&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">rows&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;rows&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">[])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">row&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">rows&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">keys&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;keys&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;page&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">keys&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;query&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">keys&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;clicks&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;clicks&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;impressions&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;impressions&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;ctr&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;ctr&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;position&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;position&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Exemplo de execução&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># df_gsc = get_gsc_data(&amp;#39;credentials.json&amp;#39;, &amp;#39;https://kenji.blog/&amp;#39;, &amp;#39;2026-08-01&amp;#39;, &amp;#39;2026-08-31&amp;#39;)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># print(df_gsc.head())&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Com este script, os dados detalhados vinculando URLs de páginas e consultas de pesquisa podem ser obtidos como um DataFrame. Isso torna possível entender de forma abrangente para quais palavras-chave artigos específicos estão aparecendo.&lt;/p>
&lt;hr>
&lt;h2 id="4-filtrando-palavras-chave-técnicas-com-expressões-regulares-regex">4. Filtrando palavras-chave técnicas com Expressões Regulares (Regex)
&lt;/h2>&lt;p>Uma funcionalidade muito poderosa na análise de blogs técnicos é o &lt;strong>filtro de expressões regulares (Regex)&lt;/strong> do GSC.
Por exemplo, se você escreve artigos variando de frontend a backend e infraestrutura, pode querer extrair apenas &amp;ldquo;artigos de tutoriais ou de erros relacionados a Python e Pandas&amp;rdquo; para priorizar a reescrita.&lt;/p>
&lt;p>Usando filtros de expressões regulares personalizadas no GSC, você pode restringir consultas sob condições complexas.&lt;/p>
&lt;p>&lt;strong>Exemplos de filtragem de palavras-chave técnicas:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Investigação de erros relacionados ao Python: &lt;code>^(python|pandas|numpy|matplotlib).* (error|exception|bug|erro|não funciona)&lt;/code>&lt;/li>
&lt;li>Construção de infraestrutura AWS: &lt;code>(aws|amazon web services|ec2|s3|lambda).* (construção|configuração|tutorial|tutorial|how to)&lt;/code>&lt;/li>
&lt;li>Atualização de versão de biblioteca específica: &lt;code>(react|vue|angular) (v17|v18|v3) (migration|migração|transição)&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Para incorporar isso numa requisição da API do GSC, você utiliza o &lt;code>dimensionFilterGroups&lt;/code> para adicionar a condição da expressão regular. Fazendo uso intensivo dessa filtragem, você consegue extrair com precisão palavras-chave altamente valiosas orientadas para a solução de problemas, que os desenvolvedores estão &amp;ldquo;buscando justamente agora por estarem com dificuldades&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="5-integração-de-dados-ga4-e-gsc-via-bigquerypandas">5. Integração de dados GA4 e GSC via BigQuery/Pandas
&lt;/h2>&lt;p>Os dados do GSC informam apenas a &amp;ldquo;classificação de pesquisa e taxa de cliques&amp;rdquo;. Para descobrir &amp;ldquo;quanto tempo os usuários que chegaram àquele artigo realmente permaneceram e se chegaram à conversão (ex: navegação para um repositório GitHub ou assinatura de newsletter)&amp;rdquo;, é necessário integrar (JOIN) com os dados do &lt;strong>Google Analytics 4 (GA4)&lt;/strong>.&lt;/p>
&lt;p>Se você está armazenando dados de exportação do GA4 e dados de exportação em massa do GSC no BigQuery, pode combiná-los usando uma consulta SQL como a seguinte. Isso permite extrair &amp;ldquo;artigos com muitas impressões e uma classificação razoável, mas que têm alta taxa de rejeição e curto tempo de engajamento&amp;rdquo;.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">WITH&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">gsc_data&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">SUM&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">impressions&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">total_impressions&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">SUM&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">clicks&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">total_clicks&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">AVG&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">sum_top_position&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">avg_position&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="o">`&lt;/span>&lt;span class="n">project&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">searchconsole&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">searchdata_url_impression&lt;/span>&lt;span class="o">`&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">data_date&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BETWEEN&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;2026-08-01&amp;#39;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AND&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;2026-08-31&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">GROUP&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">url&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">ga4_data&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">REGEXP_REPLACE&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">string_value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">UNNEST&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">event_params&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">key&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;page_location&amp;#39;&lt;/span>&lt;span class="p">),&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="s1">&amp;#39;^https?://[^/]+&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">COUNT&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">DISTINCT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">user_pseudo_id&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">users&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">AVG&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">value&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">int_value&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">UNNEST&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">event_params&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">key&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;engagement_time_msec&amp;#39;&lt;/span>&lt;span class="p">))&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1000&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">avg_engagement_sec&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="o">`&lt;/span>&lt;span class="n">project&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">analytics_123456789&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">events_&lt;/span>&lt;span class="o">*`&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">event_name&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;page_view&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">GROUP&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_impressions&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_clicks&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">SAFE_DIVIDE&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_clicks&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_impressions&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AS&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">ctr&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">avg_position&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">users&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">avg_engagement_sec&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">gsc_data&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">JOIN&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">ga4_data&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ON&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">page_path&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_impressions&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;gt;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1000&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">AND&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">avg_position&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BETWEEN&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">AND&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">15&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">ORDER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">BY&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">g&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">total_impressions&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">DESC&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Com base nestes resultados, os alvos de reescrita são classificados através da seguinte matriz:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Alta Impressão, Baixo CTR, Alto Engajamento&lt;/strong>:
Artigos em que os leitores ficam satisfeitos desde que cliquem nos resultados de pesquisa. A &lt;strong>modificação do título e da meta descrição&lt;/strong> deve ser feita com prioridade máxima.&lt;/li>
&lt;li>&lt;strong>Alto CTR, Baixo Engajamento&lt;/strong>:
Artigos em que clicam, mas cujo conteúdo decepciona, levando à saída do usuário. É necessária uma reescrita significativa do texto, como &lt;strong>melhorar a introdução, atualizar para o código mais recente ou melhorar a abrangência das informações (adicionar H2/H3)&lt;/strong>.&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="6-análise-de-lacuna-de-conteúdo-usando-pnl-e-tf-idf">6. Análise de lacuna de conteúdo usando PNL e TF-IDF
&lt;/h2>&lt;p>Uma vez identificados os artigos a serem reescritos, o passo seguinte é analisar &amp;ldquo;quais subtítulos exatos (H2/H3) e palavras-chave devem ser adicionados&amp;rdquo;. Em vez de confiar na intuição aqui também, fazemos uso do &lt;strong>TF-IDF (Frequência do Termo - Frequência Inversa do Documento) em Processamento de Linguagem Natural (PNL)&lt;/strong>.&lt;/p>
&lt;p>O TF-IDF é uma estatística para avaliar a importância de uma certa palavra dentro desse documento.&lt;/p>
$$
TF\text{-}IDF(t, d) = tf(t, d) \times \log\left(\frac{N}{df(t)}\right)
$$&lt;p>Onde,&lt;/p>
&lt;ul>
&lt;li>$tf(t, d)$ é a frequência de ocorrência da palavra $t$ no documento $d$&lt;/li>
&lt;li>$N$ é o número total de documentos&lt;/li>
&lt;li>$df(t)$ é o número de documentos em que a palavra $t$ aparece&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Abordagem:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>Obtenha os dados de texto dos top 10 artigos (sites concorrentes) para a palavra-chave alvo através de raspagem (scraping), etc.&lt;/li>
&lt;li>Prepare os dados de texto para o artigo alvo em seu próprio site.&lt;/li>
&lt;li>Usando o &lt;code>TfidfVectorizer&lt;/code> da biblioteca &lt;code>scikit-learn&lt;/code> em Python, extraia palavras-chave (palavras-recurso) que aparecem de forma consistente com altas pontuações no grupo de artigos dos principais concorrentes, mas que não existem (ou têm pontuação notavelmente baixa) no artigo de seu próprio site.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">sklearn.feature_extraction.text&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">TfidfVectorizer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">numpy&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">np&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># documents = [Texto do próprio site, Texto do concorrente 1, Texto do concorrente 2, ...]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Aqui assume-se uma lista de textos já separados por análise morfológica (MeCab, etc.) em japonês&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">extract_missing_keywords&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">documents&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">vectorizer&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">TfidfVectorizer&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">max_df&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mf">0.9&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">min_df&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">tfidf_matrix&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">vectorizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">fit_transform&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">documents&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">feature_names&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">vectorizer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get_feature_names_out&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calcula a pontuação média TF-IDF dos artigos concorrentes (índice 1 em diante)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">competitor_mean_tfidf&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">mean&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">tfidf_matrix&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">:]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">toarray&lt;/span>&lt;span class="p">(),&lt;/span> &lt;span class="n">axis&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Obtém a pontuação TF-IDF do artigo do próprio site (índice 0)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">my_article_tfidf&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">tfidf_matrix&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">toarray&lt;/span>&lt;span class="p">()[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Calcula a lacuna de palavras que são importantes nos concorrentes, mas ausentes (ou poucas) no próprio site&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">gap_scores&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">competitor_mean_tfidf&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">my_article_tfidf&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Extrai as principais palavras onde a lacuna é grande&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df_gap&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s1">&amp;#39;keyword&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">feature_names&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;gap_score&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">gap_scores&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df_gap&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df_gap&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sort_values&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">by&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;gap_score&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">ascending&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">False&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">df_gap&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">head&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">20&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Exemplo: missing_keywords = extract_missing_keywords(processed_docs)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># print(missing_keywords)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Através dessa análise, você pode descobrir quantitativamente &lt;strong>lacunas de tópicos (lacunas de conteúdo)&lt;/strong>, tais como &amp;ldquo;na verdade, os principais artigos mencionam sobre &amp;lsquo;como implantar em contêineres Docker&amp;rsquo; e &amp;lsquo;construir um pipeline CI/CD&amp;rsquo;, mas não toco nisso no meu artigo&amp;rdquo;.&lt;/p>
&lt;p>O conjunto de palavras-chave importantes descobertas não deve ser simplesmente espalhado no texto, mas sim adicionado como seções significativas como &lt;strong>cabeçalhos H2 e H3 (tags de Heading)&lt;/strong>. Escrever explicações técnicas detalhadas e trechos de código para esses cabeçalhos pode melhorar drasticamente a avaliação do Google.&lt;/p>
&lt;hr>
&lt;h2 id="7-pipeline-de-dados-e-ciclo-de-melhoria-contínua">7. Pipeline de dados e ciclo de melhoria contínua
&lt;/h2>&lt;p>O processo explicado até agora não acaba após uma única execução; transformá-lo num pipeline e executá-lo de forma contínua é a chave do sucesso em SEO. A arquitetura geral e o fluxo operacional são exibidos num fluxograma Mermaid abaixo.&lt;/p>
&lt;pre class="mermaid">
flowchart TD
A[&amp;#34;Dados da API do GSC (Impressões, Cliques, Posições)&amp;#34;] --&amp;gt; C[&amp;#34;BigQuery / Data Warehouse&amp;#34;]
B[&amp;#34;Dados de Exportação do GA4 (Visualizações de Página, Tempo de Engajamento)&amp;#34;] --&amp;gt; C
C --&amp;gt; D[&amp;#34;Junção e Análise de Dados com Python / Pandas&amp;#34;]
D --&amp;gt; E[&amp;#34;Identificar Artigos com Alta Impressão / Baixo CTR&amp;#34;]
E --&amp;gt; F[&amp;#34;Scraping de Concorrentes com PNL e Extração de Palavras-chave TF-IDF&amp;#34;]
F --&amp;gt; G[&amp;#34;Otimizar Tags H2/H3 e Reescrever Conteúdo&amp;#34;]
G --&amp;gt; H[&amp;#34;Publicar Artigo Atualizado&amp;#34;]
H --&amp;gt; I[&amp;#34;Monitorar Alterações de CTR (Esperado vs Real)&amp;#34;]
I --&amp;gt; |&amp;#34;Loop de Feedback&amp;#34;| A
&lt;/pre>
&lt;p>Ao sistematizar essa série de passos — desde a coleta de dados do GSC e GA4, passando pela seleção de alvos baseada em análise e otimização de conteúdo via PNL, até ao monitoramento dos resultados — o blog torna-se um ativo que continua crescendo de forma automática.&lt;/p>
&lt;hr>
&lt;h2 id="8-conclusão-e-perspectivas-futuras">8. Conclusão e perspectivas futuras
&lt;/h2>&lt;p>Reescrever artigos técnicos utilizando o Google Search Console não é meramente corrigir texto. Trata-se de uma engenharia avançada que faz pleno uso de dados e modelos matemáticos para apresentar uma solução otimizada para a caixa-preta que é o algoritmo do motor de busca.&lt;/p>
&lt;p>Resumindo os métodos explicados neste artigo:&lt;/p>
&lt;ol>
&lt;li>Calcular a disparidade entre a &lt;strong>CTR esperada e a CTR real&lt;/strong> para identificar artigos com um grande impacto para correção.&lt;/li>
&lt;li>Extrair automaticamente dados de desempenho utilizando a &lt;strong>API do GSC e Python&lt;/strong>.&lt;/li>
&lt;li>Integrar com os dados de engajamento do GA4 no &lt;strong>BigQuery&lt;/strong> e corrigir o corpo dos artigos com altas taxas de rejeição.&lt;/li>
&lt;li>Usar a &lt;strong>análise PNL com TF-IDF&lt;/strong> para descobrir lacunas de conteúdo face aos concorrentes e otimizar os cabeçalhos (H2/H3).&lt;/li>
&lt;/ol>
&lt;p>As tendências tecnológicas estão em constante evolução. Para responder de forma precisa aos erros e desafios que os leitores enfrentam atualmente, certifique-se de incorporar uma estratégia de reescrita baseada em dados nas suas operações diárias.&lt;/p></description></item><item><title>O que os engenheiros devem fazer para aumentar os acessos mensais no blog de tecnologia</title><link>http://kenji.blog/pt/p/tech-blog-growth-strategies-for-engineers/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/pt/p/tech-blog-growth-strategies-for-engineers/</guid><description>&lt;img src="http://kenji.blog/p/tech-blog-growth-strategies-for-engineers/img/eyecatch.jpg" alt="Featured image of post O que os engenheiros devem fazer para aumentar os acessos mensais no blog de tecnologia" />&lt;h2 id="introdução-growth-hacking-de-blog-de-tecnologia-que-só-engenheiros-podem-fazer">Introdução: Growth Hacking de blog de tecnologia que só engenheiros podem fazer
&lt;/h2>&lt;p>Muitos engenheiros de software iniciam blogs de tecnologia, mas não são muitos os casos em que conseguem atrair um certo número de acessos e manter/expandir isso por um longo período. Escrever artigos técnicos de alta qualidade é uma premissa básica, mas a era do &amp;ldquo;escreva um bom artigo e ele será lido naturalmente&amp;rdquo; já acabou. Os algoritmos atuais dos mecanismos de busca tornaram-se complexos e o fluxo de informações nas redes sociais está mais rápido do que nunca.&lt;/p>
&lt;p>No entanto, os engenheiros têm vantagens que outras profissões não têm. É o fato de que &amp;ldquo;entendem a arquitetura de sistemas, combinam ferramentas para automatizar e podem analisar dados programaticamente&amp;rdquo;. Neste artigo, em vez de nos limitarmos a meras técnicas de escrita, trataremos o blog de tecnologia como um único &amp;ldquo;produto&amp;rdquo; e explicaremos de forma extremamente detalhada e prática as estratégias para aumentar drasticamente os acessos mensais através do poder da engenharia.&lt;/p>
&lt;hr>
&lt;h2 id="1-arquitetura-de-seo-de-blog-de-tecnologia-para-engenheiros">1. Arquitetura de SEO de blog de tecnologia para engenheiros
&lt;/h2>&lt;p>O sistema que serve de base para o blog (como geradores de sites estáticos) e a estrutura HTML são os itens mais importantes para que os mecanismos de busca interpretem corretamente o conteúdo.&lt;/p>
&lt;h3 id="11-otimização-das-core-web-vitals">1.1 Otimização das Core Web Vitals
&lt;/h3>&lt;p>O Google adota a experiência da página como um fator de ranqueamento, e especialmente as &lt;strong>Core Web Vitals (LCP, FID/INP, CLS)&lt;/strong> não podem ser ignoradas nem mesmo em blogs de tecnologia.
Em blogs de tecnologia, uma grande quantidade de blocos de código-fonte, fórmulas matemáticas (MathJax / KaTeX) e imagens explicativas são frequentemente utilizados. Estes se tornam fatores que atrasam a renderização da página.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>LCP (Largest Contentful Paint)&lt;/strong>: A velocidade de carregamento do conteúdo principal na primeira visualização. Use WebP ou AVIF para a imagem de destaque (eyecatch) e adicione o atributo &lt;code>fetchpriority=&amp;quot;high&amp;quot;&lt;/code> para fazer o pré-carregamento. Além disso, projete CSS ou JS gigantes para destaque de sintaxe para carregarem de forma assíncrona ou carregarem apenas nas páginas necessárias.&lt;/li>
&lt;li>&lt;strong>CLS (Cumulative Layout Shift)&lt;/strong>: O deslocamento do layout durante o carregamento da página. Ao reservar previamente a área de exibição de fórmulas matemáticas ou imagens com propriedades CSS como &lt;code>aspect-ratio&lt;/code>, você evita os solavancos quando o DOM é inserido posteriormente.&lt;/li>
&lt;li>&lt;strong>INP (Interaction to Next Paint)&lt;/strong>: A capacidade de resposta às interações do usuário. É essencial não executar JavaScript pesado (por exemplo, pesquisa de texto completo dinâmica no lado do cliente ou execução de analisadores de Markdown gigantes) na thread principal; delegue-os para um Web Worker ou gere-os como HTML estático (SSG) durante o build.&lt;/li>
&lt;/ul>
&lt;h3 id="12-implementação-de-dados-estruturados-json-ld">1.2 Implementação de dados estruturados (JSON-LD)
&lt;/h3>&lt;p>Para informar explicitamente aos mecanismos de busca que a página é um &amp;ldquo;artigo&amp;rdquo; e &amp;ldquo;quem&amp;rdquo; é o autor, implementamos dados estruturados no formato JSON-LD. Aproveitando esquemas como &lt;code>TechArticle&lt;/code> e &lt;code>SoftwareSourceCode&lt;/code>, torna-se mais fácil aparecer nos rich results do Google, melhorando o CTR (Taxa de Clique).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;application/ld+json&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@context&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;https://schema.org&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;TechArticle&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;headline&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;O que os engenheiros devem fazer para aumentar os acessos mensais no blog de tecnologia&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;image&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;https://example.com/img/eyecatch.jpg&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;datePublished&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;2026-09-14T10:00:00+09:00&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;author&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Person&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Kenji&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;https://example.com/about/&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;publisher&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Organization&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Kenji&amp;#39;s Tech Blog&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;logo&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;ImageObject&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;https://example.com/img/logo.png&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="13-html-semântico-e-otimização-da-estrutura-do-documento">1.3 HTML semântico e otimização da estrutura do documento
&lt;/h3>&lt;p>O aninhamento adequado de cabeçalhos (&lt;code>h1&lt;/code> a &lt;code>h6&lt;/code>) é a base das bases, mas em blogs de tecnologia exige-se o uso preciso de tags semânticas do HTML5 como &lt;code>article&lt;/code>, &lt;code>section&lt;/code>, &lt;code>aside&lt;/code> e &lt;code>nav&lt;/code>. Além disso, ao usar adequadamente &lt;code>&amp;lt;code&amp;gt;&lt;/code> e &lt;code>&amp;lt;pre&amp;gt;&lt;/code> para indicar código-fonte, &lt;code>&amp;lt;kbd&amp;gt;&lt;/code> para indicar entrada de teclado e &lt;code>&amp;lt;var&amp;gt;&lt;/code> para indicar variáveis, você pode fornecer um HTML legível por máquina. Isso também é um meio muito eficaz para a indexação de conteúdo por IA (coleta de dados de treinamento para LLMs ou sistemas RAG).&lt;/p>
&lt;hr>
&lt;h2 id="2-psicologia-da-intenção-de-busca-search-intent-e-estratégia-de-palavras-chave">2. Psicologia da intenção de busca (Search Intent) e estratégia de palavras-chave
&lt;/h2>&lt;p>Para maximizar o fluxo vindo dos mecanismos de busca (tráfego orgânico), é necessário decifrar com precisão a intenção de busca, ou seja, &amp;ldquo;por que o usuário pesquisou aquela palavra-chave&amp;rdquo;. A intenção de busca técnica pode ser amplamente classificada em duas categorias.&lt;/p>
&lt;h3 id="21-tipo-resolução-de-erros-e-tipo-aprendizado-sistemático--revisão">2.1 &amp;ldquo;Tipo resolução de erros&amp;rdquo; e &amp;ldquo;Tipo aprendizado sistemático / revisão&amp;rdquo;
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>&lt;strong>Tipo resolução de erros (Troubleshooting Intent)&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Exemplo de palavras-chave de busca: &lt;code>Docker &amp;quot;no space left on device&amp;quot; solução&lt;/code>, &lt;code>Python IndexError list index out of range causa&lt;/code>&lt;/li>
&lt;li>Psicologia: Está bloqueado por um erro durante o desenvolvimento e deseja um comando ou snippet de código que seja um remédio milagroso agora mesmo.&lt;/li>
&lt;li>Estratégia: Apresente a &amp;ldquo;conclusão (código ou comando para resolver)&amp;rdquo; no início do artigo (primeira visualização). Coloque o contexto e a explicação detalhada do mecanismo depois, e primeiro satisfaça o desejo do usuário de &amp;ldquo;consertar imediatamente&amp;rdquo;. Isso permite diminuir a taxa de rejeição (bounce rate).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Tipo aprendizado sistemático / revisão (Learning &amp;amp; Review Intent)&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Exemplo de palavras-chave de busca: &lt;code>React vs Vue 2026 comparação&lt;/code>, &lt;code>Rust processamento assíncrono introdução&lt;/code>, &lt;code>GCP arquitetura de rede design&lt;/code>&lt;/li>
&lt;li>Psicologia: Está considerando a seleção de uma nova stack tecnológica ou quer aprofundar o entendimento desde a base e está preparado para passar tempo lendo.&lt;/li>
&lt;li>Estratégia: Enriqueça o índice (TOC) e use bastante diagramas explicativos ou de arquitetura (Mermaid, etc.). Compare objetivamente as vantagens e desvantagens e inclua casos de uso de como pode ser usado no trabalho real para aumentar o tempo de permanência na página.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h3 id="22-modelo-de-decaimento-exponencial-do-tráfego-e-estratégia-de-cauda-longa">2.2 Modelo de decaimento exponencial do tráfego e estratégia de cauda longa
&lt;/h3>&lt;p>O número de acessos a artigos técnicos tende a formar um pico (aumento rápido) logo após a publicação, ao viralizar em redes sociais, etc., e então diminuir exponencialmente. Este tráfego $V(t)$ pode ser aproximado pela seguinte fórmula matemática.&lt;/p>
$$ V(t) = V_0 e^{-\lambda t} + C $$&lt;p>Onde:&lt;/p>
&lt;ul>
&lt;li>$V(t)$: Volume de tráfego no tempo $t$&lt;/li>
&lt;li>$V_0$: Pico inicial de tráfego devido à viralização nas redes sociais logo após a publicação&lt;/li>
&lt;li>$\lambda$: Constante de decaimento devido à obsolescência do conteúdo ou esquecimento nas redes sociais (depende da velocidade de mudança de tendências da tecnologia)&lt;/li>
&lt;li>$C$: Fluxo orgânico estável vindo dos mecanismos de busca (tráfego base)&lt;/li>
&lt;/ul>
&lt;p>A chave para aumentar o acesso a longo prazo não é focar no pico temporário ($V_0$), mas &lt;strong>como tornar o termo constante $C$ (fluxo contínuo dos mecanismos de busca) maior&lt;/strong>. Ao cobrir uma grande quantidade de &amp;ldquo;palavras-chave de cauda longa&amp;rdquo; — como erros de nicho específicos ou métodos de integração entre ferramentas específicas — que têm baixo volume de buscas mas não têm concorrência, a soma total de $C$ crescerá para algo enorme.&lt;/p>
&lt;hr>
&lt;h2 id="3-análise-de-conteúdo-orientada-a-dados-usando-a-api-do-google-search-console">3. Análise de conteúdo orientada a dados usando a API do Google Search Console
&lt;/h2>&lt;p>Para construir uma base de tráfego estável $C$, é necessário utilizar dados do Google Search Console (GSC) e analisar de forma objetiva &amp;ldquo;como está sendo avaliado pelo Google&amp;rdquo;. No entanto, há limites para a operação manual de clicar na interface da web do GSC. Sendo um engenheiro, vamos automatizar a análise usando a API do GSC e Python.&lt;/p>
&lt;h3 id="31-abordagem-de-automação-com-api-do-gsc-e-python">3.1 Abordagem de automação com API do GSC e Python
&lt;/h3>&lt;p>Criaremos um script para detectar automaticamente &amp;ldquo;artigos desperdiçados&amp;rdquo;, onde a posição de busca de um artigo específico cai com o tempo (Decaying Content) ou onde o número de impressões é alto, mas a taxa de cliques (CTR) é anormalmente baixa.
Para isso, utilizaremos &lt;code>google-api-python-client&lt;/code> e &lt;code>pandas&lt;/code>.&lt;/p>
&lt;h3 id="32-código-de-implementação-python-extração-automática-de-conteúdo-com-queda-de-ctr">3.2 Código de implementação Python: Extração automática de conteúdo com queda de CTR
&lt;/h3>&lt;p>Abaixo está um exemplo de um script que obtém os dados de desempenho de busca dos últimos 30 dias pela API e extrai &amp;ldquo;palavras-chave e URLs de artigos com grande margem de melhora no título ou descrição&amp;rdquo;, onde o número de impressões é 1000 ou mais e o CTR é 2% ou menos.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">pandas&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">pd&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">google.oauth2&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">service_account&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">googleapiclient.discovery&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">build&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">datetime&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. Autenticação e construção do serviço de API&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">KEY_FILE_LOCATION&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;path/to/your-service-account-key.json&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">SCOPES&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;https://www.googleapis.com/auth/webmasters.readonly&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">SITE_URL&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;https://your-tech-blog.com/&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">credentials&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">service_account&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Credentials&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">from_service_account_file&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">KEY_FILE_LOCATION&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">scopes&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">SCOPES&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">webmasters_service&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">build&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;searchconsole&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;v1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">credentials&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">credentials&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. Cálculo do período da requisição (últimos 30 dias)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">today&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">datetime&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">date&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">today&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">end_date&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">today&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">datetime&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">timedelta&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">days&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">))&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">strftime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;%Y-%m-&lt;/span>&lt;span class="si">%d&lt;/span>&lt;span class="s1">&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">start_date&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">today&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">datetime&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">timedelta&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">days&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">32&lt;/span>&lt;span class="p">))&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">strftime&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;%Y-%m-&lt;/span>&lt;span class="si">%d&lt;/span>&lt;span class="s1">&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. Execução da requisição de API&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">request&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;startDate&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">start_date&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;endDate&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">end_date&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;dimensions&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;query&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;page&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;rowLimit&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">5000&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">webmasters_service&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">searchanalytics&lt;/span>&lt;span class="p">()&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">query&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">siteUrl&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">SITE_URL&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">body&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">request&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">execute&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 4. Processamento de dados e filtragem usando Pandas DataFrame&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="s1">&amp;#39;rows&amp;#39;&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">rows&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;rows&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">row&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">rows&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">data&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;Query&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;keys&amp;#39;&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;URL&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;keys&amp;#39;&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;Clicks&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;clicks&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;Impressions&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;impressions&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;CTR&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;ctr&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;Position&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">row&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;position&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">pd&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">DataFrame&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">data&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Condições de filtragem: Impressões maiores ou iguais a 1000 e CTR menor que 2%&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">target_df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">df&lt;/span>&lt;span class="p">[(&lt;/span>&lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;Impressions&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;gt;=&lt;/span> &lt;span class="mi">1000&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">&amp;amp;&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">df&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;CTR&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">&amp;lt;&lt;/span> &lt;span class="mf">0.02&lt;/span>&lt;span class="p">)]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Ordenar em ordem crescente de posição (priorizar os que têm alta posição mas não são clicados)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">target_df&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">target_df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">sort_values&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">by&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;Position&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">ascending&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;【Lista de recomendações de melhoria de título/meta descrição】&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">target_df&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">head&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Exportação para CSV, etc., se necessário&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># target_df.to_csv(&amp;#39;improve_candidates.csv&amp;#39;, index=False)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Nenhum dado encontrado.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Rodando esse script como um cron job ou como um job periódico do GitHub Actions, você pode sempre tomar decisões orientadas a dados sobre &amp;ldquo;quais títulos de artigos devem ser reescritos&amp;rdquo;. Em vez de confiar na intuição, a melhoria contínua baseada em dados (uma &amp;ldquo;Continuous Content Improvement&amp;rdquo;, em analogia a CI/CD) é importante.&lt;/p>
&lt;hr>
&lt;h2 id="4-gerenciamento-do-ciclo-de-vida-dos-artigos-e-estratégia-de-reescrita">4. Gerenciamento do ciclo de vida dos artigos e estratégia de reescrita
&lt;/h2>&lt;p>Um artigo técnico não acaba quando é publicado. Com a evolução da tecnologia (atualizações de versão de frameworks, obsolescência de APIs, etc.), o conteúdo torna-se obsoleto num piscar de olhos. Continuar a fornecer informações desatualizadas não apenas prejudica a credibilidade do blog, mas também é uma avaliação negativa do ponto de vista do SEO.&lt;/p>
&lt;h3 id="41-gerenciamento-do-ciclo-de-vida-do-conteúdo-gráfico-de-gantt">4.1 Gerenciamento do ciclo de vida do conteúdo (Gráfico de Gantt)
&lt;/h3>&lt;p>Mostramos o ciclo de vida operacional ideal de um conteúdo através de um gráfico de Gantt no Mermaid.&lt;/p>
&lt;pre class="mermaid">
gantt
title Gerenciamento do Ciclo de Vida do Conteúdo Orientado a Dados
dateFormat YYYY-MM-DD
axisFormat %m/%d
section &amp;#34;Fase 1: Planejamento / Redação&amp;#34;
&amp;#34;Análise de Palavras-chave / Tendências de Busca&amp;#34; :a1, 2026-09-01, 3d
&amp;#34;Rascunho / Verificação de Código&amp;#34; :a2, after a1, 5d
&amp;#34;Revisão / Correção&amp;#34; :a3, after a2, 2d
section &amp;#34;Fase 2: Publicação / Promoção&amp;#34;
&amp;#34;Deploy por pipeline de CI/CD&amp;#34; :p1, 2026-09-11, 1d
&amp;#34;Distribuição Automática em Redes Sociais (X, LinkedIn, RSS)&amp;#34; :p2, 2026-09-11, 1d
&amp;#34;Repercussão no Hatena Bookmark, etc.&amp;#34; :p3, after p2, 3d
section &amp;#34;Fase 3: Observação / Análise&amp;#34;
&amp;#34;Período de Acúmulo de Dados GSC&amp;#34; :m1, 2026-09-14, 28d
&amp;#34;Avaliação de Desempenho com API Python&amp;#34;:m2, after m1, 2d
section &amp;#34;Fase 4: Melhoria (Reescrita)&amp;#34;
&amp;#34;Correção de Título de Artigos com CTR Baixo&amp;#34; :r1, after m2, 3d
&amp;#34;Atualização de Código para a Versão Mais Recente&amp;#34;:r2, after r1, 4d
&lt;/pre>
&lt;p>Tratar a criação de um artigo como um projeto de desenvolvimento de software e incorporar a fase de operação e manutenção (reescrita) pós-lançamento no planejamento é o segredo para manter e aumentar o tráfego.&lt;/p>
&lt;h3 id="42-modelo-matemático-do-roi-retorno-sobre-investimento-da-criação-de-conteúdo">4.2 Modelo matemático do ROI (Retorno sobre Investimento) da criação de conteúdo
&lt;/h3>&lt;p>Dado que os engenheiros dedicam seu tempo valioso para escrever artigos, eles devem estar cientes do seu retorno sobre investimento (ROI).
O ROI de um blog pode ser formulado da seguinte maneira.&lt;/p>
$$ ROI = \frac{\sum_{t=1}^{T} \left( Rev_{ad}(t) + Val_{brand}(t) + Val_{skill}(t) \right) - Cost_{time}}{\text{Cost}_{time}} \times 100 \ (\%) $$&lt;ul>
&lt;li>$T$: Vida útil efetiva do artigo (período até se tornar obsoleto)&lt;/li>
&lt;li>$Rev_{ad}(t)$: Receita direta de publicidade, receita de afiliados e patrocínios&lt;/li>
&lt;li>$Val_{brand}(t)$: Valor monetário equivalente ao impacto positivo na carreira devido ao apelo da capacidade técnica (aumento do valor da oferta de emprego ao mudar de empresa, pedidos de palestras, etc.)&lt;/li>
&lt;li>$Val_{skill}(t)$: Valor de aprimoramento das próprias habilidades através do aprendizado e pesquisa para escrever o artigo&lt;/li>
&lt;li>$Cost_{time}$: Tempo gasto redigindo o artigo, criando ilustrações e testando o código (convertido para seu próprio salário por hora)&lt;/li>
&lt;/ul>
&lt;p>O excelente de um blog de tecnologia é que, mesmo que $Rev_{ad}$ seja pequeno, $Val_{brand}$ e $Val_{skill}$ tendem a ser extremamente grandes. Em especial, uma explicação técnica de alta qualidade torna-se um portfólio em si mesmo, mostrando um poder tremendo em atividades de procura de emprego ou obtenção de trabalhos secundários (freelancer).&lt;/p>
&lt;hr>
&lt;h2 id="5-distribuição-por-meio-de-integração-entre-github-actions-e-ferramentas-de-automação-externas">5. Distribuição por meio de integração entre GitHub Actions e ferramentas de automação externas
&lt;/h2>&lt;p>Após criar o conteúdo, o desafio é como entregá-lo eficientemente ao público-alvo (distribuição). Postar manualmente os links em cada rede social todas as vezes é ineficiente e não parece algo de um engenheiro.&lt;/p>
&lt;h3 id="51-arquitetura-de-automação-de-compartilhamento-em-mídias-sociais">5.1 Arquitetura de automação de compartilhamento em mídias sociais
&lt;/h3>&lt;p>Vamos construir uma arquitetura que automatiza completamente desde o momento em que o arquivo Markdown é mesclado na branch main do repositório GitHub, passando pelo build, deploy e notificação em múltiplas plataformas.&lt;/p>
&lt;pre class="mermaid">
flowchart TD
A[&amp;#34;Desenvolvedor (Git Push)&amp;#34;] --&amp;gt; B[&amp;#34;Repositório GitHub&amp;#34;]
B --&amp;gt;|Webhook| C[&amp;#34;GitHub Actions (CI/CD)&amp;#34;]
C --&amp;gt;|Build| D[&amp;#34;Gerador de Site Estático (Hugo/Gatsby)&amp;#34;]
D --&amp;gt;|Deploy| E[&amp;#34;Hospedagem (Vercel / Cloudflare Pages)&amp;#34;]
D --&amp;gt;|Generate| F[&amp;#34;Feed RSS (index.xml)&amp;#34;]
F --&amp;gt;|Polled by| G[&amp;#34;Zapier / IFTTT / Make&amp;#34;]
G --&amp;gt;|API Call| H[&amp;#34;Post Automático no X (Twitter)&amp;#34;]
G --&amp;gt;|API Call| I[&amp;#34;Post de Artigo no LinkedIn&amp;#34;]
G --&amp;gt;|API Call| J[&amp;#34;Webhook de Comunidade Discord / Slack&amp;#34;]
C --&amp;gt;|Actions Script| K[&amp;#34;API de Cross-Post Qiita / Zenn&amp;#34;]
&lt;/pre>
&lt;h3 id="52-pontos-de-construção-do-pipeline-de-automação">5.2 Pontos de construção do pipeline de automação
&lt;/h3>&lt;ol>
&lt;li>
&lt;p>&lt;strong>Build e Deploy via GitHub Actions&lt;/strong>
Se você estiver utilizando um gerador de site estático, use GitHub Actions para automatizar a geração de HTML e o deploy no serviço de hospedagem (Vercel, Netlify, Cloudflare Pages, etc.). Neste momento, também é eficaz integrar no pipeline de build o processo de otimização de imagens (conversão automática para WebP, etc.) como uma contramedida para o Core Web Vitals mencionado anteriormente.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Integração de Redes Sociais ativada por RSS usando Zapier/IFTTT&lt;/strong>
O gerador de sites cria o último feed RSS (XML) no momento do build. Alimente isso em um iPaaS como Zapier ou Make (anteriormente Integromat) e crie um fluxo de trabalho: &amp;ldquo;Se um novo item for adicionado ao RSS, publique o título e o URL no X (Twitter) e no LinkedIn&amp;rdquo;. Com isso, os seguidores são notificados automaticamente no momento em que o artigo é publicado.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>Cross-Post para o Qiita/Zenn (Uso de Canonical Tags)&lt;/strong>
Enquanto a força de domínio do seu próprio blog corporativo ou pessoal for fraca, emprestar o poder de atração de público de plataformas técnicas como Qiita e Zenn é uma opção. No entanto, um simples copiar e colar carrega o risco de ser penalizado por SEO como conteúdo duplicado.
Esse problema pode ser resolvido configurando a &lt;strong>Tag Canonical&lt;/strong> nos metadados do artigo no Qiita ou Zenn, especificando a URL do artigo original no seu próprio blog. Ao criar um script que faz chamadas para as APIs das diversas plataformas a partir do GitHub Actions para gerar automaticamente artigos a partir de Markdown, a distribuição multicanal pode ser totalmente automatizada.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="conclusão-girando-o-ciclo-de-melhoria-contínua">Conclusão: Girando o ciclo de melhoria contínua
&lt;/h2>&lt;p>Para aumentar drasticamente os acessos mensais do blog de tecnologia, além do ato de &amp;ldquo;escrever&amp;rdquo;, abordagens de engenharia como as apresentadas desta vez são essenciais.&lt;/p>
&lt;ol>
&lt;li>Construção de HTML e arquitetura de site robustos e com foco em SEO&lt;/li>
&lt;li>Design de artigo que compreende a intenção de busca do usuário (resolução de erros vs. aprendizado sistemático)&lt;/li>
&lt;li>Análise de dados aproveitando a API do Google Search Console e Python&lt;/li>
&lt;li>Gerenciamento do ciclo de vida e reescrita do conteúdo com foco no ROI&lt;/li>
&lt;li>Automação completa da distribuição por meio de CI/CD e integração com Zapier&lt;/li>
&lt;/ol>
&lt;p>Se conseguir montar isso como um sistema, o blog de tecnologia se tornará o ativo mais forte para impulsionar poderosamente sua própria carreira. Engenheiros que sofrem com a estagnação do número de acessos, por favor, comecem o &amp;ldquo;growth hacking de blog&amp;rdquo; a partir de hoje. Suas habilidades de programação e capacidade de design de arquitetura cultivadas nas tarefas de desenvolvimento com certeza serão suas maiores armas na gestão de um blog.&lt;/p></description></item><item><title>Otimização de SEO para Blogs Hugo: Configurações de Frontmatter para Aumentar Dramaticamente o Tráfego</title><link>http://kenji.blog/pt/p/hugo-blog-seo-frontmatter-tips/</link><pubDate>Sat, 12 Sep 2026 12:00:00 +0900</pubDate><guid>http://kenji.blog/pt/p/hugo-blog-seo-frontmatter-tips/</guid><description>&lt;img src="http://kenji.blog/p/hugo-blog-seo-frontmatter-tips/img/eyecatch.jpg" alt="Featured image of post Otimização de SEO para Blogs Hugo: Configurações de Frontmatter para Aumentar Dramaticamente o Tráfego" />&lt;p>O Hugo é um dos geradores de sites estáticos (SSG) mais rápidos do mundo, escrito na linguagem Go. Devido à sua velocidade de construção avassaladora e sistema de templates flexível, recebe grande apoio de muitos engenheiros e blogueiros. No entanto, apenas gerar e exibir um site rapidamente não é suficiente para ser bem avaliado pelos motores de busca (como Google e Bing) e entregar seus artigos aos usuários.&lt;/p>
&lt;p>Para melhorar as classificações de pesquisa, aumentar o poder de difusão nas mídias sociais e, consequentemente, aumentar dramaticamente o número de acessos ao blog, medidas meticulosas de SEO (Otimização para Motores de Busca) são essenciais. O coração do SEO no Hugo é a integração do &lt;strong>Frontmatter&lt;/strong>, escrito no início de cada artigo em markdown, e os &lt;strong>Templates (Layouts)&lt;/strong>, que o interpretam para expandir metadados dentro da tag HTML &lt;code>&amp;lt;head&amp;gt;&lt;/code>.&lt;/p>
&lt;p>Neste artigo, explicaremos de forma minuciosa, com um volume esmagador de mais de 10.000 caracteres, desde as configurações de frontmatter para extrair o máximo das funcionalidades do Hugo e implementar medidas avançadas de SEO, até várias meta tags, OGP (Open Graph Protocol), Twitter Cards, e a saída de dados estruturados usando JSON-LD.&lt;/p>
&lt;hr>
&lt;h2 id="1-contexto-matemático-do-seo-e-tráfego">1. Contexto Matemático do SEO e Tráfego
&lt;/h2>&lt;p>Antes de entrar na implementação específica, vamos entender matematicamente por que metadados detalhados de SEO são importantes. O tráfego de pesquisa $T$ que um site pode adquirir é determinado pelo volume de pesquisa da palavra-chave alvo e pela taxa de cliques (CTR) baseada na classificação da pesquisa.&lt;/p>
&lt;p>Isso pode ser expresso pela seguinte fórmula:&lt;/p>
$$ T = \sum_{i=1}^{n} V_i \times CTR(R_i) $$&lt;ul>
&lt;li>$V_i$ : Volume de pesquisa mensal da palavra-chave $i$&lt;/li>
&lt;li>$R_i$ : Classificação de pesquisa da palavra-chave $i$&lt;/li>
&lt;li>$CTR(R_i)$ : Taxa de cliques na classificação $R_i$&lt;/li>
&lt;/ul>
&lt;p>Dentre estes, a classificação de pesquisa $R_i$ depende de muitos fatores, como a qualidade do conteúdo e backlinks (PageRank), mas o algoritmo inicial de PageRank do Google é modelado da seguinte forma:&lt;/p>
$$ PR(u) = \frac{1-d}{N} + d \sum_{v \in B(u)} \frac{PR(v)}{L(v)} $$&lt;ul>
&lt;li>$PR(u)$ : PageRank da página $u$&lt;/li>
&lt;li>$d$ : Fator de amortecimento (geralmente 0.85)&lt;/li>
&lt;li>$B(u)$ : Conjunto de páginas que possuem links para a página $u$&lt;/li>
&lt;li>$L(v)$ : Número de links de saída da página $v$&lt;/li>
&lt;/ul>
&lt;p>O ponto importante aqui é: &lt;strong>além do esforço para aumentar a classificação de pesquisa $R_i$, como maximizar a taxa de cliques $CTR(R_i)$&lt;/strong>. Ao otimizar o título e o snippet (description) exibidos nos resultados de pesquisa (SERPs), e a imagem de destaque (OGP) quando compartilhada nas redes sociais, é possível aumentar intencionalmente o $CTR(R_i)$. A configuração de SEO no frontmatter está diretamente ligada à maximização desse $CTR$.&lt;/p>
&lt;hr>
&lt;h2 id="2-o-processo-de-build-do-hugo-e-o-papel-do-frontmatter">2. O Processo de Build do Hugo e o Papel do Frontmatter
&lt;/h2>&lt;p>O Hugo lê o frontmatter (YAML/TOML/JSON) dentro do arquivo markdown e o passa para o motor de templates como variáveis de página. Primeiro, vamos entender visualmente esse fluxo de informações.&lt;/p>
&lt;pre class="mermaid">
flowchart TD
A[&amp;#34;Arquivo Markdown&amp;#34;] --&amp;gt; B[&amp;#34;Análise do Frontmatter&amp;#34;]
A --&amp;gt; C[&amp;#34;Análise do Conteúdo&amp;#34;]
B --&amp;gt; D[&amp;#34;Variáveis de Página do Hugo (.Title, .Params)&amp;#34;]
C --&amp;gt; D
E[&amp;#34;layouts/partials/head.html&amp;#34;] --&amp;gt; F[&amp;#34;Motor de Templates Go&amp;#34;]
D --&amp;gt; F
F --&amp;gt; G[&amp;#34;Tag HTML Final &amp;lt;head&amp;gt;&amp;#34;]
G --&amp;gt; H[&amp;#34;Googlebot / Rastreadores&amp;#34;]
G --&amp;gt; I[&amp;#34;Scrapers de Mídia Social (OGP)&amp;#34;]
&lt;/pre>
&lt;p>Desta forma, os valores definidos no frontmatter são passados para o &lt;code>head.html&lt;/code> como variáveis, como &lt;code>.Title&lt;/code> e &lt;code>.Params.description&lt;/code>, e finalmente renderizados como metadados HTML. Portanto, o sucesso do SEO consiste em dois passos: &amp;ldquo;definir informações apropriadas no frontmatter&amp;rdquo; e &amp;ldquo;convertê-las corretamente para HTML usando templates&amp;rdquo;.&lt;/p>
&lt;hr>
&lt;h2 id="3-configurações-básicas-de-metadados-title-description-canonical-url">3. Configurações Básicas de Metadados: Title, Description, Canonical URL
&lt;/h2>&lt;p>As tags mais básicas para que os motores de busca compreendam o conteúdo de uma página são &lt;code>&amp;lt;title&amp;gt;&lt;/code> e &lt;code>&amp;lt;meta name=&amp;quot;description&amp;quot;&amp;gt;&lt;/code>. Além disso, &lt;code>&amp;lt;link rel=&amp;quot;canonical&amp;quot;&amp;gt;&lt;/code> é essencial para evitar penalidades por conteúdo duplicado.&lt;/p>
&lt;h3 id="31-exemplo-de-configuração-no-frontmatter">3.1. Exemplo de Configuração no Frontmatter
&lt;/h3>&lt;p>No frontmatter do artigo, prepare campos específicos para SEO.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">title: &amp;#39;Otimização de SEO para Blogs Hugo&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Configurações de Frontmatter para Aumentar Dramaticamente o Tráfego&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">seo_title: &amp;#39;Guia Completo de SEO no Hugo: Aumente o Tráfego com Frontmatter&amp;#39; # Opcional&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="l">Para motores de busca&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">description&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;Técnicas avançadas de SEO utilizando o frontmatter do Hugo. Explicação detalhada de como configurar OGP, JSON-LD e metadados.&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">slug&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;hugo-seo-frontmatter-tips&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">canonicalUrl&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;https://example.com/post/hugo-seo-frontmatter-tips/&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># URL canônica explícita&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="32-implementação-do-layoutspartialsheadhtml">3.2. Implementação do &lt;code>layouts/partials/head.html&lt;/code>
&lt;/h3>&lt;p>Crie um template HTML para exibir corretamente essas variáveis.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- Otimização do Título --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ $title := .Title }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ if .Params.seo_title }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {{ $title = .Params.seo_title }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">title&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>{{ $title }} | {{ .Site.Title }}&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">title&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- Otimização da Description --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ $description := .Summary | plainify | truncate 120 }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ if .Params.description }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {{ $description = .Params.description }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;description&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;{{ $description }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- Canonical URL (Normalização) --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ $canonical := .Permalink }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ if .Params.canonicalUrl }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {{ $canonical = .Params.canonicalUrl }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">link&lt;/span> &lt;span class="na">rel&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;canonical&amp;#34;&lt;/span> &lt;span class="na">href&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;{{ $canonical }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- Controle de Robôs (Configuração de noindex, etc.) --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ if .Params.noindex }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;robots&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;noindex, nofollow&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ else }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;robots&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;index, follow&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Ao usar o &lt;code>.Summary&lt;/code> do Hugo como fallback, a frase inicial do artigo pode ser extraída automaticamente, mesmo se &lt;code>description&lt;/code> não estiver definida.&lt;/p>
&lt;hr>
&lt;h2 id="4-ogp-e-twitter-cards-maximizando-o-ctr-nas-mídias-sociais">4. OGP e Twitter Cards: Maximizando o CTR nas Mídias Sociais
&lt;/h2>&lt;p>Para que os artigos sejam exibidos em um formato de cartão atraente quando compartilhados em redes sociais como Twitter (X) e Facebook, a configuração do Open Graph Protocol (OGP) e do Twitter Cards é indispensável. Eles também são gerados dinamicamente a partir do frontmatter.&lt;/p>
&lt;h3 id="41-desafios-com-templates-integrados">4.1. Desafios com Templates Integrados
&lt;/h3>&lt;p>O Hugo possui um template integrado útil &lt;code>{{ template &amp;quot;_internal/opengraph.html&amp;quot; . }}&lt;/code>, mas ele carece de personalização e pode não ser adequado para ambientes em japonês ou requisitos específicos. Portanto, é altamente recomendável implementar tags OGP personalizadas no seu &lt;code>head.html&lt;/code>.&lt;/p>
&lt;h3 id="42-especificando-imagens-no-frontmatter">4.2. Especificando Imagens no Frontmatter
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">image&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;img/eyecatch.jpg&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">images&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;img/eyecatch-large.jpg&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c"># Para caminhos absolutos ou múltiplas imagens&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="43-código-de-implementação-personalizada-de-ogp-e-twitter-cards">4.3. Código de Implementação Personalizada de OGP e Twitter Cards
&lt;/h3>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- Open Graph Protocol --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">property&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;og:title&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;{{ $title }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">property&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;og:description&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;{{ $description }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">property&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;og:type&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;{{ if .IsPage }}article{{ else }}website{{ end }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">property&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;og:url&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">property&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;og:site_name&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;{{ .Site.Title }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- Resolução da Imagem OGP --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ $ogImage := &amp;#34;&amp;#34; }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ if .Params.image }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {{ $ogImage = .Params.image | absURL }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ else if .Params.images }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {{ $ogImage = index .Params.images 0 | absURL }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ else if .Site.Params.defaultImage }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> {{ $ogImage = .Site.Params.defaultImage | absURL }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ if $ogImage }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">property&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;og:image&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;{{ $ogImage }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;twitter:image&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;{{ $ogImage }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;twitter:card&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;summary_large_image&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ else }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;twitter:card&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;summary&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- Twitter Cards --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;twitter:title&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;{{ $title }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;twitter:description&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;{{ $description }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ if .Site.Params.twitterAccount }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">meta&lt;/span> &lt;span class="na">name&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;twitter:site&amp;#34;&lt;/span> &lt;span class="na">content&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;@{{ .Site.Params.twitterAccount }}&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Ao usar a função &lt;code>absURL&lt;/code>, os URLs de imagem especificados como caminhos relativos são convertidos em caminhos absolutos. Como o OGP exige caminhos absolutos, esse processo é extremamente importante.&lt;/p>
&lt;hr>
&lt;h2 id="5-implementação-de-dados-estruturados-json-ld">5. Implementação de Dados Estruturados (JSON-LD)
&lt;/h2>&lt;p>No SEO atual, o &lt;strong>JSON-LD (JavaScript Object Notation for Linked Data)&lt;/strong> se tornou a tecnologia dominante para transmitir com precisão a estrutura semântica de uma página aos motores de busca. Ao configurar isso, é mais provável que rich snippets (avaliação com estrelas, nome do autor, data de publicação, etc.) sejam exibidos nos resultados de pesquisa.&lt;/p>
&lt;h3 id="51-estrutura-do-json-ld">5.1. Estrutura do JSON-LD
&lt;/h3>&lt;p>Em artigos de blog, implementamos principalmente dois schemas: o schema &lt;code>Article&lt;/code> (Artigo) e o schema &lt;code>BreadcrumbList&lt;/code> (Lista de Trilhas de Navegação).&lt;/p>
&lt;pre class="mermaid">
flowchart TD
A[&amp;#34;Definições do Schema.org&amp;#34;] --&amp;gt; B[&amp;#34;Schema Article&amp;#34;]
A --&amp;gt; C[&amp;#34;Schema BreadcrumbList&amp;#34;]
B --&amp;gt; D[&amp;#34;headline&amp;#34;]
B --&amp;gt; E[&amp;#34;datePublished&amp;#34;]
B --&amp;gt; F[&amp;#34;dateModified&amp;#34;]
B --&amp;gt; G[&amp;#34;author&amp;#34;]
B --&amp;gt; H[&amp;#34;image&amp;#34;]
C --&amp;gt; I[&amp;#34;Item da Lista 1&amp;#34;]
C --&amp;gt; J[&amp;#34;Item da Lista 2&amp;#34;]
I --&amp;gt; K[&amp;#34;position: 1&amp;#34;]
I --&amp;gt; L[&amp;#34;name: Home&amp;#34;]
J --&amp;gt; M[&amp;#34;position: 2&amp;#34;]
J --&amp;gt; N[&amp;#34;name: Categoria / Blog&amp;#34;]
&lt;/pre>
&lt;h3 id="52-gerando-json-ld-nos-templates-do-hugo">5.2. Gerando JSON-LD nos Templates do Hugo
&lt;/h3>&lt;p>Utilizando variáveis do frontmatter como &lt;code>.Date&lt;/code> e &lt;code>.Lastmod&lt;/code>, o JSON-LD é gerado dinamicamente. Ele é escrito no &lt;code>head.html&lt;/code> usando a tag &lt;code>&amp;lt;script type=&amp;quot;application/ld+json&amp;quot;&amp;gt;&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-html" data-lang="html">&lt;span class="line">&lt;span class="cl">{{ if .IsPage }}
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;application/ld+json&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@context&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;https://schema.org&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Article&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;mainEntityOfPage&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;WebPage&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@id&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;headline&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ .Title | htmlEscape }}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;description&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ $description | htmlEscape }}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;image&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ $ogImage }}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;datePublished&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ .Date.Format &amp;#34;&lt;/span>&lt;span class="mi">2006&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">01&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">02&lt;/span>&lt;span class="nx">T15&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">04&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">05&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">07&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">00&lt;/span>&lt;span class="s2">&amp;#34; }}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;dateModified&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ .Lastmod.Format &amp;#34;&lt;/span>&lt;span class="mi">2006&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">01&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">02&lt;/span>&lt;span class="nx">T15&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">04&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">05&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">07&lt;/span>&lt;span class="o">:&lt;/span>&lt;span class="mi">00&lt;/span>&lt;span class="s2">&amp;#34; }}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;author&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Person&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ if .Params.author }}{{ .Params.author }}{{ else }}{{ .Site.Params.author }}{{ end }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;publisher&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Organization&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ .Site.Title }}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;logo&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;ImageObject&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;url&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ .Site.Params.logo | absURL }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c">&amp;lt;!-- BreadcrumbList Schema --&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="nt">script&lt;/span> &lt;span class="na">type&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s">&amp;#34;application/ld+json&amp;#34;&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@context&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;https://schema.org&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;BreadcrumbList&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;itemListElement&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;ListItem&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;position&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;Home&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;item&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ .Site.BaseURL }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{{&lt;/span> &lt;span class="nx">$position&lt;/span> &lt;span class="o">:=&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="p">}}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{{&lt;/span> &lt;span class="nx">range&lt;/span> &lt;span class="p">.&lt;/span>&lt;span class="nx">Params&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">categories&lt;/span> &lt;span class="p">}}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;ListItem&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;position&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{{&lt;/span> &lt;span class="nx">$position&lt;/span> &lt;span class="p">}},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ . }}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;item&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ &amp;#34;&lt;/span>&lt;span class="nx">categories&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="s2">&amp;#34; | relLangURL }}{{ . | urlize | lower }}/&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{{&lt;/span> &lt;span class="nx">$position&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">add&lt;/span> &lt;span class="nx">$position&lt;/span> &lt;span class="mi">1&lt;/span> &lt;span class="p">}}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{{&lt;/span> &lt;span class="nx">end&lt;/span> &lt;span class="p">}}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">,{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;@type&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;ListItem&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;position&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="p">{{&lt;/span> &lt;span class="nx">$position&lt;/span> &lt;span class="p">}},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;name&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ .Title | htmlEscape }}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;item&amp;#34;&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s2">&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">&amp;lt;/&lt;/span>&lt;span class="nt">script&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">{{ end }}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Ao expandir strings dentro do JSON-LD, o principal ponto é usar &lt;code>htmlEscape&lt;/code> (ou &lt;code>jsonify&lt;/code>) para evitar a quebra das aspas duplas. Isso evita erros de sintaxe no JSON, independentemente de quais símbolos sejam usados no frontmatter.&lt;/p>
&lt;hr>
&lt;h2 id="6-técnicas-avançadas-para-aproveitar-o-frontmatter">6. Técnicas Avançadas para Aproveitar o Frontmatter
&lt;/h2>&lt;p>Além dos metadados básicos de SEO, o frontmatter do Hugo possui recursos para implementar estratégias de SEO ainda mais avançadas.&lt;/p>
&lt;h3 id="61-processamento-de-redirecionamento-por-aliases">6.1. Processamento de Redirecionamento por Aliases
&lt;/h3>&lt;p>Ao migrar para o Hugo de um serviço de blog anterior ou alterar a estrutura do permalink, você precisa redirecionar o acesso de URLs antigos para os novos. Ao usar o campo &lt;code>aliases&lt;/code> do Hugo, você pode gerar automaticamente páginas de atualização HTTP-Equiv (meta redirecionamento) para URLs antigos.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">title&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;Novo Título do Artigo&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">slug&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;new-seo-post&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">aliases&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;/old-category/old-seo-post/&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s2">&amp;#34;/2020/05/12/seo-tips/&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="62-expiração-de-artigos-e-agendamento">6.2. Expiração de Artigos e Agendamento
&lt;/h3>&lt;p>No caso de artigos de campanhas por tempo limitado ou informações que perdem seu valor ao envelhecer, definindo &lt;code>expiryDate&lt;/code>, você pode excluí-los do resultado do build após a data e hora especificadas e impedi-los de aparecer no site (retornando um 404). Isso evita que conteúdos antigos de baixa qualidade permaneçam no índice e reduzam a classificação geral do site.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">title&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;Técnicas de SEO Exclusivas de 2026&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">publishDate&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;2026-01-01T00:00:00Z&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nt">expiryDate&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;2026-12-31T23:59:59Z&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="nn">---&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h2 id="7-desempenho-do-site-e-core-web-vitals">7. Desempenho do Site e Core Web Vitals
&lt;/h2>&lt;p>No SEO, tão importante quanto a otimização de tags é a &lt;strong>velocidade de carregamento da página&lt;/strong>. O Google incorpora os Core Web Vitals (LCP, FID/INP, CLS) como fatores de classificação.&lt;/p>
&lt;p>Sendo um site estático, o Hugo possui um excelente TTFB (Tempo até o Primeiro Byte), mas em blogs com uso intenso de imagens, a otimização de imagens é obrigatória. Combinando o poderoso processamento de imagem do Hugo (Image Processing) com o frontmatter, você pode automatizar o redimensionamento e a conversão para formatos de próxima geração (como WebP) no momento do build.&lt;/p>
&lt;p>Por exemplo, você pode criar um shortcode que gera automaticamente uma imagem WebP no template a partir do caminho da imagem especificado no frontmatter. Isso pode melhorar dramaticamente a avaliação do seu SEO.&lt;/p>
&lt;hr>
&lt;h2 id="8-conclusão">8. Conclusão
&lt;/h2>&lt;p>Ao gerenciar um blog usando Hugo, o frontmatter não é apenas uma &amp;ldquo;lista de configurações&amp;rdquo;, mas sim um &amp;ldquo;painel de controle&amp;rdquo; para interagir com motores de busca e redes sociais.&lt;/p>
&lt;p>Implementar completamente os pontos explicados neste artigo fortalecerá de forma robusta a base de SEO do seu blog.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Geração dinâmica de metadados básicos&lt;/strong>: Saída confiável de Title, Description e Canonical&lt;/li>
&lt;li>&lt;strong>Otimização de compartilhamento social&lt;/strong>: Melhoria de CTR com implementação customizada de OGP e Twitter Cards&lt;/li>
&lt;li>&lt;strong>Suporte completo para dados estruturados&lt;/strong>: Suporte a rich results por JSON-LD (Article, Breadcrumb)&lt;/li>
&lt;li>&lt;strong>Gerenciamento avançado de tráfego&lt;/strong>: Controle de robôs através de meta tags e redirecionamentos via Aliases&lt;/li>
&lt;/ol>
&lt;p>Embora os algoritmos dos motores de busca evoluam todos os dias, o princípio fundamental do SEO de fornecer sinais para que os motores de busca &amp;ldquo;entendam corretamente o conteúdo da página&amp;rdquo; permanece o mesmo. Ao dominar o frontmatter e o motor de templates flexível do Hugo, você pode continuar enviando esse sinal com a mais alta qualidade e aumentar drasticamente o tráfego do seu blog.&lt;/p></description></item></channel></rss>