기본 내보내기는 사용자 정의 테마에 대한 유일한 계약이며, `Layout` 속성만 필수입니다. 기술적으로, VitePress 테마는 단일 Vue 컴포넌트만큼 간단할 수 있습니다.
"export default"는 커스텀 테마를 설정하는 유일한 방법이며, `Layout` 프로퍼티만 필수입니다. 따라서 기술적으로 VitePress 테마는 단일 Vue 컴포넌트처럼 간단할 수 있습니다.
레이아웃 컴포넌트 내부에서는 평소처럼 Vite + Vue 3 애플리케이션처럼 작동합니다. 테마도 [SSR-호환성이](./ssr-compat) 있어야 합니다.
레이아웃 컴포넌트 내부에서는 일반적인 Vite + Vue 3 애플리케이션처럼 동작합니다. 또한 테마가 [SSR 호환](./ssr-compat)이 되어야 합니다.
## 레이아웃 만들기 {#building-a-layout}
## 레이아웃 만들기 {#building-a-layout}
가장 기본적인 레이아웃 컴포넌트는 [`<Content />`](../reference/runtime-api#content) 컴포넌트를 포함해야 합니다:
가장 기본적인 레이아웃 컴포넌트는 [`<Content />`](../reference/runtime-api#content) 컴포넌트가 포함되어야 합니다:
```vue
```vue
<!-- .vitepress/theme/Layout.vue -->
<!-- .vitepress/theme/Layout.vue -->
<template>
<template>
<h1>사용자 정의 레이아웃!</h1>
<h1>Custom Layout!</h1>
<!-- 마크다운 내용이 여기에 렌더링됩니다 -->
<!-- 마크다운 내용은 여기에 렌더링됩니다 -->
<Content/>
<Content/>
</template>
</template>
```
```
위의 레이아웃은 각 페이지의 마크다운을 HTML로 단순히 렌더링합니다. 우리가 추가할 수 있는 첫 번째 개선 사항은 404 오류를 처리하는 것입니다:
위의 레이아웃은 각 페이지의 마크다운을 HTML로 렌더링합니다. 첫 번째로 개선 사항은 404 에러를 처리하는 것입니다:
```vue{1-4,9-12}
```vue{1-4,9-12}
<scriptsetup>
<scriptsetup>
@ -91,16 +91,16 @@ const { page } = useData()
</script>
</script>
<template>
<template>
<h1>사용자 정의 레이아웃!</h1>
<h1>Custom Layout!</h1>
<divv-if="page.isNotFound">
<divv-if="page.isNotFound">
사용자 정의 404 페이지!
Custom 404 page!
</div>
</div>
<Contentv-else/>
<Contentv-else/>
</template>
</template>
```
```
[`useData()`](../reference/runtime-api#usedata) 헬퍼는 우리가 필요로 하는 모든 런타임 데이터를 제공하여, 다른 레이아웃을 조건부로 렌더링할 수 있습니다. 우리가 접근할 수 있는 또 다른 데이터는 현재 페이지의 프론트매터입니다. 이를 활용하여 사용자가 각 페이지의 레이아웃을 제어할 수 있도록 합니다. 예를 들어, 사용자는 특별한 홈페이지 레이아웃을 사용해야 한다고 지정할 수 있습니다:
[`useData()`](../reference/runtime-api#usedata) 헬퍼는 다양한 레이아웃을 조건부로 렌더링하는 데 필요한 모든 런타임 데이터를 제공합니다. 접근할 수 있는 다른 데이터 중 하나는 현재 페이지의 전문(front-matter)입니다. 이를 활용하여 각 페이지에 맞게 레이아웃을 제어할 수 있습니다. 예를 들어 특정 페이지에서 홈 페이지 레이아웃을 사용하도록 지정할 수 있습니다:
테마 컴포넌트에서 사용할 수 있는 모든 것에 대한 [런타임 API 참조](../reference/runtime-api)를 참조하세요. 또한, [빌드할 때 데이터 로딩](./data-loading)을 활용하여 데이터 기반 레이아웃을 생성할 수 있습니다 - 예를 들어, 현재 프로젝트 내 모든 블로그 포스트를 나열하는 페이지 등.
테마 컴포넌트에서 사용할 수 있는 모든 항목에 대해서는 [런타임 API 레퍼런스](../reference/runtime-api)를 참고하세요. 또한 [빌드할 때 데이터 로딩하기](./data-loading)를 활용하여 데이터 기반의 레이아웃을 생성할 수 있습니다. 예를 들어 현재 프로젝트의 모든 블로그 게시물을 나열하는 페이지를 만들 수 있습니다.
## 사용자 정의 테마 배포하기 {#distributing-a-custom-theme}
## 사용자 정의 테마 배포하기 {#distributing-a-custom-theme}
사용자 정의 테마를 배포하는 가장 쉬운 방법은 [GitHub에서 템플릿 저장소로 제공하는 것입니다](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository).
커스텀 테마를 배포하는 가장 쉬운 방법은 [GitHub 템플릿 리포지토리](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository)로 제공하는 것입니다.
npm 패키지로 테마를 배포하려면 다음 단계를 따르세요:
테마를 npm 패키지로 배포하려면 다음 단계를 따라야 합니다:
1. 패키지 엔트리에서 테마 객체를 기본 내보내기로 내보냅니다.
1. 패키지 엔트리에서 테마 객체를 "export default" 합니다.
2. 적용된다면, 테마 설정 타입 정의를 `ThemeConfig`로 내보냅니다.
2. 해당되는 경우, 테마 구성 타입 정의를 `ThemeConfig`로 "export" 합니다.
3. 테마가 VitePress 설정을 조정해야 하는 경우, 사용자가 확장할 수 있도록 패키지 하위 경로(예: `my-theme/config`)에 해당 설정을 내보냅니다.
3. 테마에서 VitePress 구성을 조정해야 하는 경우, 사용자가 확장할 수 있도록 패키지 하위 경로(예: `my-theme/config`)에 해당 구성을 "export" 합니다.
4. 설정 파일 및 프론트매터를 통한 테마 설정 옵션을 문서화합니다.
4. 테마 구성 옵션을 문서화합니다 (구성 파일과 전문 둘 다).
5. 테마를 소비하는 방법에 대한 명확한 지침을 제공합니다(아래 참조).
5. 테마를 사용하는 방법에 대한 명확한 지침을 제공합니다(아래 참조).
## 사용자 정의 테마 소비하기 {#consuming-a-custom-theme}
## 커스텀 테마 사용하기 {#consuming-a-custom-theme}
외부 테마를 소비하려면 사용자 정의 테마 엔트리에서 가져와서 다시 내보냅니다:
외부 테마를 사용하려면, 커스텀 테마 엔트리에서 테마를 "import" 후 다시 "export"합니다:
```js
```js
// .vitepress/theme/index.js
// .vitepress/theme/index.js
@ -193,19 +193,19 @@ export default {
}
}
```
```
테마가 특별한 VitePress 설정을 요구하는 경우, 자신의 설정에서도 그 설정을 확장해야 합니다:
테마가 특별한 VitePress 구성을 요구하는 경우, 해당 구성을 (외부 커스텀 테마를 사용하는 자신의) 구성 파일에서도 확장해야 합니다:
```ts
```ts
// .vitepress/config.ts
// .vitepress/config.ts
import baseConfig from 'awesome-vitepress-theme/config'
import baseConfig from 'awesome-vitepress-theme/config'
VitePress는 **데이터 로더**라고 불리는 기능을 제공하여 임의의 데이터를 로드하고 페이지나 컴포넌트에서 가져올 수 있습니다. 데이터 로딩은 **빌드 시간에만 실행**됩니다: 결과적으로 생성된 데이터는 최종 자바스크립트 번들에 JSON으로 직렬화됩니다.
VitePress는 페이지나 컴포넌트에서 임의의 데이터를 로드하고 이를 가져올 수 있는 **데이터 로더** 기능을 제공합니다. 데이터 로딩은 **빌드할 때에만** 실행되며, 결과적으로 생성된 데이터는 최종 JavaScript 번들에 JSON으로 직렬화됩니다.
데이터 로더는 원격 데이터를 가져오거나 로컬 파일을 기반으로 메타데이터를 생성하는 데 사용할 수 있습니다. 예를 들어, 모든 로컬 API 페이지를 파싱하고 모든 API 항목의 색인을 자동으로 생성하기 위해 데이터 로더를 사용할 수 있습니다.
데이터 로더는 원격 데이터를 가져오거나 로컬 파일을 기반으로 메타데이터를 생성하는 데 사용할 수 있습니다. 예를 들어, 데이터 로더를 사용하여 모든 로컬 API 페이지를 파싱하고 모든 API 항목의 색인을 자동으로 생성할 수 있습니다.
## 기본 사용법 {#basic-usage}
## 기본 사용법 {#basic-usage}
데이터 로더 파일은 `.data.js` 또는 `.data.ts`로 끝나야 합니다. 이 파일은 `load()` 메서드를 가진 객체를 기본 내보내기해야 합니다:
데이터 로더 파일은 반드시 `.data.js` 또는 `.data.ts`로 끝나야 합니다. 이 파일은 `load()` 메서드를 가진 객체를 "export default" 해야 합니다:
```js
```js
// example.data.js
// example.data.js
@ -19,9 +19,9 @@ export default {
}
}
```
```
로더 모듈은 Node.js에서만 평가되므로, 필요에 따라 Node API와 npm 종속성을 가져올 수 있습니다.
로더 모듈은 Node.js에서만 평가되므로, 필요한 경우 Node API와 npm 종속성을 "import" 할 수 있습니다.
이 파일에서 데이터를 `.md` 페이지와 `.vue` 컴포넌트에서 `data`라는 이름으로 내보낼 수 있습니다:
그런 다음 `.md` 페이지와 `.vue` 컴포넌트에서 `data`라는 이름으로 "export" 한 데이터를 이 파일에서 "import" 할 수 있습니다:
```vue
```vue
<scriptsetup>
<scriptsetup>
@ -39,9 +39,9 @@ import { data } from './example.data.js'
}
}
```
```
데이터 로더 자체가 `data`를 내보내지 않는 것을 알 수 있습니다. 이는 VitePress가 내부에서 `load()` 메서드를 호출하고 `data`라는 이름으로 결과를 암시적으로 노출한다는 것을 의미합니다.
데이터 로더 자체가 `data`를 "export" 하지 않는다는 점에 주목하십시오. VitePress가 백그라운드에서 `load()` 메서드를 호출하고 결과를 암묵적으로 `data`라는 이름으로 "export" 하기 때문입니다.
로더가 비동기인 경우에도 작동합니다:
이 방법은 로더가 비동기적이어도 작동합니다:
```js
```js
export default {
export default {
@ -54,11 +54,11 @@ export default {
## 로컬 파일에서 데이터 가져오기 {#data-from-local-files}
## 로컬 파일에서 데이터 가져오기 {#data-from-local-files}
로컬 파일을 기반으로 데이터를 생성해야 할 때는 데이터 로더에서 `watch` 옵션을 사용해야 합니다. 그래야 해당 파일에 변경 사항이 발생했을 때 핫 업데이트를 트리거할 수 있습니다.
로컬 파일을 기반으로 데이터를 생성해야 할 때는 데이터 로더에서 `watch` 옵션을 사용해야 합니다. 이 옵션을 사용하면 이러한 파일에 변경이 있을 때 핫 업데이트를 트리거할 수 있습니다.
`watch` 옵션은 또한 여러 파일을 일치시키기 위해 [글로브 패턴](https://github.com/mrmlnc/fast-glob#pattern-syntax)을 사용할 수 있어 편리합니다. 패턴은 로더 파일 자체에 상대적이며, `load()` 함수는 일치한 파일을 절대 경로로 받습니다.
`watch` 옵션은 또한 여러 파일을 매칭하는 [glob 패턴](https://github.com/mrmlnc/fast-glob#pattern-syntax)을 사용할 수 있어서 편리합니다. 패턴은 로더 파일 자체에 상대적일 수 있으며, `load()` 함수는 매칭된 파일을 절대 경로로 받게 됩니다.
다음 예제는 [csv-parse](https://github.com/adaltas/node-csv/tree/master/packages/csv-parse/)를 사용하여 CSV 파일을 불러오고 JSON으로 변환하는 방법을 보여줍니다. 이 파일은 빌드 시간에만 실행되므로, CSV 파서를 클라이언트에 전송하지 않을 것입니다!
다음 예제는 CSV 파일을 로드하고 이를 [csv-parse](https://github.com/adaltas/node-csv/tree/master/packages/csv-parse/)를 사용하여 JSON으로 변환하는 방법을 보여줍니다. 이 파일은 빌드할 때에만 실행되므로 CSV 파서를 클라이언트로 전송하지 않습니다!
```js
```js
import fs from 'node:fs'
import fs from 'node:fs'
@ -67,9 +67,9 @@ import { parse } from 'csv-parse/sync'
export default {
export default {
watch: ['./data/*.csv'],
watch: ['./data/*.csv'],
load(watchedFiles) {
load(watchedFiles) {
// watchedFiles는 일치하는 파일의 절대 경로 배열이 될 것입니다.
// watchedFiles는 매칭된 파일의 절대 경로 배열 입니다.
// 블로그 포스트 메타데이터의 배열을 생성하여
// 테마 레이아웃에서 목록을 렌더링하는 데 사용할 수 있는
// 테마 레이아웃에서 목록을 렌더링하는 데 사용할 수 있습니다
// 블로그 포스트 메타데이터 배열을 생성합니다.
return watchedFiles.map((file) => {
return watchedFiles.map((file) => {
return parse(fs.readFileSync(file, 'utf-8'), {
return parse(fs.readFileSync(file, 'utf-8'), {
columns: true,
columns: true,
@ -82,38 +82,38 @@ export default {
## `createContentLoader`
## `createContentLoader`
콘텐츠 중심 사이트를 구축할 때, 우리는 종종 "아카이브" 또는 "인덱스" 페이지를 만들 필요가 있습니다: 우리 콘텐츠 컬렉션에서 사용 가능한 모든 항목을 나열하는 페이지, 예를 들어 블로그 게시물이나 API 페이지의 경우입니다. 데이터 로더 API를 직접 사용하여 이를 구현할 **수 있지만**, 이는 흔한 사용 사례이므로 VitePress는 이를 단순화하기 위해 `createContentLoader` 헬퍼를 제공합니다:
콘텐츠가 많은 사이트를 구축할 때, 종종 "아카이브" 또는 "인덱스" 페이지를 만들어야 합니다. 이 페이지는 콘텐츠 모음에 있는 모든 항목(예: 블로그 게시물, API 페이지)을 나열하는 페이지입니다. 데이터 로더 API를 직접 사용하여 이를 구현할 수 있지만, VitePress는 이러한 일반적인 사용 사례를 간소화하기 위해 `createContentLoader` 헬퍼를 제공합니다:
헬퍼는 [소스 디렉토리](./routing#source-directory)에 상대적인 글로브 패턴을 취하며, 기본 내보내기로 사용할 수 있는 `{ watch, load }` 데이터 로더 객체를 반환합니다. 이는 또한 파일 수정 타임스탬프를 기반으로 캐싱을 구현하여 개발 성능을 향상시킵니다.
이 헬퍼는 [소스 디렉터리](./routing#source-directory)를 기준으로 glob 패턴을 허용하고 데이터 로드 파일에서 "default export"로 사용할 수 있는 `{ watch, load }` 데이터 로더 객체를 반환합니다. 또한 파일 수정 타임스탬프를 기반으로 캐싱을 구현하여 개발 성능을 향상시킵니다.
VitePress의 기본 테마는 문서화에 최적화되어 있으며, 커스터마이징이 가능합니다. [기본 테마 구성 개요](../reference/default-theme-config)를 참조하여 가능한 옵션의 전체 목록을 확인하세요.
VitePress의 기본 테마는 문서화에 최적화되어 있으며, 커스텀할 수 있습니다. 포괄적인 옵션 목록은 [기본 테마 구성](../reference/default-theme-config)을 참고하세요.
그러나 설정만으로는 충분하지 않은 경우가 여러 번 있을 수 있습니다. 예를 들면:
그러나 구성만으로는 충분하지 않을 수 있습니다. 예를 들어:
1. CSS 스타일링을 조정해야 할 때;
1. CSS 스타일링을 조정해야 하는 경우.
2. 전역 컴포넌트 등록과 같이 Vue 앱 인스턴스를 수정해야 할 때;
2. 전역 컴포넌트를 등록하기 위해 Vue 애플리케이션 인스턴스를 수정해야 하는 경우.
3. 레이아웃 슬롯을 통해 테마에 사용자 정의 컨텐츠를 삽입해야 할 때.
3. 레이아웃 슬롯을 통해 테마에 커스텀 컨텐츠를 삽입해야 하는 경우.
이러한 고급 커스터마이징은 기본 테마를 "확장하는" 사용자 지정 테마를 사용해야 합니다.
이러한 고급 커스터마이징은 기본 테마를 "확장"하는 커스텀 테마 사용이 필요 합니다.
::: tip
::: tip
진행하기 전에, 사용자 지정 테마가 어떻게 작동하는지 이해하기 위해 [사용자 지정 테마 사용하기](./custom-theme)를 먼저 읽어보세요.
진행하기 전에, 커스텀 테마가 어떻게 작동하는지 이해하려면 먼저 [커스텀 테마 사용하기](./custom-theme)를 읽어보세요.
:::
:::
## CSS 커스터마이징하기 {#customizing-css}
## CSS 커스터마이징하기 {#customizing-css}
기본 테마의 CSS는 루트 레벨 CSS 변수를 오버라이딩하여 커스터마이즈 할 수 있습니다:
기본 테마의 CSS는 루트 레벨의 CSS 변수를 재정의하여 커스터마이징 할 수 있습니다:
```js
```js
// .vitepress/theme/index.js
// .vitepress/theme/index.js
@ -38,13 +38,13 @@ export default DefaultTheme
}
}
```
```
오버라이딩할 수 있는 [기본 테마 CSS 변수](https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css)를 확인하세요.
재정의할 수 있는 기본 테마 CSS 변수는 [여기](https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css)를 참고하세요.
## 다른 폰트 사용하기 {#using-different-fonts}
## 다른 폰트 사용하기 {#using-different-fonts}
VitePress는 기본 폰트로 [Inter](https://rsms.me/inter/)를 사용하며, 빌드 출력물에 폰트를 포함합니다. 또한, 이 폰트는 프로덕션 환경에서 자동으로 프리로드됩니다. 하지만, 다른 메인 폰트를 사용하고 싶은 경우에는 바람직하지 않을 수 있습니다.
VitePress는 기본 폰트로 [Inter](https://rsms.me/inter/)를 사용하며, 빌드 결과물에 폰트를 포함시킵니다. 폰트는 프로덕션 환경에서 자동으로 미리 로드되지만, 다른 메인 폰트를 사용하고자 할 경우 이는 바람직하지 않을 수 있습니다.
빌드 출력물에서 Inter를 포함하지 않으려면, 대신 `vitepress/theme-without-fonts`에서 테마를 임포트하세요:
[팀 페이지](../reference/default-theme-team-page)와 같은 선택적 컴포넌트를 사용하는 경우, 이들도 `vitepress/theme-without-fonts`에서 가져와야 합니다!
선택적 컴포넌트인 [팀 페이지](../reference/default-theme-team-page) 등을 사용하는 경우, 반드시 이들도 `vitepress/theme-without-fonts`에서 "import" 해야 합니다!
:::
:::
폰트가 `@font-face`를 통해 참조된 로컬 파일이라면, 자산으로 처리되어 해시된 파일명과 함께 `.vitepress/dist/assets` 아래에 포함될 것입니다. 이 파일을 프리로드하려면, [transformHead](../reference/site-config#transformhead) 빌드 훅을 사용하세요:
폰트가 `@font-face`를 통해 참조된 로컬 파일인 경우, 에셋으로 처리되어 해시된 파일 이름으로 `.vitepress/dist/assets`에 포함됩니다. 이 파일을 미리 로드하려면 [transformHead](../reference/site-config#transformhead) 빌드 훅을 사용해야 합니다:
```js
```js
// .vitepress/config.js
// .vitepress/config.js
@ -102,7 +102,7 @@ import DefaultTheme from 'vitepress/theme'
export default {
export default {
extends: DefaultTheme,
extends: DefaultTheme,
enhanceApp({ app }) {
enhanceApp({ app }) {
// 사용자 지정 전역 컴포넌트를 등록하세요
// 커스텀 전역 컴포넌트 등록
app.component('MyGlobalComponent' /* ... */)
app.component('MyGlobalComponent' /* ... */)
}
}
}
}
@ -117,17 +117,17 @@ import DefaultTheme from 'vitepress/theme'
export default {
export default {
extends: DefaultTheme,
extends: DefaultTheme,
enhanceApp({ app }) {
enhanceApp({ app }) {
// 사용자 지정 전역 컴포넌트를 등록하세요
// 커스텀 전역 컴포넌트 등록
app.component('MyGlobalComponent' /* ... */)
app.component('MyGlobalComponent' /* ... */)
}
}
} satisfies Theme
} satisfies Theme
```
```
Vite를 사용하기 때문에, Vite의 [글로브 임포트 기능](https://vitejs.dev/ko/guide/features.html#glob-import)을 활용하여 컴포넌트 디렉터리를 자동으로 등록할 수도 있습니다.
Vite를 사용하므로, Vite의 [glob import 기능](https://vitejs.dev/guide/features.html#glob-import)을 활용하여 컴포넌트 디렉터리를 자동으로 등록할 수 있습니다.
## 레이아웃 슬롯 {#layout-slots}
## 레이아웃 슬롯 {#layout-slots}
기본 테마의 `<Layout/>` 컴포넌트는 페이지의 특정 위치에 컨텐츠를 삽입할 수 있도록 몇 개의 슬롯을 제공합니다. 아웃라인 앞에 컴포넌트를 삽입하는 예시입니다:
기본 테마의 `<Layout/>` 컴포넌트는 페이지의 특정 위치에 컨텐츠를 삽입할 수 있는 몇 가지 슬롯을 가지고 있습니다. 다음은 아웃라인 앞에 컴포넌트를 삽입하는 예제입니다:
```js
```js
// .vitepress/theme/index.js
// .vitepress/theme/index.js
@ -137,7 +137,7 @@ import MyLayout from './MyLayout.vue'
뷰 전환에 대한 자세한 정보는 [Chrome 문서](https://developer.chrome.com/docs/web-platform/view-transitions/)를 참고하세요.
뷰 트랜지션에 대한 자세한 정보는 [크롬 문서](https://developer.chrome.com/docs/web-platform/view-transitions/)를 참고하세요.
### 라우트 변경 시 {#on-route-change}
### 라우트 변경 시 {#on-route-change}
곧 제공될 예정입니다.
곧 제공될 예정입니다.
## 내부 컴포넌트 오버라이딩하기 {#overriding-internal-components}
## 내부 컴포넌트 재정의하기 {#overriding-internal-components}
Vite의 [별칭](https://vitejs.dev/config/shared-options.html#resolve-alias)을 사용하여 기본 테마 컴포넌트를 사용자 지정 컴포넌트로 대체할 수 있습니다:
Vite의 [별칭](https://vitejs.dev/config/shared-options.html#resolve-alias)을 사용하여 기본 테마 컴포넌트를 커스텀 컴포넌트로 대체할 수 있습니다:
```ts
```ts
import { fileURLToPath, URL } from 'node:url'
import { fileURLToPath, URL } from 'node:url'
@ -338,4 +338,4 @@ export default defineConfig({
})
})
```
```
컴포넌트의 정확한 이름을 알고 싶다면 [저희 소스 코드](https://github.com/vuejs/vitepress/tree/main/src/client/theme-default/components)를 참조하세요. 컴포넌트가 내부적으로 사용되기 때문에, 소규모 릴리스 사이에 이름이 업데이트될 수 있습니다.
컴포넌트의 정확한 이름을 알고 싶다면 [Vitepress 소스 코드](https://github.com/vuejs/vitepress/tree/main/src/client/theme-default/components)를 참고하세요. 컴포넌트는 내부적으로 사용되기 때문에, 마이너 릴리즈 사이에 이름이 변경될 가능성이 있습니다.
VitePress는 Vue의 서버 사이드 렌더링(SSR) 기능을 사용하여 프로덕션 빌드 중에 Node.js에서 앱을 사전 렌더링합니다. 이는 테마 컴포넌트의 모든 사용자 정의 코드가 SSR 호환성을 준수해야 함을 의미합니다.
VitePress는 Vue의 서버 사이드 렌더링(SSR) 기능을 사용하여 프로덕션 빌드 중에 Node.js에서 애플리케이션을 사전 렌더링합니다. 이는 테마 컴포넌트의 모든 커스텀 코드가 SSR 호환성을 준수해야 함을 의미합니다.
[공식 Vue 문서의 SSR 섹션](https://vuejs.org/guide/scaling-up/ssr.html)은 SSR이 무엇인지, SSR/SSG 간의 관계 및 SSR 친화적인 코드 작성에 대한 일반적인 참고 사항에 대한 더 많은 컨텍스트를 제공합니다. 핵심 원칙은 브라우저/DOM API에는 Vue 컴포넌트의 `beforeMount` 또는 `mounted` 후크에서만 접근해야 합니다.
공식 Vue 문서의 [SSR 섹션](https://vuejs.org/guide/scaling-up/ssr.html)은 SSR이 무엇인지, SSR / SSG 간의 관계, 그리고 SSR 친화적인 코드를 작성할 때의 일반적인 주의 사항에 대해 더 많은 정보를 제공합니다. 핵심 원칙은 Vue 컴포넌트의 `beforeMount` 또는 `mounted` 훅에서만 브라우저 / DOM API에 접근하는 것입니다.
## `<ClientOnly>`
## `<ClientOnly>`
SSR 친화적이지 않은 컴포넌트(예: 사용자 정의 지시문이 포함된 경우)를 사용하거나 시연하는 경우, 내장된 `<ClientOnly>` 컴포넌트 내부에 이를 래핑할 수 있습니다:
SSR 친화적이지 않은 컴포넌트(예: 커스텀 디렉티브를 포함한 컴포넌트)를 사용하거나 시연하는 경우, 내장된 `<ClientOnly>` 컴포넌트로 해당 컴포넌트를 래핑할 수 있습니다:
```md
```md
<ClientOnly>
<ClientOnly>
@ -18,11 +18,11 @@ SSR 친화적이지 않은 컴포넌트(예: 사용자 정의 지시문이 포
</ClientOnly>
</ClientOnly>
```
```
## 가져오기 시 브라우저 API에 접근하는 라이브러리 {#libraries-that-access-browser-api-on-import}
## "import" 시 브라우저 API에 접근하는 라이브러리 {#libraries-that-access-browser-api-on-import}
일부 컴포넌트나 라이브러리는 **가져오기 시**에 브라우저 API에 접근합니다. 가져오기를 통해 브라우저 환경을 가정하는 코드를 사용하려면 동적으로 이를 가져와야 합니다.
일부 컴포넌트나 라이브러리는 **"import" 시** 브라우저 API에 접근합니다. "import" 시 브라우저 환경을 가정하는 코드를 사용하려면, 동적 "import"를 사용해야 합니다.