Konfigurasi

Taruh opsi plugin dan pengaturan Vite opsional di sitelo.config.js. Tidak perlu vite.config.js.

export default {
  site: 'https://example.com',
  rss: {
    site: 'https://example.com',
    title: 'Blog saya',
    description: 'Tulisan terbaru',
    routePrefix: '/blog',
  },
  vite: {
    publicDir: 'static',
    build: {
      emptyOutDir: true,
      outDir: 'public',
    },
    server: {
      port: 8888,
    },
  },
}

Opsi plugin

Bilah alat pengembangan

Selagi sitelo (pengembangan) berjalan, bilah kecil di bagian bawah tiap halaman menampilkan berkas halaman, parameter, dan berapa banyak island server yang ada di halaman itu. Gunakan tombol viewport untuk berganti pratinjau Desktop / Tablet / Mobile (berupa iframe, jadi kueri media ikut cocok), dan Copy untuk gumpalan awakutu saat melaporkan masalah. Ia tidak pernah muncul di keluaran sitelo build.

// sitelo.config.js
export default {
  devToolbar: false, // sembunyikan untuk semua orang di proyek ini
}

Opsi Vite

Apa pun di bawah vite digabungkan ke konfigurasi Vite. Flag CLI (misalnya --port) menimpa keduanya.

Build sitelo menyetel build.rollupOptions.checks.pluginTimings: false. Jika tidak, Rolldown melaporkan bahwa hook plugin mendominasi build — yang pada situs sitelo selalu benar, karena membuat halaman memang inti build-nya — sehingga ia menyebut plugin yang sama setiap kali berjalan. Setel ke true di bawah vite ketika memprofil plugin Anda sendiri.

vite.config.js yang sudah ada

Masih didukung — baik opsi khusus Vite, maupun kendali penuh atas plugin:

// Hanya opsi Vite; sitelo tetap menyuntikkan plugin
export default {
  publicDir: 'static',
  server: { port: 8888 },
}
// Daftarkan plugin sendiri
import htmlPages from 'sitelo'

export default {
  plugins: [htmlPages({
    site: 'https://example.com',
  })],
}

Jika plugin sudah ada di konfigurasi Vite Anda, taruh opsi plugin di sana — jangan sekaligus sebagai opsi plugin di sitelo.config.js (sitelo akan memberi galat).

Peta situs dan RSS

Setel site untuk menghasilkan dist/sitemap.xml.

RSS:

export default {
  rss: {
    site: 'https://example.com',
    title: 'Blog saya',
    description: 'Tulisan terbaru',
    routePrefix: '/blog',
  },
}

Menghasilkan dist/rss.xml dengan satu item untuk setiap halaman di bawah routePrefix.

Pemeriksaan tautan

<script src> dan href lembar gaya yang rusak sudah menggagalkan build (lihat missingAssets). linkCheck mengurus separuh sisanya: tautan <a href> internal yang menunjuk halaman yang tidak ada.

export default {
  linkCheck: true,   // 'warn' (bawaan), 'error', atau objek opsi
}

Setelah sitelo build, setiap tautan internal di keluaran diselesaikan dan apa pun yang tidak punya halaman di baliknya dilaporkan, dikelompokkan menurut halaman tempatnya muncul:

[sitelo] 3 tautan internal yang rusak

  index.html
    ../escape           -> keluar dari direktori keluaran
    /abuot              -> halaman tidak ada
    /blog/missing-post  -> halaman tidak ada

Bagaimana tautan diselesaikan

Pemeriksaan berjalan terhadap situs yang dihasilkan, bukan tabel rute — jadi ia memperhitungkan cleanUrls, grup rute, mapOutputPath, berkas yang disalin dari public/, dan halaman yang dihasilkan rute dinamis. Ia juga berjalan setelah optimasi gambar dan Pagefind, jadi ia melihat persis apa yang diterbitkan. Sebuah tautan sah ketika ada berkas sungguhan yang menjawabnya, dicoba dengan urutan yang dipakai hosting statis:

Tautan relatif (../about) diselesaikan terhadap halaman yang memuatnya, dan yang memanjat keluar dari direktori keluaran akan dilaporkan. String kueri diabaikan saat penyelesaian — /about?utm=x memeriksa /about.

Tautan eksternal tidak pernah diambil. https://, //cdn.example.com yang relatif protokol, mailto:, tel:, dan skema lain dilewati sepenuhnya.

Opsi

