🔴 Ao vivo: techsignal.netlify.app · Discussão técnica: post no TabNews
Site de notícias de tecnologia em HTML/CSS/JS puro que busca e exibe notícias reais, atualizadas automaticamente. Pode rodar 100% estático (sem servidor) ou, opcionalmente, com um pequeno backend de cache próprio para ganhar confiabilidade e velocidade em escala.
O site tenta, em ordem, três camadas — se uma falha, cai pra próxima, e o visitante nunca vê o site vazio:
- Worker de cache próprio (opcional, você que ativa — veja abaixo). Busca tudo no servidor, já pronto, com um fetch só.
- Busca direta no navegador (modo padrão, já vem ativo): Hacker News API (sem limite) + RSS de TechCrunch, The Verge, Wired, Ars Technica e Engadget via
rss2json.com(gratuito, mas com limite de requisições/dia). - Se tudo falhar, mostra um aviso claro em vez de travar silenciosamente.
Em qualquer camada, o site combina os resultados, remove duplicatas, categoriza (IA, Startups, Hardware, Segurança, Software, Ciência, Geral) e ordena por data, atualizando sozinho a cada 5 minutos (ou na hora, pelo botão de refresh).
signal-tech/
├── index.html → estrutura da página (inclui a faixa de newsletter)
├── styles.css → design system completo (cores, tipografia, layout, responsivo)
├── script.js → toda a lógica: fetch, worker, categorização, arte gerativa, tradução, busca, filtros, newsletter
├── worker.js → Cloudflare Worker opcional (backend de cache) — veja passo a passo abaixo
├── robots.txt → libera indexação e aponta pro sitemap
├── sitemap.xml → mapa de páginas pro Google Search Console
├── LICENSE → MIT — uso livre, com atribuição
└── README.md → este arquivo
Opção 1 — Netlify (mais fácil)
- Acesse netlify.com → "Add new site" → "Deploy manually"
- Arraste a pasta
signal-techinteira (não precisa incluir oworker.js, ele não roda aqui) - Pronto, já tem uma URL pública. Depois dá pra ligar um domínio próprio nas configurações do site.
Opção 2 — GitHub Pages
- Crie um repositório e suba os arquivos
- Settings → Pages → escolha a branch
main - O site fica em
seu-usuario.github.io/nome-do-repo
Opção 3 — Vercel
vercel deployna pasta, ou conecte o repositório pelo painel
Por que fazer isso: o rss2json.com gratuito tem limite de requisições por dia. Com várias pessoas acessando ao mesmo tempo, ele começa a falhar (o Hacker News continua indo, mas TechCrunch/Verge/etc. somem). O Worker resolve isso de vez: ele busca os feeds RSS direto, sem depender do rss2json, e guarda em cache — então mil visitantes geram o mesmo tanto de tráfego pras fontes originais que um visitante só.
Também fica mais rápido pro usuário: em vez do navegador dele fazer 6 requisições (HN + 5 RSS), ele faz uma só pro seu Worker.
Passo a passo (sem precisar de terminal):
- Crie uma conta grátis em dash.cloudflare.com
- No menu lateral: Workers e Pages → Criar aplicação → Criar Worker
- Dê um nome (ex:
signal-feed) → Implantar (ele publica um Worker de exemplo primeiro, tudo bem) - Clique em Editar código
- Apague todo o conteúdo de exemplo e cole o conteúdo inteiro do arquivo
worker.js(que já está pronto nesta entrega) - Clique em Implantar/Deploy
- Copie a URL que aparece — algo como
https://signal-feed.seu-usuario.workers.dev - Abra
script.js, ache a linhaworkerEndpoint: ''(é uma das primeiras linhas, dentro deCONFIG) e cole a URL entre as aspas:workerEndpoint: 'https://signal-feed.seu-usuario.workers.dev',
- Salve, republique o site (se for Netlify, é só arrastar a pasta de novo)
Pronto — o site passa a usar o Worker automaticamente, e se o Worker cair por qualquer motivo, ele volta sozinho pro modo direto no navegador. Não tem como quebrar.
Custo: o plano gratuito da Cloudflare cobre 100.000 requisições por dia — dá folga pra maioria dos sites, mesmo com tráfego real.
O site já tem uma faixa de captura de e-mail pronta (visualmente e funcionalmente), só falta conectar a um provedor. Recomendo o Formspree pra começar — é o mais rápido de configurar:
Passo a passo:
- Crie uma conta grátis em formspree.io (plano gratuito: 50 envios/mês)
- Crie um novo formulário, copie o endpoint (algo como
https://formspree.io/f/xxxxxxxx) - Abra
script.js, achenewsletterEndpoint: ''dentro deCONFIGe cole:newsletterEndpoint: 'https://formspree.io/f/xxxxxxxx',
- Salve e republique. Cada inscrição chega no seu e-mail cadastrado no Formspree.
Quando o site crescer, vale migrar pra uma ferramenta feita pra newsletter de verdade — Mailchimp ou ConvertKit (ambos têm plano grátis até alguns milhares de contatos). A diferença: eles deixam você desenhar o e-mail do resumo diário, automatizar o envio e ver métricas de abertura — o Formspree só avisa que alguém se inscreveu. Nesse caso, troque a URL em newsletterEndpoint pelo endpoint de formulário que o Mailchimp/ConvertKit fornece (o formato do fetch no script.js pode precisar de um pequeno ajuste — cada provedor tem seu próprio formato de campos; a documentação deles mostra o endpoint de "form action" pra copiar).
A maioria das notícias vem do Hacker News, que não tem foto própria — e usar uma foto de banco fixa por categoria fazia vários cards mostrarem exatamente a mesma imagem (além de, por um bug de categorização já corrigido, quase tudo cair na categoria "Software" por padrão).
A solução: cada card sem foto própria agora recebe arte gerada no próprio código — um ícone (2 variações por categoria) + um padrão de fundo (pontos, grade ou diagonal) + uma cor de destaque (âmbar ou ciano), escolhidos por um hash do título da notícia. Isso dá 12 combinações visuais por categoria, sempre a mesma pra aquele artigo específico (não muda a cada recarregamento), mas variando de notícia pra notícia. Vantagens sobre foto de banco:
- Nunca quebra (não depende de link externo nenhum)
- Combina com a identidade visual do site em vez de "descolar" com foto de estoque genérica
- Notícias que vêm com foto própria (comum em TechCrunch, Verge, Engadget) continuam mostrando a foto real — a arte só entra quando não há imagem, incluindo se uma foto real falhar ao carregar
Pra ajustar: os ícones SVG estão em ART_ICONS no topo do script.js — dá pra adicionar mais variações por categoria editando esse objeto.
As notícias chegam em inglês, direto da fonte. O botão "Traduzir" no topo liga uma tradução automática, sob demanda, usando a API gratuita e sem necessidade de chave do MyMemory — só traduz o que está visível na tela (destaque, ticker e os cards carregados), e guarda em memória o que já traduziu pra não repetir a mesma chamada.
Limitação importante (mesmo espírito do rss2json): o MyMemory tem um limite diário generoso, mas ainda é uma API gratuita compartilhada — em tráfego alto, pode atingir o limite e, quando isso acontece, o site simplesmente mantém o texto original em inglês (nunca quebra a experiência, só para de traduzir temporariamente). Pra um site em produção com muito tráfego, o caminho é trocar por uma API paga — Google Cloud Translation ou DeepL API — ajustando a função translateText() em script.js (a lógica de cache e fila já está pronta, só trocaria a chamada de rede).
A tradução é só do conteúdo das notícias — títulos e resumos. O resto do site (menus, categorias, textos da interface) já é em português desde a base.
O site mostra, quando você quiser, um parágrafo curto com sua opinião/análise sobre uma notícia específica — aparece destacado (borda âmbar) tanto no card quanto no destaque principal do topo. Se você comentou alguma notícia que ainda está no ar, ela vira automaticamente o destaque — sua voz fica em primeiro lugar, não só o mais recente.
Como funciona tecnicamente: o arquivo comentarios.json, aqui no repositório, é lido pelo site direto do GitHub a cada carregamento — sem precisar reenviar nada no Netlify. Editar esse arquivo em github.com já é suficiente pra atualizar o site ao vivo (efeito em poucos minutos).
Como adicionar um comentário:
- Ache a URL da notícia (clique nela no site e copie da barra de endereço, ou pegue o link "read on source")
- No GitHub, abra
comentarios.json, clique no ícone de lápis (editar) — o mesmo que você já usou pra editar o README - Adicione um bloco assim dentro dos colchetes
[ ](se já tiver outro bloco antes, separe com vírgula):{ "url": "https://cole-a-url-da-noticia-aqui", "comentario": "Sua opinião curta, 2-3 frases." } - Role até o final da página e clique em Commit changes
Exemplo completo, com duas notícias comentadas:
[
{
"url": "https://exemplo.com/noticia-1",
"comentario": "Isso conecta com o que vimos semana passada sobre X — acho que o próximo passo lógico é Y."
},
{
"url": "https://exemplo.com/noticia-2",
"comentario": "Discordo um pouco do tom da matéria; na prática, Z costuma ser mais complicado do que parece."
}
]Se der algum erro de formatação (esquecer uma vírgula, uma aspa etc.), sem problema — o site foi feito pra ignorar isso graciosamente: o pior que acontece é o comentário simplesmente não aparecer, nunca quebra o site inteiro. Se isso acontecer, confira se cada { } tem vírgula depois dele (exceto o último do array) e se todo texto está entre aspas duplas " ".
Um agregador puro (só linka manchetes de outros sites) é difícil de monetizar direto — pouco conteúdo original prejudica SEO, e o Google AdSense costuma recusar sites sem conteúdo próprio suficiente. O caminho mais realista, em ordem:
- Newsletter primeiro (já implementada acima). É o ativo mais valioso: uma lista de e-mails que você controla, diferente de tráfego de busca que pode sumir a qualquer momento.
- Adicione uma camada de opinião/análise sua em cima das notícias em destaque — um parágrafo autoral, não só o link. Isso ajuda o SEO e dá um motivo pra alguém voltar ao seu site em vez de só ler a manchete no Google Notícias.
- Afiliados, se o foco for produtos/hardware (ex: links de afiliado da Amazon nos gadgets mencionados).
- Patrocínio direto na newsletter — depois de ter uma lista de centenas/milhares de assinantes, vender um espaço fixo ("patrocinado por X") em cada edição costuma pagar mais e ser mais estável do que anúncios de banner.
- AdSense/anúncios diretos só depois de ter tráfego e conteúdo próprio consistentes — é o último passo, não o primeiro.
- Trocar o nome/marca: procure por "SIGNAL" em
index.htmlestyles.css(variável--amberdefine a cor de destaque). - Adicionar/remover fontes RSS: edite o array
feedsno topo descript.jse o arrayFEEDSno topo deworker.js(se estiver usando o Worker, mantenha os dois em sincronia). - Adicionar mais variações de arte: edite
ART_ICONSemscript.js— cada categoria aceita quantos ícones SVG você quiser na lista. - Mudar o intervalo de atualização: constante
refreshMsemscript.js(está em 5 minutos). - Paleta de cores: todas as cores estão centralizadas em
:rootno topo destyles.css.
- Mostra domínio de fetch assíncrono, tratamento de erro, cache e composição de múltiplas fontes de dados externas — inclusive um backend serverless real, não só front-end.
- Arquitetura com fallback em camadas (worker → busca direta → estado de erro) é o tipo de decisão que sites de produção de verdade precisam tomar.
- Arte gerativa determinística e tradução sob demanda com fila e cache — mostra raciocínio de engenharia além de só "chamar uma API", incluindo graceful degradation quando um serviço externo falha ou atinge limite.
- Design autoral (paleta âmbar/ciano sobre azul-marinho profundo, tipografia Space Grotesk + Inter + JetBrains Mono, conceito de "wire service" com ticker ao vivo) — não parece um template genérico.
- Responsivo, com estados de carregamento (skeleton), estado vazio, acessibilidade de foco e respeito a
prefers-reduced-motion.