사이트 구성
사이트 구성(config)은 사이트의 전역 설정을 정의할 수 있는 곳입니다. 애플리케이션 구성 옵션은 사용 중인 테마와 상관없이 모든 VitePress 사이트에 적용되는 설정을 정의합니다. 예를 들어 기본 디렉터리나 사이트의 제목 등이 있습니다.
개요
구성 분석
구성 파일은 항상 <root>/.vitepress/config.[ext]에서 처리됩니다. 여기서 <root>는 VitePress 프로젝트 루트를 의미하며, [ext]는 지원되는 파일 확장자 중 하나입니다. TypeScript는 기본적으로 지원됩니다. 지원되는 확장자에는 .js, .ts, .mjs, .mts가 포함됩니다.
구성 파일에서는 ES 모듈 구문을 사용하는 것이 권장됩니다. 구성 파일은 객체를 "default export"해야 합니다:
export default {
// 애플리케이션 레벨의 구성 옵션
lang: 'en-US',
title: 'VitePress',
description: 'Vite & Vue powered static site generator.',
...
}동적(비동기) 구성
구성을 동적으로 생성해야 하는 경우, 함수를 "default export" 할 수 있습니다. 예:
import { defineConfig } from 'vitepress'
export default async () => {
const posts = await (await fetch('https://my-cms.com/blog-posts')).json()
return defineConfig({
// 애플리케이션 레벨의 구성 옵션
lang: 'en-US',
title: 'VitePress',
description: 'Vite & Vue powered static site generator.',
// 테마 레벨의 구성 옵션
themeConfig: {
sidebar: [
...posts.map((post) => ({
text: post.name,
link: `/posts/${post.name}`
}))
]
}
})
}최상위 수준의 await도 사용할 수 있습니다. 예:
import { defineConfig } from 'vitepress'
const posts = await (await fetch('https://my-cms.com/blog-posts')).json()
export default defineConfig({
// 앱 레벨 설정 옵션
lang: 'en-US',
title: 'VitePress',
description: 'Vite & Vue를 활용한 정적 사이트 생성기.',
// 테마 레벨 설정 옵션
themeConfig: {
sidebar: [
...posts.map((post) => ({
text: post.name,
link: `/posts/${post.name}`
}))
]
}
})구성 인텔리센스
defineConfig 헬퍼를 사용하면 구성 옵션에 대해 TypeScript 기반의 인텔리센스(자동완성)를 제공받을 수 있습니다. IDE가 이를 지원하는 경우, JavaScript와 TypeScript 모두에서 작동합니다.
import { defineConfig } from 'vitepress'
export default defineConfig({
// ...
})타입이 지정된 테마 구성
기본적으로 defineConfig 헬퍼는 기본 테마에서 테마 구성 타입을 예측합니다:
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
// 타입은 `DefaultTheme.Config`
}
})커스텀 테마를 사용하고 테마 구성에 대한 타입 검사를 원한다면, defineConfigWithTheme를 사용하고 제네릭 인수를 통해 커스텀 테마의 구성 타입을 전달해야 합니다:
import { defineConfigWithTheme } from 'vitepress'
import type { ThemeConfig } from 'your-theme'
export default defineConfigWithTheme<ThemeConfig>({
themeConfig: {
// 타입은 `ThemeConfig`
}
})Vite, Vue, Markdown 설정
Vite
VitePress 구성에서 vite 옵션을 사용하여 기본 Vite 인스턴스를 구성할 수 있습니다. 별도의 Vite 구성 파일을 만들 필요는 없습니다.
Vue
VitePress는 이미 Vite의 공식 Vue 플러그인(@vitejs/plugin-vue)을 포함하고 있습니다. VitePress 구성에서 vue 옵션을 사용하여 해당 옵션을 구성할 수 있습니다.
Markdown
Markdown-It 인스턴스를 VitePress 구성에서 markdown 옵션을 사용하여 구성할 수 있습니다.
사이트 메타데이터
title
- 타입:
string - 기본값:
VitePress - 전문을 통해 페이지별로 재정의 가능
사이트의 제목입니다. 기본 테마를 사용할 경우, 이는 내비게이션 바에 표시됩니다.
titleTemplate이 정의되지 않은 경우, 모든 개별 페이지 제목의 기본 접미사로 사용됩니다. 개별 페이지의 최종 제목은 첫 번째 <h1> 헤더의 텍스트 콘텐츠와 전역 title을 접미사로 결합한 것입니다. 예를 들어 다음 구성과 페이지 콘텐츠가 있을 경우:
export default {
title: 'My Awesome Site'
}# Hello페이지의 제목은 Hello | My Awesome Site가 됩니다.
titleTemplate
- 타입:
string | boolean - 전문을 통해 페이지별로 재정의 가능
각 페이지의 제목 접미사 또는 전체 제목을 커스터마이징할 수 있습니다. 예를 들어:
export default {
title: 'My Awesome Site',
titleTemplate: 'Custom Suffix'
}# Hello페이지의 제목은 Hello | Custom Suffix가 됩니다.
제목이 렌더링되는 방식을 완전히 커스터마이징하려면 titleTemplate에서 :title 심볼을 사용할 수 있습니다:
export default {
titleTemplate: ':title - Custom Suffix'
}여기서 :title은 페이지의 첫 번째 <h1> 헤더에서 추론된 텍스트로 대체됩니다. 이전 예제 페이지의 제목은 Hello - Custom Suffix가 됩니다.
이 옵션을 false로 설정하여 제목 접미사를 비활성화할 수 있습니다.
description
- 타입:
string - 기본값:
A VitePress site - 전문을 통해 페이지별로 재정의 가능
사이트의 설명입니다. 이는 페이지 HTML의 <meta> 태그로 렌더링됩니다.
export default {
description: 'A VitePress site'
}head
- 타입:
HeadConfig[] - 기본값:
[] - 전문을 통해 페이지별로 추가 가능
페이지 HTML의 <head> 태그에 렌더링할 추가 엘리먼트입니다. 추가한 태그는 VitePress 태그 뒤 ~ 닫는 head 태그 앞에 렌더링됩니다.
type HeadConfig =
| [string, Record<string, string>]
| [string, Record<string, string>, string]예제: 파비콘 추가
export default {
head: [['link', { rel: 'icon', href: '/favicon.ico' }]]
} // favicon.ico를 public 디렉토리에 배치하거나 base가 설정된 경우,
// /base/favicon.ico를 사용하세요.
/* 다음과 같이 랜더링:
<link rel="icon" href="/favicon.ico">
*/예제: Google 폰트 추가
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' }
]
]
}
/* 다음과 같이 랜더링:
<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">
*/예제: 서비스 워커 등록
export default {
head: [
[
'script',
{ id: 'register-sw' },
`;(() => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
}
})()`
]
]
}
/* 다음과 같이 랜더링:
<script id="register-sw">
;(() => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
}
})()
</script>
*/예제: Google Analytics 사용
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');`
]
]
}
/* 다음과 같이 랜더링:
<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
- 타입:
string - 기본값:
en-US
사이트의 언어 어트리뷰트입니다. 이는 페이지 HTML의 <html lang="en-US"> 태그로 렌더링됩니다.
export default {
lang: 'en-US'
}base
- 타입:
string - 기본값:
/
사이트가 배포될 기본 URL입니다. 예를 들어 GitHub Pages와 같이 서브 경로에 사이트를 배포하려는 경우 이것을 설정해야 합니다. https://foo.github.io/bar/ 에 사이트를 배포하려면 '/bar/'로 설정해야 합니다. 항상 슬래시로 시작하고 끝나야 합니다.
이것은 다른 옵션에서 /로 시작하는 모든 URL에 자동으로 추가되므로, 한 번만 지정하면 됩니다.
export default {
base: '/base/'
}라우팅
cleanUrls
- 타입:
boolean - 기본값:
false
true로 설정하면 VitePress는 URL에서 .html을 제거합니다. 간결한 URL 생성을 참고하세요.
서버 지원 필요
이를 활성화하려면 호스팅 플랫폼에서 추가 구성이 필요할 수 있습니다. 서버가 /foo를 방문할 때 리디렉션 없이 /foo.html을 제공할 수 있어야 합니다.
rewrites
- 타입:
Record<string, string>
커스텀 디렉터리와 URL 매핑을 정의합니다. 자세한 내용은 라우팅: 라우트 재작성을 참고하세요.
export default {
rewrites: {
'source/:page': 'destination/:page'
}
}빌드
srcDir
- 타입:
string - 기본값:
.
마크다운 페이지가 저장되는 디렉터리입니다. 프로젝트 루트에 상대적입니다. 또한 루트와 소스 디렉터리를 참고하세요.
export default {
srcDir: './src'
}srcExclude
- 타입:
string - 기본값:
undefined
소스 컨텐츠에서 제외해야 하는 마크다운 파일을 매칭하기 위한 glob 패턴입니다.
export default {
srcExclude: ['**/README.md', '**/TODO.md']
}outDir
- 타입:
string - 기본값:
./.vitepress/dist
사이트의 빌드 결과물 위치입니다. 프로젝트 루트에 상대적입니다.
export default {
outDir: '../public'
}assetsDir
- 타입:
string - 기본값:
assets
생성된 에셋을 포함할 디렉터리를 지정합니다. 경로는 outDir 내에 있어야 하며, 그것을 기준으로 처리됩니다.
export default {
assetsDir: 'static'
}cacheDir
- 타입:
string - 기본값:
./.vitepress/cache
캐시 파일을 위한 디렉터리입니다. 프로젝트 루트에 상대적입니다. cacheDir을 참고하세요.
export default {
cacheDir: './.vitepress/.vite'
}ignoreDeadLinks
- 타입:
boolean | 'localhostLinks' | (string | RegExp | ((link: string, source: string) => boolean))[] - 기본값:
false
true로 설정하면, 빌드 시 죽은 링크로 인해 실패하지 않습니다.
'localhostLinks'로 설정하면, 죽은 링크가 있으면 빌드에 실패하지만 localhost 링크는 확인하지 않습니다.
export default {
ignoreDeadLinks: true
}정확히 일치하는 URL 문자열, 정규 표현식 패턴, 커스텀 필터 함수로 구성된 배열도 가능합니다.
export default {
ignoreDeadLinks: [
// "/playground"과 정확히 일치하는 url 무시
'/playground',
// 모든 localhost 링크 무시
/^https?:\/\/localhost/,
// 모든 "/repl/" 포함 링크 무시
/\/repl\//,
// 커스텀 함수, "ignore"를 포함한 모든 링크 무시
(url) => {
return url.toLowerCase().includes('ignore')
}
]
}metaChunk 실험적
- 타입:
boolean - 기본값:
false
true로 설정하면 페이지 메타데이터를 초기 HTML에 인라인으로 삽입하는 대신 별도의 JavaScript 청크로 추출합니다. 이렇게 하면 각 페이지의 HTML 페이로드가 작아지고 페이지 메타데이터를 캐시할 수 있어, 사이트에 많은 페이지가 있을 때 서버 대역폭을 줄일 수 있습니다.
mpa 실험적
- 타입:
boolean - 기본값:
false
true로 설정하면 프로덕션 애플리케이션이 MPA 모드로 빌드됩니다. MPA 모드는 기본적으로 0kb JavaScript를 제공하지만, 클라이언트 사이드 탐색을 비활성화하고 상호작용을 위한 명시적인 옵트인을 필요로 합니다.
테마
appearance
- 타입:
boolean | 'dark' | 'force-dark' | 'force-auto' | import('@vueuse/core').UseDarkOptions - 기본값:
true
다크 모드를 활성화 여부를 설정합니다 (.dark 클래스를 <html> 엘리먼트에 추가).
true: 기본 테마는 유저의 선호 색상 설정에 따라 결정됩니다.dark: 유저가 수동으로 변경하지 않는 한 기본 테마는 다크 모드가 됩니다.false: 유저는 테마를 전환할 수 없습니다.'force-dark': 테마는 항상 다크 모드가 되며 유저는 이를 전환할 수 없습니다.'force-auto': 테마는 항상 유저의 선호 색상 설정에 따라 결정되며 유저는 이를 전환할 수 없습니다.
이 옵션은 vitepress-theme-appearance 키를 사용하여 로컬 스토리지에서 유저 설정을 복원하는 인라인 스크립트를 삽입합니다. 이는 페이지가 렌더링되기 전에 .dark 클래스가 적용되어 깜박임을 방지합니다.
appearance.initialValue는 'dark' 또는 undefined만 가능합니다. Refs 또는 getter는 지원되지 않습니다.
lastUpdated
- 타입:
boolean - 기본값:
false
각 페이지의 마지막 업데이트 타임스탬프를 Git을 사용하여 가져올지 여부를 설정합니다. 타임스탬프는 각 페이지의 페이지 데이터에 포함되며, useData를 통해 접근할 수 있습니다.
기본 테마를 사용할 때, 이 옵션을 활성화하면 각 페이지의 마지막 업데이트 시간이 표시됩니다. themeConfig.lastUpdatedText 옵션을 통해 텍스트를 커스터마이징할 수 있습니다.
커스터마이징
markdown
- 타입:
MarkdownOption
마크다운 파서 옵션을 구성합니다. VitePress는 파서로 Markdown-it을 사용하고, 언어 구문 강조를 위해 Shiki를 사용합니다. 이 옵션 내에서 다양한 마크다운 관련 옵션을 전달하여 필요에 맞게 조정할 수 있습니다.
export default {
markdown: {...}
}사용 가능한 모든 옵션에 대해서는 타입 선언 및 jsdocs를 참고하세요.
vite
- 타입:
import('vite').UserConfig
내부 Vite 개발 서버/번들러에 직접 Vite 구성을 전달합니다.
export default {
vite: {
// Vite 구성 옵션
}
}vue
- 타입:
import('@vitejs/plugin-vue').Options
내부 플러그인 인스턴스에 직접 @vitejs/plugin-vue 옵션을 전달합니다.
export default {
vue: {
// @vitejs/plugin-vue 옵션
}
}빌드 훅
VitePress 빌드 훅은 웹사이트에 새로운 기능과 동작을 추가할 수 있게 합니다:
- 사이트맵
- 검색 인덱싱
- PWA
- 텔레포트
buildEnd
- 타입:
(siteConfig: SiteConfig) => Awaitable<void>
buildEnd는 빌드 CLI 훅으로, 빌드(SSG)가 완료된 후 VitePress CLI 프로세스가 종료되기 전에 실행됩니다.
export default {
async buildEnd(siteConfig) {
// ...
}
}postRender
- 타입:
(context: SSGContext) => Awaitable<SSGContext | void>
postRender는 빌드 훅으로, SSG 렌더링이 완료되었을 때 호출됩니다. 이를 통해 SSG 동안 텔레포트 콘텐츠를 핸들링 할 수 있습니다.
export default {
async postRender(context) {
// ...
}
}interface SSGContext {
content: string
teleports?: Record<string, string>
[key: string]: any
}transformHead
- 타입:
(context: TransformContext) => Awaitable<HeadConfig[]>
transformHead는 각 페이지를 생성하기 전에 헤드를 변환하는 빌드 훅입니다. VitePress 구성에 정적으로 추가할 수 없는 헤드 항목을 추가할 수 있습니다. 기존 항목과 자동으로 병합되므로 추가 항목만 반환하면 됩니다.
WARNING
context 내부의 어떤 것도 변경하지 마세요.
export default {
async transformHead(context) {
// ...
}
}interface TransformContext {
page: string // 예: index.md (srcDir에 상대적)
assets: string[] // js/css가 아닌 모든 에셋을 완전히 처리된 public URL로 표시.
siteConfig: SiteConfig
siteData: SiteData
pageData: PageData
title: string
description: string
head: HeadConfig[]
content: string
}이 훅은 사이트를 정적으로 생성할 때만 호출됩니다. 개발 중에는 호출되지 않습니다. 개발 중에 동적 헤드 항목을 추가해야 하는 경우, transformPageData 훅을 대신 사용할 수 있습니다:
export default {
transformPageData(pageData) {
pageData.frontmatter.head ??= []
pageData.frontmatter.head.push([
'meta',
{
name: 'og:title',
content:
pageData.frontmatter.layout === 'home'
? `VitePress`
: `${pageData.title} | VitePress`
}
])
}
}예제: 표준 URL <link> 추가
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 }
])
}
}transformHtml
- 타입:
(code: string, id: string, context: TransformContext) => Awaitable<string | void>
transformHtml은 각 페이지의 내용을 디스크에 저장하기 전에 변환하는 빌드 훅입니다.
WARNING
context 내부의 어떤 것도 변경하지 마세요. HTML 내용을 수정하면 런타임에 하이드레이션 문제가 발생할 수 있습니다.
export default {
async transformHtml(code, id, context) {
// ...
}
}transformPageData
- 타입:
(pageData: PageData, context: TransformPageContext) => Awaitable<Partial<PageData> | { [key: string]: any } | void>
transformPageData는 각 페이지의 pageData를 변환하는 훅입니다. pageData를 직접 변경하거나, 변경된 값을 반환하여 페이지 데이터에 병합할 수 있습니다.
WARNING
context 내부의 어떤 것도 변경하지 마세요. 이 훅에서 네트워크 요청이나 이미지 생성과 같은 무거운 연산이 있을 경우 개발 서버의 성능에 영향을 줄 수 있으니 주의하세요. 조건부 로직을 위해 process.env.NODE_ENV === 'production'을 확인할 수 있습니다.
export default {
async transformPageData(pageData, { siteConfig }) {
pageData.contributors = await getPageContributors(pageData.relativePath)
}
// 또는 병합할 데이터 반환
async transformPageData(pageData, { siteConfig }) {
return {
contributors: await getPageContributors(pageData.relativePath)
}
}
}interface TransformPageContext {
siteConfig: SiteConfig
}