Configuração
Nesta página
Põe as opções do plugin e as definições opcionais do Vite em sitelo.config.js. Não é preciso nenhum vite.config.js.
export default {
site: 'https://example.com',
rss: {
site: 'https://example.com',
title: 'O meu blogue',
description: 'Últimos artigos',
routePrefix: '/blog',
},
vite: {
publicDir: 'static',
build: {
emptyOutDir: true,
outDir: 'public',
},
server: {
port: 8888,
},
},
}Opções do plugin
pagesDir— por omissão'src'pageExtensions— que sufixos contam como páginascleanUrls— por omissãotrue(/about/index.html)site— URL base; ativa ositemap.xmlrss— configuração do feed RSSpagefind—trueou objeto de opções; indexa o site com o Pagefind depois desitelo build(requernpm install -D pagefind)images—trueou objeto de opções; otimiza as imagens em desenvolvimento e depois desitelo build(requernpm install -D sharp)missingAssets—'error'ou'warn'linkCheck— ligações internas mortas (vê Verificação de ligações)lighthouse— auditorias Lighthouse da compilação (ver Auditorias Lighthouse)generatedTypesDir— por omissão'.sitelo/types'renderConcurrency/renderBatchSize— paralelismo da compilaçãobuildReport— por omissãotrue; resumo pós-compilação com páginas, tamanho de saída, maiores ficheiros e tempos por fase.falsedesativa, ou{ top }muda quantos ficheiros grandes são listadosdebug— registo detalhadodevToolbar— por omissãotrue; põefalsepara ocultar a barra de ferramentas de desenvolvimento (ficheiro de origem, parâmetros, número de ilhas, seletor de viewport)devToolbarDocsUrl— ligação para a documentação na barra (por omissãohttps://sitelo.dev/docs)
Barra de ferramentas de desenvolvimento
Enquanto o sitelo (dev) corre, uma pequena barra no fundo de cada página mostra o ficheiro da página, os parâmetros e quantas ilhas de servidor existem nela. Usa o botão de viewport para alternar entre Desktop / Tablet / Mobile (num iframe, para que as media queries batam certo), e Copy para obteres um bloco de depuração ao abrir issues. Nunca aparece na saída de sitelo build.
// sitelo.config.js
export default {
devToolbar: false, // ocultar para toda a gente neste projeto
}Opções do Vite
Tudo o que estiver sob vite é fundido na configuração do Vite. As opções da CLI (por exemplo --port) têm precedência sobre ambas.
Se já tens um vite.config.js
Continua a ser suportado — ou só opções do Vite, ou controlo total do plugin:
// Apenas opções do Vite; o sitelo continua a injetar o plugin
export default {
publicDir: 'static',
server: { port: 8888 },
}// Registar o plugin manualmente
import htmlPages from 'sitelo'
export default {
plugins: [htmlPages({
site: 'https://example.com',
})],
}Se o plugin já estiver na tua configuração do Vite, põe aí as opções do plugin — e não também como opções de plugin em sitelo.config.js (o sitelo dará erro).
Sitemap e RSS
Define site para emitir dist/sitemap.xml.
RSS:
export default {
rss: {
site: 'https://example.com',
title: 'O meu blogue',
description: 'Últimos artigos',
routePrefix: '/blog',
},
}Produz dist/rss.xml com um item por cada página sob routePrefix.
Verificação de ligações
Os <script src> e hrefs de folhas de estilo partidos já fazem falhar a compilação (vê missingAssets). O linkCheck cobre a outra metade: as ligações internas <a href> que apontam para uma página que não existe.
export default {
linkCheck: true, // 'warn' (por omissão), 'error', ou um objeto de opções
}Depois de sitelo build, cada ligação interna da saída é resolvida e tudo o que não tenha uma página por trás é reportado, agrupado pela página onde aparece:
[sitelo] 3 ligações internas partidas
index.html
../escape -> sai do diretório de saída
/abuot -> não existe essa página
/blog/missing-post -> não existe essa páginaComo as ligações são resolvidas
A verificação corre sobre o site emitido, não sobre a tabela de rotas — por isso tem em conta cleanUrls, os grupos de rotas, mapOutputPath, os ficheiros copiados de public/ e as páginas produzidas por rotas dinâmicas. Corre também depois da otimização de imagens e do Pagefind, por isso vê exatamente o que é publicado. Uma ligação é válida quando um ficheiro real lhe responde, tentado pela ordem que um alojamento estático usaria:
/about→about, depoisabout/index.html, depoisabout.html/blog/→blog/index.html(uma barra final só pode significar índice de diretório)/→index.html
As ligações relativas (../about) são resolvidas relativamente à página que as contém, e as que saem do diretório de saída são reportadas. As query strings são ignoradas na resolução — /about?utm=x verifica /about.
As ligações externas nunca são descarregadas. https://, as relativas ao protocolo //cdn.example.com, mailto:, tel: e outros esquemas são saltados por completo.
Opções
| Opção | Por omissão | Descrição |
|---|---|---|
mode | 'warn' | 'warn' regista e continua; 'error' faz falhar a compilação — útil em CI |
exclude | [] | Globs ou expressões regulares de hrefs a saltar |
checkFragments | false | Verifica também se os destinos #fragmento existem na página ligada |
export default {
linkCheck: {
mode: 'error', // falha a compilação perante uma ligação morta
checkFragments: true, // verifica também os destinos #fragmento
exclude: ['/api/**', /^\/legacy\//],
},
}checkFragments vem desligado porque os ids acrescentados por JavaScript de cliente não estão no HTML compilado, e seriam reportados como inexistentes. Contam como destinos de fragmento tanto id como o antigo atributo de âncora name.
Sites servidos a partir de uma base
Se o teu site for implementado sob uma base (um site de projeto do GitHub Pages, por exemplo), qualquer ligação relativa à raiz que não leve essa base é reportada. Um /about num site servido a partir de /repo/ manda o navegador para a raiz do host, não para dentro do teu site — resolvê-la à mesma contra a saída esconderia precisamente o erro que vale a pena apanhar. Usa exclude quando for de propósito.
Auditorias Lighthouse
sitelo lighthouse audita a compilação final com Lighthouse. É uma dependência par opcional:
npm install -D lighthouseO sitelo serve dist/ tal como o sitelo preview, aponta um Chrome headless a cada página e imprime as pontuações:
[sitelo] lighthouse mobile - 3 pages
page perf a11y best seo
/ 98 100 100 100
/docs 95 100 100 100
/docs/routing 97 100 100 100
[sitelo] lighthouse audited 3 pages in 31.4sCada página é auditada no URL que o site liga — /docs, nunca dist/docs.html —, por isso cleanUrls, os grupos de rotas e um base ficam cobertos. Com limiares, o relatório passa a ser uma verificação: qualquer pontuação abaixo faz o comando falhar.
export default {
lighthouse: {
exclude: ['404.html'], // a página 404 raramente vale uma auditoria
thresholds: {
performance: 90,
accessibility: 100,
'best-practices': 95,
seo: 100,
},
},
}As pontuações escrevem-se como o Lighthouse as mostra (0–100); as frações de 0 a 1 também funcionam. Usa mode: 'warn' para registar sem falhar.
include/exclude— que páginas são auditadas (globs ou expressões regulares)sample— auditar esta quantidade de páginas ao acaso por padrãoinclude, em vez de todascategories—performance,accessibility,best-practices,seothresholds— pontuação mínima por categoriamode—'error'(por omissão) ou'warn'formFactor—'mobile'(por omissão),'desktop'ou ambosruns— repete a auditoria e reporta a pontuação medianaoutput/formats— guarda o relatório completo do Lighthouse de cada páginaflags/config— passados tal como estão ao Lighthouse, portanto vale tudo o que a CLI dele aceitaonBuild— auditar também no fim desitelo build
export default {
lighthouse: {
formFactor: 'desktop', // predefinição desktop do Lighthouse
runs: 3, // três execuções por página, pontuação mediana
output: true, // relatórios completos em .sitelo/lighthouse/
onBuild: true, // audita também no fim de sitelo build
flags: { throttlingMethod: 'provided' },
},
}O Lighthouse conduz um Chrome real: instala um onde a auditoria corre, ou aponta CHROME_PATH a um binário. As pontuações de desempenho variam entre execuções, por isso usa runs: 3 antes de fixares um limiar sobre elas.
Pesquisa Pagefind
Pesquisa estática opcional com o Pagefind, uma dependência de pares opcional. Instala-o quando quiseres pesquisa, depois ativa a indexação, marca o conteúdo, monta a interface e corre sitelo build.
npm install -D pagefind1. Ativa a indexação
Põe pagefind: true. Depois de sitelo build obténs dist/pagefind/ e, por omissão, uma cópia em public/pagefind/ para que o próximo sitelo (dev) ou sitelo preview possa servir /pagefind/ sem recompilar.
export default {
pagefind: true,
}2. Marca o conteúdo e acrescenta um ponto de montagem
Põe data-pagefind-body no conteúdo principal para que a navegação e o rodapé não sejam indexados. Deixa um elemento vazio para a interface de pesquisa:
export default () => `
<html lang="pt">
<head>
<title>O meu site</title>
<link rel="stylesheet" href="/styles.css">
<script type="module" src="/main.js"></script>
</head>
<body>
<header>
<a href="/">Início</a>
<div id="search"></div>
</header>
<main data-pagefind-body>
<h1>Olá</h1>
<p>Só esta região é indexada.</p>
</main>
</body>
</html>
`import {
html, head, title, link, script, body, header, a, div, main, h1, p,
} from 'javascript-to-html'
export default () =>
html({ lang: 'pt' },
head(
title('O meu site'),
link({ rel: 'stylesheet', href: '/styles.css' }),
script({ type: 'module', src: '/main.js' }),
),
body(
header(
a({ href: '/' }, 'Início'),
div({ id: 'search' }),
),
main({ 'data-pagefind-body': '' },
h1('Olá'),
p('Só esta região é indexada.'),
),
),
)export default function Home() {
return (
<html lang="pt">
<head>
<title>O meu site</title>
<link rel="stylesheet" href="/styles.css" />
<script type="module" src="/main.js" />
</head>
<body>
<header>
<a href="/">Início</a>
<div id="search" />
</header>
<main data-pagefind-body="">
<h1>Olá</h1>
<p>Só esta região é indexada.</p>
</main>
</body>
</html>
)
}3. Monta a interface do Pagefind
Carrega /pagefind/pagefind-ui.js e pagefind-ui.css a partir do teu script de cliente (só depois de uma compilação ter produzido o índice):
async function initSearch() {
const mount = document.querySelector('#search')
if (!mount) return
// O índice só existe depois de `sitelo build` (sincronizado para public/pagefind por omissão)
try {
const probe = await fetch('/pagefind/pagefind-ui.js', { method: 'HEAD' })
if (!probe.ok) return
} catch {
return
}
const style = document.createElement('link')
style.rel = 'stylesheet'
style.href = '/pagefind/pagefind-ui.css'
document.head.appendChild(style)
await new Promise((resolve, reject) => {
const script = document.createElement('script')
script.src = '/pagefind/pagefind-ui.js'
script.onload = resolve
script.onerror = reject
document.body.appendChild(script)
})
new window.PagefindUI({
element: '#search',
showImages: false,
})
}
initSearch()4. Compila e ignora o pacote sincronizado
sitelo build
# depois: sitelo preview — ou sitelo (dev) a usar public/pagefindpublic/pagefind/As opções avançadas (syncPublic, glob, idioma, seletores, …) vão num objeto: pagefind: { syncPublic: false, glob: '**/*.html' }. Todas as opções da interface: pagefind.app.
404
Cria src/404.ht.js para obteres dist/404.html. Caso contrário é gerada uma página por omissão.