4

Pitch: Um site 100% estático, zero backend — e mesmo assim precisei resolver 3 problemas clássicos de backend

Nas últimas semanas construí o SIGNAL — um agregador de notícias de tecnologia em HTML, CSS e JS puro (sem framework, sem servidor próprio) que busca manchetes reais de várias fontes e se atualiza sozinho. O objetivo era simples: peça de portfólio, sem infraestrutura paga.

No meio do caminho esbarrei numa ironia: um site sem backend ainda precisa se comportar como se tivesse um. Compartilho aqui as três decisões que mais importaram — não como "olha o que eu fiz", mas como os problemas reais que apareceram e como pensei cada solução.

  1. Dependência gratuita tem limite, e isso quebra em silêncio

O site busca manchetes do Hacker News (API própria, sem limite de uso) e de veículos como TechCrunch e The Verge via RSS, convertido pra JSON por um serviço gratuito de terceiros. Esse serviço tem cota diária de requisições. Sozinho, testando, eu nunca batia nesse limite. Mas pensando em tráfego real — várias pessoas abrindo o site ao mesmo tempo, cada navegador disparando a mesma leva de chamadas — ficou óbvio que isso quebraria exatamente quando o site tivesse mais visitantes. O pior momento possível pra falhar.

A solução foi tirar essa dependência do navegador do visitante: um Cloudflare Worker busca os feeds direto no servidor (parseando RSS na mão, sem passar pelo serviço terceiro) e cacheia o resultado por alguns minutos. Mil visitantes agora geram o mesmo tráfego pras fontes originais que um visitante só.

Mas o Worker também pode falhar — cair, ficar lento, não estar configurado ainda. Então o carregamento virou uma cadeia de fallback:

async function loadAll() {
  let items = await loadFromWorker();      // 1) tenta o cache no servidor
  if (!items) items = await loadDirect();  // 2) senão, busca direto no navegador
  // 3) se mesmo assim vier vazio, mostra um estado de erro claro
}

Cada camada existe porque a anterior pode falhar, e o visitante nunca deveria perceber isso.

  1. Uma categoria "padrão" que mentia sobre o conteúdo

Cada notícia é categorizada por palavra-chave (IA, hardware, segurança etc). O que eu não previ: boa parte do que sai no Hacker News não é sobre nenhuma dessas categorias — é filosofia, negócio, cultura. O código tratava esse caso caindo, por padrão, na categoria "Software". Resultado: um post tipo "Is The Economist Always Wrong?" aparecia catalogado como Software — e como eu usava uma foto de banco fixa por categoria, várias notícias sem nada a ver entre si acabavam mostrando literalmente a mesma imagem.

A correção não foi visual, foi lógica: criar uma categoria "Geral" de verdade em vez de forçar tudo num balde errado. E pra resolver a repetição de imagem sem depender de mais fotos de banco (que cedo ou tarde voltam a se repetir), troquei por arte gerada no próprio código — um hash do título escolhe um ícone, um padrão de fundo e uma cor de destaque. Sempre a mesma combinação pro mesmo artigo, sempre diferente de artigo pra artigo, e nunca depende de link externo que pode cair.

  1. Tradução sob demanda sem estourar limite gratuito (de novo)

As notícias chegam em inglês. Pra oferecer tradução automática sem pagar por API (Google Cloud Translate, DeepL), usei a API gratuita do MyMemory — que também tem cota diária. A saída foi: traduzir só o que está de fato visível na tela (não a lista inteira de uma vez), guardar em cache o que já foi traduzido pra nunca repetir a mesma chamada, e limitar quantas traduções rodam em paralelo. Se a tradução falhar ou bater no limite, o texto original em inglês continua aparecendo — a experiência nunca quebra, só para de traduzir temporariamente.

O padrão que se repetiu

As três situações têm a mesma forma: uma dependência gratuita e útil, com um limite real, e a pergunta "o que acontece quando esse limite é atingido?". Se a resposta é "o site quebra", isso é um problema de arquitetura, não só de código. Tratar isso como fallback em camadas — em vez de simplesmente torcer pra não acontecer — foi a decisão que mais valeu a pena no projeto inteiro.

O site tá no ar aqui: https://techsignal.netlify.app/

Fica aberto a crítica. Se alguém tiver uma abordagem diferente pra esses mesmos problemas (ou já resolveu isso de um jeito melhor em algum projeto próprio), tenho bastante interesse em ouvir nos comentários.

Carregando publicação patrocinada...
2

Seu projeto tem um backend, mas do lado do Front-end, o que o torna inseguro.

melhor separar a lógica com um backend dedicado e fazer deploy em um plano gratuito.

O seu projeto parece um wrapper em cima de outros serviços (posso estar enganado).

Não precisa traduzir usando nenhuma API, por Exemplo. O usuário pode traduzir para seu idioma usando o navegador, evitando problemas de cota e reduzindo complexidade na arquitetura.

1

Valeu pelo comentário, é o tipo de crítica que eu queria receber aqui. Vou por partes:

Sobre ser um wrapper em cima de outros serviços — procede, sim. É um agregador por definição; o valor que tentei colocar não está em ser uma fonte de dado nova, mas na camada de composição (dedup, fallback, categorização).

