mirror of https://github.com/vuejs/vitepress
Merge 5cdf556214 into d24d099cbd
commit
079665a5f4
@ -0,0 +1,67 @@
|
||||
---
|
||||
description: Pelajari cara mereferensikan dan menangani aset statis seperti gambar, media, dan font di VitePress.
|
||||
---
|
||||
|
||||
# Penanganan Aset
|
||||
|
||||
## Mereferensikan Aset Statis
|
||||
|
||||
Semua file Markdown dikompilasi menjadi komponen Vue dan diproses oleh [Vite](https://vitejs.dev/guide/assets.html). Anda dapat, **dan sebaiknya**, mereferensikan aset apa pun menggunakan URL relatif:
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
Anda dapat mereferensikan aset statis di file markdown Anda, komponen `*.vue` di tema, style, dan file `.css` biasa menggunakan path publik absolut (berdasarkan project root) atau path relatif (berdasarkan file system Anda). Yang terakhir mirip dengan perilaku yang biasa Anda gunakan jika Anda pernah menggunakan Vite, Vue CLI, atau `file-loader` webpack.
|
||||
|
||||
Tipe file gambar, media, dan font yang umum dideteksi dan disertakan sebagai aset secara otomatis.
|
||||
|
||||
::: tip File yang ditautkan tidak diperlakukan sebagai aset
|
||||
PDF atau dokumen lain yang direferensikan oleh tautan dalam file markdown tidak secara otomatis diperlakukan sebagai aset. Untuk membuat file yang ditautkan dapat diakses, Anda harus menempatkannya secara manual di dalam direktori [`public`](#direktori-public) proyek Anda.
|
||||
:::
|
||||
|
||||
Semua aset yang direferensikan, termasuk yang menggunakan path absolut, akan disalin ke direktori output dengan nama file yang di-hash pada build produksi. Aset yang tidak pernah direferensikan tidak akan disalin. Aset gambar yang lebih kecil dari 4kb akan di-inline base64, dan ini dapat dikonfigurasi melalui opsi konfigurasi [`vite`](../reference/site-config#vite).
|
||||
|
||||
Semua referensi path **statis**, termasuk path absolut, harus didasarkan pada struktur direktori kerja Anda.
|
||||
|
||||
## Direktori Public
|
||||
|
||||
Terkadang Anda mungkin perlu menyediakan aset statis yang tidak direferensikan secara langsung di komponen Markdown atau tema Anda, atau Anda mungkin ingin menyajikan file tertentu dengan nama file asli. Contoh file tersebut termasuk `robots.txt`, favicon, dan ikon PWA.
|
||||
|
||||
Anda dapat menempatkan file-file ini di direktori `public` di bawah [source directory](./routing#source-directory). Misalnya, jika project root Anda adalah `./docs` dan menggunakan lokasi source directory default, maka direktori public Anda akan menjadi `./docs/public`.
|
||||
|
||||
Aset yang ditempatkan di `public` akan disalin ke root direktori output apa adanya.
|
||||
|
||||
Perhatikan bahwa Anda harus mereferensikan file yang ditempatkan di `public` menggunakan path absolut root: misalnya, `public/icon.png` harus selalu direferensikan di kode sumber sebagai `/icon.png`.
|
||||
|
||||
## Base URL
|
||||
|
||||
Jika situs Anda dideploy ke URL non-root, Anda perlu mengatur opsi `base` di `.vitepress/config.js`. Misalnya, jika Anda berencana mendeploy situs Anda ke `https://foo.github.io/bar/`, maka `base` harus diatur ke `'/bar/'` (harus selalu dimulai dan diakhiri dengan garis miring).
|
||||
|
||||
Semua path aset statis Anda secara otomatis diproses untuk menyesuaikan dengan nilai konfigurasi `base` yang berbeda. Misalnya, jika Anda memiliki referensi absolut ke aset di bawah `public` dalam markdown Anda:
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
Anda **tidak** perlu memperbaruinya saat Anda mengubah nilai konfigurasi `base` dalam kasus ini.
|
||||
|
||||
Namun, jika Anda menulis komponen tema yang menautkan ke aset secara dinamis, misalnya gambar yang `src`-nya didasarkan pada nilai konfigurasi tema:
|
||||
|
||||
```vue
|
||||
<img :src="theme.logoPath" />
|
||||
```
|
||||
|
||||
Dalam kasus ini disarankan untuk membungkus path dengan [`withBase` helper](../reference/runtime-api#withbase) yang disediakan oleh VitePress:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { withBase, useData } from 'vitepress'
|
||||
|
||||
const { theme } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<img :src="withBase(theme.logoPath)" />
|
||||
</template>
|
||||
```
|
||||
@ -0,0 +1,57 @@
|
||||
---
|
||||
outline: deep
|
||||
description: Hubungkan VitePress ke headless CMS menggunakan rute dinamis dan data loader.
|
||||
---
|
||||
|
||||
# Menghubungkan ke CMS
|
||||
|
||||
## Alur Kerja Umum
|
||||
|
||||
Menghubungkan VitePress ke CMS sebagian besar akan berkisar pada [Rute Dinamis](./routing#dynamic-routes). Pastikan Anda memahami cara kerjanya sebelum melanjutkan.
|
||||
|
||||
Karena setiap CMS bekerja secara berbeda, di sini kami hanya dapat memberikan alur kerja umum yang perlu Anda adaptasi ke skenario spesifik Anda.
|
||||
|
||||
1. Jika CMS Anda memerlukan otentikasi, buat file `.env` untuk menyimpan token API Anda dan muat seperti ini:
|
||||
|
||||
```js
|
||||
// posts/[id].paths.js
|
||||
import { loadEnv } from 'vitepress'
|
||||
|
||||
const env = loadEnv('', process.cwd())
|
||||
```
|
||||
|
||||
2. Ambil data yang diperlukan dari CMS dan format menjadi data paths yang tepat:
|
||||
|
||||
```js
|
||||
export default {
|
||||
async paths() {
|
||||
// gunakan library klien CMS masing-masing jika diperlukan
|
||||
const data = await (await fetch('https://my-cms-api', {
|
||||
headers: {
|
||||
// token jika diperlukan
|
||||
}
|
||||
})).json()
|
||||
|
||||
return data.map(entry => {
|
||||
return {
|
||||
params: { id: entry.id, /* title, authors, date dll. */ },
|
||||
content: entry.content
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Render konten di halaman:
|
||||
|
||||
```md
|
||||
# {{ $params.title }}
|
||||
|
||||
- oleh {{ $params.author }} pada {{ $params.date }}
|
||||
|
||||
<!-- @content -->
|
||||
```
|
||||
|
||||
## Panduan Integrasi
|
||||
|
||||
Jika Anda telah menulis panduan tentang mengintegrasikan VitePress dengan CMS tertentu, silakan gunakan tautan "Edit this page" di bawah ini untuk mengirimkannya di sini!
|
||||
@ -0,0 +1,220 @@
|
||||
---
|
||||
description: Buat dan gunakan tema kustom di VitePress untuk mengontrol sepenuhnya tampilan situs Anda.
|
||||
---
|
||||
|
||||
# Menggunakan Tema Kustom
|
||||
|
||||
## Resolusi Tema
|
||||
|
||||
Anda dapat mengaktifkan tema kustom dengan membuat file `.vitepress/theme/index.js` atau `.vitepress/theme/index.ts` ("theme entry file"):
|
||||
|
||||
```
|
||||
.
|
||||
├─ docs # project root
|
||||
│ ├─ .vitepress
|
||||
│ │ ├─ theme
|
||||
│ │ │ └─ index.js # theme entry
|
||||
│ │ └─ config.js # config file
|
||||
│ └─ index.md
|
||||
└─ package.json
|
||||
```
|
||||
|
||||
VitePress akan selalu menggunakan tema kustom alih-alih tema default ketika mendeteksi keberadaan theme entry file. Namun, Anda dapat [memperluas tema default](./extending-default-theme) untuk melakukan kustomisasi lanjutan di atasnya.
|
||||
|
||||
## Antarmuka Tema
|
||||
|
||||
Tema kustom VitePress didefinisikan sebagai objek dengan antarmuka berikut:
|
||||
|
||||
```ts
|
||||
interface Theme {
|
||||
/**
|
||||
* Komponen layout root untuk setiap halaman
|
||||
* @required
|
||||
*/
|
||||
Layout: Component
|
||||
/**
|
||||
* Tingkatkan instance aplikasi Vue
|
||||
* @optional
|
||||
*/
|
||||
enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>
|
||||
/**
|
||||
* Perluas tema lain, memanggil `enhanceApp`-nya sebelum milik kita
|
||||
* @optional
|
||||
*/
|
||||
extends?: Theme
|
||||
}
|
||||
|
||||
interface EnhanceAppContext {
|
||||
app: App // instance aplikasi Vue
|
||||
router: Router // instance router VitePress
|
||||
siteData: Ref<SiteData> // metadata tingkat situs
|
||||
}
|
||||
```
|
||||
|
||||
Theme entry file harus mengekspor tema sebagai default export-nya:
|
||||
|
||||
```js [.vitepress/theme/index.js]
|
||||
|
||||
// Anda dapat langsung mengimpor file Vue di theme entry
|
||||
// VitePress sudah dikonfigurasi dengan @vitejs/plugin-vue.
|
||||
import Layout from './Layout.vue'
|
||||
|
||||
export default {
|
||||
Layout,
|
||||
enhanceApp({ app, router, siteData }) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Default export adalah satu-satunya kontrak untuk tema kustom, dan hanya properti `Layout` yang diperlukan. Jadi secara teknis, tema VitePress dapat sesederhana satu komponen Vue.
|
||||
|
||||
Di dalam komponen layout Anda, ia bekerja seperti aplikasi Vite + Vue 3 biasa. Perhatikan bahwa tema juga harus [SSR-compatible](./ssr-compat).
|
||||
|
||||
## Membangun Layout
|
||||
|
||||
Komponen layout paling dasar perlu berisi komponen [`<Content />`](../reference/runtime-api#content):
|
||||
|
||||
```vue [.vitepress/theme/Layout.vue]
|
||||
<template>
|
||||
<h1>Custom Layout!</h1>
|
||||
|
||||
<!-- di sinilah konten markdown akan dirender -->
|
||||
<Content />
|
||||
</template>
|
||||
```
|
||||
|
||||
Layout di atas hanya merender markdown setiap halaman sebagai HTML. Peningkatan pertama yang dapat kita tambahkan adalah menangani error 404:
|
||||
|
||||
```vue{1-4,9-12}
|
||||
<script setup>
|
||||
import { useData } from 'vitepress'
|
||||
const { page } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>Custom Layout!</h1>
|
||||
|
||||
<div v-if="page.isNotFound">
|
||||
Halaman 404 kustom!
|
||||
</div>
|
||||
<Content v-else />
|
||||
</template>
|
||||
```
|
||||
|
||||
Helper [`useData()`](../reference/runtime-api#usedata) memberi kita semua data runtime yang kita perlukan untuk merender layout yang berbeda secara kondisional. Salah satu data lain yang dapat kita akses adalah frontmatter halaman saat ini. Kita dapat memanfaatkan ini untuk memungkinkan pengguna akhir mengontrol layout di setiap halaman. Misalnya, pengguna dapat menunjukkan halaman harus menggunakan layout home page khusus dengan:
|
||||
|
||||
```md
|
||||
---
|
||||
layout: home
|
||||
---
|
||||
```
|
||||
|
||||
Dan kita dapat menyesuaikan tema kita untuk menangani ini:
|
||||
|
||||
```vue{3,12-14}
|
||||
<script setup>
|
||||
import { useData } from 'vitepress'
|
||||
const { page, frontmatter } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>Custom Layout!</h1>
|
||||
|
||||
<div v-if="page.isNotFound">
|
||||
Halaman 404 kustom!
|
||||
</div>
|
||||
<div v-if="frontmatter.layout === 'home'">
|
||||
Halaman home kustom!
|
||||
</div>
|
||||
<Content v-else />
|
||||
</template>
|
||||
```
|
||||
|
||||
Anda tentu saja dapat membagi layout menjadi lebih banyak komponen:
|
||||
|
||||
```vue{3-5,12-15}
|
||||
<script setup>
|
||||
import { useData } from 'vitepress'
|
||||
import NotFound from './NotFound.vue'
|
||||
import Home from './Home.vue'
|
||||
import Page from './Page.vue'
|
||||
|
||||
const { page, frontmatter } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>Custom Layout!</h1>
|
||||
|
||||
<NotFound v-if="page.isNotFound" />
|
||||
<Home v-if="frontmatter.layout === 'home'" />
|
||||
<Page v-else /> <!-- <Page /> merender <Content /> -->
|
||||
</template>
|
||||
```
|
||||
|
||||
Lihat [Referensi Runtime API](../reference/runtime-api) untuk semua yang tersedia di komponen tema. Selain itu, Anda dapat memanfaatkan [Build-Time Data Loading](./data-loading) untuk menghasilkan layout berbasis data, misalnya, halaman yang mencantumkan semua posting blog di proyek saat ini.
|
||||
|
||||
## Mendistribusikan Tema Kustom
|
||||
|
||||
Cara termudah untuk mendistribusikan tema kustom adalah dengan menyediakannya sebagai [template repository di GitHub](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository).
|
||||
|
||||
Jika Anda ingin mendistribusikan tema sebagai paket npm, ikuti langkah-langkah berikut:
|
||||
|
||||
1. Ekspor objek tema sebagai default export di entry paket Anda.
|
||||
|
||||
2. Jika berlaku, ekspor definisi tipe konfigurasi tema Anda sebagai `ThemeConfig`.
|
||||
|
||||
3. Jika tema Anda memerlukan penyesuaian konfigurasi VitePress, ekspor konfigurasi tersebut di bawah sub-path paket (mis. `my-theme/config`) sehingga pengguna dapat memperluasnya.
|
||||
|
||||
4. Dokumentasikan opsi konfigurasi tema (baik melalui file konfigurasi maupun frontmatter).
|
||||
|
||||
5. Berikan instruksi yang jelas tentang cara menggunakan tema Anda (lihat di bawah).
|
||||
|
||||
## Menggunakan Tema Kustom
|
||||
|
||||
Untuk menggunakan tema eksternal, impor dan ekspor ulang dari theme entry kustom:
|
||||
|
||||
```js [.vitepress/theme/index.js]
|
||||
import Theme from 'awesome-vitepress-theme'
|
||||
|
||||
export default Theme
|
||||
```
|
||||
|
||||
Jika tema perlu diperluas:
|
||||
|
||||
```js [.vitepress/theme/index.js]
|
||||
import Theme from 'awesome-vitepress-theme'
|
||||
|
||||
export default {
|
||||
extends: Theme,
|
||||
enhanceApp(ctx) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Jika tema memerlukan konfigurasi VitePress khusus, Anda juga perlu memperluasnya di konfigurasi Anda sendiri:
|
||||
|
||||
```ts [.vitepress/config.ts]
|
||||
import baseConfig from 'awesome-vitepress-theme/config'
|
||||
|
||||
export default {
|
||||
// perluas konfigurasi dasar tema (jika diperlukan)
|
||||
extends: baseConfig
|
||||
}
|
||||
```
|
||||
|
||||
Terakhir, jika tema menyediakan tipe untuk konfigurasi temanya:
|
||||
|
||||
```ts [.vitepress/config.ts]
|
||||
import baseConfig from 'awesome-vitepress-theme/config'
|
||||
import { defineConfigWithTheme } from 'vitepress'
|
||||
import type { ThemeConfig } from 'awesome-vitepress-theme'
|
||||
|
||||
export default defineConfigWithTheme<ThemeConfig>({
|
||||
extends: baseConfig,
|
||||
themeConfig: {
|
||||
// Type adalah `ThemeConfig`
|
||||
}
|
||||
})
|
||||
```
|
||||
@ -0,0 +1,248 @@
|
||||
---
|
||||
description: Muat data apa pun pada waktu build menggunakan data loader VitePress dan impor dari halaman atau komponen.
|
||||
---
|
||||
|
||||
# Build-Time Data Loading
|
||||
|
||||
VitePress menyediakan fitur yang disebut **data loader** yang dapat digunakan untuk memuat data apa pun dan mengimpornya dari halaman atau komponen. Pemuatan data dieksekusi **hanya pada waktu build**: data yang dihasilkan akan diserialisasi sebagai JSON dalam bundel JavaScript akhir.
|
||||
|
||||
Data loader dapat digunakan untuk mengambil data remote, atau menghasilkan metadata berdasarkan file lokal. Misalnya, Anda dapat menggunakan data loader untuk mem-parse semua halaman API lokal Anda dan secara otomatis menghasilkan indeks semua entri API.
|
||||
|
||||
## Penggunaan Dasar
|
||||
|
||||
File data loader harus diakhiri dengan `.data.js` atau `.data.ts`. File tersebut harus menyediakan default export berupa objek dengan metode `load()`:
|
||||
|
||||
```js [example.data.js]
|
||||
export default {
|
||||
load() {
|
||||
return {
|
||||
hello: 'world'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Modul loader dievaluasi hanya di Node.js, sehingga Anda dapat mengimpor Node API dan dependensi npm sesuai kebutuhan.
|
||||
|
||||
Anda kemudian dapat mengimpor data dari file ini di halaman `.md` dan komponen `.vue` menggunakan named export `data`:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { data } from './example.data.js'
|
||||
</script>
|
||||
|
||||
<pre>{{ data }}</pre>
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```json
|
||||
{
|
||||
"hello": "world"
|
||||
}
|
||||
```
|
||||
|
||||
Anda akan melihat bahwa data loader sendiri tidak mengekspor `data`. VitePress-lah yang memanggil metode `load()` di belakang layar dan secara implisit mengekspos hasilnya melalui named export `data`.
|
||||
|
||||
Ini berfungsi bahkan jika loader bersifat async:
|
||||
|
||||
```js
|
||||
export default {
|
||||
async load() {
|
||||
// ambil data remote
|
||||
return (await fetch('...')).json()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Data dari File Lokal
|
||||
|
||||
Ketika Anda perlu menghasilkan data berdasarkan file lokal, Anda harus menggunakan opsi `watch` di data loader sehingga perubahan yang dibuat pada file-file ini dapat memicu hot updates.
|
||||
|
||||
Opsi `watch` juga nyaman karena Anda dapat menggunakan [glob patterns](https://github.com/mrmlnc/fast-glob#pattern-syntax) untuk mencocokkan banyak file. Pattern dapat relatif terhadap file loader itu sendiri, dan fungsi `load()` akan menerima file yang cocok sebagai path absolut.
|
||||
|
||||
Contoh berikut menunjukkan memuat file CSV dan mengubahnya menjadi JSON menggunakan [csv-parse](https://github.com/adaltas/node-csv/tree/master/packages/csv-parse/). Karena file ini hanya dieksekusi pada waktu build, Anda tidak akan mengirimkan parser CSV ke klien!
|
||||
|
||||
```js
|
||||
import fs from 'node:fs'
|
||||
import { parse } from 'csv-parse/sync'
|
||||
|
||||
export default {
|
||||
watch: ['./data/*.csv'],
|
||||
load(watchedFiles) {
|
||||
// watchedFiles akan berupa array path absolut dari file yang cocok.
|
||||
// hasilkan array metadata posting blog yang dapat digunakan untuk
|
||||
// merender daftar di layout tema
|
||||
return watchedFiles.map((file) => {
|
||||
return parse(fs.readFileSync(file, 'utf-8'), {
|
||||
columns: true,
|
||||
skip_empty_lines: true
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## `createContentLoader`
|
||||
|
||||
Saat membangun situs yang berfokus pada konten, kita sering perlu membuat halaman "arsip" atau "indeks": halaman di mana kita mencantumkan semua entri yang tersedia dalam koleksi konten kita, misalnya posting blog atau halaman API. Kita **dapat** mengimplementasikan ini langsung dengan API data loader, tetapi karena ini adalah use case yang sangat umum, VitePress juga menyediakan helper `createContentLoader` untuk menyederhanakannya:
|
||||
|
||||
```js [posts.data.js]
|
||||
import { createContentLoader } from 'vitepress'
|
||||
|
||||
export default createContentLoader('posts/*.md', /* options */)
|
||||
```
|
||||
|
||||
Helper ini menerima glob pattern relatif terhadap [source directory](./routing#source-directory), dan mengembalikan objek data loader `{ watch, load }` yang dapat digunakan sebagai default export di file data loader. Ini juga mengimplementasikan caching berdasarkan timestamp modifikasi file untuk meningkatkan performa dev.
|
||||
|
||||
Perhatikan bahwa loader hanya bekerja dengan file Markdown; file non-Markdown yang cocok akan dilewati.
|
||||
|
||||
Data yang dimuat akan berupa array dengan tipe `ContentData[]`:
|
||||
|
||||
```ts
|
||||
interface ContentData {
|
||||
// URL yang dipetakan untuk halaman. mis. /posts/hello.html (tidak termasuk base)
|
||||
// iterasi secara manual atau gunakan `transform` kustom untuk menormalkan path
|
||||
url: string
|
||||
// data frontmatter halaman
|
||||
frontmatter: Record<string, any>
|
||||
|
||||
// berikut hanya ada jika opsi terkait diaktifkan
|
||||
// kita akan membahasnya di bawah
|
||||
src: string | undefined
|
||||
html: string | undefined
|
||||
excerpt: string | undefined
|
||||
}
|
||||
```
|
||||
|
||||
Secara default, hanya `url` dan `frontmatter` yang disediakan. Ini karena data yang dimuat akan di-inline sebagai JSON di bundel klien, jadi kita perlu berhati-hati tentang ukurannya. Berikut contoh menggunakan data untuk membangun halaman indeks blog minimal:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { data as posts } from './posts.data.js'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>Semua Posting Blog</h1>
|
||||
<ul>
|
||||
<li v-for="post of posts">
|
||||
<a :href="post.url">{{ post.frontmatter.title }}</a>
|
||||
<span>oleh {{ post.frontmatter.author }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
```
|
||||
|
||||
### Opsi
|
||||
|
||||
Data default mungkin tidak sesuai untuk semua kebutuhan. Anda dapat memilih untuk mentransformasi data menggunakan opsi:
|
||||
|
||||
```js [posts.data.js]
|
||||
import { createContentLoader } from 'vitepress'
|
||||
|
||||
export default createContentLoader('posts/*.md', {
|
||||
includeSrc: true, // sertakan sumber markdown mentah?
|
||||
render: true, // sertakan HTML halaman penuh yang dirender?
|
||||
excerpt: true, // sertakan excerpt?
|
||||
transform(rawData) {
|
||||
// map, sort, atau filter data mentah sesuai keinginan.
|
||||
// hasil akhir adalah apa yang akan dikirim ke klien.
|
||||
return rawData.sort((a, b) => {
|
||||
return +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date)
|
||||
}).map((page) => {
|
||||
page.src // sumber markdown mentah
|
||||
page.html // HTML halaman penuh yang dirender
|
||||
page.excerpt // HTML excerpt yang dirender (konten di atas `---` pertama)
|
||||
return {/* ... */}
|
||||
})
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Lihat bagaimana ini digunakan di [blog Vue.js](https://github.com/vuejs/blog/blob/main/.vitepress/theme/posts.data.ts).
|
||||
|
||||
API `createContentLoader` juga dapat digunakan di dalam [build hooks](../reference/site-config#build-hooks):
|
||||
|
||||
```js [.vitepress/config.js]
|
||||
export default {
|
||||
async buildEnd() {
|
||||
const posts = await createContentLoader('posts/*.md').load()
|
||||
// hasilkan file berdasarkan metadata posting, mis. RSS feed
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Tipe**
|
||||
|
||||
```ts
|
||||
interface ContentOptions<T = ContentData[]> {
|
||||
/**
|
||||
* Sertakan src?
|
||||
* @default false
|
||||
*/
|
||||
includeSrc?: boolean
|
||||
|
||||
/**
|
||||
* Render src ke HTML dan sertakan dalam data?
|
||||
* @default false
|
||||
*/
|
||||
render?: boolean
|
||||
|
||||
/**
|
||||
* Jika `boolean`, apakah akan mem-parse dan menyertakan excerpt? (dirender sebagai HTML)
|
||||
*
|
||||
* Jika `function`, kontrol bagaimana excerpt diekstrak dari konten.
|
||||
*
|
||||
* Jika `string`, tentukan separator kustom yang digunakan untuk mengekstrak
|
||||
* excerpt. Separator default adalah `---` jika `excerpt` adalah `true`.
|
||||
*
|
||||
* @see https://github.com/jonschlinkert/gray-matter#optionsexcerpt
|
||||
* @see https://github.com/jonschlinkert/gray-matter#optionsexcerpt_separator
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
excerpt?:
|
||||
| boolean
|
||||
| ((file: { data: { [key: string]: any }; content: string; excerpt?: string }, options?: any) => void)
|
||||
| string
|
||||
|
||||
/**
|
||||
* Transformasikan data. Perhatikan data akan di-inline sebagai JSON di
|
||||
* bundel klien jika diimpor dari komponen atau file markdown.
|
||||
*/
|
||||
transform?: (data: ContentData[]) => T | Promise<T>
|
||||
}
|
||||
```
|
||||
|
||||
## Typed Data Loader
|
||||
|
||||
Saat menggunakan TypeScript, Anda dapat mengetik loader dan ekspor `data` seperti ini:
|
||||
|
||||
```ts
|
||||
import { defineLoader } from 'vitepress'
|
||||
|
||||
export interface Data {
|
||||
// tipe data
|
||||
}
|
||||
|
||||
declare const data: Data
|
||||
export { data }
|
||||
|
||||
export default defineLoader({
|
||||
// opsi loader yang diperiksa tipe
|
||||
watch: ['...'],
|
||||
async load(): Promise<Data> {
|
||||
// ...
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Konfigurasi
|
||||
|
||||
Untuk mendapatkan informasi konfigurasi di dalam loader, Anda dapat menggunakan kode seperti ini:
|
||||
|
||||
```ts
|
||||
import type { SiteConfig } from 'vitepress'
|
||||
|
||||
const config: SiteConfig = (globalThis as any).VITEPRESS_CONFIG
|
||||
```
|
||||
@ -0,0 +1,346 @@
|
||||
---
|
||||
description: Deploy situs VitePress Anda ke platform populer seperti Netlify, Vercel, GitHub Pages, dan lainnya.
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Deploy Situs VitePress Anda
|
||||
|
||||
Panduan berikut didasarkan pada beberapa asumsi bersama:
|
||||
|
||||
- Situs VitePress berada di dalam direktori `docs` proyek Anda.
|
||||
- Anda menggunakan direktori output build default (`.vitepress/dist`).
|
||||
- VitePress diinstal sebagai dependensi lokal di proyek Anda, dan Anda telah menyiapkan script berikut di `package.json` Anda:
|
||||
|
||||
```json [package.json]
|
||||
{
|
||||
"scripts": {
|
||||
"docs:build": "vitepress build docs",
|
||||
"docs:preview": "vitepress preview docs"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Build dan Uji Secara Lokal
|
||||
|
||||
1. Jalankan perintah ini untuk membangun docs:
|
||||
|
||||
```sh
|
||||
$ npm run docs:build
|
||||
```
|
||||
|
||||
2. Setelah dibangun, pratinjau secara lokal dengan menjalankan:
|
||||
|
||||
```sh
|
||||
$ npm run docs:preview
|
||||
```
|
||||
|
||||
Perintah `preview` akan memulai server web statis lokal yang akan menyajikan direktori output `.vitepress/dist` di `http://localhost:4173`. Anda dapat menggunakan ini untuk memastikan semuanya terlihat baik sebelum push ke produksi.
|
||||
|
||||
3. Anda dapat mengonfigurasi port server dengan meneruskan `--port` sebagai argumen.
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"docs:preview": "vitepress preview docs --port 8080"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Sekarang metode `docs:preview` akan meluncurkan server di `http://localhost:8080`.
|
||||
|
||||
## Mengatur Public Base Path
|
||||
|
||||
Secara default, kami mengasumsikan situs akan dideploy di path root domain (`/`). Jika situs Anda akan disajikan di sub-path, mis. `https://mywebsite.com/blog/`, maka Anda perlu mengatur opsi [`base`](../reference/site-config#base) ke `'/blog/'` di konfigurasi VitePress.
|
||||
|
||||
**Contoh:** Jika Anda menggunakan Github (atau GitLab) Pages dan mendeploy ke `user.github.io/repo/`, maka atur `base` Anda ke `/repo/`.
|
||||
|
||||
## HTTP Cache Headers
|
||||
|
||||
Jika Anda memiliki kontrol atas header HTTP di server produksi Anda, Anda dapat mengonfigurasi header `cache-control` untuk mencapai performa yang lebih baik pada kunjungan berulang.
|
||||
|
||||
Build produksi menggunakan nama file yang di-hash untuk aset statis (JavaScript, CSS, dan aset impor lainnya yang tidak ada di `public`). Jika Anda memeriksa pratinjau produksi menggunakan tab network devtools browser Anda, Anda akan melihat file seperti `app.4f283b18.js`.
|
||||
|
||||
Hash `4f283b18` ini dihasilkan dari konten file ini. URL hash yang sama dijamin menyajikan konten file yang sama, dan jika konten berubah, URL juga berubah. Ini berarti Anda dapat dengan aman menggunakan header cache terkuat untuk file-file ini. Semua file tersebut akan ditempatkan di bawah `assets/` di direktori output, sehingga Anda dapat mengonfigurasi header berikut untuknya:
|
||||
|
||||
```
|
||||
Cache-Control: max-age=31536000,immutable
|
||||
```
|
||||
|
||||
::: details Contoh file `_headers` Netlify
|
||||
|
||||
```
|
||||
/assets/*
|
||||
cache-control: max-age=31536000
|
||||
cache-control: immutable
|
||||
```
|
||||
|
||||
Catatan: file `_headers` harus ditempatkan di [direktori public](./asset-handling#direktori-public), dalam kasus kami, `docs/public/_headers`, sehingga disalin apa adanya ke direktori output.
|
||||
|
||||
[Dokumentasi custom headers Netlify](https://docs.netlify.com/routing/headers/)
|
||||
|
||||
:::
|
||||
|
||||
::: details Contoh konfigurasi Vercel di `vercel.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"headers": [
|
||||
{
|
||||
"source": "/assets/(.*)",
|
||||
"headers": [
|
||||
{
|
||||
"key": "Cache-Control",
|
||||
"value": "max-age=31536000, immutable"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Catatan: file `vercel.json` harus ditempatkan di root **repositori** Anda.
|
||||
|
||||
[Dokumentasi Vercel tentang konfigurasi headers](https://vercel.com/docs/concepts/projects/project-configuration#headers)
|
||||
|
||||
:::
|
||||
|
||||
## Panduan Platform
|
||||
|
||||
### Netlify / Vercel / Cloudflare Pages / AWS Amplify / Render {#generic}
|
||||
|
||||
Siapkan proyek baru dan ubah pengaturan ini menggunakan dashboard Anda:
|
||||
|
||||
- **Build Command:** `npm run docs:build`
|
||||
- **Output Directory:** `docs/.vitepress/dist`
|
||||
- **Node Version:** `20` (atau di atasnya)
|
||||
|
||||
::: warning
|
||||
Jangan aktifkan opsi seperti _Auto Minify_ untuk kode HTML. Ini akan menghapus komentar dari output yang memiliki arti bagi Vue. Anda mungkin melihat error hydration mismatch jika komentar-komentar tersebut dihapus.
|
||||
:::
|
||||
|
||||
### GitHub Pages
|
||||
|
||||
1. Buat file bernama `deploy.yml` di dalam direktori `.github/workflows` proyek Anda dengan konten seperti ini:
|
||||
|
||||
```yaml [.github/workflows/deploy.yml]
|
||||
# Contoh workflow untuk membangun dan mendeploy situs VitePress ke GitHub Pages
|
||||
#
|
||||
name: Deploy VitePress site to Pages
|
||||
|
||||
on:
|
||||
# Berjalan pada push yang menargetkan branch `main`. Ubah ini ke `master` jika Anda
|
||||
# menggunakan branch `master` sebagai branch default.
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
# Memungkinkan Anda menjalankan workflow ini secara manual dari tab Actions
|
||||
workflow_dispatch:
|
||||
|
||||
# Mengatur izin GITHUB_TOKEN untuk memungkinkan deployment ke GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Izinkan hanya satu deployment bersamaan, melewatkan run yang antre antara run yang sedang berjalan dan antrean terbaru.
|
||||
# Namun, JANGAN batalkan run yang sedang berjalan karena kami ingin mengizinkan deployment produksi ini selesai.
|
||||
concurrency:
|
||||
group: pages
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Build job
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0 # Tidak diperlukan jika lastUpdated tidak diaktifkan
|
||||
# - uses: pnpm/action-setup@v4 # Uncomment blok ini jika Anda menggunakan pnpm
|
||||
# with:
|
||||
# version: 9 # Tidak diperlukan jika Anda telah mengatur "packageManager" di package.json
|
||||
# - uses: oven-sh/setup-bun@v1 # Uncomment ini jika Anda menggunakan Bun
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: npm # atau pnpm / yarn
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v4
|
||||
- name: Install dependencies
|
||||
run: npm ci # atau pnpm install / yarn install / bun install
|
||||
- name: Build with VitePress
|
||||
run: npm run docs:build # atau pnpm docs:build / yarn docs:build / bun run docs:build
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: docs/.vitepress/dist
|
||||
|
||||
# Deployment job
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
name: Deploy
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
```
|
||||
|
||||
::: warning
|
||||
Pastikan opsi `base` di VitePress Anda dikonfigurasi dengan benar. Lihat [Mengatur Public Base Path](#mengatur-public-base-path) untuk detail lebih lanjut.
|
||||
:::
|
||||
|
||||
2. Di pengaturan repositori Anda di bawah item menu "Pages", pilih "GitHub Actions" di "Build and deployment > Source".
|
||||
|
||||
3. Push perubahan Anda ke branch `main` dan tunggu workflow GitHub Actions selesai. Anda akan melihat situs Anda dideploy ke `https://<username>.github.io/[repository]/` atau `https://<custom-domain>/` tergantung pada pengaturan Anda. Situs Anda akan secara otomatis dideploy pada setiap push ke branch `main`.
|
||||
|
||||
### GitLab Pages
|
||||
|
||||
1. Atur `outDir` di konfigurasi VitePress ke `../public`. Konfigurasikan opsi `base` ke `'/<repository>/'` jika Anda ingin mendeploy ke `https://<username>.gitlab.io/<repository>/`. Anda tidak memerlukan `base` jika mendeploy ke custom domain, halaman pengguna atau grup, atau memiliki pengaturan "Use unique domain" yang diaktifkan di GitLab.
|
||||
|
||||
2. Buat file bernama `.gitlab-ci.yml` di root proyek Anda dengan konten di bawah ini. Ini akan membangun dan mendeploy situs Anda setiap kali Anda membuat perubahan pada konten Anda:
|
||||
|
||||
```yaml [.gitlab-ci.yml]
|
||||
image: node:24
|
||||
pages:
|
||||
cache:
|
||||
paths:
|
||||
- node_modules/
|
||||
script:
|
||||
# - apk add git # Uncomment ini jika Anda menggunakan docker image kecil seperti alpine dan mengaktifkan lastUpdated
|
||||
- npm install
|
||||
- npm run docs:build
|
||||
artifacts:
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
- main
|
||||
```
|
||||
|
||||
<!-- keep headings sorted alphabetically, leave nginx at the end -->
|
||||
|
||||
### Azure
|
||||
|
||||
1. Ikuti [dokumentasi resmi](https://docs.microsoft.com/en-us/azure/static-web-apps/build-configuration).
|
||||
|
||||
2. Atur nilai-nilai ini di file konfigurasi Anda (dan hapus yang tidak Anda perlukan, seperti `api_location`):
|
||||
|
||||
- **`app_location`**: `/`
|
||||
- **`output_location`**: `docs/.vitepress/dist`
|
||||
- **`app_build_command`**: `npm run docs:build`
|
||||
|
||||
### CloudRay
|
||||
|
||||
Anda dapat mendeploy proyek VitePress Anda dengan [CloudRay](https://cloudray.io/) dengan mengikuti [instruksi](https://cloudray.io/articles/how-to-deploy-vitepress-site) ini.
|
||||
|
||||
### Firebase
|
||||
|
||||
1. Buat `firebase.json` dan `.firebaserc` di root proyek Anda:
|
||||
|
||||
`firebase.json`:
|
||||
|
||||
```json [firebase.json]
|
||||
{
|
||||
"hosting": {
|
||||
"public": "docs/.vitepress/dist",
|
||||
"ignore": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`.firebaserc`:
|
||||
|
||||
```json [.firebaserc]
|
||||
{
|
||||
"projects": {
|
||||
"default": "<YOUR_FIREBASE_ID>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. Setelah menjalankan `npm run docs:build`, jalankan perintah ini untuk deploy:
|
||||
|
||||
```sh
|
||||
firebase deploy
|
||||
```
|
||||
|
||||
### Heroku
|
||||
|
||||
1. Ikuti dokumentasi dan panduan yang diberikan di [`heroku-buildpack-static`](https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-static).
|
||||
|
||||
2. Buat file bernama `static.json` di root proyek Anda dengan konten di bawah ini:
|
||||
|
||||
```json [static.json]
|
||||
{
|
||||
"root": "docs/.vitepress/dist"
|
||||
}
|
||||
```
|
||||
|
||||
### Hostinger
|
||||
|
||||
Anda dapat mendeploy proyek VitePress Anda dengan [Hostinger](https://www.hostinger.com/web-apps-hosting) dengan mengikuti [instruksi](https://www.hostinger.com/support/how-to-deploy-a-nodejs-website-in-hostinger/) ini. Saat mengonfigurasi pengaturan build, pilih VitePress sebagai framework dan sesuaikan direktori root ke `./docs`.
|
||||
|
||||
### Kinsta
|
||||
|
||||
Anda dapat mendeploy situs VitePress Anda di [Kinsta](https://kinsta.com/static-site-hosting/) dengan mengikuti [instruksi](https://kinsta.com/docs/vitepress-static-site-example/) ini.
|
||||
|
||||
### Stormkit
|
||||
|
||||
Anda dapat mendeploy proyek VitePress Anda ke [Stormkit](https://www.stormkit.io) dengan mengikuti [instruksi](https://stormkit.io/blog/how-to-deploy-vitepress) ini.
|
||||
|
||||
### Surge
|
||||
|
||||
1. Setelah menjalankan `npm run docs:build`, jalankan perintah ini untuk deploy:
|
||||
|
||||
```sh
|
||||
npx surge docs/.vitepress/dist
|
||||
```
|
||||
|
||||
### Nginx
|
||||
|
||||
Berikut adalah contoh konfigurasi blok server Nginx. Setup ini mencakup kompresi gzip untuk aset berbasis teks umum, aturan untuk menyajikan file statis situs VitePress Anda dengan header caching yang tepat serta menangani `cleanUrls: true`.
|
||||
|
||||
```nginx
|
||||
server {
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||||
|
||||
listen 80;
|
||||
server_name _;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
# lokasi konten
|
||||
root /app;
|
||||
|
||||
# exact matches -> reverse clean urls -> folders -> not found
|
||||
try_files $uri $uri.html $uri/ =404;
|
||||
|
||||
# halaman yang tidak ada
|
||||
error_page 404 /404.html;
|
||||
|
||||
# folder tanpa index.html menghasilkan 403 di setup ini
|
||||
error_page 403 /404.html;
|
||||
|
||||
# sesuaikan header caching
|
||||
# file di folder assets memiliki nama file hash
|
||||
location ~* ^/assets/ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Konfigurasi ini mengasumsikan bahwa situs VitePress yang telah dibangun terletak di direktori `/app` di server Anda. Sesuaikan directive `root` jika file situs Anda berada di tempat lain.
|
||||
|
||||
::: warning Jangan default ke index.html
|
||||
Resolusi try_files tidak boleh default ke index.html seperti di aplikasi Vue lainnya. Ini akan menghasilkan state halaman yang tidak valid.
|
||||
:::
|
||||
|
||||
Informasi lebih lanjut dapat ditemukan di [dokumentasi resmi nginx](https://nginx.org/en/docs/), di isu-isu ini [#2837](https://github.com/vuejs/vitepress/discussions/2837), [#3235](https://github.com/vuejs/vitepress/issues/3235) serta di [blog post](https://blog.mehdi.cc/articles/vitepress-cleanurls-on-nginx-environment#readings) oleh Mehdi Merah.
|
||||
@ -0,0 +1,334 @@
|
||||
---
|
||||
description: Kustomisasi dan perluas tema default VitePress dengan CSS kustom, komponen, layout, dan slot.
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Memperluas Tema Default
|
||||
|
||||
Tema default VitePress dioptimalkan untuk dokumentasi, dan dapat dikustomisasi. Lihat [Ikhtisar Konfigurasi Tema Default](../reference/default-theme-config) untuk daftar opsi yang komprehensif.
|
||||
|
||||
Namun, ada beberapa kasus di mana konfigurasi saja tidak cukup. Misalnya:
|
||||
|
||||
1. Anda perlu mengubah styling CSS;
|
||||
2. Anda perlu memodifikasi instance aplikasi Vue, misalnya untuk mendaftarkan komponen global;
|
||||
3. Anda perlu menyuntikkan konten kustom ke dalam tema melalui layout slot.
|
||||
|
||||
Kustomisasi lanjutan ini akan memerlukan penggunaan tema kustom yang "memperluas" tema default.
|
||||
|
||||
::: tip
|
||||
Sebelum melanjutkan, pastikan untuk membaca [Menggunakan Tema Kustom](./custom-theme) terlebih dahulu untuk memahami cara kerja tema kustom.
|
||||
:::
|
||||
|
||||
## Menyesuaikan CSS
|
||||
|
||||
CSS tema default dapat dikustomisasi dengan menimpa CSS variable tingkat root:
|
||||
|
||||
```js [.vitepress/theme/index.js]
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import './custom.css'
|
||||
|
||||
export default DefaultTheme
|
||||
```
|
||||
|
||||
```css
|
||||
/* .vitepress/theme/custom.css */
|
||||
:root {
|
||||
--vp-c-brand-1: #646cff;
|
||||
--vp-c-brand-2: #747bff;
|
||||
}
|
||||
```
|
||||
|
||||
Lihat [CSS variable tema default](https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css) yang dapat ditimpa.
|
||||
|
||||
## Menggunakan Font yang Berbeda
|
||||
|
||||
VitePress menggunakan [Inter](https://rsms.me/inter/) sebagai font default, dan akan menyertakan font tersebut dalam output build. Font juga otomatis di-preload di produksi. Namun, ini mungkin tidak diinginkan jika Anda ingin menggunakan font utama yang berbeda.
|
||||
|
||||
Untuk menghindari menyertakan Inter dalam output build, impor tema dari `vitepress/theme-without-fonts` sebagai gantinya:
|
||||
|
||||
```js [.vitepress/theme/index.js]
|
||||
import DefaultTheme from 'vitepress/theme-without-fonts'
|
||||
import './my-fonts.css'
|
||||
|
||||
export default DefaultTheme
|
||||
```
|
||||
|
||||
```css
|
||||
/* .vitepress/theme/my-fonts.css */
|
||||
:root {
|
||||
--vp-font-family-base: /* font teks normal */
|
||||
--vp-font-family-mono: /* font kode */
|
||||
}
|
||||
```
|
||||
|
||||
::: warning
|
||||
Jika Anda menggunakan komponen opsional seperti komponen [Team Page](../reference/default-theme-team-page), pastikan untuk juga mengimpornya dari `vitepress/theme-without-fonts`!
|
||||
:::
|
||||
|
||||
Jika font Anda adalah file lokal yang direferensikan melalui `@font-face`, itu akan diproses sebagai aset dan disertakan di bawah `.vitepress/dist/assets` dengan nama file hash. Untuk mem-preload file ini, gunakan build hook [transformHead](../reference/site-config#transformhead):
|
||||
|
||||
```js [.vitepress/config.js]
|
||||
export default {
|
||||
transformHead({ assets }) {
|
||||
// sesuaikan regex untuk mencocokkan font Anda
|
||||
const myFontFile = assets.find(file => /font-name\.[\w-]+\.woff2/.test(file))
|
||||
if (myFontFile) {
|
||||
return [
|
||||
[
|
||||
'link',
|
||||
{
|
||||
rel: 'preload',
|
||||
href: myFontFile,
|
||||
as: 'font',
|
||||
type: 'font/woff2',
|
||||
crossorigin: ''
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Mendaftarkan Komponen Global
|
||||
|
||||
```js [.vitepress/theme/index.js]
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
|
||||
/** @type {import('vitepress').Theme} */
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
enhanceApp({ app }) {
|
||||
// daftarkan komponen global kustom Anda
|
||||
app.component('MyGlobalComponent' /* ... */)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Jika Anda menggunakan TypeScript:
|
||||
```ts [.vitepress/theme/index.ts]
|
||||
import type { Theme } from 'vitepress'
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
enhanceApp({ app }) {
|
||||
// daftarkan komponen global kustom Anda
|
||||
app.component('MyGlobalComponent' /* ... */)
|
||||
}
|
||||
} satisfies Theme
|
||||
```
|
||||
|
||||
Karena kita menggunakan Vite, Anda juga dapat memanfaatkan [fitur glob import Vite](https://vitejs.dev/guide/features.html#glob-import) untuk mendaftarkan direktori komponen secara otomatis.
|
||||
|
||||
## Layout Slots
|
||||
|
||||
Komponen `<Layout/>` tema default memiliki beberapa slot yang dapat digunakan untuk menyuntikkan konten di lokasi tertentu halaman. Berikut contoh menyuntikkan komponen ke before outline:
|
||||
|
||||
```js [.vitepress/theme/index.js]
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import MyLayout from './MyLayout.vue'
|
||||
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
// timpa Layout dengan komponen wrapper yang
|
||||
// menyuntikkan slot
|
||||
Layout: MyLayout
|
||||
}
|
||||
```
|
||||
|
||||
```vue [.vitepress/theme/MyLayout.vue]
|
||||
<script setup>
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
|
||||
const { Layout } = DefaultTheme
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Layout>
|
||||
<template #aside-outline-before>
|
||||
Konten atas sidebar kustom saya
|
||||
</template>
|
||||
</Layout>
|
||||
</template>
|
||||
```
|
||||
|
||||
Atau Anda dapat menggunakan render function juga.
|
||||
|
||||
```js [.vitepress/theme/index.js]
|
||||
import { h } from 'vue'
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import MyComponent from './MyComponent.vue'
|
||||
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
Layout() {
|
||||
return h(DefaultTheme.Layout, null, {
|
||||
'aside-outline-before': () => h(MyComponent)
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Daftar lengkap slot yang tersedia di layout tema default:
|
||||
|
||||
- Ketika `layout: 'doc'` (default) diaktifkan melalui frontmatter:
|
||||
- `doc-top`
|
||||
- `doc-bottom`
|
||||
- `doc-footer-before`
|
||||
- `doc-before`
|
||||
- `doc-after`
|
||||
- `sidebar-nav-before`
|
||||
- `sidebar-nav-after`
|
||||
- `aside-top`
|
||||
- `aside-bottom`
|
||||
- `aside-outline-before`
|
||||
- `aside-outline-after`
|
||||
- `aside-ads-before`
|
||||
- `aside-ads-after`
|
||||
- Ketika `layout: 'home'` diaktifkan melalui frontmatter:
|
||||
- `home-hero-before`
|
||||
- `home-hero-info-before`
|
||||
- `home-hero-info`
|
||||
- `home-hero-info-after`
|
||||
- `home-hero-actions-before-actions`
|
||||
- `home-hero-actions-after`
|
||||
- `home-hero-image`
|
||||
- `home-hero-after`
|
||||
- `home-features-before`
|
||||
- `home-features-after`
|
||||
- Ketika `layout: 'page'` diaktifkan melalui frontmatter:
|
||||
- `page-top`
|
||||
- `page-bottom`
|
||||
- Pada halaman not found (404):
|
||||
- `not-found`
|
||||
- Selalu:
|
||||
- `layout-top`
|
||||
- `layout-bottom`
|
||||
- `nav-bar-title-before`
|
||||
- `nav-bar-title-after`
|
||||
- `nav-bar-content-before`
|
||||
- `nav-bar-content-after`
|
||||
- `nav-screen-content-before`
|
||||
- `nav-screen-content-after`
|
||||
|
||||
## Menggunakan View Transitions API
|
||||
|
||||
### Pada Toggle Appearance
|
||||
|
||||
Anda dapat memperluas tema default untuk menyediakan transisi kustom saat mode warna di-toggle. Contoh:
|
||||
|
||||
```vue [.vitepress/theme/Layout.vue]
|
||||
<script setup lang="ts">
|
||||
import { useData } from 'vitepress'
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import { nextTick, provide } from 'vue'
|
||||
|
||||
const { isDark } = useData()
|
||||
|
||||
const enableTransitions = () =>
|
||||
'startViewTransition' in document &&
|
||||
window.matchMedia('(prefers-reduced-motion: no-preference)').matches
|
||||
|
||||
provide('toggle-appearance', async ({ clientX: x, clientY: y }: MouseEvent) => {
|
||||
if (!enableTransitions()) {
|
||||
isDark.value = !isDark.value
|
||||
return
|
||||
}
|
||||
|
||||
const clipPath = [
|
||||
`circle(0px at ${x}px ${y}px)`,
|
||||
`circle(${Math.hypot(
|
||||
Math.max(x, innerWidth - x),
|
||||
Math.max(y, innerHeight - y)
|
||||
)}px at ${x}px ${y}px)`
|
||||
]
|
||||
|
||||
await document.startViewTransition(async () => {
|
||||
isDark.value = !isDark.value
|
||||
await nextTick()
|
||||
}).ready
|
||||
|
||||
document.documentElement.animate(
|
||||
{ clipPath: isDark.value ? clipPath.reverse() : clipPath },
|
||||
{
|
||||
duration: 300,
|
||||
easing: 'ease-in',
|
||||
fill: 'forwards',
|
||||
pseudoElement: `::view-transition-${isDark.value ? 'old' : 'new'}(root)`
|
||||
}
|
||||
)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DefaultTheme.Layout />
|
||||
</template>
|
||||
|
||||
<style>
|
||||
::view-transition-old(root),
|
||||
::view-transition-new(root) {
|
||||
animation: none;
|
||||
mix-blend-mode: normal;
|
||||
}
|
||||
|
||||
::view-transition-old(root),
|
||||
.dark::view-transition-new(root) {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
::view-transition-new(root),
|
||||
.dark::view-transition-old(root) {
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.VPSwitchAppearance {
|
||||
width: 22px !important;
|
||||
}
|
||||
|
||||
.VPSwitchAppearance .check {
|
||||
transform: none !important;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
Hasil (**peringatan!**: warna berkedip, gerakan tiba-tiba, cahaya terang):
|
||||
|
||||
<details>
|
||||
<summary>Demo</summary>
|
||||
|
||||

|
||||
|
||||
</details>
|
||||
|
||||
Lihat [Chrome Docs](https://developer.chrome.com/docs/web-platform/view-transitions/) untuk detail lebih lanjut tentang view transitions.
|
||||
|
||||
### Pada Perubahan Rute
|
||||
|
||||
Segera hadir.
|
||||
|
||||
## Menimpa Komponen Internal
|
||||
|
||||
Anda dapat menggunakan [alias Vite](https://vitejs.dev/config/shared-options.html#resolve-alias) untuk mengganti komponen tema default dengan yang kustom:
|
||||
|
||||
```ts
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
vite: {
|
||||
resolve: {
|
||||
alias: [
|
||||
{
|
||||
find: /^.*\/VPNavBar\.vue$/,
|
||||
replacement: fileURLToPath(
|
||||
new URL('./theme/components/CustomNavBar.vue', import.meta.url)
|
||||
)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Untuk mengetahui nama pasti komponen, lihat [kode sumber kami](https://github.com/vuejs/vitepress/tree/main/src/client/theme-default/components). Karena komponen bersifat internal, ada kemungkinan kecil namanya diperbarui di antara rilis minor.
|
||||
@ -0,0 +1,52 @@
|
||||
---
|
||||
description: Pelajari cara menggunakan YAML frontmatter di file Markdown VitePress untuk mengontrol metadata dan perilaku tingkat halaman.
|
||||
---
|
||||
|
||||
# Frontmatter
|
||||
|
||||
## Penggunaan
|
||||
|
||||
VitePress mendukung YAML frontmatter di semua file Markdown, mem-parsing-nya dengan [gray-matter](https://github.com/jonschlinkert/gray-matter). Frontmatter harus berada di bagian atas file Markdown (sebelum elemen apa pun termasuk tag `<script>`), dan harus berupa YAML valid yang ditulis di antara tiga garis hubung. Contoh:
|
||||
|
||||
```md
|
||||
---
|
||||
title: Docs with VitePress
|
||||
editLink: true
|
||||
---
|
||||
```
|
||||
|
||||
Banyak opsi konfigurasi situs atau tema default memiliki opsi terkait di frontmatter. Anda dapat menggunakan frontmatter untuk menimpa perilaku tertentu hanya untuk halaman saat ini. Untuk detailnya, lihat [Referensi Konfigurasi Frontmatter](../reference/frontmatter-config).
|
||||
|
||||
Anda juga dapat mendefinisikan data frontmatter kustom Anda sendiri, untuk digunakan dalam ekspresi Vue dinamis di halaman.
|
||||
|
||||
## Mengakses Data Frontmatter
|
||||
|
||||
Data frontmatter dapat diakses melalui variabel global khusus `$frontmatter`:
|
||||
|
||||
Berikut contoh bagaimana Anda dapat menggunakannya di file Markdown Anda:
|
||||
|
||||
```md
|
||||
---
|
||||
title: Docs with VitePress
|
||||
editLink: true
|
||||
---
|
||||
|
||||
# {{ $frontmatter.title }}
|
||||
|
||||
Konten panduan
|
||||
```
|
||||
|
||||
Anda juga dapat mengakses data frontmatter halaman saat ini di `<script setup>` dengan helper [`useData()`](../reference/runtime-api#usedata).
|
||||
|
||||
## Format Frontmatter Alternatif
|
||||
|
||||
VitePress juga mendukung sintaks frontmatter JSON, dimulai dan diakhiri dengan kurung kurawal:
|
||||
|
||||
```json
|
||||
---
|
||||
{
|
||||
"title": "Blogging Like a Hacker",
|
||||
"editLink": true
|
||||
}
|
||||
---
|
||||
```
|
||||
@ -0,0 +1,203 @@
|
||||
---
|
||||
description: Mulai dan jalankan VitePress. Pelajari cara menginstal, membuat scaffold, dan mulai mengembangkan situs dokumentasi Anda.
|
||||
---
|
||||
|
||||
# Memulai
|
||||
|
||||
## Coba Online
|
||||
|
||||
Anda dapat mencoba VitePress langsung di browser Anda di [StackBlitz](https://vitepress.new).
|
||||
|
||||
## Instalasi
|
||||
|
||||
### Prasyarat
|
||||
|
||||
- [Node.js](https://nodejs.org/) versi 20 atau lebih tinggi.
|
||||
- Terminal untuk mengakses VitePress melalui command line interface (CLI).
|
||||
- Text Editor dengan dukungan sintaks [Markdown](https://en.wikipedia.org/wiki/Markdown).
|
||||
- [VSCode](https://code.visualstudio.com/) direkomendasikan, bersama dengan [ekstensi resmi Vue](https://marketplace.visualstudio.com/items?itemName=Vue.volar).
|
||||
|
||||
VitePress dapat digunakan sendiri, atau diinstal ke dalam proyek yang sudah ada. Dalam kedua kasus, Anda dapat menginstalnya dengan:
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh [npm]
|
||||
$ npm add -D vitepress@next
|
||||
```
|
||||
|
||||
```sh [pnpm]
|
||||
$ pnpm add -D vitepress@next
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
$ yarn add -D vitepress@next vue
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
$ bun add -D vitepress@next
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
::: tip CATATAN
|
||||
|
||||
VitePress adalah paket ESM-only. Jangan gunakan `require()` untuk mengimpornya, dan pastikan `package.json` terdekat Anda berisi `"type": "module"`, atau ubah ekstensi file terkait Anda seperti `.vitepress/config.js` menjadi `.mjs`/`.mts`. Lihat [panduan troubleshooting Vite](http://vitejs.dev/guide/troubleshooting.html#this-package-is-esm-only) untuk detail lebih lanjut. Juga, di dalam konteks CJS async, Anda dapat menggunakan `await import('vitepress')` sebagai gantinya.
|
||||
|
||||
:::
|
||||
|
||||
### Setup Wizard
|
||||
|
||||
VitePress hadir dengan command line setup wizard yang akan membantu Anda membuat scaffold proyek dasar. Setelah instalasi, mulai wizard dengan menjalankan:
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh [npm]
|
||||
$ npx vitepress init
|
||||
```
|
||||
|
||||
```sh [pnpm]
|
||||
$ pnpm vitepress init
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
$ yarn vitepress init
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
$ bun vitepress init
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Anda akan disambut dengan beberapa pertanyaan sederhana:
|
||||
|
||||
<<< @/snippets/init.ansi
|
||||
|
||||
::: tip Vue sebagai Peer Dependency
|
||||
Jika Anda berniat melakukan kustomisasi yang menggunakan komponen atau API Vue, Anda juga harus menginstal `vue` secara eksplisit sebagai dependensi.
|
||||
:::
|
||||
|
||||
## Struktur File
|
||||
|
||||
Jika Anda membangun situs VitePress standalone, Anda dapat membuat scaffold situs di direktori Anda saat ini (`./`). Namun, jika Anda menginstal VitePress di proyek yang sudah ada bersama kode sumber lainnya, disarankan untuk membuat scaffold situs di direktori bersarang (mis. `./docs`) sehingga terpisah dari bagian proyek lainnya.
|
||||
|
||||
Dengan asumsi Anda memilih untuk membuat scaffold proyek VitePress di `./docs`, struktur file yang dihasilkan akan terlihat seperti ini:
|
||||
|
||||
```
|
||||
.
|
||||
├─ docs
|
||||
│ ├─ .vitepress
|
||||
│ │ └─ config.js
|
||||
│ ├─ api-examples.md
|
||||
│ ├─ markdown-examples.md
|
||||
│ └─ index.md
|
||||
└─ package.json
|
||||
```
|
||||
|
||||
Direktori `docs` dianggap sebagai **project root** dari situs VitePress. Direktori `.vitepress` adalah lokasi khusus untuk file konfigurasi VitePress, cache dev server, output build, dan kode kustomisasi tema opsional.
|
||||
|
||||
::: tip
|
||||
Secara default, VitePress menyimpan cache dev server-nya di `.vitepress/cache`, dan output build produksi di `.vitepress/dist`. Jika menggunakan Git, Anda harus menambahkannya ke file `.gitignore` Anda. Lokasi ini juga dapat [dikonfigurasi](../reference/site-config#outdir).
|
||||
:::
|
||||
|
||||
### File Konfigurasi
|
||||
|
||||
File konfigurasi (`.vitepress/config.js`) dapat digunakan untuk menyesuaikan berbagai aspek situs VitePress Anda, dengan opsi paling dasar adalah judul dan deskripsi situs:
|
||||
|
||||
```js [.vitepress/config.js]
|
||||
export default {
|
||||
// opsi tingkat situs
|
||||
title: 'VitePress',
|
||||
description: 'Just playing around.',
|
||||
|
||||
themeConfig: {
|
||||
// opsi tingkat tema
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Anda juga dapat mengonfigurasi perilaku tema melalui opsi `themeConfig`. Lihat [Referensi Konfigurasi](../reference/site-config) untuk detail lengkap semua opsi konfigurasi.
|
||||
|
||||
### File Sumber
|
||||
|
||||
File Markdown di luar direktori `.vitepress` dianggap sebagai **file sumber**.
|
||||
|
||||
VitePress menggunakan **file-based routing**: setiap file `.md` dikompilasi menjadi file `.html` yang sesuai dengan path yang sama. Misalnya, `index.md` akan dikompilasi menjadi `index.html`, dan dapat dikunjungi di path root `/` dari situs VitePress yang dihasilkan.
|
||||
|
||||
VitePress juga menyediakan kemampuan untuk menghasilkan URL yang bersih, menulis ulang path, dan menghasilkan halaman secara dinamis. Ini akan dibahas di [Panduan Routing](./routing).
|
||||
|
||||
## Menjalankan
|
||||
|
||||
Tool ini seharusnya juga telah menyuntikkan npm script berikut ke `package.json` Anda jika Anda mengizinkannya selama proses setup:
|
||||
|
||||
```json [package.json]
|
||||
{
|
||||
...
|
||||
"scripts": {
|
||||
"docs:dev": "vitepress dev docs",
|
||||
"docs:build": "vitepress build docs",
|
||||
"docs:preview": "vitepress preview docs"
|
||||
},
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Script `docs:dev` akan memulai server dev lokal dengan hot updates instan. Jalankan dengan perintah berikut:
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh [npm]
|
||||
$ npm run docs:dev
|
||||
```
|
||||
|
||||
```sh [pnpm]
|
||||
$ pnpm run docs:dev
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
$ yarn docs:dev
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
$ bun run docs:dev
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Alih-alih npm script, Anda juga dapat memanggil VitePress langsung dengan:
|
||||
|
||||
::: code-group
|
||||
|
||||
```sh [npm]
|
||||
$ npx vitepress dev docs
|
||||
```
|
||||
|
||||
```sh [pnpm]
|
||||
$ pnpm vitepress dev docs
|
||||
```
|
||||
|
||||
```sh [yarn]
|
||||
$ yarn vitepress dev docs
|
||||
```
|
||||
|
||||
```sh [bun]
|
||||
$ bun vitepress dev docs
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Penggunaan command line lainnya didokumentasikan di [Referensi CLI](../reference/cli).
|
||||
|
||||
Server pengembangan seharusnya berjalan di `http://localhost:5173`. Kunjungi URL tersebut di browser Anda untuk melihat situs baru Anda beraksi!
|
||||
|
||||
## Selanjutnya?
|
||||
|
||||
- Untuk lebih memahami bagaimana file markdown dipetakan ke HTML yang dihasilkan, lanjutkan ke [Panduan Routing](./routing).
|
||||
|
||||
- Untuk menemukan lebih banyak tentang apa yang dapat Anda lakukan di halaman, seperti menulis konten markdown atau menggunakan Komponen Vue, lihat bagian "Writing" dari panduan. Tempat yang bagus untuk memulai adalah mempelajari tentang [Ekstensi Markdown](./markdown).
|
||||
|
||||
- Untuk menjelajahi fitur yang disediakan oleh tema dokumentasi default, lihat [Referensi Konfigurasi Tema Default](../reference/default-theme-config).
|
||||
|
||||
- Jika Anda ingin lebih menyesuaikan tampilan situs Anda, jelajahi cara untuk [Memperluas Tema Default](./extending-default-theme) atau [Membangun Tema Kustom](./custom-theme).
|
||||
|
||||
- Setelah situs dokumentasi Anda mulai terbentuk, pastikan untuk membaca [Panduan Deployment](./deploy).
|
||||
@ -0,0 +1,115 @@
|
||||
---
|
||||
description: Siapkan internasionalisasi (i18n) di VitePress untuk mendukung banyak bahasa pada situs Anda.
|
||||
---
|
||||
|
||||
# Internasionalisasi
|
||||
|
||||
Untuk menggunakan fitur i18n bawaan, Anda perlu membuat struktur direktori sebagai berikut:
|
||||
|
||||
```
|
||||
docs/
|
||||
├─ es/
|
||||
│ ├─ foo.md
|
||||
├─ fr/
|
||||
│ ├─ foo.md
|
||||
├─ foo.md
|
||||
```
|
||||
|
||||
Kemudian di `docs/.vitepress/config.ts`:
|
||||
|
||||
```ts [docs/.vitepress/config.ts]
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
// properti bersama dan hal-hal top-level lainnya...
|
||||
|
||||
locales: {
|
||||
root: {
|
||||
label: 'English',
|
||||
lang: 'en'
|
||||
},
|
||||
fr: {
|
||||
label: 'French',
|
||||
lang: 'fr', // opsional, akan ditambahkan sebagai atribut `lang` pada tag `html`
|
||||
link: '/fr/guide' // default /fr/ -- ditampilkan di menu terjemahan navbar, dapat berupa eksternal
|
||||
|
||||
// properti spesifik locale lainnya...
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Properti berikut dapat ditimpa untuk setiap locale (termasuk root):
|
||||
|
||||
```ts
|
||||
interface LocaleSpecificConfig<ThemeConfig = any> {
|
||||
lang?: string
|
||||
dir?: string
|
||||
title?: string
|
||||
titleTemplate?: string | boolean
|
||||
description?: string
|
||||
head?: HeadConfig[] // akan digabung dengan entri head yang ada, tag meta duplikat otomatis dihapus
|
||||
themeConfig?: ThemeConfig // akan di-shallow merge, hal umum dapat diletakkan di entri themeConfig top-level
|
||||
}
|
||||
```
|
||||
|
||||
Lihat antarmuka [`DefaultTheme.Config`](https://github.com/vuejs/vitepress/blob/main/types/default-theme.d.ts) untuk detail tentang menyesuaikan teks placeholder tema default. Jangan menimpa `themeConfig.algolia` atau `themeConfig.carbonAds` di tingkat locale. Lihat [dokumentasi Algolia](../reference/default-theme-search#i18n) untuk menggunakan pencarian multibahasa.
|
||||
|
||||
**Pro tip:** File konfigurasi juga dapat disimpan di `docs/.vitepress/config/index.ts`. Ini dapat membantu Anda mengatur dengan membuat file konfigurasi per locale lalu menggabungkan dan mengekspornya dari `index.ts`.
|
||||
|
||||
## Direktori terpisah untuk setiap locale
|
||||
|
||||
Berikut adalah struktur yang sempurna:
|
||||
|
||||
```
|
||||
docs/
|
||||
├─ en/
|
||||
│ ├─ foo.md
|
||||
├─ es/
|
||||
│ ├─ foo.md
|
||||
├─ fr/
|
||||
├─ foo.md
|
||||
```
|
||||
|
||||
Namun, VitePress tidak akan mengalihkan `/` ke `/en/` secara default. Anda perlu mengonfigurasi server Anda untuk itu. Misalnya, di Netlify, Anda dapat menambahkan file `docs/public/_redirects` seperti ini:
|
||||
|
||||
```
|
||||
/* /es/:splat 302 Language=es
|
||||
/* /fr/:splat 302 Language=fr
|
||||
/* /en/:splat 302
|
||||
```
|
||||
|
||||
**Pro tip:** Jika menggunakan pendekatan di atas, Anda dapat menggunakan cookie `nf_lang` untuk menyimpan pilihan bahasa pengguna:
|
||||
|
||||
```ts [docs/.vitepress/theme/index.ts]
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import Layout from './Layout.vue'
|
||||
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
Layout
|
||||
}
|
||||
```
|
||||
|
||||
```vue [docs/.vitepress/theme/Layout.vue]
|
||||
<script setup lang="ts">
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import { useData, inBrowser } from 'vitepress'
|
||||
import { watchEffect } from 'vue'
|
||||
|
||||
const { lang } = useData()
|
||||
watchEffect(() => {
|
||||
if (inBrowser) {
|
||||
document.cookie = `nf_lang=${lang.value}; expires=Mon, 1 Jan 2030 00:00:00 UTC; path=/`
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DefaultTheme.Layout />
|
||||
</template>
|
||||
```
|
||||
|
||||
## Dukungan RTL (Eksperimental)
|
||||
|
||||
Untuk dukungan RTL, tentukan `dir: 'rtl'` di konfigurasi dan gunakan beberapa plugin RTLCSS PostCSS seperti <https://github.com/MohammadYounes/rtlcss>, <https://github.com/vkalinichev/postcss-rtl> atau <https://github.com/elchininet/postcss-rtlcss>. Anda perlu mengonfigurasi plugin PostCSS Anda untuk menggunakan `:where([dir="ltr"])` dan `:where([dir="rtl"])` sebagai prefix untuk mencegah masalah CSS specificity.
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,23 @@
|
||||
# Migrasi dari VitePress 0.x
|
||||
|
||||
Jika Anda berasal dari VitePress versi 0.x, ada beberapa breaking change karena fitur dan peningkatan baru. Ikuti panduan ini untuk melihat cara memigrasikan aplikasi Anda ke VitePress terbaru.
|
||||
|
||||
## App Config
|
||||
|
||||
- Fitur internasionalisasi belum diimplementasikan.
|
||||
|
||||
## Theme Config
|
||||
|
||||
- Opsi `sidebar` telah mengubah strukturnya.
|
||||
- Key `children` sekarang dinamai `items`.
|
||||
- Item tingkat atas saat ini mungkin tidak berisi `link`. Kami berencana untuk mengembalikannya.
|
||||
- `repo`, `repoLabel`, `docsDir`, `docsBranch`, `editLinks`, `editLinkText` dihapus demi API yang lebih fleksibel.
|
||||
- Untuk menambahkan tautan GitHub dengan ikon ke nav, gunakan fitur [Social Links](../reference/default-theme-nav#navigation-links).
|
||||
- Untuk menambahkan fitur "Edit this page", gunakan fitur [Edit Link](../reference/default-theme-edit-link).
|
||||
- Opsi `lastUpdated` sekarang dipisah menjadi `config.lastUpdated` dan `themeConfig.lastUpdatedText`.
|
||||
- `carbonAds.carbon` diubah menjadi `carbonAds.code`.
|
||||
|
||||
## Frontmatter Config
|
||||
|
||||
- Opsi `home: true` telah berubah menjadi `layout: home`. Selain itu, banyak pengaturan terkait Homepage telah dimodifikasi untuk menyediakan fitur tambahan. Lihat [panduan Home Page](../reference/default-theme-home-page) untuk detailnya.
|
||||
- Opsi `footer` dipindahkan ke [`themeConfig.footer`](../reference/default-theme-config#footer).
|
||||
@ -0,0 +1,30 @@
|
||||
# Migrasi dari VuePress
|
||||
|
||||
## Config
|
||||
|
||||
### Sidebar
|
||||
|
||||
Sidebar tidak lagi otomatis diisi dari frontmatter. Anda dapat [membaca frontmatter sendiri](https://github.com/vuejs/vitepress/issues/572#issuecomment-1170116225) untuk mengisi sidebar secara dinamis. [Utilitas tambahan untuk ini](https://github.com/vuejs/vitepress/issues/96) mungkin disediakan di masa mendatang.
|
||||
|
||||
## Markdown
|
||||
|
||||
### Gambar
|
||||
|
||||
Tidak seperti VuePress, VitePress menangani [`base`](./asset-handling#base-url) dari konfigurasi Anda secara otomatis saat Anda menggunakan gambar statis.
|
||||
|
||||
Oleh karena itu, sekarang Anda dapat merender gambar tanpa tag `img`.
|
||||
|
||||
```diff
|
||||
- <img :src="$withBase('/foo.png')" alt="foo">
|
||||
+ 
|
||||
```
|
||||
|
||||
::: warning
|
||||
Untuk gambar dinamis Anda tetap memerlukan `withBase` seperti yang ditunjukkan di [panduan Base URL](./asset-handling#base-url).
|
||||
:::
|
||||
|
||||
Gunakan regex `<img.*withBase\('(.*)'\).*alt="([^"]*)".*>` untuk mencari dan menggantinya dengan `` untuk mengganti semua gambar dengan sintaks ``.
|
||||
|
||||
---
|
||||
|
||||
selengkapnya menyusul...
|
||||
@ -0,0 +1,27 @@
|
||||
---
|
||||
description: Aktifkan mode MPA (Multi-Page Application) di VitePress untuk halaman tanpa JavaScript dengan performa awal yang lebih baik.
|
||||
---
|
||||
|
||||
# Mode MPA <Badge type="warning" text="eksperimental" />
|
||||
|
||||
Mode MPA (Multi-Page Application) dapat diaktifkan melalui command line dengan `vitepress build --mpa`, atau melalui konfigurasi dengan opsi `mpa: true`.
|
||||
|
||||
Dalam mode MPA, semua halaman dirender tanpa JavaScript apa pun secara default. Hasilnya, situs produksi kemungkinan akan mendapatkan skor performa kunjungan awal yang lebih baik dari alat audit.
|
||||
|
||||
Namun, karena tidak adanya navigasi SPA, tautan antar halaman akan menyebabkan reload halaman penuh. Navigasi setelah load dalam mode MPA tidak akan terasa seinstan dalam mode SPA.
|
||||
|
||||
Perhatikan juga bahwa tanpa-JS-secara-default berarti Anda pada dasarnya menggunakan Vue murni sebagai bahasa templating sisi server. Tidak ada event handler yang akan dipasang di browser, sehingga tidak akan ada interaktivitas. Untuk memuat JavaScript sisi klien, Anda perlu menggunakan tag khusus `<script client>`:
|
||||
|
||||
```html
|
||||
<script client>
|
||||
document.querySelector('h1').addEventListener('click', () => {
|
||||
console.log('client side JavaScript!')
|
||||
})
|
||||
</script>
|
||||
|
||||
# Hello
|
||||
```
|
||||
|
||||
`<script client>` adalah fitur khusus VitePress, bukan fitur Vue. Fitur ini bekerja di file `.md` maupun `.vue`, tetapi hanya dalam mode MPA. Client script di semua komponen tema akan dibundel bersama, sementara client script untuk halaman tertentu akan dipisah hanya untuk halaman tersebut.
|
||||
|
||||
Perhatikan bahwa `<script client>` **tidak dievaluasi sebagai kode komponen Vue**: ini diproses sebagai modul JavaScript biasa. Karena alasan ini, mode MPA hanya boleh digunakan jika situs Anda memerlukan interaktivitas sisi klien yang sangat minimal.
|
||||
@ -0,0 +1,451 @@
|
||||
---
|
||||
description: Pahami routing berbasis file VitePress, rute dinamis, URL bersih, dan penulisan ulang path.
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Routing
|
||||
|
||||
## File-Based Routing
|
||||
|
||||
VitePress menggunakan file-based routing, yang berarti halaman HTML yang dihasilkan dipetakan dari struktur direktori file sumber Markdown. Misalnya, dengan struktur direktori berikut:
|
||||
|
||||
```
|
||||
.
|
||||
├─ guide
|
||||
│ ├─ getting-started.md
|
||||
│ └─ index.md
|
||||
├─ index.md
|
||||
└─ prologue.md
|
||||
```
|
||||
|
||||
Halaman HTML yang dihasilkan akan menjadi:
|
||||
|
||||
```
|
||||
index.md --> /index.html (dapat diakses sebagai /)
|
||||
prologue.md --> /prologue.html
|
||||
guide/index.md --> /guide/index.html (dapat diakses sebagai /guide/)
|
||||
guide/getting-started.md --> /guide/getting-started.html
|
||||
```
|
||||
|
||||
HTML yang dihasilkan dapat dihosting di server web apa pun yang dapat menyajikan file statis.
|
||||
|
||||
## Root dan Source Directory
|
||||
|
||||
Ada dua konsep penting dalam struktur file proyek VitePress: **project root** dan **source directory**.
|
||||
|
||||
### Project Root
|
||||
|
||||
Project root adalah tempat VitePress akan mencoba mencari direktori khusus `.vitepress`. Direktori `.vitepress` adalah lokasi khusus untuk file konfigurasi VitePress, cache dev server, output build, dan kode kustomisasi tema opsional.
|
||||
|
||||
Ketika Anda menjalankan `vitepress dev` atau `vitepress build` dari command line, VitePress akan menggunakan direktori kerja saat ini sebagai project root. Untuk menentukan sub-direktori sebagai root, Anda perlu meneruskan path relatif ke perintah. Misalnya, jika proyek VitePress Anda terletak di `./docs`, Anda harus menjalankan `vitepress dev docs`:
|
||||
|
||||
```
|
||||
.
|
||||
├─ docs # project root
|
||||
│ ├─ .vitepress # config dir
|
||||
│ ├─ getting-started.md
|
||||
│ └─ index.md
|
||||
└─ ...
|
||||
```
|
||||
|
||||
```sh
|
||||
vitepress dev docs
|
||||
```
|
||||
|
||||
Ini akan menghasilkan pemetaan sumber-ke-HTML berikut:
|
||||
|
||||
```
|
||||
docs/index.md --> /index.html (dapat diakses sebagai /)
|
||||
docs/getting-started.md --> /getting-started.html
|
||||
```
|
||||
|
||||
### Source Directory
|
||||
|
||||
Source directory adalah tempat file sumber Markdown Anda berada. Secara default, ini sama dengan project root. Namun, Anda dapat mengonfigurasinya melalui opsi konfigurasi [`srcDir`](../reference/site-config#srcdir).
|
||||
|
||||
Opsi `srcDir` diselesaikan relatif terhadap project root. Misalnya, dengan `srcDir: 'src'`, struktur file Anda akan terlihat seperti ini:
|
||||
|
||||
```
|
||||
. # project root
|
||||
├─ .vitepress # config dir
|
||||
└─ src # source dir
|
||||
├─ getting-started.md
|
||||
└─ index.md
|
||||
```
|
||||
|
||||
Pemetaan sumber-ke-HTML yang dihasilkan:
|
||||
|
||||
```
|
||||
src/index.md --> /index.html (dapat diakses sebagai /)
|
||||
src/getting-started.md --> /getting-started.html
|
||||
```
|
||||
|
||||
## Menautkan Antar Halaman
|
||||
|
||||
Anda dapat menggunakan path absolut dan relatif saat menautkan antar halaman. Perhatikan bahwa meskipun ekstensi `.md` dan `.html` akan berfungsi, praktik terbaik adalah menghilangkan ekstensi file sehingga VitePress dapat menghasilkan URL akhir berdasarkan konfigurasi Anda.
|
||||
|
||||
```md
|
||||
<!-- Lakukan -->
|
||||
[Getting Started](./getting-started)
|
||||
[Getting Started](../guide/getting-started)
|
||||
|
||||
<!-- Jangan -->
|
||||
[Getting Started](./getting-started.md)
|
||||
[Getting Started](./getting-started.html)
|
||||
```
|
||||
|
||||
Pelajari lebih lanjut tentang menautkan ke aset seperti gambar di [Penanganan Aset](./asset-handling).
|
||||
|
||||
### Menautkan ke Halaman Non-VitePress
|
||||
|
||||
Jika Anda ingin menautkan ke halaman di situs Anda yang tidak dihasilkan oleh VitePress, Anda perlu menggunakan URL penuh (terbuka di tab baru) atau secara eksplisit menentukan target:
|
||||
|
||||
**Input**
|
||||
|
||||
```md
|
||||
[Link to pure.html](/pure.html){target="_self"}
|
||||
```
|
||||
|
||||
**Output**
|
||||
|
||||
[Link to pure.html](/pure.html){target="_self"}
|
||||
|
||||
::: tip Catatan
|
||||
|
||||
Dalam tautan Markdown, `base` secara otomatis ditambahkan ke URL. Ini berarti jika Anda ingin menautkan ke halaman di luar base Anda, Anda perlu sesuatu seperti `../../pure.html` di tautan (diselesaikan relatif terhadap halaman saat ini oleh browser).
|
||||
|
||||
Alternatifnya, Anda dapat langsung menggunakan sintaks tag anchor:
|
||||
|
||||
```md
|
||||
<a href="/pure.html" target="_self">Link to pure.html</a>
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## Menghasilkan URL Bersih
|
||||
|
||||
::: warning Dukungan Server Diperlukan
|
||||
Untuk menyajikan URL bersih dengan VitePress, dukungan sisi server diperlukan.
|
||||
:::
|
||||
|
||||
Secara default, VitePress menyelesaikan tautan masuk ke URL yang diakhiri dengan `.html`. Namun, beberapa pengguna mungkin lebih suka "Clean URLs" tanpa ekstensi `.html`, misalnya, `example.com/path` alih-alih `example.com/path.html`.
|
||||
|
||||
Beberapa server atau platform hosting (misalnya Netlify, Vercel, GitHub Pages) menyediakan kemampuan untuk memetakan URL seperti `/foo` ke `/foo.html` jika ada, tanpa redirect:
|
||||
|
||||
- Netlify dan GitHub Pages mendukung ini secara default.
|
||||
- Vercel memerlukan pengaktifan [opsi `cleanUrls` di `vercel.json`](https://vercel.com/docs/concepts/projects/project-configuration#cleanurls).
|
||||
|
||||
Jika fitur ini tersedia untuk Anda, Anda juga dapat mengaktifkan opsi konfigurasi [`cleanUrls`](../reference/site-config#cleanurls) milik VitePress sehingga:
|
||||
|
||||
- Tautan masuk antar halaman dihasilkan tanpa ekstensi `.html`.
|
||||
- Jika path saat ini diakhiri dengan `.html`, router akan melakukan redirect sisi klien ke path tanpa ekstensi.
|
||||
|
||||
Namun, jika Anda tidak dapat mengonfigurasi server Anda dengan dukungan tersebut, Anda harus secara manual menggunakan struktur direktori berikut:
|
||||
|
||||
```
|
||||
.
|
||||
├─ getting-started
|
||||
│ └─ index.md
|
||||
├─ installation
|
||||
│ └─ index.md
|
||||
└─ index.md
|
||||
```
|
||||
|
||||
## Route Rewrites
|
||||
|
||||
Anda dapat menyesuaikan pemetaan antara struktur source directory dan halaman yang dihasilkan. Ini berguna ketika Anda memiliki struktur proyek yang kompleks. Misalnya, katakanlah Anda memiliki monorepo dengan banyak paket, dan ingin menempatkan dokumentasi bersama file sumber seperti ini:
|
||||
|
||||
```
|
||||
.
|
||||
└─ packages
|
||||
├─ pkg-a
|
||||
│ └─ src
|
||||
│ ├─ foo.md
|
||||
│ └─ index.md
|
||||
└─ pkg-b
|
||||
└─ src
|
||||
├─ bar.md
|
||||
└─ index.md
|
||||
```
|
||||
|
||||
Dan Anda ingin halaman VitePress dihasilkan seperti ini:
|
||||
|
||||
```
|
||||
packages/pkg-a/src/index.md --> /pkg-a/index.html
|
||||
packages/pkg-a/src/foo.md --> /pkg-a/foo.html
|
||||
packages/pkg-b/src/index.md --> /pkg-b/index.html
|
||||
packages/pkg-b/src/bar.md --> /pkg-b/bar.html
|
||||
```
|
||||
|
||||
Anda dapat mencapai ini dengan mengonfigurasi opsi [`rewrites`](../reference/site-config#rewrites) seperti ini:
|
||||
|
||||
```ts [.vitepress/config.js]
|
||||
export default {
|
||||
rewrites: {
|
||||
'packages/pkg-a/src/index.md': 'pkg-a/index.md',
|
||||
'packages/pkg-a/src/foo.md': 'pkg-a/foo.md',
|
||||
'packages/pkg-b/src/index.md': 'pkg-b/index.md',
|
||||
'packages/pkg-b/src/bar.md': 'pkg-b/bar.md'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Opsi `rewrites` juga mendukung parameter rute dinamis. Pada contoh di atas, akan sangat verbose untuk mencantumkan semua path jika Anda memiliki banyak paket. Mengingat semuanya memiliki struktur file yang sama, Anda dapat menyederhanakan konfigurasi seperti ini:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
rewrites: {
|
||||
'packages/:pkg/src/:slug*': ':pkg/:slug*'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Path rewrite dikompilasi menggunakan paket `path-to-regexp`; lihat [dokumentasinya](https://github.com/pillarjs/path-to-regexp/tree/6.x#parameters) untuk sintaks yang lebih lanjut.
|
||||
|
||||
`rewrites` juga dapat berupa fungsi yang menerima path asli dan mengembalikan path baru:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
rewrites(id) {
|
||||
return id.replace(/^packages\/([^/]+)\/src\//, '$1/')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
::: warning Tautan Relatif dengan Rewrites
|
||||
|
||||
Ketika rewrite diaktifkan, **tautan relatif harus didasarkan pada path yang di-rewrite**. Misalnya, untuk membuat tautan relatif dari `packages/pkg-a/src/pkg-a-code.md` ke `packages/pkg-b/src/pkg-b-code.md`, Anda harus menggunakan:
|
||||
|
||||
```md
|
||||
[Link to PKG B](../pkg-b/pkg-b-code)
|
||||
```
|
||||
:::
|
||||
|
||||
## Rute Dinamis
|
||||
|
||||
Anda dapat menghasilkan banyak halaman menggunakan satu file Markdown dan data dinamis. Misalnya, Anda dapat membuat file `packages/[pkg].md` yang menghasilkan halaman terkait untuk setiap paket dalam sebuah proyek. Di sini, segmen `[pkg]` adalah **parameter** rute yang membedakan setiap halaman dari yang lain.
|
||||
|
||||
### File Paths Loader
|
||||
|
||||
Karena VitePress adalah generator situs statis, path halaman yang mungkin harus ditentukan pada waktu build. Oleh karena itu, halaman rute dinamis **harus** disertai dengan **file paths loader**. Untuk `packages/[pkg].md`, kita akan memerlukan `packages/[pkg].paths.js` (`.ts` juga didukung):
|
||||
|
||||
```
|
||||
.
|
||||
└─ packages
|
||||
├─ [pkg].md # template rute
|
||||
└─ [pkg].paths.js # route paths loader
|
||||
```
|
||||
|
||||
Paths loader harus menyediakan objek dengan metode `paths` sebagai default export-nya. Metode `paths` harus mengembalikan array objek dengan properti `params`. Setiap objek ini akan menghasilkan halaman yang sesuai.
|
||||
|
||||
Dengan array `paths` berikut:
|
||||
|
||||
```js
|
||||
// packages/[pkg].paths.js
|
||||
export default {
|
||||
paths() {
|
||||
return [
|
||||
{ params: { pkg: 'foo' }},
|
||||
{ params: { pkg: 'bar' }}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Halaman HTML yang dihasilkan akan menjadi:
|
||||
|
||||
```
|
||||
.
|
||||
└─ packages
|
||||
├─ foo.html
|
||||
└─ bar.html
|
||||
```
|
||||
|
||||
### Type-safe loader dengan `defineRoutes`
|
||||
|
||||
Jika Anda menggunakan TypeScript, Anda dapat membungkus loader dengan `defineRoutes` dari `vitepress` untuk mendapatkan petunjuk tipe untuk hook rute seperti `paths`, `watch`, dan `transformPageData`:
|
||||
|
||||
```ts
|
||||
// packages/[pkg].paths.ts
|
||||
import { defineRoutes } from 'vitepress'
|
||||
|
||||
export default defineRoutes({
|
||||
watch: ['../data/**/*.json'],
|
||||
async paths() {
|
||||
return [
|
||||
{ params: { pkg: 'foo' } },
|
||||
{ params: { pkg: 'bar' } }
|
||||
]
|
||||
},
|
||||
async transformPageData(pageData) {
|
||||
pageData.title = `${pageData.title} · Packages`
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
`defineRoutes` bersifat opsional, tetapi direkomendasikan saat menulis file `.paths.ts`.
|
||||
|
||||
### Multiple Params
|
||||
|
||||
Rute dinamis dapat berisi beberapa params:
|
||||
|
||||
**Struktur File**
|
||||
|
||||
```
|
||||
.
|
||||
└─ packages
|
||||
├─ [pkg]-[version].md
|
||||
└─ [pkg]-[version].paths.js
|
||||
```
|
||||
|
||||
**Paths Loader**
|
||||
|
||||
```js
|
||||
export default {
|
||||
paths: () => [
|
||||
{ params: { pkg: 'foo', version: '1.0.0' }},
|
||||
{ params: { pkg: 'foo', version: '2.0.0' }},
|
||||
{ params: { pkg: 'bar', version: '1.0.0' }},
|
||||
{ params: { pkg: 'bar', version: '2.0.0' }}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Output**
|
||||
|
||||
```
|
||||
.
|
||||
└─ packages
|
||||
├─ foo-1.0.0.html
|
||||
├─ foo-2.0.0.html
|
||||
├─ bar-1.0.0.html
|
||||
└─ bar-2.0.0.html
|
||||
```
|
||||
|
||||
### Menghasilkan Path Secara Dinamis
|
||||
|
||||
Modul paths loader dijalankan di Node.js dan hanya dieksekusi selama waktu build. Anda dapat menghasilkan array paths secara dinamis menggunakan data apa pun, baik lokal maupun remote.
|
||||
|
||||
Menghasilkan path dari file lokal:
|
||||
|
||||
```js
|
||||
import fs from 'fs'
|
||||
|
||||
export default {
|
||||
paths() {
|
||||
return fs
|
||||
.readdirSync('packages')
|
||||
.map((pkg) => {
|
||||
return { params: { pkg }}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Menghasilkan path dari data remote:
|
||||
|
||||
```js
|
||||
export default {
|
||||
async paths() {
|
||||
const pkgs = await (await fetch('https://my-api.com/packages')).json()
|
||||
|
||||
return pkgs.map((pkg) => {
|
||||
return {
|
||||
params: {
|
||||
pkg: pkg.name,
|
||||
version: pkg.version
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Memantau File Template dan Data
|
||||
|
||||
Saat menghasilkan konten halaman dari template atau sumber data eksternal, Anda dapat menggunakan opsi watch untuk secara otomatis membangun ulang halaman ketika file-file tersebut berubah selama pengembangan:
|
||||
|
||||
```js
|
||||
// posts/[slug].paths.js
|
||||
import fs from 'node:fs'
|
||||
import { renderTemplate } from './templates/renderer.js'
|
||||
|
||||
export default {
|
||||
// Pantau perubahan pada file template dan sumber data
|
||||
watch: [
|
||||
'./templates/**/*.njk', // File template
|
||||
'../data/**/*.json' // File data
|
||||
],
|
||||
|
||||
paths(watchedFiles) {
|
||||
// watchedFiles akan berupa array path absolut dari file yang cocok
|
||||
// Baca file data untuk menghasilkan rute
|
||||
const dataFiles = watchedFiles.filter(file => file.endsWith('.json'))
|
||||
|
||||
return dataFiles.map(file => {
|
||||
const data = JSON.parse(fs.readFileSync(file, 'utf-8'))
|
||||
|
||||
return {
|
||||
params: { slug: data.slug },
|
||||
content: renderTemplate(data) // Gunakan template untuk menghasilkan konten
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Opsi `watch` bekerja dengan cara yang sama seperti pada [data loader](./data-loading#data-dari-file-lokal):
|
||||
|
||||
- Menerima [glob patterns](https://github.com/mrmlnc/fast-glob#pattern-syntax) untuk mencocokkan file
|
||||
- Pattern relatif terhadap file `.paths.js` itu sendiri
|
||||
- Perubahan pada file yang dipantau memicu regenerasi halaman dan HMR selama pengembangan
|
||||
- Pada build produksi, semua halaman dihasilkan sekali terlepas dari konfigurasi watch
|
||||
|
||||
### Mengakses Params di Halaman
|
||||
|
||||
Anda dapat menggunakan params untuk meneruskan data tambahan ke setiap halaman. File rute Markdown dapat mengakses params halaman saat ini dalam ekspresi Vue melalui properti global `$params`:
|
||||
|
||||
```md
|
||||
- nama paket: {{ $params.pkg }}
|
||||
- versi: {{ $params.version }}
|
||||
```
|
||||
|
||||
Anda juga dapat mengakses params halaman saat ini melalui runtime API [`useData`](../reference/runtime-api#usedata). Ini tersedia baik di file Markdown maupun komponen Vue:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { useData } from 'vitepress'
|
||||
|
||||
// params adalah Vue ref
|
||||
const { params } = useData()
|
||||
|
||||
console.log(params.value)
|
||||
</script>
|
||||
```
|
||||
|
||||
### Merender Konten Mentah
|
||||
|
||||
Params yang diteruskan ke halaman akan diserialisasi dalam payload JavaScript klien, jadi Anda harus menghindari meneruskan data berat dalam params, misalnya konten Markdown mentah atau HTML yang diambil dari CMS remote.
|
||||
|
||||
Sebagai gantinya, Anda dapat meneruskan konten tersebut ke setiap halaman menggunakan properti `content` pada setiap objek path:
|
||||
|
||||
```js
|
||||
export default {
|
||||
async paths() {
|
||||
const posts = await (await fetch('https://my-cms.com/blog-posts')).json()
|
||||
|
||||
return posts.map((post) => {
|
||||
return {
|
||||
params: { id: post.id },
|
||||
content: post.content // Markdown mentah atau HTML
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Kemudian, gunakan sintaks khusus berikut untuk merender konten sebagai bagian dari file Markdown itu sendiri:
|
||||
|
||||
```md
|
||||
<!-- @content -->
|
||||
```
|
||||
@ -0,0 +1,62 @@
|
||||
---
|
||||
description: Hasilkan file sitemap.xml untuk situs VitePress Anda untuk meningkatkan keterlihatan mesin pencari.
|
||||
---
|
||||
|
||||
# Pembuatan Sitemap
|
||||
|
||||
VitePress hadir dengan dukungan bawaan untuk menghasilkan file `sitemap.xml` untuk situs Anda. Untuk mengaktifkannya, tambahkan yang berikut ke `.vitepress/config.js` Anda:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
sitemap: {
|
||||
hostname: 'https://example.com'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Untuk memiliki tag `<lastmod>` di `sitemap.xml` Anda, Anda dapat mengaktifkan opsi [`lastUpdated`](../reference/default-theme-last-updated).
|
||||
|
||||
## Opsi
|
||||
|
||||
Dukungan sitemap didukung oleh modul [`sitemap`](https://www.npmjs.com/package/sitemap). Anda dapat meneruskan opsi apa pun yang didukung olehnya ke opsi `sitemap` di file konfigurasi Anda. Ini akan diteruskan langsung ke konstruktor `SitemapStream`. Lihat [dokumentasi `sitemap`](https://www.npmjs.com/package/sitemap#options-you-can-pass) untuk detail lebih lanjut. Contoh:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
sitemap: {
|
||||
hostname: 'https://example.com',
|
||||
lastmodDateOnly: false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Jika Anda menggunakan `base` di konfigurasi Anda, Anda harus menambahkannya ke opsi `hostname`:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
base: '/my-site/',
|
||||
sitemap: {
|
||||
hostname: 'https://example.com/my-site/'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Hook `transformItems`
|
||||
|
||||
Anda dapat menggunakan hook `sitemap.transformItems` untuk memodifikasi item sitemap sebelum ditulis ke file `sitemap.xml`. Hook ini dipanggil dengan array item sitemap dan mengharapkan array item sitemap dikembalikan. Contoh:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
sitemap: {
|
||||
hostname: 'https://example.com',
|
||||
transformItems: (items) => {
|
||||
// tambahkan item baru atau modifikasi/filter item yang ada
|
||||
items.push({
|
||||
url: '/extra-page',
|
||||
changefreq: 'monthly',
|
||||
priority: 0.8
|
||||
})
|
||||
return items
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -0,0 +1,135 @@
|
||||
---
|
||||
description: Pastikan komponen tema VitePress dan kode kustom Anda kompatibel dengan server-side rendering.
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Kompatibilitas SSR
|
||||
|
||||
VitePress melakukan pre-render aplikasi di Node.js selama build produksi, menggunakan kemampuan Server-Side Rendering (SSR) Vue. Ini berarti semua kode kustom di komponen tema tunduk pada Kompatibilitas SSR.
|
||||
|
||||
[Bagian SSR di dokumen resmi Vue](https://vuejs.org/guide/scaling-up/ssr.html) menyediakan lebih banyak konteks tentang apa itu SSR, hubungan antara SSR / SSG, dan catatan umum tentang menulis kode yang ramah SSR. Aturan umumnya adalah hanya mengakses browser / DOM API di hook `beforeMount` atau `mounted` komponen Vue.
|
||||
|
||||
## `<ClientOnly>`
|
||||
|
||||
Jika Anda menggunakan atau mendemokan komponen yang tidak ramah SSR (misalnya, berisi custom directive), Anda dapat membungkusnya di dalam komponen bawaan `<ClientOnly>`:
|
||||
|
||||
```md
|
||||
<ClientOnly>
|
||||
<NonSSRFriendlyComponent />
|
||||
</ClientOnly>
|
||||
```
|
||||
|
||||
## Library yang Mengakses Browser API Saat Import
|
||||
|
||||
Beberapa komponen atau library mengakses browser API **saat import**. Untuk menggunakan kode yang mengasumsikan lingkungan browser saat import, Anda perlu mengimpornya secara dinamis.
|
||||
|
||||
### Mengimpor di Hook Mounted
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { onMounted } from 'vue'
|
||||
|
||||
onMounted(() => {
|
||||
import('./lib-that-access-window-on-import').then((module) => {
|
||||
// gunakan kode
|
||||
})
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
### Conditional Import
|
||||
|
||||
Anda juga dapat mengimpor dependensi secara kondisional menggunakan flag `import.meta.env.SSR` (bagian dari [Vite env variables](https://vitejs.dev/guide/env-and-mode.html#env-variables)):
|
||||
|
||||
```js
|
||||
if (!import.meta.env.SSR) {
|
||||
import('./lib-that-access-window-on-import').then((module) => {
|
||||
// gunakan kode
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Karena [`Theme.enhanceApp`](./custom-theme#theme-interface) dapat bersifat async, Anda dapat mengimpor dan mendaftarkan plugin Vue yang mengakses browser API saat import secara kondisional:
|
||||
|
||||
```js [.vitepress/theme/index.js]
|
||||
/** @type {import('vitepress').Theme} */
|
||||
export default {
|
||||
// ...
|
||||
async enhanceApp({ app }) {
|
||||
if (!import.meta.env.SSR) {
|
||||
const plugin = await import('plugin-that-access-window-on-import')
|
||||
app.use(plugin.default)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Jika Anda menggunakan TypeScript:
|
||||
```ts [.vitepress/theme/index.ts]
|
||||
import type { Theme } from 'vitepress'
|
||||
|
||||
export default {
|
||||
// ...
|
||||
async enhanceApp({ app }) {
|
||||
if (!import.meta.env.SSR) {
|
||||
const plugin = await import('plugin-that-access-window-on-import')
|
||||
app.use(plugin.default)
|
||||
}
|
||||
}
|
||||
} satisfies Theme
|
||||
```
|
||||
|
||||
### `defineClientComponent`
|
||||
|
||||
VitePress menyediakan helper untuk mengimpor komponen Vue yang mengakses browser API saat import.
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { defineClientComponent } from 'vitepress'
|
||||
|
||||
const ClientComp = defineClientComponent(() => {
|
||||
return import('component-that-access-window-on-import')
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientComp />
|
||||
</template>
|
||||
```
|
||||
|
||||
Anda juga dapat meneruskan props/children/slots ke komponen target:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { defineClientComponent } from 'vitepress'
|
||||
|
||||
const clientCompRef = ref(null)
|
||||
const ClientComp = defineClientComponent(
|
||||
() => import('component-that-access-window-on-import'),
|
||||
|
||||
// args diteruskan ke h() - https://vuejs.org/api/render-function.html#h
|
||||
[
|
||||
{
|
||||
ref: clientCompRef
|
||||
},
|
||||
{
|
||||
default: () => 'default slot',
|
||||
foo: () => h('div', 'foo'),
|
||||
bar: () => [h('span', 'one'), h('span', 'two')]
|
||||
}
|
||||
],
|
||||
|
||||
// callback setelah komponen dimuat, dapat async
|
||||
() => {
|
||||
console.log(clientCompRef.value)
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientComp />
|
||||
</template>
|
||||
```
|
||||
|
||||
Komponen target hanya akan diimpor di hook mounted dari komponen wrapper.
|
||||
@ -0,0 +1,295 @@
|
||||
---
|
||||
description: Gunakan komponen Vue dan fitur templating dinamis langsung di dalam file Markdown di VitePress.
|
||||
---
|
||||
|
||||
# Menggunakan Vue di Markdown
|
||||
|
||||
Di VitePress, setiap file Markdown dikompilasi menjadi HTML dan kemudian diproses sebagai [Vue Single-File Component](https://vuejs.org/guide/scaling-up/sfc.html). Ini berarti Anda dapat menggunakan fitur Vue apa pun di dalam Markdown, termasuk templating dinamis, menggunakan komponen Vue, atau logika komponen Vue dalam halaman apa pun dengan menambahkan tag `<script>`.
|
||||
|
||||
Perlu dicatat bahwa VitePress memanfaatkan compiler Vue untuk secara otomatis mendeteksi dan mengoptimalkan bagian konten Markdown yang murni statis. Konten statis dioptimalkan menjadi single placeholder node dan dihilangkan dari payload JavaScript halaman untuk kunjungan awal. Konten tersebut juga dilewati selama client-side hydration. Singkatnya, Anda hanya membayar untuk bagian dinamis pada halaman tertentu.
|
||||
|
||||
::: tip Kompatibilitas SSR
|
||||
Semua penggunaan Vue harus kompatibel dengan SSR. Lihat [Kompatibilitas SSR](./ssr-compat) untuk detail dan solusi umum.
|
||||
:::
|
||||
|
||||
## Templating
|
||||
|
||||
### Interpolasi
|
||||
|
||||
Setiap file Markdown pertama-tama dikompilasi menjadi HTML dan kemudian diteruskan sebagai komponen Vue ke pipeline proses Vite. Ini berarti Anda dapat menggunakan interpolasi gaya Vue dalam teks:
|
||||
|
||||
**Input**
|
||||
|
||||
```md
|
||||
{{ 1 + 1 }}
|
||||
```
|
||||
|
||||
**Output**
|
||||
|
||||
<div class="language-text"><pre><code>{{ 1 + 1 }}</code></pre></div>
|
||||
|
||||
### Directive
|
||||
|
||||
Directive juga berfungsi (perhatikan bahwa secara desain, HTML mentah juga valid di Markdown):
|
||||
|
||||
**Input**
|
||||
|
||||
```html
|
||||
<span v-for="i in 3">{{ i }}</span>
|
||||
```
|
||||
|
||||
**Output**
|
||||
|
||||
<div class="language-text"><pre><code><span v-for="i in 3">{{ i }} </span></code></pre></div>
|
||||
|
||||
## `<script>` dan `<style>`
|
||||
|
||||
Tag `<script>` dan `<style>` tingkat root di file Markdown berfungsi seperti di Vue SFC, termasuk `<script setup>`, `<style module>`, dll. Perbedaan utama di sini adalah tidak ada tag `<template>`: semua konten tingkat root lainnya adalah Markdown. Perhatikan juga bahwa semua tag harus ditempatkan **setelah** frontmatter:
|
||||
|
||||
```html
|
||||
---
|
||||
hello: world
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
|
||||
const count = ref(0)
|
||||
</script>
|
||||
|
||||
## Konten Markdown
|
||||
|
||||
Hitungannya: {{ count }}
|
||||
|
||||
<button :class="$style.button" @click="count++">Increment</button>
|
||||
|
||||
<style module>
|
||||
.button {
|
||||
color: red;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
::: warning Hindari `<style scoped>` di Markdown
|
||||
Ketika digunakan di Markdown, `<style scoped>` memerlukan penambahan atribut khusus ke setiap elemen di halaman saat ini, yang akan secara signifikan memperbesar ukuran halaman. `<style module>` lebih disarankan ketika styling dengan cakupan lokal diperlukan di halaman.
|
||||
:::
|
||||
|
||||
Anda juga memiliki akses ke runtime API VitePress seperti helper [`useData`](../reference/runtime-api#usedata), yang menyediakan akses ke metadata halaman saat ini:
|
||||
|
||||
**Input**
|
||||
|
||||
```html
|
||||
<script setup>
|
||||
import { useData } from 'vitepress'
|
||||
|
||||
const { page } = useData()
|
||||
</script>
|
||||
|
||||
<pre>{{ page }}</pre>
|
||||
```
|
||||
|
||||
**Output**
|
||||
|
||||
```json
|
||||
{
|
||||
"path": "/using-vue.html",
|
||||
"title": "Using Vue in Markdown",
|
||||
"frontmatter": {},
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Menggunakan Komponen
|
||||
|
||||
Anda dapat mengimpor dan menggunakan komponen Vue langsung di file Markdown.
|
||||
|
||||
### Mengimpor di Markdown
|
||||
|
||||
Jika sebuah komponen hanya digunakan oleh beberapa halaman, disarankan untuk mengimpornya secara eksplisit di tempat penggunaannya. Ini memungkinkan komponen tersebut di-code-split dengan benar dan hanya dimuat ketika halaman terkait ditampilkan:
|
||||
|
||||
```md
|
||||
<script setup>
|
||||
import CustomComponent from '../components/CustomComponent.vue'
|
||||
</script>
|
||||
|
||||
# Docs
|
||||
|
||||
Ini adalah .md yang menggunakan komponen kustom
|
||||
|
||||
<CustomComponent />
|
||||
|
||||
## More docs
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### Mendaftarkan Komponen Secara Global
|
||||
|
||||
Jika sebuah komponen akan digunakan di sebagian besar halaman, komponen tersebut dapat didaftarkan secara global dengan menyesuaikan instance aplikasi Vue. Lihat bagian terkait di [Memperluas Tema Default](./extending-default-theme#registering-global-components) untuk contohnya.
|
||||
|
||||
::: warning PENTING
|
||||
Pastikan nama komponen kustom mengandung tanda hubung atau dalam PascalCase. Jika tidak, ia akan diperlakukan sebagai elemen inline dan dibungkus dalam tag `<p>`, yang akan menyebabkan hydration mismatch karena `<p>` tidak memungkinkan elemen blok ditempatkan di dalamnya.
|
||||
:::
|
||||
|
||||
### Menggunakan Komponen di Header <ComponentInHeader />
|
||||
|
||||
Anda dapat menggunakan komponen Vue di header, tetapi perhatikan perbedaan antara sintaks berikut:
|
||||
|
||||
| Markdown | Output HTML | Header yang Diparsing |
|
||||
| ------------------------------------------------------- | ----------------------------------------- | --------------------- |
|
||||
| <pre v-pre><code> # text <Tag/> </code></pre> | `<h1>text <Tag/></h1>` | `text` |
|
||||
| <pre v-pre><code> # text \`<Tag/>\` </code></pre> | `<h1>text <code><Tag/></code></h1>` | `text <Tag/>` |
|
||||
|
||||
HTML yang dibungkus oleh `<code>` akan ditampilkan apa adanya; hanya HTML yang **tidak** dibungkus yang akan diparsing oleh Vue.
|
||||
|
||||
::: tip
|
||||
Output HTML dihasilkan oleh [Markdown-it](https://github.com/Markdown-it/Markdown-it), sementara header yang diparsing ditangani oleh VitePress (dan digunakan untuk sidebar dan judul dokumen).
|
||||
:::
|
||||
|
||||
|
||||
## Escaping
|
||||
|
||||
Anda dapat meng-escape interpolasi Vue dengan membungkusnya dalam `<span>` atau elemen lain dengan directive `v-pre`:
|
||||
|
||||
**Input**
|
||||
|
||||
```md
|
||||
This <span v-pre>{{ will be displayed as-is }}</span>
|
||||
```
|
||||
|
||||
**Output**
|
||||
|
||||
<div class="escape-demo">
|
||||
<p>This <span v-pre>{{ will be displayed as-is }}</span></p>
|
||||
</div>
|
||||
|
||||
Alternatifnya, Anda dapat membungkus seluruh paragraf dalam custom container `v-pre`:
|
||||
|
||||
```md
|
||||
::: v-pre
|
||||
{{ This will be displayed as-is }}
|
||||
:::
|
||||
```
|
||||
|
||||
**Output**
|
||||
|
||||
<div class="escape-demo">
|
||||
|
||||
::: v-pre
|
||||
{{ This will be displayed as-is }}
|
||||
:::
|
||||
|
||||
</div>
|
||||
|
||||
## Unescape di Blok Kode
|
||||
|
||||
Secara default, semua fenced code block secara otomatis dibungkus dengan `v-pre`, sehingga tidak ada sintaks Vue yang akan diproses di dalamnya. Untuk mengaktifkan interpolasi gaya Vue di dalam fences, Anda dapat menambahkan suffix `-vue` ke bahasa, mis. `js-vue`:
|
||||
|
||||
**Input**
|
||||
|
||||
````md
|
||||
```js-vue
|
||||
Hello {{ 1 + 1 }}
|
||||
```
|
||||
````
|
||||
|
||||
**Output**
|
||||
|
||||
```js-vue
|
||||
Hello {{ 1 + 1 }}
|
||||
```
|
||||
|
||||
Perhatikan bahwa ini mungkin mencegah token tertentu disorot sintaksnya dengan benar.
|
||||
|
||||
## Menggunakan CSS Pre-processor
|
||||
|
||||
VitePress memiliki [dukungan bawaan](https://vitejs.dev/guide/features.html#css-pre-processors) untuk CSS pre-processor: file `.scss`, `.sass`, `.less`, `.styl` dan `.stylus`. Tidak perlu menginstal plugin khusus Vite untuknya, tetapi pre-processor yang sesuai harus diinstal:
|
||||
|
||||
```
|
||||
# .scss dan .sass
|
||||
npm install -D sass
|
||||
|
||||
# .less
|
||||
npm install -D less
|
||||
|
||||
# .styl dan .stylus
|
||||
npm install -D stylus
|
||||
```
|
||||
|
||||
Kemudian Anda dapat menggunakan yang berikut di Markdown dan komponen tema:
|
||||
|
||||
```vue
|
||||
<style lang="sass">
|
||||
.title
|
||||
font-size: 20px
|
||||
</style>
|
||||
```
|
||||
|
||||
## Menggunakan Teleports
|
||||
|
||||
VitePress saat ini memiliki dukungan SSG untuk teleport ke body saja. Untuk target lain, Anda dapat membungkusnya di dalam komponen bawaan `<ClientOnly>` atau menyuntikkan markup teleport ke lokasi yang benar di HTML halaman akhir Anda melalui hook [`postRender`](../reference/site-config#postrender).
|
||||
|
||||
<ModalDemo />
|
||||
|
||||
::: details
|
||||
<<< @/components/ModalDemo.vue
|
||||
:::
|
||||
|
||||
```md
|
||||
<ClientOnly>
|
||||
<Teleport to="#modal">
|
||||
<div>
|
||||
// ...
|
||||
</div>
|
||||
</Teleport>
|
||||
</ClientOnly>
|
||||
```
|
||||
|
||||
<script setup>
|
||||
import ModalDemo from '../../components/ModalDemo.vue'
|
||||
import ComponentInHeader from '../../components/ComponentInHeader.vue'
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.escape-demo {
|
||||
border: 1px solid var(--vp-c-border);
|
||||
border-radius: 8px;
|
||||
padding: 0 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
## Dukungan VS Code IntelliSense
|
||||
|
||||
<!-- Berdasarkan https://github.com/vuejs/language-tools/pull/4321 -->
|
||||
|
||||
Vue menyediakan dukungan IntelliSense bawaan melalui [plugin Vue - Official VS Code](https://marketplace.visualstudio.com/items?itemName=Vue.volar). Namun, untuk mengaktifkannya untuk file `.md`, Anda perlu melakukan beberapa penyesuaian pada file konfigurasi.
|
||||
|
||||
|
||||
1. Tambahkan pattern `.md` ke opsi `include` dan `vueCompilerOptions.vitePressExtensions` di file tsconfig/jsconfig:
|
||||
|
||||
::: code-group
|
||||
```json [tsconfig.json]
|
||||
{
|
||||
"include": [
|
||||
"docs/**/*.ts",
|
||||
"docs/**/*.vue",
|
||||
"docs/**/*.md",
|
||||
],
|
||||
"vueCompilerOptions": {
|
||||
"vitePressExtensions": [".md"],
|
||||
},
|
||||
}
|
||||
```
|
||||
:::
|
||||
|
||||
2. Tambahkan `markdown` ke opsi `vue.server.includeLanguages` di pengaturan VS Code:
|
||||
|
||||
::: code-group
|
||||
```json [.vscode/settings.json]
|
||||
{
|
||||
"vue.server.includeLanguages": ["vue", "markdown"]
|
||||
}
|
||||
```
|
||||
:::
|
||||
@ -0,0 +1,61 @@
|
||||
---
|
||||
description: VitePress adalah generator situs statis yang dirancang untuk membangun situs cepat dan berfokus pada konten berbasis Vite dan Vue.
|
||||
---
|
||||
|
||||
# Apa Itu VitePress?
|
||||
|
||||
VitePress adalah [Static Site Generator](https://en.wikipedia.org/wiki/Static_site_generator) (SSG) yang dirancang untuk membangun situs cepat yang berfokus pada konten. Secara singkat, VitePress mengambil konten sumber Anda yang ditulis dalam [Markdown](https://en.wikipedia.org/wiki/Markdown), menerapkan tema padanya, dan menghasilkan halaman HTML statis yang dapat dideploy dengan mudah di mana saja.
|
||||
|
||||
<div class="tip custom-block" style="padding-top: 8px">
|
||||
|
||||
Hanya ingin mencobanya? Langsung ke [Panduan Cepat](./getting-started).
|
||||
|
||||
</div>
|
||||
|
||||
## Use Cases
|
||||
|
||||
- **Dokumentasi**
|
||||
|
||||
VitePress hadir dengan tema default yang dirancang untuk dokumentasi teknis. Tema ini mendukung halaman yang sedang Anda baca saat ini, beserta dokumentasi untuk [Vite](https://vitejs.dev/), [Rollup](https://rollupjs.org/), [Pinia](https://pinia.vuejs.org/), [VueUse](https://vueuse.org/), [Vitest](https://vitest.dev/), [D3](https://d3js.org/), [UnoCSS](https://unocss.dev/), [Iconify](https://iconify.design/) dan [banyak lagi](https://github.com/search?q=/%22vitepress%22:+/+path:/(?:package%7Cdeno)%5C.jsonc?$/+NOT+is:fork+NOT+is:archived&type=code).
|
||||
|
||||
[Dokumentasi resmi Vue.js](https://vuejs.org/) juga berbasis VitePress, tetapi menggunakan tema kustom yang dibagikan di antara berbagai terjemahan.
|
||||
|
||||
- **Blog, Portofolio, dan Situs Marketing**
|
||||
|
||||
VitePress mendukung [tema yang sepenuhnya dikustomisasi](./custom-theme), dengan pengalaman developer setara aplikasi Vite + Vue standar. Dibangun di atas Vite juga berarti Anda dapat langsung memanfaatkan plugin Vite dari ekosistemnya yang kaya. Selain itu, VitePress menyediakan API yang fleksibel untuk [memuat data](./data-loading) (lokal atau remote) dan [menghasilkan rute secara dinamis](./routing#dynamic-routes). Anda dapat menggunakannya untuk membangun hampir apa pun selama data dapat ditentukan pada waktu build.
|
||||
|
||||
[Blog resmi Vue.js](https://blog.vuejs.org/) adalah blog sederhana yang menghasilkan halaman indeks berdasarkan konten lokal.
|
||||
|
||||
## Developer Experience
|
||||
|
||||
VitePress bertujuan memberikan Developer Experience (DX) yang hebat saat bekerja dengan konten Markdown.
|
||||
|
||||
- **[Berbasis Vite:](https://vitejs.dev/)** server langsung menyala, dengan perubahan selalu langsung tercermin (<100ms) tanpa reload halaman.
|
||||
|
||||
- **[Ekstensi Markdown Bawaan:](./markdown)** Frontmatter, tabel, syntax highlighting... semua tersedia. Secara khusus, VitePress menyediakan banyak fitur lanjutan untuk bekerja dengan blok kode, menjadikannya ideal untuk dokumentasi yang sangat teknis.
|
||||
|
||||
- **[Markdown yang Diperkuat Vue:](./using-vue)** setiap halaman Markdown juga merupakan Vue [Single-File Component](https://vuejs.org/guide/scaling-up/sfc.html), berkat kompatibilitas sintaks 100% template Vue dengan HTML. Anda dapat menyematkan interaktivitas dalam konten statis Anda menggunakan fitur templating Vue atau komponen Vue yang diimpor.
|
||||
|
||||
## Performa
|
||||
|
||||
Tidak seperti banyak SSG tradisional di mana setiap navigasi menghasilkan reload halaman penuh, situs yang dihasilkan oleh VitePress menyajikan HTML statis pada kunjungan awal, tetapi menjadi [Single Page Application](https://en.wikipedia.org/wiki/Single-page_application) (SPA) untuk navigasi selanjutnya di dalam situs. Model ini, menurut kami, memberikan keseimbangan optimal untuk performa:
|
||||
|
||||
- **Initial Load Cepat**
|
||||
|
||||
Kunjungan awal ke halaman mana pun akan disajikan HTML statis yang telah di-pre-render untuk kecepatan loading yang cepat dan SEO optimal. Halaman kemudian memuat bundel JavaScript yang mengubah halaman menjadi Vue SPA ("hydration"). Bertentangan dengan asumsi umum bahwa hydration SPA lambat, proses ini sebenarnya sangat cepat berkat performa mentah Vue 3 dan optimasi compiler. Pada [PageSpeed Insights](https://pagespeed.web.dev/report?url=https%3A%2F%2Fvitepress.dev%2F), situs VitePress umum mencapai skor performa hampir sempurna bahkan pada perangkat seluler kelas bawah dengan jaringan lambat.
|
||||
|
||||
- **Navigasi Setelah Load Cepat**
|
||||
|
||||
Lebih penting lagi, model SPA menghasilkan pengalaman pengguna yang lebih baik **setelah** initial load. Navigasi selanjutnya di dalam situs tidak lagi menyebabkan reload halaman penuh. Sebaliknya, konten halaman yang masuk akan diambil dan diperbarui secara dinamis. VitePress juga secara otomatis melakukan pre-fetch potongan halaman untuk tautan yang berada dalam viewport. Dalam kebanyakan kasus, navigasi setelah load akan terasa instan.
|
||||
|
||||
- **Interaktivitas Tanpa Dampak Negatif**
|
||||
|
||||
Untuk dapat menghidrasi bagian Vue dinamis yang tertanam di dalam Markdown statis, setiap halaman Markdown diproses sebagai komponen Vue dan dikompilasi menjadi JavaScript. Ini mungkin terdengar tidak efisien, tetapi compiler Vue cukup pintar untuk memisahkan bagian statis dan dinamis, meminimalkan biaya hydration dan ukuran payload. Untuk initial load halaman, bagian statis secara otomatis dihilangkan dari payload JavaScript dan dilewati selama hydration.
|
||||
|
||||
## Bagaimana dengan VuePress?
|
||||
|
||||
VitePress adalah penerus spiritual VuePress 1. VuePress 1 asli berbasis Vue 2 dan webpack. Dengan Vue 3 dan Vite di baliknya, VitePress memberikan DX yang jauh lebih baik, performa produksi yang lebih baik, tema default yang lebih halus, dan API kustomisasi yang lebih fleksibel.
|
||||
|
||||
Perbedaan API antara VitePress dan VuePress 1 sebagian besar terletak pada tema dan kustomisasi. Jika Anda menggunakan VuePress 1 dengan tema default, seharusnya relatif mudah untuk bermigrasi ke VitePress.
|
||||
|
||||
Mempertahankan dua SSG secara paralel tidak berkelanjutan, sehingga tim Vue telah memutuskan untuk fokus pada VitePress sebagai SSG utama yang direkomendasikan dalam jangka panjang. Sekarang VuePress 1 telah deprecated, dan VuePress 2 telah diserahkan ke tim komunitas VuePress untuk pengembangan dan pemeliharaan lebih lanjut.
|
||||
@ -0,0 +1,36 @@
|
||||
---
|
||||
description: VitePress adalah generator situs statis berbasis Vite dan Vue untuk membuat situs dokumentasi yang indah dari Markdown.
|
||||
layout: home
|
||||
|
||||
hero:
|
||||
name: VitePress
|
||||
text: Generator Situs Statis Berbasis Vite dan Vue
|
||||
tagline: Dari Markdown ke dokumentasi indah dalam hitungan menit
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Apa itu VitePress?
|
||||
link: ./guide/what-is-vitepress
|
||||
- theme: alt
|
||||
text: Mulai Cepat
|
||||
link: ./guide/getting-started
|
||||
- theme: alt
|
||||
text: GitHub
|
||||
link: https://github.com/vuejs/vitepress
|
||||
image:
|
||||
src: /vitepress-logo-large.svg
|
||||
alt: VitePress
|
||||
|
||||
features:
|
||||
- icon: 📝
|
||||
title: Fokus pada konten Anda
|
||||
details: Buat situs dokumentasi yang indah dengan mudah, cukup dengan markdown.
|
||||
- icon: <svg xmlns="http://www.w3.org/2000/svg" width="30" viewBox="0 0 256 256.32"><defs><linearGradient id="a" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"/><stop offset="100%" stop-color="#BD34FE"/></linearGradient><linearGradient id="b" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"/><stop offset="8.333%" stop-color="#FFDD35"/><stop offset="100%" stop-color="#FFA800"/></linearGradient></defs><path fill="url(#a)" d="M255.153 37.938 134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"/><path fill="url(#b)" d="M185.432.063 96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028 72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"/></svg>
|
||||
title: Nikmati Vite DX
|
||||
details: Server menyala instan, hot update secepat kilat, dan manfaatkan plugin ekosistem Vite.
|
||||
- icon: <svg xmlns="http://www.w3.org/2000/svg" width="30" viewBox="0 0 256 220.8"><path fill="#41B883" d="M204.8 0H256L128 220.8 0 0h97.92L128 51.2 157.44 0h47.36Z"/><path fill="#41B883" d="m0 0 128 220.8L256 0h-51.2L128 132.48 50.56 0H0Z"/><path fill="#35495E" d="M50.56 0 128 133.12 204.8 0h-47.36L128 51.2 97.92 0H50.56Z"/></svg>
|
||||
title: Kustomisasi dengan Vue
|
||||
details: Gunakan sintaks dan komponen Vue langsung di markdown, atau bangun tema kustom dengan Vue.
|
||||
- icon: 🚀
|
||||
title: Bangun situs cepat
|
||||
details: Muat awal yang cepat dengan HTML statis, navigasi cepat setelah muat dengan client-side routing.
|
||||
---
|
||||
@ -0,0 +1,77 @@
|
||||
---
|
||||
description: Referensi perintah CLI VitePress termasuk dev, build, preview, dan init.
|
||||
---
|
||||
|
||||
# Command Line Interface
|
||||
|
||||
## `vitepress dev`
|
||||
|
||||
Memulai server pengembangan VitePress menggunakan direktori yang ditentukan sebagai root. Default ke direktori saat ini. Perintah `dev` juga dapat dihilangkan ketika dijalankan di direktori saat ini.
|
||||
|
||||
### Penggunaan
|
||||
|
||||
```sh
|
||||
# mulai di direktori saat ini, tanpa menuliskan `dev`
|
||||
vitepress
|
||||
|
||||
# mulai di subdirektori
|
||||
vitepress dev [root]
|
||||
```
|
||||
|
||||
### Opsi
|
||||
|
||||
| Opsi | Deskripsi |
|
||||
| --------------- | ------------------------------------------------------------------------ |
|
||||
| `--open [path]` | Buka browser saat startup (`boolean \| string`) |
|
||||
| `--port <port>` | Tentukan port (`number`) |
|
||||
| `--base <path>` | Public base path (default: `/`) (`string`) |
|
||||
| `--cors` | Aktifkan CORS |
|
||||
| `--strictPort` | Keluar jika port yang ditentukan sedang digunakan (`boolean`) |
|
||||
| `--force` | Paksa optimizer mengabaikan cache dan melakukan re-bundle (`boolean`) |
|
||||
|
||||
## `vitepress build`
|
||||
|
||||
Membangun situs VitePress untuk production.
|
||||
|
||||
### Penggunaan
|
||||
|
||||
```sh
|
||||
vitepress build [root]
|
||||
```
|
||||
|
||||
### Opsi
|
||||
|
||||
| Opsi | Deskripsi |
|
||||
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--mpa` (eksperimental) | Build dalam [mode MPA](../guide/mpa-mode) tanpa client-side hydration (`boolean`) |
|
||||
| `--base <path>` | Public base path (default: `/`) (`string`) |
|
||||
| `--target <target>` | Target transpile (default: `"modules"`) (`string`) |
|
||||
| `--outDir <dir>` | Direktori output relatif terhadap **cwd** (default: `<root>/.vitepress/dist`) (`string`) |
|
||||
| `--assetsInlineLimit <number>` | Batas aset statis yang di-inline sebagai base64 dalam byte (default: `4096`) (`number`) |
|
||||
|
||||
## `vitepress preview`
|
||||
|
||||
Pratinjau hasil build production secara lokal.
|
||||
|
||||
### Penggunaan
|
||||
|
||||
```sh
|
||||
vitepress preview [root]
|
||||
```
|
||||
|
||||
### Opsi
|
||||
|
||||
| Opsi | Deskripsi |
|
||||
| --------------- | ---------------------------------------- |
|
||||
| `--base <path>` | Public base path (default: `/`) (`string`) |
|
||||
| `--port <port>` | Tentukan port (`number`) |
|
||||
|
||||
## `vitepress init`
|
||||
|
||||
Memulai [Setup Wizard](../guide/getting-started#setup-wizard) di direktori saat ini.
|
||||
|
||||
### Penggunaan
|
||||
|
||||
```sh
|
||||
vitepress init
|
||||
```
|
||||
@ -0,0 +1,73 @@
|
||||
---
|
||||
description: Gunakan komponen Badge untuk menambahkan label status pada heading di dokumentasi VitePress.
|
||||
---
|
||||
|
||||
# Badge
|
||||
|
||||
Dengan Badge, Anda dapat menambahkan status pada heading. Misalnya, ini dapat berguna untuk menentukan jenis bagian, atau versi yang didukung.
|
||||
|
||||
## Penggunaan
|
||||
|
||||
Anda dapat menggunakan komponen `Badge` yang tersedia secara global.
|
||||
|
||||
```html
|
||||
### Judul <Badge type="info" text="default" />
|
||||
### Judul <Badge type="tip" text="^1.9.0" />
|
||||
### Judul <Badge type="warning" text="beta" />
|
||||
### Judul <Badge type="danger" text="caution" />
|
||||
```
|
||||
|
||||
Kode di atas menghasilkan tampilan seperti:
|
||||
|
||||
### Title <Badge type="info" text="default" />
|
||||
### Title <Badge type="tip" text="^1.9.0" />
|
||||
### Title <Badge type="warning" text="beta" />
|
||||
### Title <Badge type="danger" text="caution" />
|
||||
|
||||
## Custom Children
|
||||
|
||||
`<Badge>` menerima `children`, yang akan ditampilkan di dalam badge.
|
||||
|
||||
```html
|
||||
### Judul <Badge type="info">custom element</Badge>
|
||||
```
|
||||
|
||||
### Title <Badge type="info">custom element</Badge>
|
||||
|
||||
## Menyesuaikan Warna Tipe
|
||||
|
||||
Anda dapat menyesuaikan gaya badge dengan menimpa variabel css. Berikut adalah nilai default:
|
||||
|
||||
```css
|
||||
:root {
|
||||
--vp-badge-info-border: transparent;
|
||||
--vp-badge-info-text: var(--vp-c-text-2);
|
||||
--vp-badge-info-bg: var(--vp-c-default-soft);
|
||||
|
||||
--vp-badge-tip-border: transparent;
|
||||
--vp-badge-tip-text: var(--vp-c-brand-1);
|
||||
--vp-badge-tip-bg: var(--vp-c-brand-soft);
|
||||
|
||||
--vp-badge-warning-border: transparent;
|
||||
--vp-badge-warning-text: var(--vp-c-warning-1);
|
||||
--vp-badge-warning-bg: var(--vp-c-warning-soft);
|
||||
|
||||
--vp-badge-danger-border: transparent;
|
||||
--vp-badge-danger-text: var(--vp-c-danger-1);
|
||||
--vp-badge-danger-bg: var(--vp-c-danger-soft);
|
||||
}
|
||||
```
|
||||
|
||||
## `<Badge>`
|
||||
|
||||
Komponen `<Badge>` menerima props berikut:
|
||||
|
||||
```ts
|
||||
interface Props {
|
||||
// Ketika `<slot>` diberikan, nilai ini diabaikan.
|
||||
text?: string
|
||||
|
||||
// Default ke `tip`.
|
||||
type?: 'info' | 'tip' | 'warning' | 'danger'
|
||||
}
|
||||
```
|
||||
@ -0,0 +1,29 @@
|
||||
---
|
||||
description: Integrasikan Carbon Ads ke situs VitePress Anda menggunakan dukungan bawaan tema default.
|
||||
---
|
||||
|
||||
# Carbon Ads
|
||||
|
||||
VitePress memiliki dukungan bawaan untuk [Carbon Ads](https://www.carbonads.net/). Dengan mendefinisikan kredensial Carbon Ads di config, VitePress akan menampilkan iklan pada halaman.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
carbonAds: {
|
||||
code: 'your-carbon-code',
|
||||
placement: 'your-carbon-placement',
|
||||
format: 'classic'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Nilai-nilai ini digunakan untuk memanggil script CDN carbon seperti yang ditunjukkan di bawah.
|
||||
|
||||
Opsi `format` mendukung `classic`, `responsive`, dan `cover`.
|
||||
|
||||
```js
|
||||
`//cdn.carbonads.com/carbon.js?serve=${code}&placement=${placement}&format=${format}`
|
||||
```
|
||||
|
||||
Untuk mempelajari lebih lanjut tentang konfigurasi Carbon Ads, kunjungi [situs Carbon Ads](https://www.carbonads.net/).
|
||||
@ -0,0 +1,500 @@
|
||||
---
|
||||
description: Referensi semua opsi konfigurasi yang tersedia untuk tema default VitePress.
|
||||
---
|
||||
|
||||
# Konfigurasi Tema Default
|
||||
|
||||
Dengan konfigurasi tema, Anda dapat menyesuaikan tema. Anda dapat mendefinisikan konfigurasi tema melalui opsi `themeConfig` di file config:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
lang: 'en-US',
|
||||
title: 'VitePress',
|
||||
description: 'Vite & Vue powered static site generator.',
|
||||
|
||||
// Konfigurasi terkait tema.
|
||||
themeConfig: {
|
||||
logo: '/logo.svg',
|
||||
nav: [...],
|
||||
sidebar: { ... }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Opsi yang didokumentasikan di halaman ini hanya berlaku untuk tema default.** Tema yang berbeda mengharapkan konfigurasi tema yang berbeda. Ketika menggunakan tema kustom, objek konfigurasi tema akan diteruskan ke tema sehingga tema dapat menentukan perilaku kondisional berdasarkan konfigurasi tersebut.
|
||||
|
||||
## i18nRouting
|
||||
|
||||
- Tipe: `boolean`
|
||||
|
||||
Mengubah locale misalnya ke `zh` akan mengubah URL dari `/foo` (atau `/en/foo/`) menjadi `/zh/foo`. Anda dapat menonaktifkan perilaku ini dengan mengatur `themeConfig.i18nRouting` ke `false`.
|
||||
|
||||
## logo
|
||||
|
||||
- Tipe: `ThemeableImage`
|
||||
|
||||
File logo untuk ditampilkan di bilah nav, tepat sebelum judul situs. Menerima string path, atau objek untuk mengatur logo yang berbeda untuk mode terang/gelap.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
logo: '/logo.svg'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
type ThemeableImage =
|
||||
| string
|
||||
| { src: string; alt?: string }
|
||||
| { light: string; dark: string; alt?: string }
|
||||
```
|
||||
|
||||
## siteTitle
|
||||
|
||||
- Tipe: `string | false`
|
||||
|
||||
Anda dapat menyesuaikan item ini untuk mengganti judul situs default (`title` di config aplikasi) di nav. Ketika diatur ke `false`, judul di nav akan dinonaktifkan. Berguna ketika Anda memiliki `logo` yang sudah berisi teks judul situs.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
siteTitle: 'Hello World'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## nav
|
||||
|
||||
- Tipe: `NavItem`
|
||||
|
||||
Konfigurasi untuk item menu nav. Detail lebih lanjut di [Default Theme: Nav](./default-theme-nav#navigation-links).
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
nav: [
|
||||
{ text: 'Guide', link: '/guide' },
|
||||
{
|
||||
text: 'Dropdown Menu',
|
||||
items: [
|
||||
{ text: 'Item A', link: '/item-1' },
|
||||
{ text: 'Item B', link: '/item-2' },
|
||||
{ text: 'Item C', link: '/item-3' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
type NavItem = NavItemWithLink | NavItemWithChildren
|
||||
|
||||
interface NavItemWithLink {
|
||||
text: string
|
||||
link: string | ((payload: PageData) => string)
|
||||
activeMatch?: string
|
||||
target?: string
|
||||
rel?: string
|
||||
noIcon?: boolean
|
||||
}
|
||||
|
||||
interface NavItemChildren {
|
||||
text?: string
|
||||
items: NavItemWithLink[]
|
||||
}
|
||||
|
||||
interface NavItemWithChildren {
|
||||
text?: string
|
||||
items: (NavItemChildren | NavItemWithLink)[]
|
||||
activeMatch?: string
|
||||
}
|
||||
```
|
||||
|
||||
## sidebar
|
||||
|
||||
- Tipe: `Sidebar`
|
||||
|
||||
Konfigurasi untuk item menu sidebar. Detail lebih lanjut di [Default Theme: Sidebar](./default-theme-sidebar).
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
sidebar: [
|
||||
{
|
||||
text: 'Guide',
|
||||
items: [
|
||||
{ text: 'Introduction', link: '/introduction' },
|
||||
{ text: 'Getting Started', link: '/getting-started' },
|
||||
...
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
export type Sidebar = SidebarItem[] | SidebarMulti
|
||||
|
||||
export interface SidebarMulti {
|
||||
[path: string]: SidebarItem[] | { items: SidebarItem[]; base: string }
|
||||
}
|
||||
|
||||
export type SidebarItem = {
|
||||
/**
|
||||
* Label teks dari item.
|
||||
*/
|
||||
text?: string
|
||||
|
||||
/**
|
||||
* Tautan dari item.
|
||||
*/
|
||||
link?: string
|
||||
|
||||
/**
|
||||
* Children dari item.
|
||||
*/
|
||||
items?: SidebarItem[]
|
||||
|
||||
/**
|
||||
* Jika tidak ditentukan, grup tidak dapat diciutkan.
|
||||
*
|
||||
* Jika `true`, grup dapat diciutkan dan diciutkan secara default
|
||||
*
|
||||
* Jika `false`, grup dapat diciutkan tetapi diperluas secara default
|
||||
*/
|
||||
collapsed?: boolean
|
||||
|
||||
/**
|
||||
* Path dasar untuk item children.
|
||||
*/
|
||||
base?: string
|
||||
|
||||
/**
|
||||
* Menyesuaikan teks yang muncul di footer halaman sebelumnya/berikutnya.
|
||||
*/
|
||||
docFooterText?: string
|
||||
|
||||
rel?: string
|
||||
target?: string
|
||||
}
|
||||
```
|
||||
|
||||
## aside
|
||||
|
||||
- Tipe: `boolean | 'left'`
|
||||
- Default: `true`
|
||||
- Dapat ditimpa per halaman melalui [frontmatter](./frontmatter-config#aside)
|
||||
|
||||
Mengatur nilai ini ke `false` mencegah rendering kontainer aside.\
|
||||
Mengatur nilai ini ke `true` merender aside di sebelah kanan.\
|
||||
Mengatur nilai ini ke `left` merender aside di sebelah kiri.
|
||||
|
||||
Jika Anda ingin menonaktifkannya untuk semua viewport, sebaiknya gunakan `outline: false`.
|
||||
|
||||
## outline
|
||||
|
||||
- Tipe: `Outline | Outline['level'] | false`
|
||||
- Level dapat ditimpa per halaman melalui [frontmatter](./frontmatter-config#outline)
|
||||
|
||||
Mengatur nilai ini ke `false` mencegah rendering kontainer outline. Lihat interface ini untuk detail lebih lanjut:
|
||||
|
||||
```ts
|
||||
interface Outline {
|
||||
/**
|
||||
* Level heading yang akan ditampilkan di outline.
|
||||
* Angka tunggal berarti hanya heading pada level tersebut yang akan ditampilkan.
|
||||
* Jika tuple diberikan, angka pertama adalah level minimum dan angka kedua adalah level maksimum.
|
||||
* `'deep'` sama dengan `[2, 6]`, yang berarti semua heading dari `<h2>` hingga `<h6>` akan ditampilkan.
|
||||
*
|
||||
* @default 2
|
||||
*/
|
||||
level?: number | [number, number] | 'deep'
|
||||
|
||||
/**
|
||||
* Judul yang akan ditampilkan pada outline.
|
||||
*
|
||||
* @default 'On this page'
|
||||
*/
|
||||
label?: string
|
||||
}
|
||||
```
|
||||
|
||||
## socialLinks
|
||||
|
||||
- Tipe: `SocialLink[]`
|
||||
|
||||
Anda dapat mendefinisikan opsi ini untuk menampilkan tautan akun sosial Anda dengan ikon di nav.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
socialLinks: [
|
||||
// Anda dapat menambahkan ikon apa pun dari simple-icons (https://simpleicons.org/):
|
||||
{ icon: 'github', link: 'https://github.com/vuejs/vitepress' },
|
||||
{ icon: 'twitter', link: '...' },
|
||||
// Anda juga dapat menambahkan ikon kustom dengan mengirimkan SVG sebagai string:
|
||||
{
|
||||
icon: {
|
||||
svg: '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Dribbble</title><path d="M12...6.38z"/></svg>'
|
||||
},
|
||||
link: '...',
|
||||
// Anda dapat menyertakan label kustom untuk aksesibilitas juga (opsional tetapi direkomendasikan):
|
||||
ariaLabel: 'cool link'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
interface SocialLink {
|
||||
icon: string | { svg: string }
|
||||
link: string
|
||||
ariaLabel?: string
|
||||
}
|
||||
```
|
||||
|
||||
## footer
|
||||
|
||||
- Tipe: `Footer`
|
||||
- Dapat ditimpa per halaman melalui [frontmatter](./frontmatter-config#footer)
|
||||
|
||||
Konfigurasi footer. Anda dapat menambahkan pesan atau teks hak cipta di footer, namun, ini hanya akan ditampilkan ketika halaman tidak memiliki sidebar. Ini karena pertimbangan desain.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
footer: {
|
||||
message: 'Released under the MIT License.',
|
||||
copyright: 'Copyright © 2019-present Evan You'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
export interface Footer {
|
||||
message?: string
|
||||
copyright?: string
|
||||
}
|
||||
```
|
||||
|
||||
## editLink
|
||||
|
||||
- Tipe: `EditLink`
|
||||
- Dapat ditimpa per halaman melalui [frontmatter](./frontmatter-config#editlink)
|
||||
|
||||
Edit Link dapat digunakan untuk menampilkan tautan untuk mengedit halaman pada layanan manajemen Git seperti GitHub atau GitLab. Lihat [Default Theme: Edit Link](./default-theme-edit-link) untuk detail lebih lanjut.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
editLink: {
|
||||
pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path',
|
||||
text: 'Edit this page on GitHub'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
export interface EditLink {
|
||||
pattern: string
|
||||
text?: string
|
||||
}
|
||||
```
|
||||
|
||||
## lastUpdated
|
||||
|
||||
- Tipe: `LastUpdatedOptions`
|
||||
|
||||
Memungkinkan penyesuaian untuk teks last updated dan format tanggal.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
lastUpdated: {
|
||||
text: 'Updated at',
|
||||
formatOptions: {
|
||||
dateStyle: 'full',
|
||||
timeStyle: 'medium'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
export interface LastUpdatedOptions {
|
||||
/**
|
||||
* @default 'Last updated'
|
||||
*/
|
||||
text?: string
|
||||
|
||||
/**
|
||||
* @default
|
||||
* { dateStyle: 'short', timeStyle: 'short' }
|
||||
*/
|
||||
formatOptions?: Intl.DateTimeFormatOptions & { forceLocale?: boolean }
|
||||
}
|
||||
```
|
||||
|
||||
## algolia
|
||||
|
||||
- Tipe: `AlgoliaSearch`
|
||||
|
||||
Opsi untuk mendukung pencarian di situs dokumentasi Anda menggunakan [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch). Pelajari lebih lanjut di [Default Theme: Search](./default-theme-search)
|
||||
|
||||
```ts
|
||||
export interface AlgoliaSearchOptions extends DocSearchProps {
|
||||
locales?: Record<string, Partial<DocSearchProps>>
|
||||
}
|
||||
```
|
||||
|
||||
Lihat opsi lengkap [di sini](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts).
|
||||
|
||||
## carbonAds {#carbon-ads}
|
||||
|
||||
- Tipe: `CarbonAdsOptions`
|
||||
|
||||
Opsi untuk menampilkan [Carbon Ads](https://www.carbonads.net/).
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
carbonAds: {
|
||||
code: 'your-carbon-code',
|
||||
placement: 'your-carbon-placement'
|
||||
format: 'classic'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
export interface CarbonAdsOptions {
|
||||
code: string
|
||||
placement: string
|
||||
format?: 'classic' | 'responsive' | 'cover'
|
||||
}
|
||||
```
|
||||
|
||||
Pelajari lebih lanjut di [Default Theme: Carbon Ads](./default-theme-carbon-ads)
|
||||
|
||||
## docFooter
|
||||
|
||||
- Tipe: `DocFooter`
|
||||
|
||||
Dapat digunakan untuk menyesuaikan teks yang muncul di atas tautan sebelumnya dan berikutnya. Berguna jika tidak menulis dokumen dalam bahasa Inggris. Juga dapat digunakan untuk menonaktifkan tautan prev/next secara global. Jika Anda ingin mengaktifkan/menonaktifkan tautan prev/next secara selektif, Anda dapat menggunakan [frontmatter](./default-theme-prev-next-links).
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
docFooter: {
|
||||
prev: 'Pagina prior',
|
||||
next: 'Proxima pagina'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
export interface DocFooter {
|
||||
prev?: string | false
|
||||
next?: string | false
|
||||
}
|
||||
```
|
||||
|
||||
## darkModeSwitchLabel
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `Appearance`
|
||||
|
||||
Dapat digunakan untuk menyesuaikan label tombol mode gelap. Label ini hanya ditampilkan di tampilan mobile.
|
||||
|
||||
## lightModeSwitchTitle
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `Switch to light theme`
|
||||
|
||||
Dapat digunakan untuk menyesuaikan judul tombol mode terang yang muncul saat hover.
|
||||
|
||||
## darkModeSwitchTitle
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `Switch to dark theme`
|
||||
|
||||
Dapat digunakan untuk menyesuaikan judul tombol mode gelap yang muncul saat hover.
|
||||
|
||||
## sidebarMenuLabel
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `Menu`
|
||||
|
||||
Dapat digunakan untuk menyesuaikan label menu sidebar. Label ini hanya ditampilkan di tampilan mobile.
|
||||
|
||||
## returnToTopLabel
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `Return to top`
|
||||
|
||||
Dapat digunakan untuk menyesuaikan label tombol kembali ke atas. Label ini hanya ditampilkan di tampilan mobile.
|
||||
|
||||
## langMenuLabel
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `Change language`
|
||||
|
||||
Dapat digunakan untuk menyesuaikan aria-label tombol pengganti bahasa di navbar. Ini hanya digunakan jika Anda menggunakan [i18n](../guide/i18n).
|
||||
|
||||
## skipToContentLabel
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `Skip to content`
|
||||
|
||||
Dapat digunakan untuk menyesuaikan label tautan skip to content. Tautan ini ditampilkan ketika pengguna menavigasi situs menggunakan keyboard.
|
||||
|
||||
## externalLinkIcon
|
||||
|
||||
- Tipe: `boolean`
|
||||
- Default: `false`
|
||||
|
||||
Apakah akan menampilkan ikon tautan eksternal di samping tautan eksternal di markdown.
|
||||
|
||||
## `useLayout` <Badge type="info" text="composable" />
|
||||
|
||||
Mengembalikan data terkait layout. Objek yang dikembalikan memiliki tipe berikut:
|
||||
|
||||
```ts
|
||||
interface {
|
||||
isHome: ComputedRef<boolean>
|
||||
|
||||
sidebar: Readonly<ShallowRef<DefaultTheme.SidebarItem[]>>
|
||||
sidebarGroups: ComputedRef<DefaultTheme.SidebarItem[]>
|
||||
hasSidebar: ComputedRef<boolean>
|
||||
isSidebarEnabled: ComputedRef<boolean>
|
||||
|
||||
hasAside: ComputedRef<boolean>
|
||||
leftAside: ComputedRef<boolean>
|
||||
|
||||
headers: Readonly<ShallowRef<DefaultTheme.OutlineItem[]>>
|
||||
hasLocalNav: ComputedRef<boolean>
|
||||
}
|
||||
```
|
||||
|
||||
**Contoh:**
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { useLayout } from 'vitepress/theme'
|
||||
|
||||
const { hasSidebar } = useLayout()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="hasSidebar">Hanya tampil ketika sidebar ada</div>
|
||||
</template>
|
||||
```
|
||||
@ -0,0 +1,64 @@
|
||||
---
|
||||
description: Tampilkan tautan edit pada halaman dokumen untuk memungkinkan pengguna menyarankan perubahan di GitHub atau GitLab.
|
||||
---
|
||||
|
||||
# Edit Link
|
||||
|
||||
## Konfigurasi Tingkat Situs
|
||||
|
||||
Edit Link dapat digunakan untuk menampilkan tautan untuk mengedit halaman pada layanan manajemen Git seperti GitHub atau GitLab. Untuk mengaktifkannya, tambahkan opsi `themeConfig.editLink` ke config Anda.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
editLink: {
|
||||
pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Opsi `pattern` mendefinisikan struktur URL untuk tautan, dan `:path` akan diganti dengan path halaman.
|
||||
|
||||
Anda juga dapat memberikan fungsi murni yang menerima [`PageData`](./runtime-api#usedata) sebagai argumen dan mengembalikan string URL.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
editLink: {
|
||||
pattern: ({ filePath }) => {
|
||||
if (filePath.startsWith('packages/')) {
|
||||
return `https://github.com/acme/monorepo/edit/main/${filePath}`
|
||||
} else {
|
||||
return `https://github.com/acme/monorepo/edit/main/docs/${filePath}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Fungsi ini tidak boleh memiliki side-effect atau mengakses apa pun di luar cakupannya karena akan diserialisasi dan dijalankan di browser.
|
||||
|
||||
Secara default, ini akan menambahkan teks tautan "Edit this page" di bagian bawah halaman dokumen. Anda dapat menyesuaikan teks ini dengan mendefinisikan opsi `text`.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
editLink: {
|
||||
pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path',
|
||||
text: 'Edit this page on GitHub'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Konfigurasi Frontmatter
|
||||
|
||||
Ini dapat dinonaktifkan per halaman menggunakan opsi `editLink` di frontmatter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
editLink: false
|
||||
---
|
||||
```
|
||||
@ -0,0 +1,57 @@
|
||||
---
|
||||
description: Konfigurasikan footer global yang ditampilkan di bagian bawah halaman VitePress.
|
||||
---
|
||||
|
||||
# Footer
|
||||
|
||||
VitePress akan menampilkan footer global di bagian bawah halaman ketika `themeConfig.footer` tersedia.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
footer: {
|
||||
message: 'Released under the MIT License.',
|
||||
copyright: 'Copyright © 2019-present Evan You'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
export interface Footer {
|
||||
// Pesan yang ditampilkan tepat sebelum copyright.
|
||||
message?: string
|
||||
|
||||
// Teks copyright sebenarnya.
|
||||
copyright?: string
|
||||
}
|
||||
```
|
||||
|
||||
Konfigurasi di atas juga mendukung string HTML. Jadi, misalnya, jika Anda ingin mengonfigurasi teks footer agar memiliki beberapa tautan, Anda dapat menyesuaikan konfigurasi sebagai berikut:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
themeConfig: {
|
||||
footer: {
|
||||
message: 'Dirilis di bawah <a href="https://github.com/vuejs/vitepress/blob/main/LICENSE">Lisensi MIT</a>.',
|
||||
copyright: 'Hak Cipta © 2019-sekarang <a href="https://github.com/yyx990803">Evan You</a>'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
::: warning
|
||||
Hanya elemen inline yang dapat digunakan di `message` dan `copyright` karena dirender di dalam elemen `<p>`. Jika Anda ingin menambahkan elemen block, pertimbangkan untuk menggunakan slot [`layout-bottom`](../guide/extending-default-theme#layout-slots).
|
||||
:::
|
||||
|
||||
Perhatikan bahwa footer tidak akan ditampilkan ketika [SideBar](./default-theme-sidebar) terlihat.
|
||||
|
||||
## Konfigurasi Frontmatter
|
||||
|
||||
Ini dapat dinonaktifkan per halaman menggunakan opsi `footer` di frontmatter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
footer: false
|
||||
---
|
||||
```
|
||||
@ -0,0 +1,199 @@
|
||||
---
|
||||
description: Konfigurasikan layout halaman beranda tema default VitePress dengan bagian hero, fitur, dan konten kustom.
|
||||
---
|
||||
|
||||
# Halaman Beranda
|
||||
|
||||
Tema default VitePress menyediakan layout homepage, yang juga dapat Anda lihat digunakan di [beranda situs ini](../). Anda dapat menggunakannya di halaman mana pun dengan menentukan `layout: home` di [frontmatter](./frontmatter-config).
|
||||
|
||||
```yaml
|
||||
---
|
||||
layout: home
|
||||
---
|
||||
```
|
||||
|
||||
Namun, opsi ini saja tidak akan banyak berpengaruh. Anda dapat menambahkan beberapa "bagian" pra-template yang berbeda ke beranda dengan mengatur opsi tambahan lainnya seperti `hero` dan `features`.
|
||||
|
||||
## Bagian Hero
|
||||
|
||||
Bagian Hero muncul di bagian atas beranda. Berikut cara Anda mengonfigurasi bagian Hero.
|
||||
|
||||
```yaml
|
||||
---
|
||||
layout: home
|
||||
|
||||
hero:
|
||||
name: VitePress
|
||||
text: Vite & Vue powered static site generator.
|
||||
tagline: Lorem ipsum...
|
||||
image:
|
||||
src: /logo.png
|
||||
alt: VitePress
|
||||
actions:
|
||||
- theme: brand
|
||||
text: Get Started
|
||||
link: /guide/what-is-vitepress
|
||||
- theme: alt
|
||||
text: View on GitHub
|
||||
link: https://github.com/vuejs/vitepress
|
||||
---
|
||||
```
|
||||
|
||||
```ts
|
||||
interface Hero {
|
||||
// String yang ditampilkan di atas `text`. Menggunakan warna brand
|
||||
// dan diharapkan pendek, seperti nama produk.
|
||||
name?: string
|
||||
|
||||
// Teks utama untuk bagian hero. Ini akan didefinisikan
|
||||
// sebagai tag `h1`.
|
||||
text: string
|
||||
|
||||
// Tagline yang ditampilkan di bawah `text`.
|
||||
tagline?: string
|
||||
|
||||
// Gambar ditampilkan di samping area teks dan tagline.
|
||||
image?: ThemeableImage
|
||||
|
||||
// Tombol aksi untuk ditampilkan di bagian hero beranda.
|
||||
actions?: HeroAction[]
|
||||
}
|
||||
|
||||
type ThemeableImage =
|
||||
| string
|
||||
| { src: string; alt?: string }
|
||||
| { light: string; dark: string; alt?: string }
|
||||
|
||||
interface HeroAction {
|
||||
// Tema warna tombol. Default ke `brand`.
|
||||
theme?: 'brand' | 'alt'
|
||||
|
||||
// Label tombol.
|
||||
text: string
|
||||
|
||||
// Tautan tujuan tombol.
|
||||
link: string
|
||||
|
||||
// Atribut target tautan.
|
||||
target?: string
|
||||
|
||||
// Atribut rel tautan.
|
||||
rel?: string
|
||||
}
|
||||
```
|
||||
|
||||
### Menyesuaikan warna name
|
||||
|
||||
VitePress menggunakan warna brand (`--vp-c-brand-1`) untuk `name`. Namun, Anda dapat menyesuaikan warna ini dengan menimpa variabel `--vp-home-hero-name-color`.
|
||||
|
||||
```css
|
||||
:root {
|
||||
--vp-home-hero-name-color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
Anda juga dapat menyesuaikannya lebih lanjut dengan menggabungkan `--vp-home-hero-name-background` untuk memberikan warna gradien pada `name`.
|
||||
|
||||
```css
|
||||
:root {
|
||||
--vp-home-hero-name-color: transparent;
|
||||
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe, #41d1ff);
|
||||
}
|
||||
```
|
||||
|
||||
## Bagian Features
|
||||
|
||||
Di bagian Features, Anda dapat mencantumkan sejumlah fitur yang ingin ditampilkan tepat setelah bagian Hero. Untuk mengonfigurasinya, berikan opsi `features` ke frontmatter.
|
||||
|
||||
Anda dapat memberikan ikon untuk setiap fitur, yang dapat berupa emoji atau jenis gambar apa pun. Ketika ikon yang dikonfigurasi adalah gambar (svg, png, jpeg...), Anda harus memberikan ikon dengan lebar dan tinggi yang tepat; Anda juga dapat memberikan deskripsi, ukuran intrinsiknya serta varian untuk tema gelap dan terang jika diperlukan.
|
||||
|
||||
```yaml
|
||||
---
|
||||
layout: home
|
||||
|
||||
features:
|
||||
- icon: 🛠️
|
||||
title: Simple and minimal, always
|
||||
details: Lorem ipsum...
|
||||
- icon:
|
||||
src: /cool-feature-icon.svg
|
||||
title: Another cool feature
|
||||
details: Lorem ipsum...
|
||||
- icon:
|
||||
dark: /dark-feature-icon.svg
|
||||
light: /light-feature-icon.svg
|
||||
title: Another cool feature
|
||||
details: Lorem ipsum...
|
||||
---
|
||||
```
|
||||
|
||||
```ts
|
||||
interface Feature {
|
||||
// Tampilkan ikon pada setiap kotak fitur.
|
||||
icon?: FeatureIcon
|
||||
|
||||
// Judul fitur.
|
||||
title: string
|
||||
|
||||
// Detail fitur.
|
||||
details: string
|
||||
|
||||
// Tautan ketika diklik pada komponen fitur. Tautan dapat
|
||||
// berupa internal atau eksternal.
|
||||
//
|
||||
// mis. `guide/reference/default-theme-home-page` atau `https://example.com`
|
||||
link?: string
|
||||
|
||||
// Teks tautan yang akan ditampilkan di dalam komponen fitur. Paling baik
|
||||
// digunakan dengan opsi `link`.
|
||||
//
|
||||
// mis. `Learn more`, `Visit page`, dll.
|
||||
linkText?: string
|
||||
|
||||
// Atribut rel tautan untuk opsi `link`.
|
||||
//
|
||||
// mis. `external`
|
||||
rel?: string
|
||||
|
||||
// Atribut target tautan untuk opsi `link`.
|
||||
target?: string
|
||||
}
|
||||
|
||||
type FeatureIcon =
|
||||
| string
|
||||
| { src: string; alt?: string; width?: string; height: string }
|
||||
| {
|
||||
light: string
|
||||
dark: string
|
||||
alt?: string
|
||||
width?: string
|
||||
height: string
|
||||
}
|
||||
```
|
||||
|
||||
## Konten Markdown
|
||||
|
||||
Anda dapat menambahkan konten tambahan ke beranda situs Anda hanya dengan menambahkan Markdown di bawah pembatas frontmatter `---`.
|
||||
|
||||
````md
|
||||
---
|
||||
layout: home
|
||||
|
||||
hero:
|
||||
name: VitePress
|
||||
text: Vite & Vue powered static site generator.
|
||||
---
|
||||
|
||||
## Memulai
|
||||
|
||||
Anda dapat mulai menggunakan VitePress langsung menggunakan `npx`!
|
||||
|
||||
```sh
|
||||
npm init
|
||||
npx vitepress init
|
||||
```
|
||||
````
|
||||
|
||||
::: info
|
||||
VitePress tidak selalu menata konten tambahan dari halaman `layout: home` secara otomatis. Untuk kembali ke perilaku lama, Anda dapat menambahkan `markdownStyles: false` ke frontmatter.
|
||||
:::
|
||||
@ -0,0 +1,50 @@
|
||||
---
|
||||
description: Tampilkan timestamp terakhir diperbarui pada halaman VitePress berdasarkan riwayat commit Git.
|
||||
---
|
||||
|
||||
# Last Updated
|
||||
|
||||
Waktu pembaruan konten terakhir akan ditampilkan di sudut kanan bawah halaman. Untuk mengaktifkannya, tambahkan opsi `lastUpdated` ke config Anda.
|
||||
|
||||
::: info
|
||||
VitePress menampilkan waktu "last updated" menggunakan timestamp dari commit Git terbaru untuk setiap file. Untuk mengaktifkannya, file Markdown harus di-commit ke Git.
|
||||
|
||||
Secara internal, VitePress menjalankan `git log -1 --pretty="%ai"` pada setiap file untuk mengambil timestamp-nya. Jika semua halaman menampilkan waktu pembaruan yang sama, kemungkinan besar disebabkan oleh shallow cloning (umum di lingkungan CI), yang membatasi riwayat Git.
|
||||
|
||||
Untuk memperbaikinya di **GitHub Actions**, gunakan yang berikut dalam workflow Anda:
|
||||
|
||||
```yaml{4}
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
```
|
||||
|
||||
Platform CI/CD lain memiliki pengaturan serupa.
|
||||
|
||||
Jika opsi tersebut tidak tersedia, Anda dapat menambahkan perintah `docs:build` di `package.json` Anda dengan fetch manual:
|
||||
|
||||
```json
|
||||
"docs:build": "git fetch --unshallow && vitepress build docs"
|
||||
```
|
||||
:::
|
||||
|
||||
## Konfigurasi Tingkat Situs
|
||||
|
||||
```js
|
||||
export default {
|
||||
lastUpdated: true
|
||||
}
|
||||
```
|
||||
|
||||
## Konfigurasi Frontmatter
|
||||
|
||||
Ini dapat dinonaktifkan per halaman menggunakan opsi `lastUpdated` di frontmatter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
lastUpdated: false
|
||||
---
|
||||
```
|
||||
|
||||
Lihat juga [Default Theme: Last Updated](./default-theme-config#lastupdated) untuk detail lebih lanjut. Nilai truthy apa pun di tingkat tema juga akan mengaktifkan fitur ini kecuali dinonaktifkan secara eksplisit di tingkat situs atau halaman.
|
||||
@ -0,0 +1,66 @@
|
||||
---
|
||||
description: Pilih antara layout doc, page, dan home di tema default VitePress.
|
||||
---
|
||||
|
||||
# Layout
|
||||
|
||||
Anda dapat memilih layout halaman dengan mengatur opsi `layout` di [frontmatter](./frontmatter-config) halaman. Tersedia 3 opsi layout, `doc`, `page`, dan `home`. Jika tidak ada yang ditentukan, maka halaman diperlakukan sebagai halaman `doc`.
|
||||
|
||||
```yaml
|
||||
---
|
||||
layout: doc
|
||||
---
|
||||
```
|
||||
|
||||
## Layout Doc
|
||||
|
||||
Opsi `doc` adalah layout default dan memberikan gaya pada seluruh konten Markdown menjadi tampilan "dokumentasi". Ini bekerja dengan membungkus seluruh konten dalam kelas css `vp-doc`, dan menerapkan gaya pada elemen-elemen di dalamnya.
|
||||
|
||||
Hampir semua elemen generik seperti `p`, atau `h2` mendapatkan gaya khusus. Oleh karena itu, perlu diingat bahwa jika Anda menambahkan HTML kustom di dalam konten Markdown, elemen-elemen tersebut juga akan terpengaruh oleh gaya tersebut.
|
||||
|
||||
Layout ini juga menyediakan fitur khusus dokumentasi yang tercantum di bawah. Fitur-fitur ini hanya diaktifkan di layout ini.
|
||||
|
||||
- Edit Link
|
||||
- Prev Next Link
|
||||
- Outline
|
||||
- [Carbon Ads](./default-theme-carbon-ads)
|
||||
|
||||
## Layout Page
|
||||
|
||||
Opsi `page` diperlakukan sebagai "halaman kosong". Markdown akan tetap di-parse, dan semua [Ekstensi Markdown](../guide/markdown) bekerja sama seperti layout `doc`, tetapi konten tidak mendapatkan gaya default apa pun.
|
||||
|
||||
Dengan layout page, Anda dapat mengatur gaya semuanya sendiri tanpa tema VitePress memengaruhi markup. Ini berguna ketika Anda ingin membuat halaman kustom Anda sendiri.
|
||||
|
||||
Perhatikan bahwa bahkan di layout ini, sidebar tetap akan muncul jika halaman memiliki konfigurasi sidebar yang cocok.
|
||||
|
||||
## Layout Home
|
||||
|
||||
Opsi `home` akan menghasilkan "Homepage" bertemplate. Dalam layout ini, Anda dapat mengatur opsi tambahan seperti `hero` dan `features` untuk menyesuaikan konten lebih lanjut. Kunjungi [Default Theme: Home Page](./default-theme-home-page) untuk detail lebih lanjut.
|
||||
|
||||
## Tanpa Layout
|
||||
|
||||
Jika Anda tidak menginginkan layout apa pun, Anda dapat mengirimkan `layout: false` melalui frontmatter. Opsi ini berguna jika Anda menginginkan landing page yang sepenuhnya dapat disesuaikan (tanpa sidebar, navbar, atau footer secara default).
|
||||
|
||||
## Layout Kustom
|
||||
|
||||
Anda juga dapat menggunakan layout kustom:
|
||||
|
||||
```md
|
||||
---
|
||||
layout: foo
|
||||
---
|
||||
```
|
||||
|
||||
Ini akan mencari komponen bernama `foo` yang terdaftar dalam konteks. Misalnya, Anda dapat mendaftarkan komponen Anda secara global di `.vitepress/theme/index.ts`:
|
||||
|
||||
```ts
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import Foo from './Foo.vue'
|
||||
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
enhanceApp({ app }) {
|
||||
app.component('foo', Foo)
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -0,0 +1,220 @@
|
||||
---
|
||||
description: Konfigurasikan bilah navigasi di tema default VitePress termasuk judul situs, logo, dan tautan menu.
|
||||
---
|
||||
|
||||
# Nav
|
||||
|
||||
Nav adalah bilah navigasi yang ditampilkan di bagian atas halaman. Ini berisi judul situs, tautan menu global, dan lain-lain.
|
||||
|
||||
## Judul Situs dan Logo
|
||||
|
||||
Secara default, nav menampilkan judul situs yang merujuk pada nilai [`config.title`](./site-config#title). Jika Anda ingin mengubah apa yang ditampilkan di nav, Anda dapat mendefinisikan teks kustom di opsi `themeConfig.siteTitle`.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
siteTitle: 'My Custom Title'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Jika Anda memiliki logo untuk situs Anda, Anda dapat menampilkannya dengan memberikan path ke gambar. Anda sebaiknya menempatkan logo langsung di dalam `public`, dan mendefinisikan path absolut ke sana.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
logo: '/my-logo.svg'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Ketika menambahkan logo, logo akan ditampilkan bersama dengan judul situs. Jika logo saja sudah cukup dan Anda ingin menyembunyikan teks judul situs, atur opsi `siteTitle` ke `false`.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
logo: '/my-logo.svg',
|
||||
siteTitle: false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Anda juga dapat memberikan objek sebagai logo jika ingin menambahkan atribut `alt` atau menyesuaikannya berdasarkan mode gelap/terang. Lihat [`themeConfig.logo`](./default-theme-config#logo) untuk detailnya.
|
||||
|
||||
## Tautan Navigasi
|
||||
|
||||
Anda dapat mendefinisikan opsi `themeConfig.nav` untuk menambahkan tautan ke nav Anda.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
nav: [
|
||||
{ text: 'Guide', link: '/guide' },
|
||||
{ text: 'Config', link: '/config' },
|
||||
{ text: 'Changelog', link: 'https://github.com/...' }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`text` adalah teks aktual yang ditampilkan di nav, dan `link` adalah tautan yang akan dinavigasi ketika teks diklik. Untuk tautan, atur path ke file aktual tanpa awalan `.md`, dan selalu mulai dengan `/`.
|
||||
|
||||
`link` juga dapat berupa fungsi yang menerima [`PageData`](./runtime-api#usedata) sebagai argumen dan mengembalikan path.
|
||||
|
||||
Tautan nav juga dapat berupa menu dropdown. Untuk melakukan ini, atur kunci `items` pada opsi tautan.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
nav: [
|
||||
{ text: 'Guide', link: '/guide' },
|
||||
{
|
||||
text: 'Dropdown Menu',
|
||||
items: [
|
||||
{ text: 'Item A', link: '/item-1' },
|
||||
{ text: 'Item B', link: '/item-2' },
|
||||
{ text: 'Item C', link: '/item-3' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Perhatikan bahwa judul menu dropdown (`Dropdown Menu` pada contoh di atas) tidak dapat memiliki properti `link` karena berfungsi sebagai tombol untuk membuka dialog dropdown.
|
||||
|
||||
Anda juga dapat menambahkan "bagian" ke item menu dropdown dengan memberikan item bersarang lebih lanjut.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
nav: [
|
||||
{ text: 'Guide', link: '/guide' },
|
||||
{
|
||||
text: 'Dropdown Menu',
|
||||
items: [
|
||||
{
|
||||
// Judul untuk bagian.
|
||||
text: 'Section A Title',
|
||||
items: [
|
||||
{ text: 'Section A Item A', link: '...' },
|
||||
{ text: 'Section B Item B', link: '...' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Dropdown Menu',
|
||||
items: [
|
||||
{
|
||||
// Anda juga dapat menghilangkan judul.
|
||||
items: [
|
||||
{ text: 'Section A Item A', link: '...' },
|
||||
{ text: 'Section B Item B', link: '...' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Menyesuaikan status "active" tautan
|
||||
|
||||
Item menu nav akan disorot ketika halaman saat ini berada di bawah path yang cocok. Jika Anda ingin menyesuaikan path yang akan dicocokkan, definisikan properti `activeMatch` dan regex sebagai nilai string.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
nav: [
|
||||
// Tautan ini mendapatkan status active ketika pengguna
|
||||
// berada di path `/config/`.
|
||||
{
|
||||
text: 'Guide',
|
||||
link: '/guide',
|
||||
activeMatch: '/config/'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
::: warning
|
||||
`activeMatch` diharapkan berupa string regex, tetapi Anda harus mendefinisikannya sebagai string. Kita tidak dapat menggunakan objek RegExp aktual di sini karena tidak dapat diserialisasi selama waktu build.
|
||||
:::
|
||||
|
||||
### Menyesuaikan atribut "target" dan "rel" tautan
|
||||
|
||||
Secara default, VitePress secara otomatis menentukan atribut `target` dan `rel` berdasarkan apakah tautan tersebut merupakan tautan eksternal. Tetapi jika Anda mau, Anda juga dapat menyesuaikannya.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
nav: [
|
||||
{
|
||||
text: 'Merchandise',
|
||||
link: 'https://www.thegithubshop.com/',
|
||||
target: '_self',
|
||||
rel: 'sponsored'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tautan Sosial
|
||||
|
||||
Lihat [`socialLinks`](./default-theme-config#sociallinks).
|
||||
|
||||
## Komponen Kustom
|
||||
|
||||
Anda dapat menyertakan komponen kustom di bilah navigasi dengan menggunakan opsi `component`. Kunci `component` harus berupa nama komponen Vue, dan harus didaftarkan secara global menggunakan [Theme.enhanceApp](../guide/custom-theme#theme-interface).
|
||||
|
||||
```js [.vitepress/config.js]
|
||||
export default {
|
||||
themeConfig: {
|
||||
nav: [
|
||||
{
|
||||
text: 'My Menu',
|
||||
items: [
|
||||
{
|
||||
component: 'MyCustomComponent',
|
||||
// Props opsional untuk diteruskan ke komponen
|
||||
props: {
|
||||
title: 'My Custom Component'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
component: 'AnotherCustomComponent'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Kemudian, Anda perlu mendaftarkan komponen secara global:
|
||||
|
||||
```js [.vitepress/theme/index.js]
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
|
||||
import MyCustomComponent from './components/MyCustomComponent.vue'
|
||||
import AnotherCustomComponent from './components/AnotherCustomComponent.vue'
|
||||
|
||||
/** @type {import('vitepress').Theme} */
|
||||
export default {
|
||||
extends: DefaultTheme,
|
||||
enhanceApp({ app }) {
|
||||
app.component('MyCustomComponent', MyCustomComponent)
|
||||
app.component('AnotherCustomComponent', AnotherCustomComponent)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Komponen Anda akan dirender di bilah navigasi. VitePress akan memberikan props tambahan berikut ke komponen:
|
||||
|
||||
- `screenMenu`: boolean opsional yang menunjukkan apakah komponen berada di dalam menu navigasi mobile
|
||||
|
||||
Anda dapat melihat contoh di e2e tests [di sini](https://github.com/vuejs/vitepress/tree/main/__tests__/e2e/.vitepress).
|
||||
@ -0,0 +1,47 @@
|
||||
---
|
||||
description: Sesuaikan tautan halaman sebelumnya dan berikutnya yang ditampilkan di bagian bawah halaman dokumen di VitePress.
|
||||
---
|
||||
|
||||
# Prev Next Links
|
||||
|
||||
Anda dapat menyesuaikan teks dan tautan untuk halaman sebelumnya dan berikutnya (ditampilkan di footer dokumen). Ini berguna jika Anda menginginkan teks yang berbeda dari yang ada di sidebar. Selain itu, Anda mungkin merasa berguna untuk menonaktifkan footer atau menautkan ke halaman yang tidak termasuk dalam sidebar Anda.
|
||||
|
||||
## prev
|
||||
|
||||
- Tipe: `string | false | { text?: string; link?: string }`
|
||||
|
||||
- Detail:
|
||||
|
||||
Menentukan teks/tautan yang akan ditampilkan pada tautan ke halaman sebelumnya. Jika Anda tidak mengatur ini di frontmatter, teks/tautan akan disimpulkan dari konfigurasi sidebar.
|
||||
|
||||
- Contoh:
|
||||
|
||||
- Untuk menyesuaikan hanya teks:
|
||||
|
||||
```yaml
|
||||
---
|
||||
prev: 'Memulai | Markdown'
|
||||
---
|
||||
```
|
||||
|
||||
- Untuk menyesuaikan teks dan tautan:
|
||||
|
||||
```yaml
|
||||
---
|
||||
prev:
|
||||
text: 'Markdown'
|
||||
link: '/guide/markdown'
|
||||
---
|
||||
```
|
||||
|
||||
- Untuk menyembunyikan halaman sebelumnya:
|
||||
|
||||
```yaml
|
||||
---
|
||||
prev: false
|
||||
---
|
||||
```
|
||||
|
||||
## next
|
||||
|
||||
Sama seperti `prev` tetapi untuk halaman berikutnya.
|
||||
@ -0,0 +1,186 @@
|
||||
---
|
||||
description: Konfigurasikan navigasi sidebar di tema default VitePress dengan grup, bagian yang dapat diciutkan, dan multiple sidebar.
|
||||
---
|
||||
|
||||
# Sidebar
|
||||
|
||||
Sidebar adalah blok navigasi utama untuk dokumentasi Anda. Anda dapat mengonfigurasi menu sidebar di [`themeConfig.sidebar`](./default-theme-config#sidebar).
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
sidebar: [
|
||||
{
|
||||
text: 'Guide',
|
||||
items: [
|
||||
{ text: 'Introduction', link: '/introduction' },
|
||||
{ text: 'Getting Started', link: '/getting-started' },
|
||||
...
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Dasar-dasar
|
||||
|
||||
Bentuk paling sederhana dari menu sidebar adalah dengan memberikan array tunggal tautan. Item level pertama mendefinisikan "bagian" untuk sidebar. Ini harus berisi `text`, yang merupakan judul bagian, dan `items` yang merupakan tautan navigasi aktual.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
sidebar: [
|
||||
{
|
||||
text: 'Section Title A',
|
||||
items: [
|
||||
{ text: 'Item A', link: '/item-a' },
|
||||
{ text: 'Item B', link: '/item-b' },
|
||||
...
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Section Title B',
|
||||
items: [
|
||||
{ text: 'Item C', link: '/item-c' },
|
||||
{ text: 'Item D', link: '/item-d' },
|
||||
...
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Setiap `link` harus menentukan path ke file aktual dimulai dengan `/`. Jika Anda menambahkan trailing slash di akhir tautan, itu akan menampilkan `index.md` dari direktori terkait.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
sidebar: [
|
||||
{
|
||||
text: 'Guide',
|
||||
items: [
|
||||
// Ini menampilkan halaman `/guide/index.md`.
|
||||
{ text: 'Introduction', link: '/guide/' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Anda dapat menyarangkan item sidebar hingga sedalam 6 level dihitung dari level root. Perhatikan bahwa item bersarang lebih dalam dari 6 level akan diabaikan dan tidak akan ditampilkan di sidebar.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
sidebar: [
|
||||
{
|
||||
text: 'Level 1',
|
||||
items: [
|
||||
{
|
||||
text: 'Level 2',
|
||||
items: [
|
||||
{
|
||||
text: 'Level 3',
|
||||
items: [
|
||||
...
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Multiple Sidebar
|
||||
|
||||
Anda dapat menampilkan sidebar yang berbeda tergantung pada path halaman. Misalnya, seperti yang ditunjukkan di situs ini, Anda mungkin ingin membuat bagian konten terpisah dalam dokumentasi Anda seperti halaman "Guide" dan halaman "Config".
|
||||
|
||||
Untuk melakukannya, pertama atur halaman Anda ke dalam direktori untuk setiap bagian yang diinginkan:
|
||||
|
||||
```
|
||||
.
|
||||
├─ guide/
|
||||
│ ├─ index.md
|
||||
│ ├─ one.md
|
||||
│ └─ two.md
|
||||
└─ config/
|
||||
├─ index.md
|
||||
├─ three.md
|
||||
└─ four.md
|
||||
```
|
||||
|
||||
Kemudian, perbarui konfigurasi Anda untuk mendefinisikan sidebar untuk setiap bagian. Kali ini, Anda harus memberikan objek, bukan array.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
sidebar: {
|
||||
// Sidebar ini ditampilkan ketika pengguna
|
||||
// berada di direktori `guide`.
|
||||
'/guide/': [
|
||||
{
|
||||
text: 'Guide',
|
||||
items: [
|
||||
{ text: 'Index', link: '/guide/' },
|
||||
{ text: 'One', link: '/guide/one' },
|
||||
{ text: 'Two', link: '/guide/two' }
|
||||
]
|
||||
}
|
||||
],
|
||||
|
||||
// Sidebar ini ditampilkan ketika pengguna
|
||||
// berada di direktori `config`.
|
||||
'/config/': [
|
||||
{
|
||||
text: 'Config',
|
||||
items: [
|
||||
{ text: 'Index', link: '/config/' },
|
||||
{ text: 'Three', link: '/config/three' },
|
||||
{ text: 'Four', link: '/config/four' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Grup Sidebar yang Dapat Diciutkan
|
||||
|
||||
Dengan menambahkan opsi `collapsed` ke grup sidebar, ini menampilkan tombol toggle untuk menyembunyikan/menampilkan setiap bagian.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
sidebar: [
|
||||
{
|
||||
text: 'Section Title A',
|
||||
collapsed: false,
|
||||
items: [...]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Semua bagian "terbuka" secara default. Jika Anda menginginkannya "tertutup" saat halaman pertama dimuat, atur opsi `collapsed` ke `true`.
|
||||
|
||||
```js
|
||||
export default {
|
||||
themeConfig: {
|
||||
sidebar: [
|
||||
{
|
||||
text: 'Section Title A',
|
||||
collapsed: true,
|
||||
items: [...]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
@ -0,0 +1,260 @@
|
||||
---
|
||||
description: Buat halaman tim dengan profil anggota menggunakan komponen tim bawaan VitePress.
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import { VPTeamMembers } from 'vitepress/theme'
|
||||
|
||||
const members = [
|
||||
{
|
||||
avatar: 'https://github.com/yyx990803.png',
|
||||
name: 'Evan You',
|
||||
title: 'Creator',
|
||||
links: [
|
||||
{ icon: 'github', link: 'https://github.com/yyx990803' },
|
||||
{ icon: 'twitter', link: 'https://twitter.com/youyuxi' }
|
||||
]
|
||||
},
|
||||
{
|
||||
avatar: 'https://github.com/kiaking.png',
|
||||
name: 'Kia King Ishii',
|
||||
title: 'Developer',
|
||||
links: [
|
||||
{ icon: 'github', link: 'https://github.com/kiaking' },
|
||||
{ icon: 'twitter', link: 'https://twitter.com/KiaKing85' }
|
||||
]
|
||||
}
|
||||
]
|
||||
</script>
|
||||
|
||||
# Halaman Tim
|
||||
|
||||
Jika Anda ingin memperkenalkan tim Anda, Anda dapat menggunakan komponen Team untuk membuat Halaman Tim. Ada dua cara menggunakan komponen ini. Salah satunya adalah menyematkannya di halaman dokumen, dan yang lainnya adalah membuat Halaman Tim penuh.
|
||||
|
||||
## Menampilkan anggota tim di sebuah halaman
|
||||
|
||||
Anda dapat menggunakan komponen `<VPTeamMembers>` yang diekspos dari `vitepress/theme` untuk menampilkan daftar anggota tim di halaman mana pun.
|
||||
|
||||
```html
|
||||
<script setup>
|
||||
import { VPTeamMembers } from 'vitepress/theme'
|
||||
|
||||
const members = [
|
||||
{
|
||||
avatar: 'https://www.github.com/yyx990803.png',
|
||||
name: 'Evan You',
|
||||
title: 'Creator',
|
||||
links: [
|
||||
{ icon: 'github', link: 'https://github.com/yyx990803' },
|
||||
{ icon: 'twitter', link: 'https://twitter.com/youyuxi' }
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
</script>
|
||||
|
||||
# Tim Kami
|
||||
|
||||
Sapa tim hebat kami.
|
||||
|
||||
<VPTeamMembers size="small" :members />
|
||||
```
|
||||
|
||||
Di atas akan menampilkan anggota tim dalam elemen bergaya kartu. Seharusnya menampilkan sesuatu yang mirip dengan di bawah ini.
|
||||
|
||||
<VPTeamMembers size="small" :members />
|
||||
|
||||
Komponen `<VPTeamMembers>` tersedia dalam 2 ukuran berbeda, `small` dan `medium`. Meskipun tergantung pada preferensi Anda, biasanya ukuran `small` lebih cocok ketika digunakan di halaman dokumen. Anda juga dapat menambahkan lebih banyak properti ke setiap anggota seperti menambahkan tombol "description" atau "sponsor". Pelajari lebih lanjut di [`<VPTeamMembers>`](#vpteammembers).
|
||||
|
||||
Menyematkan anggota tim di halaman dokumen cocok untuk tim berukuran kecil di mana memiliki halaman tim penuh khusus mungkin terlalu berlebihan, atau memperkenalkan sebagian anggota sebagai referensi untuk konteks dokumentasi.
|
||||
|
||||
Jika Anda memiliki jumlah anggota yang banyak, atau hanya ingin memiliki lebih banyak ruang untuk menampilkan anggota tim, pertimbangkan untuk [membuat halaman tim penuh](#create-a-full-team-page).
|
||||
|
||||
## Membuat Halaman Tim Penuh
|
||||
|
||||
Alih-alih menambahkan anggota tim ke halaman dokumen, Anda juga dapat membuat Halaman Tim penuh, mirip dengan cara Anda membuat [Home Page](./default-theme-home-page) kustom.
|
||||
|
||||
Untuk membuat halaman tim, pertama, buat file md baru. Nama file tidak masalah, tetapi di sini kita sebut saja `team.md`. Di file ini, atur opsi frontmatter `layout: page`, lalu Anda dapat menyusun struktur halaman Anda menggunakan komponen `TeamPage`.
|
||||
|
||||
```html
|
||||
---
|
||||
layout: page
|
||||
---
|
||||
<script setup>
|
||||
import {
|
||||
VPTeamPage,
|
||||
VPTeamPageTitle,
|
||||
VPTeamMembers
|
||||
} from 'vitepress/theme'
|
||||
|
||||
const members = [
|
||||
{
|
||||
avatar: 'https://www.github.com/yyx990803.png',
|
||||
name: 'Evan You',
|
||||
title: 'Creator',
|
||||
links: [
|
||||
{ icon: 'github', link: 'https://github.com/yyx990803' },
|
||||
{ icon: 'twitter', link: 'https://twitter.com/youyuxi' }
|
||||
]
|
||||
},
|
||||
...
|
||||
]
|
||||
</script>
|
||||
|
||||
<VPTeamPage>
|
||||
<VPTeamPageTitle>
|
||||
<template #title>
|
||||
Tim Kami
|
||||
</template>
|
||||
<template #lead>
|
||||
Pengembangan VitePress dipandu oleh tim internasional,
|
||||
beberapa di antaranya telah memilih untuk ditampilkan di bawah.
|
||||
</template>
|
||||
</VPTeamPageTitle>
|
||||
<VPTeamMembers :members />
|
||||
</VPTeamPage>
|
||||
```
|
||||
|
||||
Ketika membuat halaman tim penuh, ingatlah untuk membungkus semua komponen dengan komponen `<VPTeamPage>`. Komponen ini akan memastikan semua komponen terkait tim yang bersarang mendapatkan struktur layout yang tepat seperti spasi.
|
||||
|
||||
Komponen `<VPPageTitle>` menambahkan bagian judul halaman. Judul berupa heading `<h1>`. Gunakan slot `#title` dan `#lead` untuk mendokumentasikan tentang tim Anda.
|
||||
|
||||
`<VPMembers>` bekerja sama seperti ketika digunakan di halaman dokumen. Ini akan menampilkan daftar anggota.
|
||||
|
||||
### Menambahkan bagian untuk membagi anggota tim
|
||||
|
||||
Anda dapat menambahkan "bagian" ke halaman tim. Misalnya, Anda mungkin memiliki berbagai jenis anggota tim seperti Anggota Tim Inti dan Mitra Komunitas. Anda dapat membagi anggota-anggota ini menjadi beberapa bagian untuk menjelaskan peran masing-masing grup dengan lebih baik.
|
||||
|
||||
Untuk melakukannya, tambahkan komponen `<VPTeamPageSection>` ke file `team.md` yang kita buat sebelumnya.
|
||||
|
||||
```html
|
||||
---
|
||||
layout: page
|
||||
---
|
||||
<script setup>
|
||||
import {
|
||||
VPTeamPage,
|
||||
VPTeamPageTitle,
|
||||
VPTeamMembers,
|
||||
VPTeamPageSection
|
||||
} from 'vitepress/theme'
|
||||
|
||||
const coreMembers = [...]
|
||||
const partners = [...]
|
||||
</script>
|
||||
|
||||
<VPTeamPage>
|
||||
<VPTeamPageTitle>
|
||||
<template #title>Tim Kami</template>
|
||||
<template #lead>...</template>
|
||||
</VPTeamPageTitle>
|
||||
<VPTeamMembers size="medium" :members="coreMembers" />
|
||||
<VPTeamPageSection>
|
||||
<template #title>Mitra</template>
|
||||
<template #lead>...</template>
|
||||
<template #members>
|
||||
<VPTeamMembers size="small" :members="partners" />
|
||||
</template>
|
||||
</VPTeamPageSection>
|
||||
</VPTeamPage>
|
||||
```
|
||||
|
||||
Komponen `<VPTeamPageSection>` dapat memiliki slot `#title` dan `#lead` mirip dengan komponen `VPTeamPageTitle`, dan juga slot `#members` untuk menampilkan anggota tim.
|
||||
|
||||
Ingatlah untuk menempatkan komponen `<VPTeamMembers>` di dalam slot `#members`.
|
||||
|
||||
## `<VPTeamMembers>`
|
||||
|
||||
Komponen `<VPTeamMembers>` menampilkan daftar anggota yang diberikan.
|
||||
|
||||
```html
|
||||
<VPTeamMembers
|
||||
size="medium"
|
||||
:members="[
|
||||
{ avatar: '...', name: '...' },
|
||||
{ avatar: '...', name: '...' },
|
||||
...
|
||||
]"
|
||||
/>
|
||||
```
|
||||
|
||||
```ts
|
||||
interface Props {
|
||||
// Ukuran setiap anggota. Default ke `medium`.
|
||||
size?: 'small' | 'medium'
|
||||
|
||||
// Daftar anggota yang akan ditampilkan.
|
||||
members: TeamMember[]
|
||||
}
|
||||
|
||||
interface TeamMember {
|
||||
// Gambar avatar untuk anggota.
|
||||
avatar: string
|
||||
|
||||
// Nama anggota.
|
||||
name: string
|
||||
|
||||
// Judul yang akan ditampilkan di bawah nama anggota.
|
||||
// mis. Developer, Software Engineer, dll.
|
||||
title?: string
|
||||
|
||||
// Organisasi tempat anggota bernaung.
|
||||
org?: string
|
||||
|
||||
// URL untuk organisasi.
|
||||
orgLink?: string
|
||||
|
||||
// Deskripsi untuk anggota.
|
||||
desc?: string
|
||||
|
||||
// Tautan sosial. mis. GitHub, Twitter, dll. Anda dapat memberikan
|
||||
// objek Social Links di sini.
|
||||
// Lihat: https://vitepress.dev/reference/default-theme-config.html#sociallinks
|
||||
links?: SocialLink[]
|
||||
|
||||
// URL untuk halaman sponsor anggota.
|
||||
sponsor?: string
|
||||
|
||||
// Teks untuk tautan sponsor. Default ke 'Sponsor'.
|
||||
actionText?: string
|
||||
}
|
||||
```
|
||||
|
||||
## `<VPTeamPage>`
|
||||
|
||||
Komponen root ketika membuat halaman tim penuh. Ini hanya menerima satu slot. Ini akan menata semua komponen terkait tim yang diberikan.
|
||||
|
||||
## `<VPTeamPageTitle>`
|
||||
|
||||
Menambahkan bagian "judul" halaman. Paling baik digunakan di bagian paling awal di bawah `<VPTeamPage>`. Ini menerima slot `#title` dan `#lead`.
|
||||
|
||||
```html
|
||||
<VPTeamPage>
|
||||
<VPTeamPageTitle>
|
||||
<template #title>
|
||||
Tim Kami
|
||||
</template>
|
||||
<template #lead>
|
||||
Pengembangan VitePress dipandu oleh tim internasional,
|
||||
beberapa di antaranya telah memilih untuk ditampilkan di bawah.
|
||||
</template>
|
||||
</VPTeamPageTitle>
|
||||
</VPTeamPage>
|
||||
```
|
||||
|
||||
## `<VPTeamPageSection>`
|
||||
|
||||
Membuat "bagian" di dalam halaman tim. Ini menerima slot `#title`, `#lead`, dan `#members`. Anda dapat menambahkan bagian sebanyak yang Anda suka di dalam `<VPTeamPage>`.
|
||||
|
||||
```html
|
||||
<VPTeamPage>
|
||||
...
|
||||
<VPTeamPageSection>
|
||||
<template #title>Mitra</template>
|
||||
<template #lead>Lorem ipsum...</template>
|
||||
<template #members>
|
||||
<VPTeamMembers :members="data" />
|
||||
</template>
|
||||
</VPTeamPageSection>
|
||||
</VPTeamPage>
|
||||
```
|
||||
@ -0,0 +1,241 @@
|
||||
---
|
||||
outline: deep
|
||||
description: Referensi semua opsi konfigurasi frontmatter yang tersedia untuk halaman Markdown VitePress.
|
||||
---
|
||||
|
||||
# Konfigurasi Frontmatter
|
||||
|
||||
Frontmatter mengaktifkan konfigurasi berbasis halaman. Di setiap file markdown, Anda dapat menggunakan konfigurasi frontmatter untuk menimpa opsi konfigurasi tingkat situs atau tingkat tema. Selain itu, ada opsi konfigurasi yang hanya dapat Anda definisikan di frontmatter.
|
||||
|
||||
Contoh penggunaan:
|
||||
|
||||
```md
|
||||
---
|
||||
title: Docs with VitePress
|
||||
editLink: true
|
||||
---
|
||||
```
|
||||
|
||||
Anda dapat mengakses data frontmatter melalui global `$frontmatter` dalam ekspresi Vue:
|
||||
|
||||
```md
|
||||
{{ $frontmatter.title }}
|
||||
```
|
||||
|
||||
## title
|
||||
|
||||
- Tipe: `string`
|
||||
|
||||
Judul untuk halaman. Sama dengan [config.title](./site-config#title), dan ini menimpa konfigurasi tingkat situs.
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: VitePress
|
||||
---
|
||||
```
|
||||
|
||||
## titleTemplate
|
||||
|
||||
- Tipe: `string | boolean`
|
||||
|
||||
Sufiks untuk judul. Sama dengan [config.titleTemplate](./site-config#titletemplate), dan ini menimpa konfigurasi tingkat situs.
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: VitePress
|
||||
titleTemplate: Vite & Vue powered static site generator
|
||||
---
|
||||
```
|
||||
|
||||
## description
|
||||
|
||||
- Tipe: `string`
|
||||
|
||||
Deskripsi untuk halaman. Sama dengan [config.description](./site-config#description), dan ini menimpa konfigurasi tingkat situs.
|
||||
|
||||
```yaml
|
||||
---
|
||||
description: VitePress
|
||||
---
|
||||
```
|
||||
|
||||
## head
|
||||
|
||||
- Tipe: `HeadConfig[]`
|
||||
|
||||
Menentukan tag head tambahan untuk disuntikkan untuk halaman saat ini. Akan ditambahkan setelah tag head yang disuntikkan oleh konfigurasi tingkat situs.
|
||||
|
||||
```yaml
|
||||
---
|
||||
head:
|
||||
- - meta
|
||||
- name: description
|
||||
content: hello
|
||||
- - meta
|
||||
- name: keywords
|
||||
content: super duper SEO
|
||||
---
|
||||
```
|
||||
|
||||
```ts
|
||||
type HeadConfig =
|
||||
| [string, Record<string, string>]
|
||||
| [string, Record<string, string>, string]
|
||||
```
|
||||
|
||||
## Hanya Tema Default
|
||||
|
||||
Opsi frontmatter berikut hanya berlaku ketika menggunakan tema default.
|
||||
|
||||
### layout
|
||||
|
||||
- Tipe: `doc | home | page`
|
||||
- Default: `doc`
|
||||
|
||||
Menentukan layout halaman.
|
||||
|
||||
- `doc` - Menerapkan gaya dokumentasi default ke konten markdown.
|
||||
- `home` - Layout khusus untuk "Home Page". Anda dapat menambahkan opsi tambahan seperti `hero` dan `features` untuk membuat landing page yang indah dengan cepat.
|
||||
- `page` - Berperilaku mirip dengan `doc` tetapi tidak menerapkan gaya apa pun ke konten. Berguna ketika Anda ingin membuat halaman yang sepenuhnya kustom.
|
||||
|
||||
```yaml
|
||||
---
|
||||
layout: doc
|
||||
---
|
||||
```
|
||||
|
||||
### hero <Badge type="info" text="hanya halaman beranda" />
|
||||
|
||||
Mendefinisikan konten bagian hero beranda ketika `layout` diatur ke `home`. Detail lebih lanjut di [Default Theme: Home Page](./default-theme-home-page).
|
||||
|
||||
### features <Badge type="info" text="hanya halaman beranda" />
|
||||
|
||||
Mendefinisikan item untuk ditampilkan di bagian features ketika `layout` diatur ke `home`. Detail lebih lanjut di [Default Theme: Home Page](./default-theme-home-page).
|
||||
|
||||
### navbar
|
||||
|
||||
- Tipe: `boolean`
|
||||
- Default: `true`
|
||||
|
||||
Apakah akan menampilkan [navbar](./default-theme-nav).
|
||||
|
||||
```yaml
|
||||
---
|
||||
navbar: false
|
||||
---
|
||||
```
|
||||
|
||||
### sidebar
|
||||
|
||||
- Tipe: `boolean`
|
||||
- Default: `true`
|
||||
|
||||
Apakah akan menampilkan [sidebar](./default-theme-sidebar).
|
||||
|
||||
```yaml
|
||||
---
|
||||
sidebar: false
|
||||
---
|
||||
```
|
||||
|
||||
### aside
|
||||
|
||||
- Tipe: `boolean | 'left'`
|
||||
- Default: `true`
|
||||
|
||||
Mendefinisikan lokasi komponen aside di layout `doc`.
|
||||
|
||||
Mengatur nilai ini ke `false` mencegah rendering kontainer aside.\
|
||||
Mengatur nilai ini ke `true` merender aside di sebelah kanan.\
|
||||
Mengatur nilai ini ke `'left'` merender aside di sebelah kiri.
|
||||
|
||||
```yaml
|
||||
---
|
||||
aside: false
|
||||
---
|
||||
```
|
||||
|
||||
### outline
|
||||
|
||||
- Tipe: `number | [number, number] | 'deep' | false`
|
||||
- Default: `2`
|
||||
|
||||
Level heading di outline yang akan ditampilkan untuk halaman. Sama dengan [config.themeConfig.outline.level](./default-theme-config#outline), dan ini menimpa nilai yang diatur di konfigurasi tingkat situs.
|
||||
|
||||
```yaml
|
||||
---
|
||||
outline: [2, 4]
|
||||
---
|
||||
```
|
||||
|
||||
### lastUpdated
|
||||
|
||||
- Tipe: `boolean | Date`
|
||||
- Default: `true`
|
||||
|
||||
Apakah akan menampilkan teks [last updated](./default-theme-last-updated) di footer halaman saat ini. Jika datetime ditentukan, itu akan ditampilkan alih-alih timestamp git yang terakhir dimodifikasi.
|
||||
|
||||
```yaml
|
||||
---
|
||||
lastUpdated: false
|
||||
---
|
||||
```
|
||||
|
||||
### editLink
|
||||
|
||||
- Tipe: `boolean`
|
||||
- Default: `true`
|
||||
|
||||
Apakah akan menampilkan [edit link](./default-theme-edit-link) di footer halaman saat ini.
|
||||
|
||||
```yaml
|
||||
---
|
||||
editLink: false
|
||||
---
|
||||
```
|
||||
|
||||
### footer
|
||||
|
||||
- Tipe: `boolean`
|
||||
- Default: `true`
|
||||
|
||||
Apakah akan menampilkan [footer](./default-theme-footer).
|
||||
|
||||
```yaml
|
||||
---
|
||||
footer: false
|
||||
---
|
||||
```
|
||||
|
||||
### pageClass
|
||||
|
||||
- Tipe: `string`
|
||||
|
||||
Menambahkan nama kelas tambahan ke halaman tertentu.
|
||||
|
||||
```yaml
|
||||
---
|
||||
pageClass: custom-page-class
|
||||
---
|
||||
```
|
||||
|
||||
Kemudian Anda dapat menyesuaikan gaya halaman tertentu ini di file `.vitepress/theme/custom.css`:
|
||||
|
||||
```css
|
||||
.custom-page-class {
|
||||
/* gaya khusus halaman */
|
||||
}
|
||||
```
|
||||
|
||||
### isHome
|
||||
|
||||
- Tipe: `boolean`
|
||||
|
||||
Tema default mengandalkan pemeriksaan seperti `frontmatter.layout === 'home'` untuk menentukan apakah halaman saat ini adalah halaman beranda.\
|
||||
Ini berguna ketika Anda ingin memaksa menampilkan elemen halaman beranda di layout kustom.
|
||||
|
||||
```yaml
|
||||
---
|
||||
isHome: true
|
||||
---
|
||||
```
|
||||
@ -0,0 +1,177 @@
|
||||
---
|
||||
description: Referensi API runtime VitePress termasuk composable, fungsi helper, dan komponen bawaan.
|
||||
---
|
||||
|
||||
# Runtime API
|
||||
|
||||
VitePress menawarkan beberapa API bawaan untuk mengakses data aplikasi. VitePress juga dilengkapi dengan beberapa komponen bawaan yang dapat digunakan secara global.
|
||||
|
||||
Metode helper dapat diimpor secara global dari `vitepress` dan biasanya digunakan dalam komponen Vue tema kustom. Namun, metode ini juga dapat digunakan di dalam halaman `.md` karena file markdown dikompilasi menjadi [Single-File Components](https://vuejs.org/guide/scaling-up/sfc.html) Vue.
|
||||
|
||||
Metode yang dimulai dengan `use*` menunjukkan bahwa itu adalah fungsi [Vue 3 Composition API](https://vuejs.org/guide/introduction.html#composition-api) ("Composable") yang hanya dapat digunakan di dalam `setup()` atau `<script setup>`.
|
||||
|
||||
## `useData` <Badge type="info" text="composable" />
|
||||
|
||||
Mengembalikan data spesifik halaman. Objek yang dikembalikan memiliki tipe berikut:
|
||||
|
||||
```ts
|
||||
interface VitePressData<T = any> {
|
||||
/**
|
||||
* Metadata tingkat situs
|
||||
*/
|
||||
site: Ref<SiteData<T>>
|
||||
/**
|
||||
* themeConfig dari .vitepress/config.js
|
||||
*/
|
||||
theme: Ref<T>
|
||||
/**
|
||||
* Metadata tingkat halaman
|
||||
*/
|
||||
page: Ref<PageData>
|
||||
/**
|
||||
* Frontmatter halaman
|
||||
*/
|
||||
frontmatter: Ref<PageData['frontmatter']>
|
||||
/**
|
||||
* Parameter rute dinamis
|
||||
*/
|
||||
params: Ref<PageData['params']>
|
||||
title: Ref<string>
|
||||
description: Ref<string>
|
||||
lang: Ref<string>
|
||||
isDark: Ref<boolean>
|
||||
dir: Ref<string>
|
||||
localeIndex: Ref<string>
|
||||
/**
|
||||
* Hash lokasi saat ini
|
||||
*/
|
||||
hash: Ref<string>
|
||||
}
|
||||
|
||||
interface PageData {
|
||||
title: string
|
||||
titleTemplate?: string | boolean
|
||||
description: string
|
||||
relativePath: string
|
||||
filePath: string
|
||||
headers: Header[]
|
||||
frontmatter: Record<string, any>
|
||||
params?: Record<string, any>
|
||||
isNotFound?: boolean
|
||||
lastUpdated?: number
|
||||
}
|
||||
```
|
||||
|
||||
**Contoh:**
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
import { useData } from 'vitepress'
|
||||
|
||||
const { theme } = useData()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ theme.footer.copyright }}</h1>
|
||||
</template>
|
||||
```
|
||||
|
||||
## `useRoute` <Badge type="info" text="composable" />
|
||||
|
||||
Mengembalikan objek rute saat ini dengan tipe berikut:
|
||||
|
||||
```ts
|
||||
interface Route {
|
||||
path: string
|
||||
data: PageData
|
||||
component: Component | null
|
||||
}
|
||||
```
|
||||
|
||||
## `useRouter` <Badge type="info" text="composable" />
|
||||
|
||||
Mengembalikan instance router VitePress sehingga Anda dapat bernavigasi ke halaman lain secara terprogram.
|
||||
|
||||
```ts
|
||||
interface Router {
|
||||
/**
|
||||
* Rute saat ini.
|
||||
*/
|
||||
route: Route
|
||||
/**
|
||||
* Navigasi ke URL baru.
|
||||
*/
|
||||
go: (to?: string) => Promise<void>
|
||||
/**
|
||||
* Dipanggil sebelum rute berubah. Kembalikan `false` untuk membatalkan navigasi.
|
||||
*/
|
||||
onBeforeRouteChange?: (to: string) => Awaitable<void | boolean>
|
||||
/**
|
||||
* Dipanggil sebelum komponen halaman dimuat (setelah state riwayat diperbarui).
|
||||
* Kembalikan `false` untuk membatalkan navigasi.
|
||||
*/
|
||||
onBeforePageLoad?: (to: string) => Awaitable<void | boolean>
|
||||
/**
|
||||
* Dipanggil setelah komponen halaman dimuat (sebelum komponen halaman diperbarui).
|
||||
*/
|
||||
onAfterPageLoad?: (to: string) => Awaitable<void>
|
||||
/**
|
||||
* Dipanggil setelah rute berubah.
|
||||
*/
|
||||
onAfterRouteChange?: (to: string) => Awaitable<void>
|
||||
}
|
||||
```
|
||||
|
||||
## `withBase` <Badge type="info" text="helper" />
|
||||
|
||||
- **Tipe**: `(path: string) => string`
|
||||
|
||||
Menambahkan [`base`](./site-config#base) yang dikonfigurasi ke path URL yang diberikan. Lihat juga [Base URL](../guide/asset-handling#base-url).
|
||||
|
||||
## `<Content />` <Badge type="info" text="component" />
|
||||
|
||||
Komponen `<Content />` menampilkan konten markdown yang dirender. Berguna [ketika membuat tema Anda sendiri](../guide/custom-theme).
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<h1>Custom Layout!</h1>
|
||||
<Content />
|
||||
</template>
|
||||
```
|
||||
|
||||
## `<ClientOnly />` <Badge type="info" text="component" />
|
||||
|
||||
Komponen `<ClientOnly />` merender slot-nya hanya di sisi klien.
|
||||
|
||||
Karena aplikasi VitePress dirender di server dalam Node.js ketika menghasilkan build statis, penggunaan Vue apa pun harus mematuhi persyaratan kode universal. Singkatnya, pastikan hanya mengakses API Browser / DOM di hook beforeMount atau mounted.
|
||||
|
||||
Jika Anda menggunakan atau mendemokan komponen yang tidak SSR-friendly (misalnya, berisi custom directives), Anda dapat membungkusnya di dalam komponen `ClientOnly`.
|
||||
|
||||
```vue-html
|
||||
<ClientOnly>
|
||||
<NonSSRFriendlyComponent />
|
||||
</ClientOnly>
|
||||
```
|
||||
|
||||
- Terkait: [SSR Compatibility](../guide/ssr-compat)
|
||||
|
||||
## `$frontmatter` <Badge type="info" text="template global" />
|
||||
|
||||
Langsung mengakses data [frontmatter](../guide/frontmatter) halaman saat ini dalam ekspresi Vue.
|
||||
|
||||
```md
|
||||
---
|
||||
title: Hello
|
||||
---
|
||||
|
||||
# {{ $frontmatter.title }}
|
||||
```
|
||||
|
||||
## `$params` <Badge type="info" text="template global" />
|
||||
|
||||
Langsung mengakses [parameter rute dinamis](../guide/routing#dynamic-routes) halaman saat ini dalam ekspresi Vue.
|
||||
|
||||
```md
|
||||
- package name: {{ $params.pkg }}
|
||||
- version: {{ $params.version }}
|
||||
```
|
||||
@ -0,0 +1,753 @@
|
||||
---
|
||||
outline: deep
|
||||
description: Referensi lengkap opsi konfigurasi situs VitePress termasuk pengaturan tingkat aplikasi, tema, dan opsi build.
|
||||
---
|
||||
|
||||
# Konfigurasi Situs
|
||||
|
||||
Konfigurasi situs adalah tempat Anda dapat mendefinisikan pengaturan global situs. Opsi konfigurasi aplikasi mendefinisikan pengaturan yang berlaku untuk setiap situs VitePress, terlepas dari tema apa yang digunakannya. Misalnya, direktori dasar atau judul situs.
|
||||
|
||||
## Ringkasan
|
||||
|
||||
### Resolusi Config
|
||||
|
||||
File config selalu di-resolve dari `<root>/.vitepress/config.[ext]`, di mana `<root>` adalah [root proyek](../guide/routing#root-and-source-directory) VitePress Anda, dan `[ext]` adalah salah satu ekstensi file yang didukung. TypeScript didukung secara bawaan. Ekstensi yang didukung meliputi `.js`, `.ts`, `.mjs`, dan `.mts`.
|
||||
|
||||
Disarankan untuk menggunakan sintaks modul ES di file config. File config harus mengekspor default sebuah objek:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
// opsi config tingkat aplikasi
|
||||
lang: 'en-US',
|
||||
title: 'VitePress',
|
||||
description: 'Vite & Vue powered static site generator.',
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
::: details Config Dinamis (Async)
|
||||
|
||||
Jika Anda perlu menghasilkan config secara dinamis, Anda juga dapat mengekspor default sebuah fungsi. Misalnya:
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default async () => {
|
||||
const posts = await (await fetch('https://my-cms.com/blog-posts')).json()
|
||||
|
||||
return defineConfig({
|
||||
// opsi config tingkat aplikasi
|
||||
lang: 'en-US',
|
||||
title: 'VitePress',
|
||||
description: 'Vite & Vue powered static site generator.',
|
||||
|
||||
// opsi config tingkat tema
|
||||
themeConfig: {
|
||||
sidebar: [
|
||||
...posts.map((post) => ({
|
||||
text: post.name,
|
||||
link: `/posts/${post.name}`
|
||||
}))
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Anda juga dapat menggunakan `await` tingkat atas. Misalnya:
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
const posts = await (await fetch('https://my-cms.com/blog-posts')).json()
|
||||
|
||||
export default defineConfig({
|
||||
// opsi config tingkat aplikasi
|
||||
lang: 'en-US',
|
||||
title: 'VitePress',
|
||||
description: 'Vite & Vue powered static site generator.',
|
||||
|
||||
// opsi config tingkat tema
|
||||
themeConfig: {
|
||||
sidebar: [
|
||||
...posts.map((post) => ({
|
||||
text: post.name,
|
||||
link: `/posts/${post.name}`
|
||||
}))
|
||||
]
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
### Intellisense Config
|
||||
|
||||
Menggunakan helper `defineConfig` akan memberikan intellisense berbasis TypeScript untuk opsi config. Dengan asumsi IDE Anda mendukungnya, ini seharusnya berfungsi di JavaScript dan TypeScript.
|
||||
|
||||
```js
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
### Konfigurasi Tema Bertipe
|
||||
|
||||
Secara default, helper `defineConfig` mengharapkan tipe config tema dari tema default:
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
themeConfig: {
|
||||
// Tipe adalah `DefaultTheme.Config`
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Jika Anda menggunakan tema kustom dan menginginkan pengecekan tipe untuk config tema, Anda perlu menggunakan `defineConfigWithTheme`, dan mengirimkan tipe config untuk tema kustom Anda melalui argumen generik:
|
||||
|
||||
```ts
|
||||
import { defineConfigWithTheme } from 'vitepress'
|
||||
import type { ThemeConfig } from 'your-theme'
|
||||
|
||||
export default defineConfigWithTheme<ThemeConfig>({
|
||||
themeConfig: {
|
||||
// Tipe adalah `ThemeConfig`
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### Konfigurasi Vite, Vue, dan Markdown
|
||||
|
||||
- **Vite**
|
||||
|
||||
Anda dapat mengonfigurasi instance Vite yang mendasarinya menggunakan opsi [vite](#vite) di config VitePress Anda. Tidak perlu membuat file config Vite terpisah.
|
||||
|
||||
- **Vue**
|
||||
|
||||
VitePress sudah menyertakan plugin Vue resmi untuk Vite ([@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue)). Anda dapat mengonfigurasi opsinya menggunakan opsi [vue](#vue) di config VitePress Anda.
|
||||
|
||||
- **Markdown**
|
||||
|
||||
Anda dapat mengonfigurasi instance [Markdown-It](https://github.com/markdown-it/markdown-it) yang mendasarinya menggunakan opsi [markdown](#markdown) di config VitePress Anda.
|
||||
|
||||
## Metadata Situs
|
||||
|
||||
### title
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `VitePress`
|
||||
- Dapat ditimpa per halaman melalui [frontmatter](./frontmatter-config#title)
|
||||
|
||||
Judul untuk situs. Ketika menggunakan tema default, ini akan ditampilkan di bilah nav.
|
||||
|
||||
Ini juga akan digunakan sebagai sufiks default untuk semua judul halaman individual, kecuali [`titleTemplate`](#titletemplate) didefinisikan. Judul akhir halaman individual akan berupa konten teks dari header `<h1>` pertamanya, digabungkan dengan `title` global sebagai sufiks. Misalnya dengan config dan konten halaman berikut:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
title: 'My Awesome Site'
|
||||
}
|
||||
```
|
||||
|
||||
```md
|
||||
# Hello
|
||||
```
|
||||
|
||||
Judul halaman akan menjadi `Hello | My Awesome Site`.
|
||||
|
||||
### titleTemplate
|
||||
|
||||
- Tipe: `string | boolean`
|
||||
- Dapat ditimpa per halaman melalui [frontmatter](./frontmatter-config#titletemplate)
|
||||
|
||||
Memungkinkan penyesuaian sufiks judul setiap halaman atau seluruh judul. Misalnya:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
title: 'My Awesome Site',
|
||||
titleTemplate: 'Custom Suffix'
|
||||
}
|
||||
```
|
||||
|
||||
```md
|
||||
# Hello
|
||||
```
|
||||
|
||||
Judul halaman akan menjadi `Hello | Custom Suffix`.
|
||||
|
||||
Untuk sepenuhnya menyesuaikan bagaimana judul harus dirender, Anda dapat menggunakan simbol `:title` di `titleTemplate`:
|
||||
|
||||
```ts
|
||||
export default {
|
||||
titleTemplate: ':title - Custom Suffix'
|
||||
}
|
||||
```
|
||||
|
||||
Di sini `:title` akan diganti dengan teks yang disimpulkan dari header `<h1>` pertama halaman. Judul halaman contoh sebelumnya akan menjadi `Hello - Custom Suffix`.
|
||||
|
||||
Opsi ini dapat diatur ke `false` untuk menonaktifkan sufiks judul.
|
||||
|
||||
### description
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `A VitePress site`
|
||||
- Dapat ditimpa per halaman melalui [frontmatter](./frontmatter-config#description)
|
||||
|
||||
Deskripsi untuk situs. Ini akan dirender sebagai tag `<meta>` di HTML halaman.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
description: 'A VitePress site'
|
||||
}
|
||||
```
|
||||
|
||||
### head
|
||||
|
||||
- Tipe: `HeadConfig[]`
|
||||
- Default: `[]`
|
||||
- Dapat ditambahkan per halaman melalui [frontmatter](./frontmatter-config#head)
|
||||
|
||||
Elemen tambahan untuk dirender di tag `<head>` di HTML halaman. Tag yang ditambahkan pengguna dirender sebelum tag penutup `head`, setelah tag VitePress.
|
||||
|
||||
```ts
|
||||
type HeadConfig =
|
||||
| [string, Record<string, string>]
|
||||
| [string, Record<string, string>, string]
|
||||
```
|
||||
|
||||
#### Contoh: Menambahkan favicon
|
||||
|
||||
```ts
|
||||
export default {
|
||||
head: [['link', { rel: 'icon', href: '/favicon.ico' }]]
|
||||
} // letakkan favicon.ico di direktori public, jika base diatur, gunakan /base/favicon.ico
|
||||
|
||||
/* Akan merender:
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
*/
|
||||
```
|
||||
|
||||
#### Contoh: Menambahkan Google Fonts
|
||||
|
||||
```ts
|
||||
export default {
|
||||
head: [
|
||||
[
|
||||
'link',
|
||||
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' }
|
||||
],
|
||||
[
|
||||
'link',
|
||||
{ rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' }
|
||||
],
|
||||
[
|
||||
'link',
|
||||
{ href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap', rel: 'stylesheet' }
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
/* Akan merender:
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
|
||||
*/
|
||||
```
|
||||
|
||||
#### Contoh: Mendaftarkan service worker
|
||||
|
||||
```ts
|
||||
export default {
|
||||
head: [
|
||||
[
|
||||
'script',
|
||||
{ id: 'register-sw' },
|
||||
`;(() => {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('/sw.js')
|
||||
}
|
||||
})()`
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
/* Akan merender:
|
||||
<script id="register-sw">
|
||||
;(() => {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('/sw.js')
|
||||
}
|
||||
})()
|
||||
</script>
|
||||
*/
|
||||
```
|
||||
|
||||
#### Contoh: Menggunakan Google Analytics
|
||||
|
||||
```ts
|
||||
export default {
|
||||
head: [
|
||||
[
|
||||
'script',
|
||||
{ async: '', src: 'https://www.googletagmanager.com/gtag/js?id=TAG_ID' }
|
||||
],
|
||||
[
|
||||
'script',
|
||||
{},
|
||||
`window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'TAG_ID');`
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
/* Akan merender:
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=TAG_ID"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'TAG_ID');
|
||||
</script>
|
||||
*/
|
||||
```
|
||||
|
||||
### lang
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `en-US`
|
||||
|
||||
Atribut lang untuk situs. Ini akan dirender sebagai tag `<html lang="en-US">` di HTML halaman.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
lang: 'en-US'
|
||||
}
|
||||
```
|
||||
|
||||
### base
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `/`
|
||||
|
||||
URL dasar tempat situs akan di-deploy. Anda perlu mengatur ini jika berencana men-deploy situs Anda di bawah sub path, misalnya, GitHub pages. Jika Anda berencana men-deploy situs Anda ke `https://foo.github.io/bar/`, maka Anda harus mengatur base ke `'/bar/'`. Ini harus selalu dimulai dan diakhiri dengan slash. Base relatif tidak didukung.
|
||||
|
||||
Base secara otomatis ditambahkan di depan semua URL yang dimulai dengan / di opsi lain, jadi Anda hanya perlu menentukannya sekali.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
base: '/base/'
|
||||
}
|
||||
```
|
||||
|
||||
## Routing
|
||||
|
||||
### cleanUrls
|
||||
|
||||
- Tipe: `boolean`
|
||||
- Default: `false`
|
||||
|
||||
Ketika diatur ke `true`, VitePress akan menghapus `.html` di akhir URL. Lihat juga [Generating Clean URLs](../guide/routing#generating-clean-urls).
|
||||
|
||||
::: warning Diperlukan Dukungan Server
|
||||
Mengaktifkan ini mungkin memerlukan konfigurasi tambahan di platform hosting Anda. Agar berfungsi, server Anda harus dapat menyajikan `/foo.html` ketika mengunjungi `/foo` **tanpa redirect**.
|
||||
:::
|
||||
|
||||
### rewrites
|
||||
|
||||
- Tipe: `Record<string, string>`
|
||||
|
||||
Mendefinisikan pemetaan direktori kustom <-> URL. Lihat [Routing: Route Rewrites](../guide/routing#route-rewrites) untuk detail lebih lanjut.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
rewrites: {
|
||||
'source/:page': 'destination/:page'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Build
|
||||
|
||||
### srcDir
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `.`
|
||||
|
||||
Direktori tempat halaman markdown Anda disimpan, relatif terhadap root proyek. Lihat juga [Root and Source Directory](../guide/routing#root-and-source-directory).
|
||||
|
||||
```ts
|
||||
export default {
|
||||
srcDir: './src'
|
||||
}
|
||||
```
|
||||
|
||||
### srcExclude
|
||||
|
||||
- Tipe: `string[]`
|
||||
- Default: `undefined`
|
||||
|
||||
Pola [glob](https://github.com/mrmlnc/fast-glob#pattern-syntax) untuk mencocokkan file markdown yang harus dikecualikan sebagai konten sumber.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
srcExclude: ['**/README.md', '**/TODO.md']
|
||||
}
|
||||
```
|
||||
|
||||
### outDir
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `./.vitepress/dist`
|
||||
|
||||
Lokasi output build untuk situs, relatif terhadap [root proyek](../guide/routing#root-and-source-directory).
|
||||
|
||||
```ts
|
||||
export default {
|
||||
outDir: '../public'
|
||||
}
|
||||
```
|
||||
|
||||
### assetsDir
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `assets`
|
||||
|
||||
Menentukan direktori untuk menyarangkan aset yang dihasilkan. Path harus berada di dalam [`outDir`](#outdir) dan di-resolve relatif terhadapnya.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
assetsDir: 'static'
|
||||
}
|
||||
```
|
||||
|
||||
### cacheDir
|
||||
|
||||
- Tipe: `string`
|
||||
- Default: `./.vitepress/cache`
|
||||
|
||||
Direktori untuk file cache, relatif terhadap [root proyek](../guide/routing#root-and-source-directory). Lihat juga: [cacheDir](https://vitejs.dev/config/shared-options.html#cachedir).
|
||||
|
||||
```ts
|
||||
export default {
|
||||
cacheDir: './.vitepress/.vite'
|
||||
}
|
||||
```
|
||||
|
||||
### ignoreDeadLinks
|
||||
|
||||
- Tipe: `boolean | 'localhostLinks' | (string | RegExp | ((link: string, source: string) => boolean))[]`
|
||||
- Default: `false`
|
||||
|
||||
Ketika diatur ke `true`, VitePress tidak akan menggagalkan build karena dead link.
|
||||
|
||||
Ketika diatur ke `'localhostLinks'`, build akan gagal pada dead link, tetapi tidak akan memeriksa tautan `localhost`.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
ignoreDeadLinks: true
|
||||
}
|
||||
```
|
||||
|
||||
Ini juga dapat berupa array dari string URL persis, pola regex, atau fungsi filter kustom.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
ignoreDeadLinks: [
|
||||
// abaikan URL persis "/playground"
|
||||
'/playground',
|
||||
// abaikan semua tautan localhost
|
||||
/^https?:\/\/localhost/,
|
||||
// abaikan semua tautan yang menyertakan "/repl/"
|
||||
/\/repl\//,
|
||||
// fungsi kustom, abaikan semua tautan yang menyertakan "ignore"
|
||||
(url) => {
|
||||
return url.toLowerCase().includes('ignore')
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### metaChunk <Badge type="warning" text="eksperimental" />
|
||||
|
||||
- Tipe: `boolean`
|
||||
- Default: `false`
|
||||
|
||||
Ketika diatur ke `true`, mengekstrak metadata halaman ke chunk JavaScript terpisah alih-alih meng-inline-nya di HTML awal. Ini membuat payload HTML setiap halaman lebih kecil dan membuat metadata halaman dapat di-cache, sehingga mengurangi bandwidth server ketika Anda memiliki banyak halaman di situs.
|
||||
|
||||
### mpa <Badge type="warning" text="eksperimental" />
|
||||
|
||||
- Tipe: `boolean`
|
||||
- Default: `false`
|
||||
|
||||
Ketika diatur ke `true`, aplikasi production akan dibangun dalam [Mode MPA](../guide/mpa-mode). Mode MPA mengirimkan 0kb JavaScript secara default, dengan mengorbankan penonaktifan navigasi sisi klien dan memerlukan opt-in eksplisit untuk interaktivitas.
|
||||
|
||||
## Tema
|
||||
|
||||
### appearance
|
||||
|
||||
- Tipe: `boolean | 'dark' | 'force-dark' | 'force-auto' | import('@vueuse/core').UseDarkOptions`
|
||||
- Default: `true`
|
||||
|
||||
Apakah akan mengaktifkan mode gelap (dengan menambahkan kelas `.dark` ke elemen `<html>`).
|
||||
|
||||
- Jika opsi diatur ke `true`, tema default akan ditentukan oleh skema warna pilihan pengguna.
|
||||
- Jika opsi diatur ke `dark`, tema akan menjadi gelap secara default, kecuali pengguna secara manual mengubahnya.
|
||||
- Jika opsi diatur ke `false`, pengguna tidak akan dapat mengubah tema.
|
||||
- Jika opsi diatur ke `'force-dark'`, tema akan selalu gelap dan pengguna tidak akan dapat mengubahnya.
|
||||
- Jika opsi diatur ke `'force-auto'`, tema akan selalu ditentukan oleh skema warna pilihan pengguna dan pengguna tidak akan dapat mengubahnya.
|
||||
|
||||
Opsi ini menyuntikkan script inline yang memulihkan pengaturan pengguna dari local storage menggunakan kunci `vitepress-theme-appearance`. Ini memastikan kelas `.dark` diterapkan sebelum halaman dirender untuk menghindari flickering.
|
||||
|
||||
`appearance.initialValue` hanya dapat berupa `'dark' | undefined`. Ref atau getter tidak didukung.
|
||||
|
||||
### lastUpdated
|
||||
|
||||
- Tipe: `boolean`
|
||||
- Default: `false`
|
||||
|
||||
Apakah akan mendapatkan timestamp terakhir diperbarui untuk setiap halaman menggunakan Git. Timestamp akan disertakan dalam data halaman setiap halaman, dapat diakses melalui [`useData`](./runtime-api#usedata).
|
||||
|
||||
Ketika menggunakan tema default, mengaktifkan opsi ini akan menampilkan waktu terakhir diperbarui setiap halaman. Anda dapat menyesuaikan teksnya melalui opsi [`themeConfig.lastUpdatedText`](./default-theme-config#lastupdatedtext).
|
||||
|
||||
## Kustomisasi
|
||||
|
||||
### markdown
|
||||
|
||||
- Tipe: `MarkdownOption`
|
||||
|
||||
Mengonfigurasi opsi parser Markdown. VitePress menggunakan [Markdown-it](https://github.com/markdown-it/markdown-it) sebagai parser, dan [Shiki](https://github.com/shikijs/shiki) untuk menyorot sintaks bahasa. Di dalam opsi ini, Anda dapat memberikan berbagai opsi terkait Markdown sesuai kebutuhan Anda.
|
||||
|
||||
```js
|
||||
export default {
|
||||
markdown: {...}
|
||||
}
|
||||
```
|
||||
|
||||
Periksa [deklarasi tipe dan jsdocs](https://github.com/vuejs/vitepress/blob/main/src/node/markdown/markdown.ts) untuk semua opsi yang tersedia.
|
||||
|
||||
### vite
|
||||
|
||||
- Tipe: `import('vite').UserConfig`
|
||||
|
||||
Meneruskan [Vite Config](https://vitejs.dev/config/) mentah ke Vite dev server / bundler internal.
|
||||
|
||||
```js
|
||||
export default {
|
||||
vite: {
|
||||
// opsi config Vite
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### vue
|
||||
|
||||
- Tipe: `import('@vitejs/plugin-vue').Options`
|
||||
|
||||
Meneruskan [opsi `@vitejs/plugin-vue`](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#options) mentah ke instance plugin internal.
|
||||
|
||||
```js
|
||||
export default {
|
||||
vue: {
|
||||
// opsi @vitejs/plugin-vue
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Build Hooks
|
||||
|
||||
Build hooks VitePress dapat digunakan untuk menambahkan fungsionalitas dan perilaku baru ke situs Anda:
|
||||
|
||||
- Sitemap
|
||||
- Search Indexing
|
||||
- PWA
|
||||
- Teleports
|
||||
|
||||
### buildEnd
|
||||
|
||||
- Tipe: `(siteConfig: SiteConfig) => Awaitable<void>`
|
||||
|
||||
`buildEnd` adalah build CLI hook, ini akan berjalan setelah build (SSG) selesai tetapi sebelum proses VitePress CLI keluar.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
async buildEnd(siteConfig) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### postRender
|
||||
|
||||
- Tipe: `(context: SSGContext) => Awaitable<SSGContext | void>`
|
||||
|
||||
`postRender` adalah build hook, dipanggil ketika rendering SSG selesai. Hook ini dapat digunakan untuk menangani konten teleports selama SSG.
|
||||
|
||||
```ts
|
||||
export default {
|
||||
async postRender(context) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
interface SSGContext {
|
||||
content: string
|
||||
teleports?: Record<string, string>
|
||||
[key: string]: any
|
||||
}
|
||||
```
|
||||
|
||||
### transformHead
|
||||
|
||||
- Tipe: `(context: TransformContext) => Awaitable<HeadConfig[]>`
|
||||
|
||||
`transformHead` adalah build hook untuk menambahkan tag tambahan ke `<head>` setiap halaman. Hook ini dapat digunakan untuk menambahkan entri head yang tidak dapat ditambahkan secara statis ke config VitePress Anda. Anda hanya perlu mengembalikan entri tambahan, mereka akan digabungkan secara otomatis dengan yang sudah ada.
|
||||
|
||||
::: warning
|
||||
Jangan memutasi apa pun di dalam `context`.
|
||||
:::
|
||||
|
||||
```ts
|
||||
export default {
|
||||
async transformHead(context) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
interface TransformContext {
|
||||
page: string // mis. index.md (relatif terhadap srcDir)
|
||||
assets: string[] // semua aset non-js/css sebagai URL publik yang sepenuhnya di-resolve
|
||||
siteConfig: SiteConfig
|
||||
siteData: SiteData
|
||||
pageData: PageData
|
||||
title: string
|
||||
description: string
|
||||
head: HeadConfig[]
|
||||
content: string
|
||||
}
|
||||
```
|
||||
|
||||
Hook ini hanya dipanggil ketika melakukan build, tidak dipanggil selama dev.
|
||||
|
||||
Tag tambahan akan ditambahkan ke file HTML statis yang dihasilkan oleh build. Mereka tidak akan diperbarui selama navigasi sisi klien.
|
||||
|
||||
Dalam banyak kasus, menggunakan hook [`transformPageData`](#transformpagedata) adalah solusi yang lebih bersih. Hook itu juga akan diterapkan pada navigasi sisi klien dan selama dev. Namun jika menghasilkan tag head membutuhkan komputasi yang mahal, maka `transformHead` akan menghindari overhead tersebut selama dev.
|
||||
|
||||
#### Contoh: Menambahkan meta `og:image`
|
||||
|
||||
```ts
|
||||
export default {
|
||||
async transformHead(context) {
|
||||
if (context.page === '404.md') {
|
||||
return
|
||||
}
|
||||
|
||||
// Detail implementasi `generatePageImage` akan bergantung
|
||||
// pada kebutuhan Anda. Di sini kita asumsikan ia menghasilkan
|
||||
// gambar yang sesuai untuk setiap halaman dan mengembalikan URL gambar.
|
||||
const imageUrl = await generatePageImage(context)
|
||||
|
||||
return [[
|
||||
'meta',
|
||||
{ name: 'og:image', content: imageUrl }
|
||||
]]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Di sini kita mengasumsikan bahwa URL gambar bersifat dinamis dan memakan waktu untuk dihasilkan. Menggunakan `transformHead` menghindari overhead tersebut selama pengembangan.
|
||||
|
||||
Untuk kasus yang lebih sederhana, mungkin dapat menggunakan pengaturan [`head`](./frontmatter-config#head) di frontmatter, atau [`transformPageData`](#transformpagedata).
|
||||
|
||||
### transformHtml
|
||||
|
||||
- Tipe: `(code: string, id: string, context: TransformContext) => Awaitable<string | void>`
|
||||
|
||||
`transformHtml` adalah build hook untuk mentransformasi konten setiap halaman sebelum disimpan ke disk.
|
||||
|
||||
::: warning
|
||||
Jangan memutasi apa pun di dalam `context`. Selain itu, memodifikasi konten html dapat menyebabkan masalah hidrasi di runtime.
|
||||
:::
|
||||
|
||||
```ts
|
||||
export default {
|
||||
async transformHtml(code, id, context) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### transformPageData
|
||||
|
||||
- Tipe: `(pageData: PageData, context: TransformPageContext) => Awaitable<Partial<PageData> | { [key: string]: any } | void>`
|
||||
|
||||
`transformPageData` adalah hook untuk mentransformasi `pageData` setiap halaman. Anda dapat langsung memutasi `pageData` atau mengembalikan nilai yang diubah yang akan digabungkan ke dalam data halaman.
|
||||
|
||||
::: warning
|
||||
Jangan memutasi apa pun di dalam `context` dan berhati-hatilah bahwa ini dapat memengaruhi kinerja server pengembangan, terutama jika Anda memiliki beberapa permintaan jaringan atau komputasi berat (seperti menghasilkan gambar) di hook. Anda dapat memeriksa `process.env.NODE_ENV === 'production'` untuk logika kondisional.
|
||||
:::
|
||||
|
||||
```ts
|
||||
export default {
|
||||
async transformPageData(pageData, { siteConfig }) {
|
||||
pageData.contributors = await getPageContributors(pageData.relativePath)
|
||||
}
|
||||
|
||||
// atau kembalikan data untuk digabungkan
|
||||
async transformPageData(pageData, { siteConfig }) {
|
||||
return {
|
||||
contributors: await getPageContributors(pageData.relativePath)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
interface TransformPageContext {
|
||||
siteConfig: SiteConfig
|
||||
}
|
||||
```
|
||||
|
||||
#### Contoh: Menambahkan `<meta name="og:title">`
|
||||
|
||||
```ts
|
||||
export default {
|
||||
transformPageData(pageData) {
|
||||
const title = pageData.frontmatter.layout === 'home'
|
||||
? 'VitePress'
|
||||
: `${pageData.title} | VitePress`
|
||||
|
||||
pageData.frontmatter.head ??= []
|
||||
pageData.frontmatter.head.push([
|
||||
'meta',
|
||||
{ name: 'og:title', content: title }
|
||||
])
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Contoh: Menambahkan URL kanonikal `<link>`
|
||||
|
||||
```ts
|
||||
export default {
|
||||
transformPageData(pageData) {
|
||||
const canonicalUrl = `https://example.com/${pageData.relativePath}`
|
||||
.replace(/index\.md$/, '')
|
||||
.replace(/\.md$/, '.html')
|
||||
|
||||
pageData.frontmatter.head ??= []
|
||||
pageData.frontmatter.head.push([
|
||||
'link',
|
||||
{ rel: 'canonical', href: canonicalUrl }
|
||||
])
|
||||
}
|
||||
}
|
||||
```
|
||||
Loading…
Reference in new issue