Million Dollar Homepage: 21 Anos Depois, o Que Uma Pagina de 2005 Ensina Sobre Link Rot
Ola HaWkers, no dia 26 de agosto de 2026 a Million Dollar Homepage completou 21 anos no ar. Um estudante de 21 anos chamado Alex Tew, de Cricklade, na Inglaterra, colocou no ar em 26 de agosto de 2005 uma pagina com uma grade de 1000 por 1000 pixels e vendeu cada pixel por 1 dolar, em blocos minimos de 10 por 10 por 100 dolares. Em janeiro de 2006 ele leiloou os ultimos 1.000 pixels no eBay: o leilao abriu em 1 de janeiro, fechou em 11 de janeiro com lance de 38.100 dolares e levou o total bruto para 1.037.100 dolares.
A parte que interessa para quem escreve codigo nao e o dinheiro. Enquanto escrevo este artigo, milliondollarhomepage.com respondeu HTTP 200. A pagina esta la, na mesma URL, 21 anos depois. E os links que ela vendeu, esses morreram. Quantas das suas URLs de 2019 ainda respondem hoje? E quantos dos links que voce citou nos seus ultimos dez artigos ainda levam a algum lugar?
A pagina que vendeu um milhao de pixels
O modelo era ridiculamente simples e por isso funcionou. Tew precisava de dinheiro para a faculdade, montou uma pagina com um <img> gigante de 1000 por 1000, um mapa de imagem por cima e vendeu espaco publicitario por pixel. Cada anunciante mandava a arte do bloco e a URL de destino. Em cinco meses, de agosto de 2005 a janeiro de 2006, a coisa toda fechou em 1.037.100 dolares brutos.
Tecnicamente, o que existe ali e o minimo possivel:
- HTML estatico servido direto.
- Uma imagem grande com um
<map>e centenas de elementos<area>. - Nenhum banco de dados na frente, nenhum framework, nenhum passo de build.
Essa escolha nao foi visionaria, foi so o que dava para fazer em 2005. Mas e exatamente por isso que a pagina atravessou tres decadas de mudanca de stack sem precisar de manutencao. Nao tem dependencia para atualizar, nao tem runtime para migrar, nao tem versao de Node para subir. Se voce gosta desse tipo de arqueologia, ja escrevi sobre como recriar aquela estetica no artigo de estilo retro no web design com CSS e JavaScript.
O paradoxo: a pagina vive, os links dela morreram
Aqui esta a virada. O container sobreviveu, o conteudo apontado por ele nao.
Em 2014, quando a pagina tinha nove anos, uma analise citada pelo Guardian e pelo Gizmodo encontrou 22% dos links mortos, o equivalente a 221.900 pixels. Desses, 23.200 pixels ja nasceram quebrados, porque o anunciante nunca entregou a URL de destino. Ou seja: cerca de 20% dos links morreram ao longo de oito anos. Em 2017, a estimativa registrada na Wikipedia ja era de aproximadamente 40% dos links afetados por link rot.
Repare no que aconteceu. Alex Tew fez a parte dele: manteve a URL viva por duas decadas. Quem quebrou o trato foram as centenas de empresas que compraram pixel, mudaram de dominio, foram compradas, trocaram o site inteiro ou simplesmente sumiram. A durabilidade da sua pagina nao depende so de voce. Depende de todo mundo que voce cita.
Link rot nao e anedota, e estatistica
O Pew Research Center publicou em 17 de maio de 2024 o relatorio "When Online Content Disappears", e os numeros sao brutais:
- 38% das paginas que existiam em 2013 nao estavam mais acessiveis em outubro de 2023.
- 25% de todas as paginas que existiram em algum momento entre 2013 e 2023 ja tinham sumido.
- 8% das paginas que existiam em 2023 ja tinham sumido no mesmo ano. A decomposicao comeca rapido.
- 23% das paginas de noticia tem pelo menos um link quebrado.
- 21% das paginas de sites governamentais tambem.
- 54% das paginas da Wikipedia tem pelo menos um link morto na secao de referencias.
E nas redes o prazo de validade e ainda menor: acompanhando uma amostra de tweets por tres meses, quase 1 em cada 5 deixou de ser publicamente visivel. Em 60% dos casos a conta virou privada, foi suspensa ou apagada; nos outros 40% o autor apagou so aquele post. Para tweets em turco ou arabe, mais de 40% sumiram em tres meses.
Traduzindo para o seu blog: se voce publica ha cinco anos, uma parte relevante das suas fontes ja e ficcao. O texto continua afirmando algo com um link que nao prova mais nada.
Cool URIs don't change: a regra de 1998 que continua valendo
Em 1998, Tim Berners-Lee escreveu um documento curto chamado "Cool URIs don't change", hospedado em w3.org/Provider/Style/URI. A tese cabe em uma linha: depois que voce cria uma URI, e sua obrigacao manter ela funcionando para sempre; se o documento mudar de lugar, a URL antiga vira redirecionamento.
Enquanto escrevia este artigo, testei aquele endereco. Ele respondeu HTTP 200. Vinte e oito anos na mesma URL, praticando o que prega.
A parte que a maioria dos times ignora e que URL nao e detalhe de implementacao, e contrato publico. Os erros classicos:
- Colocar a tecnologia na URL:
/artigo.php,/posts.aspx. A tecnologia troca, a URL fica presa. - Colocar data ou status na URL:
/2024/novo/produto. Ano que vem nada disso e verdade. - Reestruturar o site e deixar o 404 resolver. Nao resolve: voce perde o link externo, o ranqueamento e a citacao.
Regra pratica: URL curta, sem extensao, sem estado, e todo caminho antigo vira 301 permanente.
Auditando os links do seu proprio site
Chega de teoria. O primeiro passo e saber quantos links do seu conteudo ja estao mortos. Da para fazer isso com Node puro, sem instalar nada:
// scripts/check-links.mjs
// Varre os markdown do conteudo e testa cada link externo.
import { readdir, readFile } from 'node:fs/promises'
import { join } from 'node:path'
const CONTENT_DIR = 'content/blog'
const CONCURRENCY = 8
const TIMEOUT_MS = 10000
async function collectLinks(dir) {
const files = await readdir(dir, { withFileTypes: true })
const found = new Map() // url -> arquivos onde aparece
for (const file of files) {
if (!file.isFile() || !file.name.endsWith('.md')) continue
const raw = await readFile(join(dir, file.name), 'utf8')
// Captura apenas links markdown para http/https
const matches = raw.matchAll(/\]\((https?:\/\/[^)\s]+)\)/g)
for (const [, url] of matches) {
if (!found.has(url)) found.set(url, [])
found.get(url).push(file.name)
}
}
return found
}
async function probe(url) {
const controller = new AbortController()
const timer = setTimeout(() => controller.abort(), TIMEOUT_MS)
try {
// HEAD e mais barato, mas muitos servidores respondem 405
let res = await fetch(url, { method: 'HEAD', redirect: 'follow', signal: controller.signal })
if (res.status === 405 || res.status === 501) {
res = await fetch(url, { method: 'GET', redirect: 'follow', signal: controller.signal })
}
return { url, status: res.status, ok: res.ok }
} catch (error) {
return { url, status: 0, ok: false, error: error.name }
} finally {
clearTimeout(timer)
}
}
const links = await collectLinks(CONTENT_DIR)
const queue = [...links.keys()]
const broken = []
// Pool manual de concorrencia: nao derruba o servidor alheio nem o seu
await Promise.all(
Array.from({ length: CONCURRENCY }, async () => {
while (queue.length) {
const url = queue.shift()
const result = await probe(url)
if (!result.ok) broken.push({ ...result, files: links.get(url) })
}
})
)
console.log(`Links unicos verificados: ${links.size}`)
console.log(`Quebrados: ${broken.length}`)
for (const item of broken) {
console.log(`${item.status || item.error}\t${item.url}\t${item.files.slice(0, 3).join(', ')}`)
}
process.exit(broken.length > 0 ? 1 : 0)Rode isso uma vez no seu conteudo antigo. O resultado costuma doer.
Colocando o check no CI toda semana
Auditoria manual e aquela que voce faz uma vez e nunca mais. Agende:
# .github/workflows/link-check.yml
name: link-check
on:
schedule:
# Toda segunda as 06:00 UTC
- cron: '0 6 * * 1'
workflow_dispatch:
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
# Falha o job quando aparece link morto, e o alerta chega por e-mail
- run: node scripts/check-links.mjs
Redirecionar em vez de deletar
Quando voce muda um slug, o link externo que apontava para o antigo nao muda junto. A unica saida honesta e o redirecionamento permanente. Em um projeto Nuxt, isso vive nas routeRules:
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
// 301: permanente. O Google transfere a autoridade do link antigo.
'/blog/post-antigo': { redirect: { to: '/blog/post-novo', statusCode: 301 } },
// Secao inteira que mudou de lugar
'/artigos/**': { redirect: { to: '/blog/**', statusCode: 301 } },
},
})Tres detalhes que fazem diferenca:
- 301, nao 302. O 302 e temporario e diz ao buscador para continuar indexando a URL antiga. Se a mudanca e definitiva, use 301.
- Nao encadeie redirecionamentos.
A -> B -> Cfunciona no navegador e desperdica orcamento de rastreamento. AponteA -> Cdireto. - Nunca redirecione tudo para a home. Para o buscador, redirecionar conteudo que sumiu para a home e tratado como 404 disfarcado. Se nao existe destino equivalente, devolva um 410 honesto.
Salvando o que voce cita antes que suma
Voce controla as suas URLs. Nao controla as URLs que voce cita. A defesa e arquivar a fonte no momento em que voce escreve, e nao no dia em que ela quebra.
// scripts/archive-sources.mjs
// Manda cada fonte para o Wayback Machine e guarda o snapshot.
const SAVE_ENDPOINT = 'https://web.archive.org/save/'
const AVAILABILITY = 'https://archive.org/wayback/available?url='
export async function ensureArchived(url) {
// 1. Ja existe snapshot?
const check = await fetch(`${AVAILABILITY}${encodeURIComponent(url)}`)
const data = await check.json()
const snapshot = data?.archived_snapshots?.closest
if (snapshot?.available) {
return { url, archived: snapshot.url, created: false }
}
// 2. Nao existe: pede o arquivamento agora
const saved = await fetch(`${SAVE_ENDPOINT}${url}`, { method: 'GET', redirect: 'follow' })
if (!saved.ok) {
throw new Error(`Falha ao arquivar ${url}: HTTP ${saved.status}`)
}
return { url, archived: saved.url, created: true }
}Com isso, quando a fonte morrer, o seu artigo continua provando o que afirma. Nas citacoes mais importantes, vale linkar direto para o snapshot e deixar o original como referencia secundaria.
Um checklist para paginas que atravessam a decada
O que a Million Dollar Homepage acertou sem querer, voce pode fazer de proposito:
- Saida estatica sempre que possivel. HTML que nao depende de runtime nao quebra quando o runtime for descontinuado. Um site gerado estaticamente sobrevive a mudanca de host com um
rsync. - Menos dependencias. Cada pacote no
package.jsone uma chance de o build de amanha nao rodar. A pagina de 2005 tem zero. - Nada de conteudo preso em API de terceiro. Se o texto do seu artigo so existe dentro de um CMS SaaS, o seu arquivo esta na mao do plano de precos daquela empresa.
- URLs sem tecnologia e sem data.
/blog/nome-do-assuntosobrevive a qualquer migracao. - Assets no seu dominio. Imagem hospedada em servico gratuito de terceiro e link rot com data marcada.
- Sitemap e
lastmodcorretos. Ajuda o buscador a perceber o que ainda esta vivo. - Backup do conteudo em texto puro, versionado em Git. Markdown em repositorio e o formato mais duravel que existe hoje: texto simples, legivel sem ferramenta nenhuma.
Nada disso e exotico. E o oposto: e escolher o chato e o simples em vez do impressionante e fragil.
O que isso muda para quem publica em 2026
Existe uma ironia boa aqui. Em 2005, publicar uma pagina que dura era o padrao acidental, porque a stack era pobre. Em 2026, com todo o ferramental que temos, publicar algo que dure virou uma decisao deliberada, que exige disciplina contra a tentacao de adicionar mais uma camada.
E a pressao aumentou. Com buscadores e assistentes de IA resumindo conteudo em vez de mandar clique, a citacao que sobra e o link. Quando esse link morre, some tambem a evidencia de que o seu trabalho existiu primeiro. Manter URL viva deixou de ser boa pratica de SEO e virou preservacao de autoria.
A Million Dollar Homepage nao e um caso de sucesso de marketing viral, ou nao so isso. Ela e a prova de que a coisa mais dificil na web nao e publicar. E continuar publicado. Alex Tew fez o dele por 21 anos: rode o script de auditoria no seu conteudo hoje e descubra quantos anos voce ja perdeu.
Bora pra cima! 🦅
📚 Quer Acompanhar o Que Vem Por Ai?
Este artigo cobriu link rot, URLs permanentes e como auditar o proprio conteudo, mas o ecossistema muda toda semana e nem tudo vira artigo aqui.
No X eu compartilho o que estou testando, os bastidores dos projetos e as novidades que aparecem antes de virarem post.
Me Segue La
💡 Conteudo diario sobre desenvolvimento, carreira e as ferramentas que eu realmente uso