Sobre separar a lógica num backend dedicado com deploy gratuito — isso já existe no projeto, é justamente o item 1 do post: o Cloudflare Worker. Ele roda no plano gratuito da Cloudflare e faz exatamente isso, busca e parseia os feeds no servidor. Deixei ele como camada opcional (não obrigatória) porque queria que o projeto continuasse rodando com zero configuração pra quem só quiser subir os arquivos estáticos — o Worker é o upgrade de quem precisa de mais escala, não um requisito.

Sobre ser inseguro por rodar do lado do front-end — aqui eu preciso que você seja mais específico, porque não estou enxergando qual vulnerabilidade concreta isso introduz. Não tem segredo/API key exposta (as APIs usadas são públicas e sem chave), não tem dado de usuário, não tem autenticação. Rodar a busca no navegador tem desvantagem real (a que você já citou, cota/confiabilidade — resolvida pelo Worker), mas eu não vejo isso como "inseguro" sem um vetor de ataque concreto por trás. Qual seria o risco que você tem em mente?

Sobre não precisar de API de tradução, usar o tradutor do navegador — esse é o ponto que mais me fez pensar. É genuinamente uma alternativa mais simples, e reduz complexidade de verdade. A razão de eu ter optado por uma tradução embutida no próprio site foi querer que funcionasse com um clique só, sem depender de o visitante ter o tradutor do navegador configurado (nem todo mundo usa Chrome, ou tem a opção ativada) — mas reconheço que isso é uma escolha de UX, não uma necessidade técnica, e trocar por confiar no navegador do usuário reduziria bastante a superfície da aplicação. Vou pensar nisso com calma.

2

Para ser mais específico, a prática de deixar a lógica no front-end é inseguro, mesmo que não manipule dados confidenciais.

Outro ponto que levei em consideração é que no futuro pode escalar e precisar manipular esse tipo de informação. Mover toda a lógica para p bankend vai exigir esforço máximo.

Em resumo, a prática (ato) de deixar lógica no Fronto-end é inseguro, mesmo que não manipule nada confidencial. Dependendo do caso pode ser possível abusar das cotas, ou algo do tipo.

De qualquer forma, parabéns pelo o projeto! Da para perceber que você colocou esforço genuíno nele.

2

Faz sentido, e acho que a gente tá falando de duas coisas diferentes por trás da mesma palavra. O que você descreveu agora: Abuso de cota, esforço de migração se precisar escalar — é real, mas eu chamaria isso de risco de disponibilidade/custo de evolução, não de insegurança no sentido de confidencialidade ou autorização.

E na prática, o cenário de abuso de cota que você descreve é exatamente o que o Worker (item 1 do post) resolve: como ele cacheia a resposta por alguns minutos, mesmo que alguém tente fazer hammering na página, quem sofre é o cache, não a cota das fontes originais. Sem o Worker ativo, concordo que esse risco existe de verdade.

De qualquer forma, valeu por detalhar — ajudou a deixar mais preciso o que exatamente tava em jogo. E obrigado pelo elogio!

0

achei bem legal inclusive lá achei uns blogs bem interessante que vou começar a seguir, mas sinceramente eu recomendo dá um trato na UI para algo mais original para o site, porque dá claramente de ver que teve um dedo de IA e para mim isso perde um pouco da confiabilidade.

não tô dizendo que ia que cria sites é ruim nem nada inclusive eu uso bastante Lovable para projetos pessoais, a questão é sobre ter um design próprio.

2

Cara,
Eu não sei se você usou ou não ia no desenvolvimento do layout. Não sei se isso é bom ou ruim (usar E não usar...)
Eu achei o site bonito. Bem bonito até.
A faixa laranja ficou boa. Chama a atenção e o que senti depois foi bom.
Acho que se fosse o caso de haver dúvidas sobre a qualidade do produto a opção de não inovar seria menos atraente.

Não tenho certeza se o projeto é sério mesmo. Não sei se é de código-aberto (não sei se tá no github)
Não sei sobre monetização nem nada disso...

Mas como eu fiquei com uma boa impressão (e estou ativamente buscando oportunidade)
Eu ofereço ajuda. Eu tenho umas habilidades e eu tenho tempo. É o que eu ofereço.

😀

1

Rodrigo, muito obrigado pela oferta, e pela sinceridade também!

Respondendo direto: o projeto ainda não tá no GitHub — é uma das coisas que pretendo resolver, só ainda não aconteceu. Sobre ser "sério": começou mesmo como peça de portfólio, sem modelo de monetização definido ainda.

Fico com a oferta de ajuda, sim — topo trocar ideia sobre como isso funcionaria na prática. Tem alguma forma de eu te chamar (e-mail, LinkedIn, Discord, o que for mais fácil pra você)?

1
1

Valeu por essa, e que bom que os blogs que apareceram lá te interessaram — é exatamente pra isso que o site existe.

Sobre o design: é justo, e vou ser transparente — teve ajuda de IA em boa parte da construção, inclusive na parte visual. Curti o resultado, mas entendo o ponto sobre ter uma identidade mais própria, menos reconhecível como "gerada". Vou levar isso a sério pra próxima iteração — se tiver algum exemplo específico do que te pareceu mais genérico (paleta, tipografia, algum componente em especial), eu adoraria ouvir. Ajuda bem mais que um "deixa mais original" solto.

0