OpsiBawaanDeskripsi
mode'warn''warn' mencatat lalu melanjutkan; 'error' menggagalkan build — berguna di CI
exclude[]Glob atau ekspresi reguler href yang dilewati
checkFragmentsfalseJuga memastikan target #fragment ada di halaman yang ditautkan
export default {
  linkCheck: {
    mode: 'error',                    // gagalkan build saat ada tautan mati
    checkFragments: true,             // verifikasi juga target #fragmen
    exclude: ['/api/**', /^\/legacy\//],
  },
}

checkFragments mati secara bawaan karena id yang ditambahkan JavaScript sisi klien tidak ada di HTML hasil build, dan akan dilaporkan hilang. Atribut id maupun name jangkar lama sama-sama dihitung sebagai target fragmen.

Situs yang disajikan dari sebuah base

Jika situs Anda diterapkan di bawah sebuah base (katakanlah situs proyek GitHub Pages), tautan relatif-akar yang tidak membawa base itu akan dilaporkan. /about pada situs yang disajikan dari /repo/ mengirim peramban ke akar host, bukan ke dalam situs Anda — menyelesaikannya terhadap keluaran justru akan menyembunyikan kekeliruan yang layak ditangkap. Gunakan exclude bila itu memang disengaja.

Audit Lighthouse

sitelo lighthouse mengaudit build yang sudah jadi dengan Lighthouse. Ini dependensi rekan opsional:

npm install -D lighthouse

sitelo menyajikan dist/ sebagaimana sitelo preview melakukannya, mengarahkan Chrome tanpa kepala ke setiap halaman, lalu mencetak skornya:

[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.4s

Setiap halaman diaudit pada URL yang ditautkan situs — /docs, bukan dist/docs.html — jadi cleanUrls, grup rute, dan base semuanya diperhitungkan. Tambahkan ambang batas dan laporannya berubah menjadi pemeriksaan: skor apa pun di bawah ambangnya menggagalkan perintah itu.

export default {
  lighthouse: {
    exclude: ['404.html'],   // halaman 404 jarang layak diaudit
    thresholds: {
      performance: 90,
      accessibility: 100,
      'best-practices': 95,
      seo: 100,
    },
  },
}

Skor ditulis seperti cara Lighthouse menampilkannya (0–100); pecahan 0–1 miliknya sendiri juga bisa. Gunakan mode: 'warn' untuk mencatat alih-alih menggagalkan.

export default {
  lighthouse: {
    formFactor: 'desktop',   // praatur desktop Lighthouse
    runs: 3,                 // tiga kali jalan per halaman, skor median
    output: true,            // laporan lengkap di .sitelo/lighthouse/
    onBuild: true,           // audit juga di akhir sitelo build
    flags: { throttlingMethod: 'provided' },
  },
}

Lighthouse menjalankan Chrome sungguhan: pasang satu di tempat auditnya berjalan, atau arahkan CHROME_PATH ke sebuah biner. Skor performa berayun antarjalannya, jadi gunakan runs: 3 sebelum menyematkan ambang batas padanya.

Pencarian Pagefind

Pencarian statis opsional yang ditenagai Pagefind, sebuah dependensi rekan opsional. Pasang ketika Anda menginginkan pencarian, lalu aktifkan pengindeksan, tandai kontennya, pasang antarmukanya, dan jalankan sitelo build.

npm install -D pagefind

1. Aktifkan pengindeksan

Setel pagefind: true. Setelah sitelo build Anda mendapat dist/pagefind/, dan secara bawaan sebuah salinan di public/pagefind/ sehingga sitelo (pengembangan) atau sitelo preview berikutnya dapat menyajikan /pagefind/ tanpa membangun ulang.

export default {
  pagefind: true,
}

2. Tandai konten dan tambahkan titik pasang

Taruh data-pagefind-body pada konten utama agar navigasi dan footer tidak ikut terindeks. Sisakan elemen kosong untuk antarmuka pencarian:

import {
  html, head, title, link, script, body, header, a, div, main, h1, p,
} from 'javascript-to-html'

export default () =>
  html({ lang: 'id' },
    head(
      title('Situs saya'),
      link({ rel: 'stylesheet', href: '/styles.css' }),
      script({ type: 'module', src: '/main.js' }),
    ),
    body(
      header(
        a({ href: '/' }, 'Beranda'),
        div({ id: 'search' }),
      ),
      main({ 'data-pagefind-body': '' },
        h1('Halo'),
        p('Hanya wilayah ini yang diindeks.'),
      ),
    ),
  )

3. Pasang antarmuka Pagefind

Muat /pagefind/pagefind-ui.js dan pagefind-ui.css dari skrip klien Anda (hanya setelah sebuah build menghasilkan indeksnya):

async function initSearch() {
  const mount = document.querySelector('#search')
  if (!mount) return

  // Indeks baru ada setelah `sitelo build` (secara bawaan disinkronkan ke public/pagefind)
  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. Build dan abaikan bundel yang disinkronkan

sitelo build
# lalu: sitelo preview — atau sitelo (dev) memakai public/pagefind
public/pagefind/

Opsi lanjutan (syncPublic, glob, bahasa, pemilih, …) diletakkan pada sebuah objek: pagefind: { syncPublic: false, glob: '**/*.html' }. Opsi antarmuka selengkapnya: pagefind.app.

404

Buat src/404.ht.js untuk dist/404.html. Jika tidak, versi bawaan yang rapi akan dihasilkan.