pull/5477/merge
Intense 4 days ago committed by GitHub
commit 237fde80e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -10,6 +10,7 @@ import {
} from 'vitepress-plugin-group-icons' } from 'vitepress-plugin-group-icons'
import llmstxt from 'vitepress-plugin-llms' import llmstxt from 'vitepress-plugin-llms'
import { markdown as deMarkdown } from '../de/config.ts'
import { markdown as esMarkdown } from '../es/config.ts' import { markdown as esMarkdown } from '../es/config.ts'
import { markdown as faMarkdown } from '../fa/config.ts' import { markdown as faMarkdown } from '../fa/config.ts'
import { markdown as jaMarkdown } from '../ja/config.ts' import { markdown as jaMarkdown } from '../ja/config.ts'
@ -31,7 +32,8 @@ const localeToOgLocaleMap: Record<string, string> = {
es: 'es_ES', es: 'es_ES',
ko: 'ko_KR', ko: 'ko_KR',
fa: 'fa_IR', fa: 'fa_IR',
ja: 'ja_JP' ja: 'ja_JP',
de: 'de_DE'
} }
export default defineConfig({ export default defineConfig({
@ -103,6 +105,7 @@ export default defineConfig({
// prettier-ignore // prettier-ignore
locales: { locales: {
root: { label: 'English', lang: 'en-US', dir: 'ltr' }, root: { label: 'English', lang: 'en-US', dir: 'ltr' },
de: { label: 'Deutsch', lang:'de-DE', dir: 'ltr', markdown: deMarkdown },
zh: { label: '简体中文', lang: 'zh-Hans', dir: 'ltr', markdown: zhMarkdown }, zh: { label: '简体中文', lang: 'zh-Hans', dir: 'ltr', markdown: zhMarkdown },
pt: { label: 'Português', lang: 'pt-BR', dir: 'ltr', markdown: ptMarkdown }, pt: { label: 'Português', lang: 'pt-BR', dir: 'ltr', markdown: ptMarkdown },
ru: { label: 'Русский', lang: 'ru-RU', dir: 'ltr', markdown: ruMarkdown }, ru: { label: 'Русский', lang: 'ru-RU', dir: 'ltr', markdown: ruMarkdown },

@ -0,0 +1,347 @@
import {
defineAdditionalConfig,
type DefaultTheme,
type MarkdownLocaleOptions
} from 'vitepress'
import pkg from 'vitepress/package.json' with { type: 'json' }
export const markdown: MarkdownLocaleOptions = {
container: {
tipLabel: 'TIPP',
infoLabel: 'INFO',
warningLabel: 'WARNUNG',
dangerLabel: 'GEFAHR',
detailsLabel: 'DETAILS',
noteLabel: 'NOTIZ',
importantLabel: 'WICHTIG',
cautionLabel: 'VORSICHT'
},
codeCopyButton: {
tooltipText: 'Code kopieren',
copiedText: 'Kopiert'
}
}
export default defineAdditionalConfig({
description: 'Static-Site-Generator mit Vue und Vite',
head: [
[
'link',
// für die in .vitepress/theme/styles.css definierte Vazirmatn-Schrift
{ rel: 'preconnect', href: 'https://cdn.jsdelivr.net', crossorigin: '' }
]
],
themeConfig: {
nav: nav(),
search: { options: searchOptions() },
sidebar: {
'/de/guide/': { base: '/de/guide/', items: sidebarAnleitung() },
'/de/reference/': { base: '/de/reference/', items: sidebarReference() }
},
editLink: {
pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path',
text: 'Diese Seite auf GitHub bearbeiten'
},
footer: {
message: 'Veröffentlicht unter der MIT-Lizenz',
copyright: 'Copyright © 2019-heute Evan You'
},
docFooter: {
prev: 'Zurück',
next: 'Weiter'
},
outline: {
label: 'Auf dieser Seite'
},
lastUpdated: {
text: 'Zuletzt aktualisiert'
},
notFound: {
title: 'Seite nicht gefunden',
quote:
'Doch wenn du deine Richtung nicht änderst und weiter in diese Richtung blickst, könntest du tatsächlich dort landen, worauf du zusteuerst.',
linkLabel: 'Zur Startseite',
linkText: 'Bring mich zur Startseite'
},
langMenuLabel: 'Sprache ändern',
returnToTopLabel: 'Nach oben',
sidebarMenuLabel: 'Seitenleiste',
darkModeSwitchLabel: 'Dunkelmodus',
lightModeSwitchTitle: 'Zum Hellmodus wechseln',
darkModeSwitchTitle: 'Zum Dunkelmodus wechseln',
siteTitle: 'VitePress'
}
})
function nav(): DefaultTheme.NavItem[] {
return [
{
text: 'Anleitung',
link: 'de/guide/what-is-vitepress',
activeMatch: '/guide/'
},
{
text: 'Referenz',
link: 'de/reference/site-config',
activeMatch: '/reference/'
},
{
text: pkg.version,
items: [
{
text: '1.6.4',
link: 'https://vuejs.github.io/vitepress/v1/fa/'
},
{
text: 'Änderungen',
link: 'https://github.com/vuejs/vitepress/blob/main/CHANGELOG.md'
},
{
text: 'Mitwirken',
link: 'https://github.com/vuejs/vitepress/blob/main/.github/contributing.md'
}
]
}
]
}
function sidebarAnleitung(): DefaultTheme.SidebarItem[] {
return [
{
text: 'Einführung',
collapsed: false,
items: [
{ text: 'Was ist VitePress?', link: 'what-is-vitepress' },
{ text: 'Erste Schritte', link: 'getting-started' },
{ text: 'Routing', link: 'routing' },
{ text: 'Bereitstellung', link: 'deploy' }
]
},
{
text: 'Schreiben',
collapsed: false,
items: [
{ text: 'Markdown Erweiterungen', link: 'markdown' },
{ text: 'Asset-Handhabung', link: 'asset-handling' },
{ text: 'Frontmatter', link: 'frontmatter' },
{ text: 'Vue in Markdown benutzen', link: 'using-vue' },
{ text: 'Internationalisierung', link: 'i18n' }
]
},
{
text: 'Anpassung',
collapsed: false,
items: [
{ text: 'Ein eigenes Theme nutzen', link: 'custom-theme' },
{
text: 'Standard-Theme erweitern',
link: 'extending-default-theme'
},
{ text: 'Daten laden', link: 'data-loading' },
{ text: 'SSR-Kompatibilität', link: 'ssr-compat' },
{ text: 'Mit einem CMS verbinden', link: 'cms' }
]
},
{
text: 'Experimentell',
collapsed: false,
items: [
{ text: 'MPA-Modus', link: 'mpa-mode' },
{ text: 'Sitemap-Generation', link: 'sitemap-generation' }
]
},
{ text: 'Konfiguration und API-Referenz', base: 'de/reference/', link: 'site-config' }
]
}
function sidebarReference(): DefaultTheme.SidebarItem[] {
return [
{
text: 'Referenz',
base: 'de/reference/',
items: [
{ text: 'Seiten-Konfiguration', link: 'site-config' },
{ text: 'Frontmatter-Konfiguration', link: 'frontmatter-config' },
{ text: 'Runtime-API', link: 'runtime-api' },
{ text: 'CLI', link: 'cli' },
{
text: 'Standard-Theme',
base: 'de/reference/default-theme-',
items: [
{ text: 'Übersicht', link: 'config' },
{ text: 'Navigation', link: 'nav' },
{ text: 'Seitenleiste', link: 'sidebar' },
{ text: 'Startseite', link: 'home-page' },
{ text: 'Fußzeile', link: 'footer' },
{ text: 'Layout', link: 'layout' },
{ text: 'Badge', link: 'badge' },
{ text: 'Team-Seite', link: 'team-page' },
{ text: 'Vorher / Nachher Links', link: 'prev-next-links' },
{ text: 'Link bearbeiten', link: 'edit-link' },
{ text: 'Zuletzt aktualisiert Zeitstempel', link: 'last-updated' },
{ text: 'Suche', link: 'search' },
{ text: 'Carbon Ads', link: 'carbon-ads' }
]
}
]
}
]
}
function searchOptions(): Partial<DefaultTheme.AlgoliaSearchOptions> {
return {
translations: {
button: {
buttonText: 'Suche',
buttonAriaLabel: 'Suche'
},
modal: {
searchBox: {
clearButtonTitle: 'Löschen',
clearButtonAriaLabel: 'Suchverlauf löschen',
closeButtonText: 'Schließen',
closeButtonAriaLabel: 'Schließen',
placeholderText: 'Dokumentation durchsuchen oder KI fragen',
placeholderTextAskAi: 'Stell noch eine Frage...',
placeholderTextAskAiStreaming: 'Antwort generieren...',
searchInputLabel: 'Suche',
backToKeywordSearchButtonText: 'Zurück zur Stichwortsuche',
backToKeywordSearchButtonAriaLabel: 'Zurück zur Stichwortsuche',
newConversationPlaceholder: 'Eine Frage stellen',
conversationHistoryTitle: 'Mein Gesprächsverlauf',
startNewConversationText: 'Neue Konversation beginnen',
viewConversationHistoryText: 'Gesprächsverlauf',
threadDepthErrorPlaceholder: 'Gesprächslimit erreicht'
},
newConversation: {
newConversationTitle: 'Wie kann ich dir heute helfen?',
newConversationDescription:
'Ich werde die Dokumentation durchsuchen, um schnell Einrichtungsanleitungen, Details zu Funktionen und Tipps zur Fehlerbehebung zu finden.'
},
footer: {
selectText: 'Auswählen',
submitQuestionText: 'Frage absenden',
selectKeyAriaLabel: 'Eingabetaste', //unsure
navigateText: 'Navigieren',
navigateUpKeyAriaLabel: 'Pfeil hoch',
navigateDownKeyAriaLabel: 'Pfeil runter',
closeText: 'Schließen',
backToSearchText: 'Zurück zur Suche',
closeKeyAriaLabel: 'Escape-Taste',
poweredByText: 'Bereitgestellt von'
},
errorScreen: {
titleText: 'Ergebnisse konnten nicht abgerufen werden.',
helpText: 'Möglicherweise müssen Sie Ihre Netzwerkverbindung überprüfen.'
},
startScreen: {
recentSearchesTitle: 'Zuletzt',
noRecentSearchesText: 'Keine kürzlichen Suchanfragen',
saveRecentSearchButtonTitle: 'Diese Suche speichern',
removeRecentSearchButtonTitle: 'Diese Suche aus dem Verlauf entfernen',
favoriteSearchesTitle: 'Favoriten',
removeFavoriteSearchButtonTitle: 'Diese Suche von Favoriten entfernen',
recentConversationsTitle: 'Kürzliche Konversationen',
removeRecentConversationButtonTitle:
'Diese Unterhaltung aus dem Verlauf entfernen'
},
noResultsScreen: {
noResultsText: 'Keine Ergebnisse für',
suggestedQueryText: 'Versuchen Sie',
reportMissingResultsText:
'Glaubst du, diese Suche sollte Ergebnisse liefern?',
reportMissingResultsLinkText: 'Lass es uns wissen.'
},
resultsScreen: {
askAiPlaceholder: 'Frag KI: ',
noResultsAskAiPlaceholder:
'Nicht in der Dokumentation fündig geworden? Fragen Sie die KI: '
},
askAiScreen: {
disclaimerText:
'Die Antworten werden von einer KI generiert und können ungenau sein. Bitte überprüfen Sie diese.',
relatedSourcesText: 'Verwandte Quellen',
thinkingText: 'Nachdenken...',
copyButtonText: 'Kopieren',
copyButtonCopiedText: 'Kopiert!',
copyButtonTitle: 'Kopieren',
likeButtonTitle: 'Hilfreich',
dislikeButtonTitle: 'Nicht hilfreich',
thanksForFeedbackText: 'Danke für Ihr Feedback!',
preToolCallText: 'Suchen...',
duringToolCallText: 'Suchen...',
afterToolCallText: 'Suche nach',
stoppedStreamingText: 'Du hast diese Antwort angehalten',
errorTitleText: 'Konversationsfehler',
startNewConversationButtonText: 'Neue Konversation beginnen'
}
}
},
askAi: {
sidePanel: {
button: {
translations: {
buttonText: 'Frag KI',
buttonAriaLabel: 'Frag KI'
}
},
panel: {
translations: {
header: {
title: 'Frag KI',
conversationHistoryTitle: 'Mein Gesprächsverlauf',
newConversationText: 'Neue Konversation beginnen',
viewConversationHistoryText: 'Gesprächsverlauf'
},
promptForm: {
promptPlaceholderText: 'Eine Frage stellen',
promptAnsweringText: 'Antwort generieren...',
promptAskAnotherQuestionText: 'Frage eine weitere Frage',
promptDisclaimerText:
'Die Antworten werden von einer KI generiert und können ungenau sein.',
promptLabelText:
'Drücken Sie die Eingabetaste zum Absenden oder Umschalt+Eingabetaste für eine neue Zeile.',
promptAriaLabelText: 'Frageeingabe'
},
conversationScreen: {
preToolCallText: 'Suchen...',
searchingText: 'Suchen...',
toolCallResultText: 'Suche nach',
conversationDisclaimer:
'Die Antworten werden von einer KI generiert und können ungenau sein. Bitte überprüfen Sie diese.',
reasoningText: 'Nachdenken...',
thinkingText: 'Nachdenken...',
relatedSourcesText: 'Verwandte Quellen',
stoppedStreamingText: 'Du hast diese Antwort angehalten',
copyButtonText: 'Kopieren',
copyButtonCopiedText: 'Kopiert!',
likeButtonTitle: 'Hilfreich',
dislikeButtonTitle: 'Nicht hilfreich',
thanksForFeedbackText: 'Danke für dein Feedback!',
errorTitleText: 'Konversationsfehler'
},
newConversationScreen: {
titleText: 'Wie kann ich dir heute helfen?',
introductionText:
'Ich werde Ihre Dokumentation durchsuchen, um schnell Einrichtungsanleitungen, Details zu Funktionen und Tipps zur Fehlerbehebung zu finden.'
},
logo: {
poweredByText: 'Bereitgestellt von'
}
}
}
}
}
}
}

@ -0,0 +1,82 @@
---
description: Erfahre, wie du statische Assets wie Bilder, Medien und Schriftarten in VitePress referenzierst und verwaltest.
---
# Asset-Verwaltung
## Statische Assets referenzieren
Alle Markdown-Dateien werden in Vue-Komponenten kompiliert und von [Vite](https://vite.dev/guide/assets.html) verarbeitet. Du kannst und solltest Assets über relative URLs referenzieren:
\`\`\`md
![Ein Bild](./image.png)
\`\`\`
Du kannst statische Assets in deinen Markdown-Dateien, deinen \`*.vue\`-Komponenten im Theme, Styles und normalen \`.css\`-Dateien entweder über absolute öffentliche Pfade (bezogen auf das Projektverzeichnis) oder über relative Pfade (bezogen auf dein Dateisystem) referenzieren. Letzteres funktioniert ähnlich wie bei Vite, Vue CLI oder Webpacks \`file-loader\`.
Gängige Bild-, Medien- und Schriftdateitypen werden automatisch erkannt und als Assets eingebunden.
::: tip Verknüpfte Dateien werden nicht als Assets behandelt
PDFs oder andere Dokumente, auf die in Markdown-Dateien verlinkt wird, werden nicht automatisch als Assets behandelt. Damit verknüpfte Dateien zugänglich sind, musst du sie manuell im Verzeichnis [\`public\`](#das-public-verzeichnis) deines Projekts ablegen.
:::
Alle referenzierten Assets, einschließlich solcher mit absoluten Pfaden, werden beim Produktions-Build mit einem gehashten Dateinamen in das Ausgabeverzeichnis kopiert. Nicht referenzierte Assets werden nicht kopiert. Bild-Assets unter 4 KB werden als Base64 eingebettet. Dies kann über die [\`vite\`](../reference/site-config#vite)-Konfigurationsoption angepasst werden.
Alle **statischen** Pfadangaben, einschließlich absoluter Pfade, sollten auf deiner Arbeitsverzeichnisstruktur basieren.
## Das Public-Verzeichnis
Manchmal musst du statische Assets bereitstellen, die in keiner deiner Markdown-Dateien oder Theme-Komponenten direkt referenziert werden, oder bestimmte Dateien unter ihrem ursprünglichen Dateinamen ausliefern. Beispiele hierfür sind \`robots.txt\`, Favicons und PWA-Icons.
Du kannst diese Dateien im Verzeichnis \`public\` unterhalb des [Quellverzeichnisses](./routing#quellverzeichnis) ablegen. Wenn dein Projektverzeichnis beispielsweise \`./docs\` ist und das Standard-Quellverzeichnis verwendet wird, lautet dein Public-Verzeichnis \`./docs/public\`.
Assets im Verzeichnis \`public\` werden unverändert in das Stammverzeichnis des Ausgabeverzeichnisses kopiert.
Beachte, dass du Dateien aus \`public\` mit einem absoluten Pfad vom Stammverzeichnis referenzieren solltest. \`public/icon.png\` sollte im Quellcode beispielsweise immer als \`/icon.png\` referenziert werden.
## Basis-URL
Wenn deine Website unter einer URL bereitgestellt wird, die nicht dem Stammverzeichnis entspricht, setze die Option [\`base\`](../reference/site-config#base). Wenn du deine Website beispielsweise unter \`https://foo.github.io/bar/\` bereitstellen möchtest, sollte \`base\` auf \`'/bar/'\` gesetzt werden.
Referenzen auf statische Assets werden automatisch an \`base\` angepasst. Eine absolute Referenz auf eine Datei in \`public\` funktioniert daher mit jedem \`base\` und muss nicht aktualisiert werden:
\`\`\`md
![Ein Bild](/image-innerhalb-public.png)
\`\`\`
Nur dynamisch erzeugte Pfade benötigen besondere Behandlung – beispielsweise ein Bild, dessen \`src\` auf einem Wert aus der Theme-Konfiguration basiert. Um den Basis-Pfad zur Laufzeit voranzustellen, umschließe solche Pfade mit dem [\`withBase\`-Helper](../reference/runtime-api#withbase):
\`\`\`vue
<script setup>
import { withBase, useData } from 'vitepress'
const { theme } = useData()
</script>
<template>
<img :src="withBase(theme.logoPath)" />
</template>
\`\`\`
## Assets über ein CDN ausliefern
Um generierte Assets – Skripte, Styles, Schriftarten und aus Markdown oder Komponenten importierte Bilder – von einer anderen Herkunft als den Seiten auszuliefern, setze [\`assetsBase\`](../reference/site-config#assetsbase):
\`\`\`ts
export default {
base: '/',
assetsBase: 'https://cdn.example.com/'
}
\`\`\`
Lade das Verzeichnis \`assets\` aus dem Ausgabeverzeichnis auf das CDN hoch, sodass es unter \`https://cdn.example.com/assets/\` erreichbar ist, und stelle die übrige Ausgabe wie gewohnt auf deiner Website bereit. Dateien in \`public\` werden relativ zu \`base\` referenziert und bleiben bei den Seiten.
Da der Wert häufig von der Umgebung abhängt, kann er auch über die Kommandozeile übergeben werden:
\`\`\`sh
vitepress build docs --assetsBase "$CDN_URL"
\`\`\`
::: warning CORS erforderlich
Modul-Skripte werden immer im CORS-Modus geladen. Daher muss ein CDN über verschiedene Origins einen passenden \`Access-Control-Allow-Origin\`-Header zurückgeben.
:::

@ -0,0 +1,57 @@
---
outline: deep
description: Verbinde VitePress mit einem Headless-CMS mithilfe dynamischer Routen und Datenlader.
---
# Mit einem CMS verbinden
## Allgemeiner Ablauf
Die Verbindung von VitePress mit einem CMS dreht sich hauptsächlich um [dynamische Routen](./routing#dynamische-routen). Stelle sicher, dass du verstanden hast, wie sie funktionieren, bevor du fortfährst.
Da jedes CMS anders funktioniert, können wir hier nur einen allgemeinen Ablauf beschreiben, den du an dein konkretes Szenario anpassen musst.
1. Wenn dein CMS eine Authentifizierung erfordert, erstelle eine `.env`-Datei zum Speichern deiner API-Tokens und lade sie:
```js
// posts/[id].paths.js
import { loadEnv } from 'vitepress'
const env = loadEnv('', process.cwd())
```
2. Rufe die benötigten Daten aus dem CMS ab und formatiere sie als gültige Pfaddaten:
```js
export default {
async paths() {
// Verwende bei Bedarf die Client-Bibliothek des jeweiligen CMS.
const data = await (await fetch('https://my-cms-api', {
headers: {
// Token, falls erforderlich.
}
})).json()
return data.map(entry => {
return {
params: { id: entry.id, /* title, authors, date etc. */ },
content: entry.content
}
})
}
}
```
3. Rendere den Inhalt auf der Seite:
```md
# {{ $params.title }}
- von {{ $params.author }} am {{ $params.date }}
<!-- @content -->
```
## Integrationsanleitungen
Wenn du eine Anleitung zur Integration von VitePress in ein bestimmtes CMS geschrieben hast, verwende bitte den Link „Diese Seite bearbeiten“ unten auf der Seite, um sie hier einzureichen.

@ -0,0 +1,266 @@
---
description: Erstelle und verwende ein eigenes Theme in VitePress, um das Erscheinungsbild und Verhalten deiner Website vollständig zu steuern.
---
# Ein eigenes Theme verwenden
## Theme-Auflösung
Du kannst ein eigenes Theme aktivieren, indem du eine Datei `.vitepress/theme/index.js` oder `.vitepress/theme/index.ts` (die „Theme-Einstiegsdatei“) erstellst:
```
.
├─ docs # Projektstammverzeichnis
│ ├─ .vitepress
│ │ ├─ theme
│ │ │ └─ index.js # Theme-Einstiegsdatei
│ │ └─ config.js # Konfigurationsdatei
│ └─ index.md
└─ package.json
```
VitePress verwendet immer das eigene Theme anstelle des Standard-Themes, sobald es eine Theme-Einstiegsdatei erkennt. Du kannst jedoch [das Standard-Theme erweitern](./extending-default-theme), um darauf aufbauend fortgeschrittene Anpassungen vorzunehmen.
## Theme-Schnittstelle
Ein eigenes VitePress-Theme wird als Objekt mit der folgenden Schnittstelle definiert:
```ts
interface Theme {
/**
* Stamm-Layout-Komponente für jede Seite
* @required
*/
Layout: Component
/**
* Vue-App-Instanz erweitern
* @optional
*/
enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>
/**
* Wird innerhalb von `setup()` der Stammkomponente ausgeführt
* @optional
*/
setup?: () => void
/**
* Ein anderes Theme erweitern und dessen `enhanceApp` und `setup` vor unserem aufrufen
* @optional
*/
extends?: Theme
}
interface EnhanceAppContext {
app: App // Vue-App-Instanz
router: Router // VitePress-Router-Instanz
siteData: Ref<SiteData> // Metadaten auf Website-Ebene
}
```
Die Theme-Einstiegsdatei sollte das Theme als Standardexport exportieren:
```js [.vitepress/theme/index.js]
// Vue-Dateien können direkt in der Theme-Einstiegsdatei importiert werden
// VitePress ist bereits mit @vitejs/plugin-vue vorkonfiguriert.
import Layout from './Layout.vue'
export default {
Layout,
enhanceApp({ app, router, siteData }) {
// app.component(...)
// app.use(...)
}
}
```
Der `enhanceApp`-Hook ermöglicht den Zugriff auf die [Vue-App-Instanz](https://vuejs.org/api/application.html) und andere Laufzeitdaten. Damit kannst du beispielsweise [globale Komponenten registrieren](./extending-default-theme.md#registering-global-components), Vue-Bibliotheken integrieren usw.
Der Wert `router` ist dieselbe VitePress-Router-Instanz, die von [`useRouter()`](../reference/runtime-api#userouter). Um auf Routenänderungen zu reagieren, weist du dem Router Handler zu:
```ts [.vitepress/theme/index.ts]
export default {
enhanceApp({ router }) {
router.onBeforeRouteChange = (to) => {
console.log('navigiere zu', to)
}
router.onAfterRouteChange = (to) => {
console.log('weitergeleitet zu', to)
}
}
}
```
Gib von `onBeforeRouteChange` or `onBeforePageLoad` `false` zurück, um die Navigation abzubrechen.
Der `setup`-Hook wird innerhalb von `setup()` der Stammkomponente ausgeführt. Deshalb funktionieren Aufrufe der Composition API (`onMounted`, `watch`, composables, ...) dort ohne dass du die Layout-Komponente umschließen musst:
```ts [.vitepress/theme/index.ts]
import { watch } from 'vue'
import { useData } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
setup() {
const { page } = useData()
watch(() => page.value.relativePath, (path) => {
console.log('now viewing', path)
})
}
}
```
Mit `extends` wird das `setup` jedes Themes wie bei `enhanceApp` von der Basis ausgehend ausgeführt. Es läuft außerdem während des SSR-/SSG-Renderings. Browser-spezifische Arbeit sollte daher innerhalb von `onMounted` bleiben.
Der Standardexport ist der einzige Vertrag für ein eigenes Theme, und nur die Eigenschaft `Layout` ist erforderlich. Technisch kann ein VitePress-Theme daher aus nur einer einzigen Vue-Komponente bestehen.
Innerhalb deiner Layout-Komponente funktioniert alles wie in einer normalen Vite- + Vue-3-Anwendung. Beachte, dass das Theme außerdem [mit SSR kompatibel](./ssr-compat) sein muss.
## Ein Layout erstellen
Die einfachste Layout-Komponente muss eine [`<Content />`](../reference/runtime-api#content) -Komponente enthalten:
```vue [.vitepress/theme/Layout.vue]
<template>
<h1>Eigenes Layout!</h1>
<!-- Hier wird der Markdown-Inhalt gerendert -->
<Content />
</template>
```
Das obige Layout rendert den Markdown-Inhalt jeder Seite einfach als HTML. Als erste Verbesserung können wir die Behandlung von 404-Fehlern hinzufügen:
```vue{1-4,9-12}
<script setup>
import { useData } from 'vitepress'
const { page } = useData()
</script>
<template>
<h1>Eigenes Layout!</h1>
<div v-if="page.isNotFound">
Eigene 404-Seite!
</div>
<Content v-else />
</template>
```
Der [`useData()`](../reference/runtime-api#usedata)-Helper stellt uns alle Laufzeitdaten zur Verfügung, die wir benötigen, um verschiedene Layouts bedingt zu rendern. Zu den Daten, auf die wir zugreifen können, gehört das Frontmatter der aktuellen Seite. Damit können wir dem Endbenutzer ermöglichen, das Layout jeder Seite zu steuern. Zum Beispiel kann der Benutzer angeben, dass die Seite ein spezielles Startseitenlayout verwenden soll:
```md
---
layout: home
---
```
Anschließend können wir unser Theme entsprechend anpassen:
```vue{3,12-14}
<script setup>
import { useData } from 'vitepress'
const { page, frontmatter } = useData()
</script>
<template>
<h1>Eigenes Layout!</h1>
<div v-if="page.isNotFound">
Eigene 404-Seite!
</div>
<div v-if="frontmatter.layout === 'home'">
Eigene Startseite!
</div>
<Content v-else />
</template>
```
Natürlich kannst du das Layout auch auf mehrere Komponenten aufteilen:
```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>Eigenes Layout!</h1>
<NotFound v-if="page.isNotFound" />
<Home v-if="frontmatter.layout === 'home'" />
<Page v-else /> <!-- <Page /> renders <Content /> -->
</template>
```
In der [Runtime API Referenz](../reference/runtime-api) findest du alles, was in Theme-Komponenten verfügbar ist. Zusätzlich kannst du [Build-Time Data Loading](./data-loading) nutzen, um datenbasierte Layouts zu erzeugen – beispielsweise eine Seite, die alle Blogbeiträge des aktuellen Projekts auflistet.
## Ein eigenes Theme verteilen
Am einfachsten verteilst du ein eigenes Theme, indem du es als [template repository on GitHub](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-template-repository).
Wenn du das Theme als npm-Paket verteilen möchtest, gehe folgendermaßen vor:
1. Exportiere das Theme-Objekt als Standardexport des Paketeintrags.
2. Falls zutreffend, exportiere die Typdefinition deiner Theme-Konfiguration als `ThemeConfig`.
3. Wenn dein Theme Anpassungen an der VitePress-Konfiguration erfordert, exportiere diese Konfiguration unter einem Paket-Unterpfad (e.g. `my-theme/config`) damit Benutzer sie erweitern können.
4. Dokumentiere die Optionen der Theme-Konfiguration sowohl über die Konfigurationsdatei als auch über Frontmatter.
5. Stelle klare Anweisungen zur Verwendung deines Themes bereit (siehe unten).
## Ein eigenes Theme verwenden
Um ein externes Theme zu verwenden, importiere und exportiere es aus der Theme-Einstiegsdatei erneut:
```js [.vitepress/theme/index.js]
import Theme from 'awesome-vitepress-theme'
export default Theme
```
Wenn das Theme erweitert werden muss:
```js [.vitepress/theme/index.js]
import Theme from 'awesome-vitepress-theme'
export default {
extends: Theme,
enhanceApp(ctx) {
// ...
}
}
```
Wenn das Theme eine spezielle VitePress-Konfiguration benötigt, musst du sie auch in deiner eigenen Konfiguration erweitern:
```ts [.vitepress/config.ts]
import baseConfig from 'awesome-vitepress-theme/config'
export default {
// Basis-Konfiguration des Themes erweitern (falls erforderlich)
extends: baseConfig
}
```
Wenn das Theme schließlich Typen für seine Theme-Konfiguration bereitstellt:
```ts [.vitepress/config.ts]
import baseConfig from 'awesome-vitepress-theme/config'
import { defineConfig } from 'vitepress'
import type { ThemeConfig } from 'awesome-vitepress-theme'
export default defineConfig<ThemeConfig>({
extends: baseConfig,
themeConfig: {
// Typ ist `ThemeConfig`
}
})
```

@ -0,0 +1,248 @@
---
description: Lade beliebige Daten zur Erstellungszeit mit VitePress-Datenladern und importiere sie in Seiten oder Komponenten.
---
# Daten zur Erstellungszeit laden
VitePress stellt eine Funktion namens **Datenlader** bereit, mit der du beliebige Daten laden und in Seiten oder Komponenten importieren kannst. Das Laden der Daten wird **nur zur Erstellungszeit** ausgeführt: Die resultierenden Daten werden als JSON im endgültigen JavaScript-Bundle serialisiert.
Data Loader können verwendet werden, um entfernte Daten abzurufen oder Metadaten auf Grundlage lokaler Dateien zu erzeugen. Zum Beispiel kannst du damit deine lokalen API-Seiten analysieren und automatisch einen Index aller API-Einträge erzeugen.
## Grundlegende Verwendung
Eine Data-Loader-Datei muss mit `.data.js` oder `.data.ts` enden. Die Datei sollte ein Objekt als Standardexport bereitstellen, das die `load()`-Methode enthält:
```js [example.data.js]
export default {
load() {
return {
hello: 'world'
}
}
}
```
Das Loader-Modul wird nur in Node.js ausgewertet. Du kannst daher nach Bedarf Node-APIs und npm-Abhängigkeiten importieren.
Du kannst anschließend Daten aus dieser Datei in `.md`-Seiten und `.vue`-Komponenten mit dem `data` named export:
```vue
<script setup>
import { data } from './example.data.js'
</script>
<pre>{{ data }}</pre>
```
Ausgabe:
```json
{
"hello": "world"
}
```
Du wirst feststellen, dass der Data Loader selbst `data` nicht exportiert. Stattdessen ruft VitePress im Hintergrund die Methode `load()` auf und stellt das Ergebnis implizit über den benannten Export `data` bereit.
Das funktioniert auch, wenn der Loader asynchron ist:
```js
export default {
async load() {
// entfernte Daten abrufen
return (await fetch('...')).json()
}
}
```
## Daten aus lokalen Dateien
Wenn du Daten auf Grundlage lokaler Dateien erzeugen musst, solltest du die Option `watch` im Datenlader verwenden, damit Änderungen an diesen Dateien automatische Aktualisierungen während der Entwicklung auslösen können.
Die Option `watch` ist außerdem praktisch, weil du [Glob-Muster](https://github.com/mrmlnc/fast-glob#pattern-syntax) verwenden kannst, um mehrere Dateien zu finden. Die Muster können relativ zur Loader-Datei angegeben werden, und die Funktion `load()` erhält die gefundenen Dateien als absolute Pfade.
Das folgende Beispiel zeigt, wie CSV-Dateien mit [csv-parse](https://github.com/adaltas/node-csv/tree/master/packages/csv-parse/) geladen werden. Da diese Datei nur zur Build-Zeit ausgeführt wird, wird der CSV-Parser nicht an den Client ausgeliefert!
```js
import fs from 'node:fs'
import { parse } from 'csv-parse/sync'
export default {
watch: ['./data/*.csv'],
load(watchedFiles) {
// watchedFiles ist ein Array mit den absoluten Pfaden der gefundenen Dateien.
// Erzeuge ein Array mit Metadaten von Blogbeiträgen, das zum Rendern
// einer Liste im Theme-Layout verwendet werden kann
return watchedFiles.map((file) => {
return parse(fs.readFileSync(file, 'utf-8'), {
columns: true,
skip_empty_lines: true
})
})
}
}
```
## `createContentLoader`
Beim Erstellen einer inhaltsorientierten Website müssen wir häufig eine „Archiv“- oder „Index“-Seite erstellen: eine Seite, auf der wir alle verfügbaren Einträge unserer Inhaltssammlung auflisten, beispielsweise Blogbeiträge oder API-Seiten. Wir **können** dies direkt mit der Data-Loader-API umsetzen. Da dies jedoch ein sehr häufiger Anwendungsfall ist, stellt VitePress den Helper `createContentLoader` bereit, der dies vereinfacht:
```js [posts.data.js]
import { createContentLoader } from 'vitepress'
export default createContentLoader('posts/*.md', /* options */)
```
Der Helper akzeptiert ein Glob-Muster relativ zum [Quellverzeichnis](./routing#source-directory), und gibt ein `{ watch, load }`-Datenlader-Objekt zurück, das als Standardexport in einer Data-Loader-Datei verwendet werden kann. Außerdem wird ein Cache auf Grundlage der Änderungszeitpunkte von Dateien verwendet, um die Leistung während der Entwicklung zu verbessern.
Hinweis: Der Loader funktioniert nur mit Markdown-Dateien – gefundene Dateien ohne Markdown-Endung werden übersprungen.
Die geladenen Daten sind ein Array vom Typ `ContentData[]`:
```ts
interface ContentData {
// Zugeordnete URL der Seite, z. B. /posts/hello.html (enthält base nicht)
// Pfade manuell durchlaufen oder mit `transform` normalisieren
url: string
// Frontmatter-Daten der Seite
frontmatter: Record<string, any>
// Die folgenden Eigenschaften sind nur vorhanden, wenn die entsprechenden Optionen aktiviert sind
// Wir besprechen sie weiter unten
src: string | undefined
html: string | undefined
excerpt: string | undefined
}
```
Standardmäßig werden nur `url` und `frontmatter` bereitgestellt. Da die geladenen Daten als JSON in das Client-Bundle eingebettet werden, müssen wir auf ihre Größe achten. Hier ist ein Beispiel dafür, wie du die Daten für eine minimale Blog-Indexseite verwendest:
```vue
<script setup>
import { data as posts } from './posts.data.js'
</script>
<template>
<h1>Alle Blogbeiträge</h1>
<ul>
<li v-for="post of posts">
<a :href="post.url">{{ post.frontmatter.title }}</a>
<span>von {{ post.frontmatter.author }}</span>
</li>
</ul>
</template>
```
### Optionen
Die Standarddaten sind möglicherweise nicht für alle Anwendungsfälle geeignet. Du kannst die Daten mithilfe von Optionen transformieren:
```js [posts.data.js]
import { createContentLoader } from 'vitepress'
export default createContentLoader('posts/*.md', {
includeSrc: true, // Rohquelle des Markdown einschließen?
render: true, // Gerendertes vollständiges HTML der Seite einschließen?
excerpt: true, // Auszug einschließen?
transform(rawData) {
// Rohdaten nach Bedarf abbilden, sortieren oder filtern.
// Das Endergebnis wird an den Client ausgeliefert.
return rawData.sort((a, b) => {
return +new Date(b.frontmatter.date) - +new Date(a.frontmatter.date)
}).map((page) => {
page.src // Rohquelle des Markdown
page.html // Gerendertes vollständiges HTML der Seite
page.excerpt // Gerendertes HTML des Auszugs (Inhalt vor dem ersten `---`)
return {/* ... */}
})
}
})
```
Sieh dir an, wie dies im [Vue.js blog](https://github.com/vuejs/blog/blob/main/.vitepress/theme/posts.data.ts).
Die `createContentLoader`-API kann auch innerhalb von [build hooks](../reference/site-config#build-hooks):
```js [.vitepress/config.js]
export default {
async buildEnd() {
const posts = await createContentLoader('posts/*.md').load()
// Dateien anhand der Beitragsmetadaten erzeugen, z. B. einen RSS-Feed
}
}
```
**Typen**
```ts
interface ContentOptions<T = ContentData[]> {
/**
* src einschließen?
* @default false
*/
includeSrc?: boolean
/**
* src in HTML rendern und in die Daten aufnehmen?
* @default false
*/
render?: boolean
/**
* Wenn `boolean`: ob ein Auszug verarbeitet und aufgenommen werden soll (als HTML gerendert).
*
* Wenn `function`: steuert, wie der Auszug aus dem Inhalt extrahiert wird.
*
* Wenn `string`: definiert ein benutzerdefiniertes Trennzeichen zum Extrahieren des
* excerpt. Das Standardtrennzeichen ist `---` if `excerpt` is `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
/**
* Daten transformieren. Beachte, dass die Daten als JSON im Client-Bundle eingebettet werden, wenn sie aus Komponenten oder Markdown-Dateien
* importiert werden.
*/
transform?: (data: ContentData[]) => T | Promise<T>
}
```
## Typisierte Data Loader
Bei Verwendung von TypeScript kannst du deinen Loader und den `data`-Export wie folgt typisieren:
```ts
import { defineLoader } from 'vitepress'
export interface Data {
// Datentyp
}
declare const data: Data
export { data }
export default defineLoader({
// Typgeprüfte Loader-Optionen
watch: ['...'],
async load(): Promise<Data> {
// ...
}
})
```
## Konfiguration
Um innerhalb eines Loaders auf die Konfigurationsinformationen zuzugreifen, kannst du beispielsweise folgenden Code verwenden:
```ts
import type { SiteConfig } from 'vitepress'
const config: SiteConfig = (globalThis as any).VITEPRESS_CONFIG
```

@ -0,0 +1,406 @@
---
outline: deep
description: Stelle deine VitePress-Website auf beliebten Plattformen wie Netlify, Vercel, GitHub Pages und weiteren Plattformen bereit.
---
# Deine VitePress-Website bereitstellen
Die folgenden Anleitungen basieren auf einigen gemeinsamen Voraussetzungen:
- Die VitePress-Website befindet sich im Verzeichnis `docs` deines Projekts.
- Du verwendest das standardmäßige Ausgabeverzeichnis (`.vitepress/dist`).
- VitePress ist als lokale Abhängigkeit in deinem Projekt installiert, und du hast die folgenden Skripte in deiner `package.json`:
```json [package.json]
{
"scripts": {
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
}
}
```
## Lokal erstellen und testen
1. Führe diesen Befehl aus, um die Dokumentation zu erstellen:
```sh
$ npm run docs:build
```
2. Nach dem Erstellen kannst du die Website lokal mit folgendem Befehl anzeigen:
```sh
$ npm run docs:preview
```
Der Befehl `preview` startet einen lokalen statischen Webserver, der das Ausgabeverzeichnis `.vitepress/dist` unter `http://localhost:4173` bereitstellt. Du kannst damit überprüfen, ob alles korrekt aussieht, bevor du die Website in die Produktion überträgst.
3. Du kannst den Port des Servers ändern, indem du `--port` als Argument übergibst.
```json
{
"scripts": {
"docs:preview": "vitepress preview docs --port 8080"
}
}
```
Das Skript `docs:preview` startet den Server nun unter `http://localhost:8080`.
## Einen öffentlichen Basispfad festlegen
Standardmäßig wird angenommen, dass die Website am Stammpfad einer Domain (`/`) bereitgestellt wird. Wenn deine Website unter einem Unterpfad wie `https://mywebsite.com/blog/` bereitgestellt wird, musst du die Option [`base`](../reference/site-config#base) in der VitePress-Konfiguration auf `'/blog/'` setzen.
**Beispiel:** Wenn du GitHub- (oder GitLab-) Pages verwendest und deine Website unter `user.github.io/repo/` bereitstellst, setze `base` auf `/repo/`.
## Verschiebbare Builds (relativer Basispfad) {#relocatable-builds-relative-base}
Wenn die endgültige URL der Website zur Erstellungszeit noch nicht bekannt ist – etwa bei einem IPFS-Gateway (`https://gateway/ipfs/<cid>/…`), der Wayback Machine, einem freigegebenen Ordner oder in eine App eingebetteter Dokumentation –, setze `base` auf `'./'`:
```ts
export default {
base: './'
}
```
Jede Seite referenziert Assets und andere Seiten dann relativ zu ihrem eigenen Speicherort. Die Client-Laufzeit ermittelt beim Laden der Seite den tatsächlichen Einhängepunkt. Dieselbe Ausgabe funktioniert von **jedem** Unterpfad aus ohne erneute Erstellung – auch von mehreren Pfaden gleichzeitig – während Routing, Suche und Prefetching vollständig funktionieren.
Das direkte Öffnen der erzeugten HTML-Dateien über das Dateisystem (`file://`) funktioniert ebenfalls als vollständig navigierbare statische Website mit Formatierung. Browser blockieren JavaScript-Module über `file://`, daher findet dort keine Hydration statt – interaktive Funktionen wie die Suche bleiben inaktiv, während alle vorgerenderten Inhalte und Links weiterhin funktionieren.
Einige Dinge solltest du beachten:
- Lasse [`cleanUrls`](../reference/site-config#cleanurls) deaktiviert (Standardeinstellung): Für portable Ausgaben müssen Links mit `.html` enden, da kein Server vorhanden ist, der saubere URLs umschreibt.
- `404.html` wird für die Stammebene erzeugt. Hosts, die sie als Fallback für beliebig tiefe URLs ausliefern, rendern sie ohne Styles (für eine unbekannte Pfadtiefe gibt es keinen korrekten relativen Präfix).
- [`head`](../reference/site-config#head)-Einträge werden wie immer unverändert ausgegeben – vermeide dort absolute Pfade wie `/favicon.ico` und bevorzuge absolute URLs oder `transformHead`.
- Rohe HTML-`<a>`-Tags in Markdown behalten ihr `href` unverändert – verwende für absolute Links innerhalb der Website die Markdown-Linksyntax (eingebettete `<img>`-Quellen werden über die Asset-Pipeline verarbeitet).
- Von [`createContentLoader`](./data-loading#createcontentloader) erzeugte Links bleiben absolut zur Website (ihr HTML wird in andere Seiten eingebettet, daher gibt es keinen einheitlichen relativen Präfix) – sie funktionieren nur bei einer Bereitstellung am Stammverzeichnis.
- Stelle Seiten unter ihren kanonischen URLs bereit: das Stammverzeichnis als `/dir/` (nicht `/dir`) und ohne zusätzliche abschließende Schrägstriche bei Seiten-URLs. Der relative Präfix wird anhand der URL aufgelöst, die der Browser tatsächlich anzeigt, und praktisch alle statischen Hoster verwenden bereits diese kanonische Form.
- Der Entwicklungsserver stellt immer unter `/` bereit; das relative Verhalten gilt für den Produktionsausgabe.
## HTTP-Cache-Header
Wenn du Kontrolle über die HTTP-Header deines Produktionsservers hast, kannst du `cache-control`-Header konfigurieren, um bei wiederholten Besuchen eine bessere Leistung zu erzielen.
Der Produktionsausgabe verwendet gehashte Dateinamen für statische Assets (JavaScript, CSS und andere importierte Assets, die nicht in `public` liegen). Wenn du die Produktionsvorschau mit dem Netzwerk-Tab der Browser-Entwicklertools untersuchst, siehst du Dateien wie `app.4f283b18.js`.
Dieser Hash `4f283b18` wird aus dem Inhalt dieser Datei erzeugt. Dieselbe gehashte URL liefert garantiert denselben Dateiinhalt – wenn sich der Inhalt ändert, ändern sich auch die URLs. Das bedeutet, dass du für diese Dateien bedenkenlos die stärksten Cache-Header verwenden kannst. Alle solchen Dateien werden im Ausgabeverzeichnis unter `assets/` abgelegt. Dafür kannst du den folgenden Header konfigurieren:
```
Cache-Control: max-age=31536000,immutable
```
::: details Beispiel für die Netlify-Datei `_headers`
```
/assets/*
cache-control: max-age=31536000
cache-control: immutable
```
Hinweis: Die Datei `_headers` sollte im [Public-Verzeichnis](./asset-handling#the-public-directory) – in diesem Fall `docs/public/_headers` – liegen, damit sie unverändert in das Ausgabeverzeichnis kopiert wird.
[Netlify-Dokumentation zu benutzerdefinierten Headern](https://docs.netlify.com/routing/headers/)
:::
::: details Beispiel für die Vercel-Konfiguration in `vercel.json`
```json
{
"headers": [
{
"source": "/assets/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "max-age=31536000, immutable"
}
]
}
]
}
```
Hinweis: Die Datei `vercel.json` sollte im Stammverzeichnis deines **Repositorys** liegen.
[Vercel-Dokumentation zur Header-Konfiguration](https://vercel.com/docs/concepts/projects/project-Konfiguration#headers)
:::
## Anleitungen für Plattformen
### Netlify / Vercel / Cloudflare Pages / AWS Amplify / Render {#generic}
Richte ein neues Projekt ein und ändere diese Einstellungen über dein Dashboard:
- **Build-Befehl:** `npm run docs:build`
- **Ausgabeverzeichnis:** `docs/.vitepress/dist`
- **Node-Version:** `20` (oder höher)
::: warning
Aktiviere keine Optionen wie _Auto Minify_ für HTML-Code. Dadurch werden Kommentare aus der Ausgabe entfernt, die für Vue Bedeutung haben. Wenn sie entfernt werden, können Hydration-Mismatch-Fehler auftreten.
:::
### GitHub Pages
1. Erstelle eine Datei namens `deploy.yml` im Verzeichnis `.github/workflows` deines Projekts, beispielsweise mit folgendem Inhalt:
```yaml [.github/workflows/deploy.yml]
# Beispiel-Workflow zum Erstellen und Bereitstellen einer VitePress-Website auf GitHub Pages
#
name: VitePress-Website auf Pages bereitstellen
on:
# Wird bei Pushes auf den `main`-Branch ausgeführt. Ändere dies zu `master`, wenn du
# den `master`-Branch als Standard-Branch verwendest.
push:
branches: [main]
# Ermöglicht das manuelle Ausführen dieses Workflows über den Actions-Tab
workflow_dispatch:
# Legt die Berechtigungen des GITHUB_TOKEN für die Bereitstellung auf GitHub Pages fest
permissions:
contents: read
pages: write
id-token: write
# Erlaubt nur eine gleichzeitige Bereitstellung und überspringt zwischenzeitlich eingereihtes Ausführungen.
# Laufende Ausführungen dürfen jedoch NICHT abgebrochen werden, damit diese Produktionsbereitstellungen abgeschlossen werden können.
concurrency:
group: pages
cancel-in-progress: false
jobs:
# Build-Aufgabe
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0 # Nicht erforderlich, wenn lastUpdated nicht aktiviert ist
# - uses: pnpm/action-setup@v4 # Entferne die Kommentarzeichen bei Verwendung von pnpm
# with:
# version: 9 # Not needed wenn you've set "packageManager" in package.json
# - uses: oven-sh/setup-bun@v1 # Uncomment this wenn you're using Bun
- name: Setup Node
uses: actions/setup-node@v6
with:
node-version: 24
cache: npm # or pnpm / yarn
- name: Cache VitePress
uses: actions/cache@v4
with:
path: docs/.vitepress/cache
key: ${{ runner.os }}-vitepress-${{ hashFiles('docs/**', 'package-lock.json', 'pnpm-lock.yaml', 'yarn.lock', 'bun.lockb') }}
restore-keys: |
${{ runner.os }}-vitepress-
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Install dependencies
run: npm ci # or pnpm install / yarn install / bun install
- name: Build with VitePress
run: npm run docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: docs/.vitepress/dist
# Bereitstellungsaufgabe
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
needs: build
runs-on: ubuntu-latest
name: Bereitstellen
steps:
- name: Bereitstellen to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
```
::: warning
Stelle sicher, dass die Option `base` in deiner VitePress-Konfiguration korrekt konfiguriert ist. Weitere Informationen findest du unter [Einen öffentlichen Basispfad festlegen](#setting-a-public-base-path).
:::
2. Wähle in den Repository-Einstellungen unter „Pages“ bei „Build and deployment > Source“ die Option „GitHub Actions“ aus.
3. Übertrage deine Änderungen auf den `main`-Branch und warte, bis der GitHub-Actions-Workflow abgeschlossen ist. Deine Website sollte anschließend unter `https://<username>.github.io/[repository]/` oder `https://<custom-domain>/` bereitstehen, abhängig von deinen Einstellungen. Deine Website wird bei jedem Push auf den `main`-Branch automatisch bereitgestellt.
### GitLab Pages
1. Setze `outDir` in der VitePress-Konfiguration auf `../public`. Konfiguriere die Option `base` auf `'/<repository>/'` wenn du unter `https://<username>.gitlab.io/<repository>/`. Du benötigst `base` nicht, wenn du eine benutzerdefinierte Domain, Benutzer- oder Gruppenseiten verwendest oder die Einstellung „Eindeutige Domain verwenden“ in GitLab aktiviert hast.
2. Erstelle eine Datei namens `.gitlab-ci.yml` im Stammverzeichnis deines Projekts mit folgendem Inhalt. Dadurch wird deine Website bei jeder Änderung am Inhalt erstellt und bereitgestellt:
```yaml [.gitlab-ci.yml]
image: node:24
pages:
cache:
paths:
- node_modules/
script:
# - apk add git # Uncomment this wenn you're using small docker images like alpine and have lastUpdated enabled
- npm install
- npm run docs:build
artifacts:
paths:
- public
only:
- main
```
<!-- Überschriften alphabetisch sortiert halten, nginx am Ende lassen -->
### Azure
1. Folge der [offiziellen Dokumentation](https://docs.microsoft.com/en-us/azure/static-web-apps/build-Konfiguration).
2. Setze diese Werte in deiner Konfigurationsdatei (und entferne nicht benötigte Werte wie `api_location`):
- **`app_location`**: `/`
- **`output_location`**: `docs/.vitepress/dist`
- **`app_build_command`**: `npm run docs:build`
### CloudRay
Du kannst deploy your VitePress project mit [CloudRay](https://cloudray.io/) by following these [instructions](https://cloudray.io/articles/how-to-deploy-vitepress-site).
### Firebase
1. Erstelle `firebase.json` und `.firebaserc` im Stammverzeichnis deines Projekts:
`firebase.json`:
```json [firebase.json]
{
"hosting": {
"public": "docs/.vitepress/dist",
"ignore": []
}
}
```
`.firebaserc`:
```json [.firebaserc]
{
"projects": {
"default": "<YOUR_FIREBASE_ID>"
}
}
```
2. Nach `npm run docs:build` führe diesen Befehl aus, um die Website bereitzustellen:
```sh
firebase deploy
```
### Heroku
1. Folge der Dokumentation und Anleitung für [`heroku-buildpack-static`](https://elements.heroku.com/buildpacks/heroku/heroku-buildpack-static).
2. Erstelle eine Datei namens `static.json` im Stammverzeichnis deines Projekts mit folgendem Inhalt:
```json [static.json]
{
"root": "docs/.vitepress/dist"
}
```
### Hostinger
Du kannst deploy your VitePress project mit [Hostinger](https://www.hostinger.com/web-apps-hosting) by following these [instructions](https://www.hostinger.com/Unterstützung/how-to-deploy-a-nodejs-website-in-hostinger/). Wähle bei der Build-Konfiguration VitePress als Framework und setze das Stammverzeichnis auf `./docs`.
### Lizard
[Lizard (lizard.build)](https://lizard.build) builds VitePress sites von source and serves the generated HTML. For the layout verwendet in this guide, it detects `docs:build` and serves `docs/.vitepress/dist` on port `80`.
Install the [Lizard CLI](https://lizard.build/docs/cli) and sign in mit `lizard login`. To deploy a local Quellverzeichnis, run these commands von the Projektstammverzeichnis containing `package.json`:
```sh
lizard init --name vitepress-docs
lizard add --service web
lizard up --service web --port 80
```
Lasse Überschreibungen für Build- und Startbefehle leer, damit die automatische Erkennung verwendet wird. Für GitHub-Bereitstellungen oder andere Strukturen siehe die [Lizard VitePress guide](https://lizard.build/docs/framework-guides/vitepress).
### Stormkit
Du kannst deploy your VitePress project to [Stormkit](https://www.stormkit.io) by following these [instructions](https://stormkit.io/blog/how-to-deploy-vitepress).
### Surge
Nach `npm run docs:build` führe diesen Befehl aus, um die Website auf [Surge](https://surge.sh):
```sh
npx surge docs/.vitepress/dist
```
### harvis
Nach `npm run docs:build` führe diesen Befehl aus, um die Website auf [harvis](https://harvis.dev):
```sh
npx harvis docs/.vitepress/dist
```
### nginx
Hier ist ein Beispiel für die Konfiguration eines nginx-Serverblocks. Diese Konfiguration enthält Gzip-Komprimierung für gängige textbasierte Assets, Regeln zum Ausliefern der statischen Dateien deiner VitePress-Website mit geeigneten Cache-Headern sowie die Behandlung von `cleanUrls: true`.
```nginx
map $uri $cache_control {
~^/assets/ "public, max-age=31536000, immutable";
default "no-cache";
}
server {
listen 8080;
listen [::]:8080;
server_name _;
root /usr/share/nginx/html;
index index.html;
charset utf-8;
server_tokens off;
absolute_redirect off;
gzip on;
gzip_vary on;
gzip_comp_level 5;
gzip_min_length 1024;
gzip_types
application/javascript
application/json
application/manifest+json
image/svg+xml
text/css
text/javascript
text/plain;
add_header Cache-Control $cache_control always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
location / {
try_files $uri $uri.html $uri/index.html =404;
}
location ~ ^(?<page>.+)/$ {
if (-f $document_root$page.html) {
return 301 $page$is_args$args;
}
try_files $page/index.html =404;
}
error_page 404 /404.html;
}
```

@ -0,0 +1,302 @@
---
outline: deep
description: Passe das VitePress-Standard-Theme mit benutzerdefiniertem CSS, Komponenten, Layouts und Slots an und erweitere es.
---
# Standard-Theme erweitern
Das VitePress-Standard-Theme ist für Dokumentation optimiert und kann angepasst werden. Eine umfassende Liste der Optionen findest du in der [Übersicht zur Standard-Theme-Konfiguration](../reference/default-theme-config).
Es gibt jedoch einige Fälle, in denen die Konfiguration allein nicht ausreicht. Zum Beispiel:
1. Du musst die CSS-Gestaltung anpassen;
2. Du musst die Vue-App-Instanz ändern, zum Beispiel um globale Komponenten zu registrieren;
3. Du musst über Layout-Slots benutzerdefinierte Inhalte in das Theme einfügen.
Diese fortgeschrittenen Anpassungen erfordern ein eigenes Theme, das das Standard-Theme „erweitert“.
::: tip
Bevor du fortfährst, lies zunächst [Ein eigenes Theme verwenden](./custom-theme), um zu verstehen, wie eigene Themes funktionieren.
:::
## Anpassen CSS
Das CSS des Standard-Themes kann durch Überschreiben der CSS-Variablen auf Stammebene angepasst werden:
```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;
}
```
Siehe die [CSS-Variablen des Standard-Themes](https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css), die überschrieben werden können.
### Navbar
Die Navigationsleiste verwendet eine einzelne, über CSS-Variablen gesteuerte Hintergrundfläche. Ihr Erscheinungsbild kann daher geändert werden, ohne die Interna der Komponenten anzupassen:
```css
:root {
/* Höhe und Hintergrund der Leiste */
--vp-nav-height: 4rem;
--vp-nav-bg-color: var(--vp-c-bg);
/* Hintergrund am oberen Rand der Startseite (nicht gescrollt);
auf var(--vp-nav-bg-color) setzen, um die Transparenz zu deaktivieren */
--vp-nav-home-bg-color: transparent;
/* Filter für den Inhalt hinter der Leiste */
--vp-nav-backdrop-filter: none;
/* untere Linie der Leiste und Hintergrund des mobilen Menüs */
--vp-nav-divider-color: var(--vp-c-gutter);
--vp-nav-screen-bg-color: var(--vp-c-bg);
}
```
Zum Beispiel, a frosted-glass navbar:
```css
:root {
--vp-nav-bg-color: color-mix(in srgb, var(--vp-c-bg) 65%, transparent);
--vp-nav-backdrop-filter: saturate(180%) blur(8px);
}
```
Dieselbe Gestaltung gilt auch für die lokale Navigation: `--vp-local-nav-bg-color` folgt standardmäßig der Oberflächenfarbe der Navigationsleiste. Wo die beiden Leisten zusammentreffen, teilen sie sich eine einzige verschwommene Fläche, sodass der Glaseffekt durchgehend bleibt.
::: warning
`backdrop-filter` kann die Scrollleistung messbar beeinträchtigen, insbesondere auf großen Bildschirmen oder Bildschirmen mit hoher Pixeldichte. Wenn du eine halbtransparente Leiste verwendest, prüfe daher den Kontrast des Textes gegenüber deinem Seiteninhalt. Safari 17 und ältere Versionen wenden variablenbasierte Hintergrundfilter nicht an und zeigen daher die halbtransparente Farbe ohne Unschärfe.
:::
Wenn the nav items don't fit the verfügbar width, they move in the `⋯` menu at the end of the navbar instead of being clipped, starting mit the social links, the appearance switch and the locale switcher, followed by the nav items right-to-left. Its button label can be localized mit [`extraMenuLabel`](../reference/default-theme-config#extramenulabel).
## Andere Schriftarten verwenden
VitePress verwendet [Inter](https://rsms.me/inter/) als Standardschriftart und fügt die Schriftarten der Build-Ausgabe hinzu. Die Schriftart wird in der Produktion außerdem automatisch vorab geladen. Das ist möglicherweise nicht erwünscht, wenn du eine andere Hauptschriftart verwenden möchtest.
To avoid including Inter in the Build-Ausgabe, import the theme von `vitepress/theme-ohne-fonts` instead:
```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: /* normal text font */
--vp-font-family-mono: /* code font */
}
```
::: warning
Wenn du are Verwendung optional components like the [Team Seite](../reference/default-theme-team-page) components, make sure to also import them von `vitepress/theme-ohne-fonts`!
:::
Wenn your font is a local file referenced via `@font-face`, it will be processed as an asset and included under `.vitepress/dist/assets` mit hashed filename. To preload this file, use the [transformHead](../reference/site-config#transformhead) build hook:
```js [.vitepress/config.js]
export default {
transformHead({ assets }) {
// adjust the regex accordingly to match your font
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: ''
}
]
]
}
}
}
```
## Registering Global Components
```js [.vitepress/theme/index.js]
import DefaultTheme from 'vitepress/theme'
/** @type {import('vitepress').Theme} */
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
// register your custom global components
app.component('MyGlobalComponent' /* ... */)
}
}
```
Wenn du're Verwendung TypeScript:
```ts [.vitepress/theme/index.ts]
import type { Theme } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
// register your custom global components
app.component('MyGlobalComponent' /* ... */)
}
} satisfies Theme
```
Since we are Verwendung Vite, du kannst außerdem leverage Vite's [glob import feature](https://vite.dev/guide/features.html#glob-import) to auto register a directory of components.
## Layout Slots
The Standard-Theme's `<Layout/>` component has a few slots that can be verwendet to inject content at certain locations of die Seite. Here's an example of injecting a component in the bevor outline:
```js [.vitepress/theme/index.js]
import DefaultTheme from 'vitepress/theme'
import MyLayout from './MyLayout.vue'
export default {
extends: DefaultTheme,
// override the Layout with a wrapper component that
// injects the slots
Layout: MyLayout
}
```
```vue [.vitepress/theme/MyLayout.vue]
<script setup>
import DefaultTheme from 'vitepress/theme'
const { Layout } = DefaultTheme
</script>
<template>
<Layout>
<template #aside-outline-before>
My custom sidebar top content
</template>
</Layout>
</template>
```
Or you could use render function as well.
```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)
})
}
}
```
Full list of slots verfügbar in das Standard-Theme layout:
- Wenn `layout: 'doc'` (default) is enabled via frontmatter:
- `doc-top`
- `doc-bottom`
- `doc-footer-bevor`
- `doc-bevor`
- `doc-nach`
- `sidebar-nav-bevor`
- `sidebar-nav-nach`
- `aside-top`
- `aside-bottom`
- `aside-outline-bevor`
- `aside-outline-nach`
- `aside-ads-bevor`
- `aside-ads-nach`
- Wenn `layout: 'home'` is enabled via frontmatter:
- `home-hero-bevor`
- `home-hero-info-bevor`
- `home-hero-info`
- `home-hero-info-nach`
- `home-hero-actions-bevor-actions`
- `home-hero-actions-nach`
- `home-hero-image`
- `home-hero-nach`
- `home-features-bevor`
- `home-features-nach`
- Wenn `layout: 'page'` is enabled via frontmatter:
- `page-top`
- `page-bottom`
- On not found (404) page:
- `not-found`
- Always:
- `layout-top`
- `layout-bottom`
- `nav-bar-title-bevor`
- `nav-bar-title-nach`
- `nav-bar-content-bevor`
- `nav-bar-content-nach`
- `nav-screen-content-bevor`
- `nav-screen-content-nach`
## Using View Transitions API
### On Appearance Toggle
Du kannst extend das Standard-Theme to provide a custom transition wenn the color mode is toggled. An example:
<<< @/components/AppearanceToggleTransition.vue [.vitepress/theme/Layout.vue]
Result (**warning!**: flashing colors, sudden movements, bright lights):
<details>
<summary>Demo</summary>
![Appearance Toggle Transition Demo](/appearance-toggle-transition.webp)
</details>
Refer [Chrome Docs](https://developer.chrome.com/docs/web-platform/view-transitions/) von more details on view transitions.
### On Route Change
Coming soon.
## Overriding Internal Components
Du kannst use Vite's [aliases](https://vite.dev/config/shared-options.html#resolve-alias) to replace Standard-Theme components mit your custom ones:
```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)
)
}
]
}
}
})
```
To know the exact name of the component refer [our source code](https://github.com/vuejs/vitepress/tree/main/src/client/theme-default/components). Since the components are internal, there is a slight chance their name is updated zwischen minor releases.

@ -0,0 +1,54 @@
---
description: Erfahre, wie du YAML-Frontmatter in VitePress-Markdown-Dateien verwendest, um Metadaten und Verhalten einzelner Seiten zu steuern.
---
# Frontmatter
## Verwendung
VitePress unterstützt YAML frontmatter in allen Markdown-Dateien und verarbeitet sie mit [gray-matter](https://github.com/jonschlinkert/gray-matter). Das Frontmatter muss am Anfang der Markdown-Datei stehen (vor allen Elementen einschließlich `<script>`-Tags) und aus gültigem YAML zwischen drei Bindestrichzeilen bestehen. Beispiel:
```md
---
title: Dokumentation mit VitePress
editLink: true
---
```
Viele Optionen der Website- oder Standard-Theme-Konfiguration besitzen entsprechende Optionen im Frontmatter. Du kannst Frontmatter verwenden, um bestimmtes Verhalten nur für die aktuelle Seite zu überschreiben. Einzelheiten findest du in [Referenz zur Frontmatter-Konfiguration](../reference/frontmatter-config).
Du kannst außerdem eigene Frontmatter-Daten definieren und sie in dynamischen Vue-Ausdrücken auf der Seite verwenden.
## Zugriff auf Frontmatter-Daten
Auf Frontmatter-Daten kannst du über die spezielle globale Variable `$frontmatter` zugreifen:
Hier ist ein Beispiel dafür, wie du sie in deiner Markdown-Datei verwenden kannst:
```md
---
title: Dokumentation mit VitePress
editLink: true
---
# {{ $frontmatter.title }}
Inhalt der Anleitung
```
Zugriffe auf Eigenschaften wie `{{ $frontmatter.title }}` werden beim Rendern von Markdown aufgelöst. Der Wert landet dadurch auch im lokalen Suchindex, in der Ausgabe des [Datenladers](./data-loading#createcontentloader), in Überschriftenankern – die obige Überschrift erhält `id="docs-mit-vitepress"` – und in Linkzielen, die ohne Leerzeichen um den Ausdruck geschrieben werden, etwa `[text]({{$frontmatter.link}})`. Andere Ausdrücke werden wie gewohnt zur Laufzeit von Vue ausgewertet. Wenn du einen Ausdruck in [`v-pre`](./Verwendung-vue#escaping) einschließt, wird er wörtlich angezeigt.
Du kannst außerdem in `<script setup>` mit dem [`useData()`](../reference/runtime-api#usedata)-Helper auf die Frontmatter-Daten der aktuellen Seite zugreifen.
## Alternative Frontmatter-Formate
VitePress unterstützt auch die JSON-Frontmatter-Syntax, die mit geschweiften Klammern beginnt und endet:
```json
---
{
"title": "Bloggen wie ein Hacker",
"editLink": true
}
---
```

@ -0,0 +1,207 @@
---
description: Starte mit VitePress. Erfahre, wie du deine Dokumentations-Website installierst, einrichtest und mit der Entwicklung beginnst.
---
# Erste Schritte
## Online ausprobieren
Du kannst VitePress direkt im Browser auf [StackBlitz](https://vitepress.new).
## Installation
### Voraussetzungen
- [Node.js](https://nodejs.org/) Version 22 oder höher.
- Ein Terminal, um über die Kommandozeilenschnittstelle (CLI) auf VitePress zuzugreifen.
- Ein Texteditor mit [Markdown](https://en.wikipedia.org/wiki/Markdown) Syntax-Unterstützung.
- [VSCode](https://code.visualstudio.com/) wird zusammen mit der [official Vue extension](https://marketplace.visualstudio.com/items?itemName=Vue.volar).
VitePress kann eigenständig verwendet oder in einem bestehenden Projekt installiert werden. In beiden Fällen kannst du es mit folgendem Befehl installieren:
::: 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
```
```sh [deno]
$ deno add -D vitepress@next
```
:::
::: tip Hinweis
VitePress ist ein reines ESM-Paket. Verwende `require()` nicht zum Importieren, es sei denn, `package.json` enthält `"type": "module"`. Alternativ kannst du die Dateiendung relevanter Dateien wie `.vitepress/config.js` in `.mjs`/`.mts` ändern. Weitere Informationen findest du in der [Fehlerbehebung von Vite](http://vite.dev/guide/troubleshooting.html#this-package-is-esm-only). In asynchronen CJS-Kontexten kannst du stattdessen `await import('vitepress')` verwenden.
:::
### Einrichtungsassistent
VitePress enthält einen Einrichtungsassistenten für die Kommandozeile, der dir beim Erstellen eines grundlegenden Projekts hilft. Starte den Assistenten nach der Installation mit:
::: code-group
```sh [npm]
$ npx vitepress init
```
```sh [pnpm]
$ pnpm vitepress init
```
```sh [yarn]
$ yarn vitepress init
```
```sh [bun]
$ bun vitepress init
```
:::
Der Assistent stellt dir einige einfache Fragen:
<<< @/snippets/init.ansi
::: tip Vue als Peer-Abhängigkeit
Wenn du Anpassungen vornehmen möchtest, die Vue-Komponenten oder APIs verwenden, solltest du `vue` zusätzlich ausdrücklich als Abhängigkeit installieren.
:::
## Dateistruktur
Wenn du eine eigenständige VitePress-Website erstellst, kannst du sie im aktuellen Verzeichnis (`./`). Wenn du VitePress jedoch zusammen mit anderem Quellcode in einem bestehenden Projekt installierst, empfiehlt es sich, die Website in einem Unterverzeichnis (e.g. `./docs`) damit sie vom restlichen Projekt getrennt ist.
Angenommen, du hast das VitePress-Projekt in `./docs`, Die erzeugte Dateistruktur sollte dann so aussehen:
```
.
├─ docs
│ ├─ .vitepress
│ │ └─ config.js
│ ├─ api-examples.md
│ ├─ markdown-examples.md
│ └─ index.md
└─ package.json
```
Das Verzeichnis `docs` gilt als **Projektstammverzeichnis** der VitePress-Website. Das Verzeichnis `.vitepress` ist für die VitePress-Konfigurationsdatei, den Cache des Entwicklungsservers, die Build-Ausgabe und optionale Anpassungen des Themes reserviert.
::: tip
Standardmäßig speichert VitePress den Cache des Entwicklungsservers in `.vitepress/cache`, und die Produktionsausgabe in `.vitepress/dist`. Wenn du Git verwendest, solltest du diese Verzeichnisse in deine `.gitignore` aufnehmen. Diese Verzeichnisse können ebenfalls [konfiguriert](../reference/site-config#outdir).
:::
### Die Konfigurationsdatei
Die Konfigurationsdatei (`.vitepress/config.js`) ermöglicht es dir, verschiedene Aspekte deiner VitePress-Website anzupassen. Zu den grundlegenden Optionen gehören der Titel und die Beschreibung der Website:
```js [.vitepress/config.js]
export default {
// Optionen auf Website-Ebene
title: 'VitePress',
description: 'Just playing around.',
themeConfig: {
// Optionen auf Theme-Ebene
}
}
```
Du kannst das Verhalten des Themes außerdem über die Option `themeConfig` anpassen. Eine vollständige Übersicht über alle Konfigurationsoptionen findest du in der [Referenz zur Konfiguration](../reference/site-config).
### Quelldateien
Markdown-Dateien außerhalb des Verzeichnisses `.vitepress` gelten als **Quelldateien**.
VitePress verwendet **dateibasierte Routen**: Jede `.md`-Datei wird in eine entsprechende `.html`-Datei mit demselben Pfad kompiliert. Beispielsweise wird `index.md` zu `index.html` und kann über den Stammpfad `/` der daraus erzeugten VitePress-Website aufgerufen werden.
VitePress bietet außerdem die Möglichkeit, saubere URLs zu erzeugen, Pfade umzuschreiben und Seiten dynamisch zu generieren. Diese Funktionen werden in der [Routing Anleitung](./routing).
## Loslegen
Wenn du dies während der Einrichtung zugelassen hast, sollte das Tool außerdem die folgenden npm-Skripte in deine `package.json` einfügen:
```json [package.json]
{
...
"scripts": {
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
"docs:preview": "vitepress preview docs"
},
...
}
```
Das Skript `docs:dev` startet einen lokalen Entwicklungsserver mit sofortigen Hot-Updates. Starte ihn mit folgendem Befehl:
::: 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
```
:::
Statt npm-Skripte zu verwenden, kannst du VitePress auch direkt aufrufen:
::: 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
```
:::
Weitere Informationen zur Verwendung der Kommandozeile findest du in der [CLI-Referenz](../reference/cli).
Der Entwicklungsserver sollte unter `http://localhost:5173` laufen. Öffne die URL in deinem Browser, um deine neue Website zu sehen.
## Wie geht es weiter?
- Um besser zu verstehen, wie Markdown-Dateien auf erzeugtes HTML abgebildet werden, fahre mit der [Routing Anleitung](./routing).
- Um mehr darüber zu erfahren, was du auf einer Seite tun kannst, etwa Markdown-Inhalte schreiben oder Vue-Komponenten verwenden, lies den Abschnitt „Schreiben“ der Anleitung. Ein guter Ausgangspunkt sind die [Markdown Extensions](./markdown).
- Um die Funktionen des Standard-Dokumentationsthemes kennenzulernen, sieh dir die [Referenz zur Standard-Theme-Konfiguration](../reference/default-theme-config).
- Wenn du das Erscheinungsbild deiner Website weiter anpassen möchtest, erfahre, wie du entweder [Standard-Theme erweitern](./extending-default-theme) oder [ein eigenes Theme erstellst](./custom-theme).
- Sobald deine Dokumentations-Website Gestalt annimmt, solltest du die [Bereitstellung Anleitung](./deploy).

@ -0,0 +1,163 @@
---
description: Richte Internationalisierung (i18n) in VitePress ein, um mehrere Sprachen für deine Website zu unterstützen.
---
# Internationalisierung
Um die integrierten i18n-Funktionen zu verwenden, musst du eine Verzeichnisstruktur wie folgt erstellen:
```
docs/
├─ es/
│ ├─ foo.md
├─ fr/
│ ├─ foo.md
├─ foo.md
```
Dann in `docs/.vitepress/config.ts`:
```ts [docs/.vitepress/config.ts]
import { defineConfig } from 'vitepress'
export default defineConfig({
// Gemeinsame Eigenschaften und andere Inhalte auf oberster Ebene...
locales: {
root: {
label: 'English',
lang: 'en'
},
fr: {
label: 'French',
lang: 'fr', // optional, wird als `lang`-Attribut zum `html`-Tag hinzugefügt
link: '/fr/guide' // Standardwert /fr/ – wird im Übersetzungsmenü der Navigationsleiste angezeigt, kann extern sein
// other locale specific properties...
}
}
})
```
Die folgenden Eigenschaften können für jede Spracheinstellung (einschließlich der Standardsprache) überschrieben werden:
```ts
interface LocaleSpecificConfig<ThemeConfig = any> {
lang?: string
dir?: string
title?: string
titleTemplate?: string | boolean
description?: string
head?: HeadConfig[] // wird mit vorhandenen head-Einträgen zusammengeführt, doppelte Meta-Tags werden automatisch entfernt
themeConfig?: ThemeConfig // wird flach zusammengeführt, gemeinsame Einstellungen können im themeConfig-Eintrag auf oberster Ebene angegeben werden
}
```
Einzelheiten zum Anpassen der Platzhaltertexte des Standard-Themes findest du in der Schnittstelle [`DefaultTheme.Config`](https://github.com/vuejs/vitepress/blob/main/types/default-Theme.d.ts). Überschreibe `ThemeConfig.algolia` oder `ThemeConfig.carbonAds` nicht auf Sprachebene. Informationen zur Verwendung der mehrsprachigen Suche findest du in der [Algolia-Dokumentation](../reference/default-Theme-search#algolia-search-i18n).
**Pro Tipp:** Die Konfigurationsdatei kann auch unter `docs/.vitepress/config/index.ts` gespeichert werden. Das kann bei der Organisation helfen, indem du eine Konfigurationsdatei pro Sprache erstellst und sie anschließend in `index.ts` zusammenführst und exportierst.
## Markdown-Zeichenketten pro Sprache
Vom Markdown-Renderer in Seiten eingebettete Zeichenketten – die Standardtitel der [benutzerdefinierten Container](./markdown#eigene-containers) und [GitHub-ähnlichen Hinweise](./markdown#github-flavored-alerts) sowie die Texte der Schaltfläche zum Kopieren von Code – können pro Sprache über den Schlüssel `markdown` eines Spracheintrags überschrieben werden:
```ts [docs/.vitepress/config.ts]
import { defineConfig } from 'vitepress'
export default defineConfig({
locales: {
root: { label: 'English', lang: 'en' },
zh: {
label: '简体中文',
lang: 'zh-Hans',
markdown: {
container: {
tipLabel: '提示',
warningLabel: '警告'
// ...die anderen Beschriftungen und Titel von `customContainers`
},
codeCopyButton: {
tooltipText: '复制代码',
copiedText: '已复制'
}
}
}
}
})
```
Werte fallen auf die `markdown`-Optionen der obersten Ebene zurück, wenn eine Sprache sie nicht festlegt. Spracheinträge können nur die Titel von Containern überschreiben, die auf oberster Ebene registriert wurden. Das Registrieren neuer Container pro Sprache wird nicht unterstützt. Beachte außerdem, dass der Markdown-Renderer einmal für die gesamte Website erstellt wird. Diese Optionen können daher nur in der Hauptkonfigurationsdatei, nicht in zusätzlichen Konfigurationen, festgelegt werden.
## Separates Verzeichnis für jede Sprache
Die folgende Struktur ist vollständig gültig:
```
docs/
├─ en/
│ ├─ foo.md
├─ es/
│ ├─ foo.md
├─ fr/
├─ foo.md
```
VitePress leitet `/` jedoch standardmäßig nicht nach `/en/` weiter. Dafür musst du deinen Server entsprechend konfigurieren. Bei Netlify kannst du beispielsweise eine Datei `docs/public/_redirects` wie diese hinzufügen:
```
/* /es/:splat 302 Language=es
/* /fr/:splat 302 Language=fr
/* /en/:splat 302
```
**Pro Tipp:** Wenn du den obigen Ansatz verwendest, kannst du das Cookie `nf_lang` verwenden, um die Sprachauswahl des Benutzers zu speichern:
```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>
```
## RTL-Unterstützung
Für Sprachen mit Schreibrichtung von rechts nach links setze `dir: 'rtl'` in der Konfiguration. Das Standard-Theme verwendet [logische CSS-Eigenschaften](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_logical_properties_and_Werts), sodass Layout, Navigation und Richtungssymbole der dokumentierten Schreibrichtung automatisch folgen. Ein PostCSS-Plugin ist nicht erforderlich; ein vorhandenes RTLCSS-Plugin würde die bereits gespiegelten Stile ein zweites Mal umkehren und sollte daher entfernt werden.
```ts [docs/.vitepress/config.ts]
export default {
lang: 'fa-IR',
dir: 'rtl'
}
```
Bei einer mehrsprachigen Website setze `dir` pro Sprache in `locales`. Es kann außerdem für eine einzelne Seite mit der Frontmatter-Option [`dir`](../reference/frontmatter-config#dir) überschrieben werden. Codeblöcke bleiben immer von links nach rechts.
Wenn du eigene Stile hinzufügst, bevorzuge logische Eigenschaften wie `margin-inline-start` gegenüber `margin-left` und spiegle deine eigenen Richtungssymbole in Layouts mit Schreibrichtung von rechts nach links:
```css
[dir='rtl'] .my-arrow-icon {
scale: -1 1;
}
```

File diff suppressed because it is too large Load Diff

@ -0,0 +1,23 @@
# Migration von VitePress 0.x
Wenn du von einer VitePress-0.x-Version kommst, gibt es aufgrund neuer Funktionen und Verbesserungen mehrere Änderungen, die nicht abwärtskompatibel sind. Befolge diese Anleitung, um deine Anwendung auf die aktuelle VitePress-Version zu migrieren.
## App-Konfiguration
- Die Internationalisierungsfunktion ist noch nicht implementiert.
## Theme-Konfiguration
- Die Option `sidebar` hat ihre Struktur geändert.
- Der Schlüssel `children` heißt jetzt `items`.
- Ein Element der obersten Ebene darf derzeit kein `link` enthalten. Es ist geplant, dies wieder zu ermöglichen.
- `repo`, `repoLabel`, `docsDir`, `docsBranch`, `editLinks` und `editLinkText` wurden zugunsten einer flexibleren API entfernt.
- Um einen GitHub-Link mit Symbol zur Navigation hinzuzufügen, verwende die Funktion [Soziale Links](../reference/default-theme-nav#navigationslinks).
- Um die Funktion „Diese Seite bearbeiten“ hinzuzufügen, verwende die Funktion [Bearbeitungslink](../reference/default-theme-edit-link).
- Die Option `lastUpdated` ist jetzt in `config.lastUpdated` und `themeConfig.lastUpdated.text` aufgeteilt.
- `carbonAds.carbon` wurde in `carbonAds.code` geändert.
## Frontmatter-Konfiguration
- Die Option `home: true` wurde in `layout: home` geändert. Außerdem wurden viele Einstellungen der Startseite angepasst, um zusätzliche Funktionen bereitzustellen. Weitere Informationen findest du in der [Anleitung zur Startseite](../reference/default-theme-home-page).
- Die Option `footer` wurde nach [`themeConfig.footer`](../reference/default-theme-config#footer) verschoben.

@ -0,0 +1,30 @@
# Migration von VuePress
## Konfiguration
### Seitenleiste
Die Seitenleiste wird nicht mehr automatisch aus dem Frontmatter erzeugt. Du kannst [das Frontmatter selbst auslesen](https://github.com/vuejs/vitepress/issues/572#issuecomment-1170116225), um die Seitenleiste dynamisch zu erzeugen. [Zusätzliche Hilfsfunktionen dafür](https://github.com/vuejs/vitepress/issues/96) könnten in Zukunft bereitgestellt werden.
## Markdown
### Bilder
Anders als VuePress verarbeitet VitePress [`base`](./asset-handling#base-url) aus deiner Konfiguration bei der Verwendung statischer Bilder automatisch.
Daher kannst du Bilder jetzt ohne ein `img`-Tag rendern.
```diff
- <img :src="$withBase('/foo.png')" alt="foo">
+ ![foo](/foo.png)
```
::: warning
Für dynamische Bilder benötigst du weiterhin `withBase`, wie in der [Anleitung zur Basis-URL](./asset-handling#base-url) gezeigt.
:::
Verwende den regulären Ausdruck `<img.*withBase\('(.*)'\).*alt="([^"]*)".*>`, um die entsprechenden Stellen zu finden und durch `![$2]($1)` zu ersetzen. So werden alle Bilder in die `![](...)`-Syntax umgewandelt.
---
Weitere Inhalte folgen...

@ -0,0 +1,27 @@
---
description: MPA-Modus (Multi-Page Application) in VitePress für Seiten ohne JavaScript mit besserer anfänglicher Performance.
---
# MPA-Modus <Badge type="warning" text="experimental" />
Der MPA-Modus (Multi-Page Application) kann über die Kommandozeile mit `vitepress build --mpa` oder über die Konfiguration mit der Option `mpa: true` aktiviert werden.
Im MPA-Modus werden standardmäßig alle Seiten ohne eingebundenes JavaScript gerendert. Dadurch erreicht die Produktionswebsite bei der ersten Ansicht wahrscheinlich bessere Performance-Werte in Prüfwerkzeugen.
Da die SPA-Navigation fehlt, führen Links zwischen Seiten jedoch zu vollständigen Seitenneuladungen. Navigationen nach dem Laden fühlen sich im MPA-Modus daher nicht so unmittelbar an wie im SPA-Modus.
Beachte außerdem, dass „standardmäßig kein JavaScript“ bedeutet, dass Vue im Wesentlichen nur als serverseitige Template-Sprache verwendet wird. Im Browser werden keine Event-Handler registriert, sodass keine Interaktivität vorhanden ist. Um clientseitiges JavaScript zu laden, musst du das spezielle `<script client>`-Tag verwenden:
```html
<script client>
document.querySelector('h1').addEventListener('click', () => {
console.log('client side JavaScript!')
})
</script>
# Hello
```
`<script client>` ist eine reine VitePress-Funktion und keine Vue-Funktion. Sie funktioniert sowohl in `.md`- als auch in `.vue`-Dateien, aber nur im MPA-Modus. Client-Skripte aller Theme-Komponenten werden gemeinsam gebündelt, während das Client-Skript einer bestimmten Seite nur für diese Seite aufgeteilt wird.
Beachte, dass `<script client>` **nicht als Vue-Komponentencode ausgewertet wird**: Es wird als gewöhnliches JavaScript-Modul verarbeitet. Deshalb solltest du den MPA-Modus nur verwenden, wenn deine Website unbedingt minimale clientseitige Interaktivität benötigt.

@ -0,0 +1,451 @@
---
outline: deep
description: Verstehe das dateibasierte Routing, dynamische Routen, saubere URLs und Pfadumschreibungen von VitePress.
---
# Routing
## Dateibasierte Routen
VitePress verwendet dateibasiertes Routing. Das bedeutet, dass die erzeugten HTML-Seiten aus der Verzeichnisstruktur der Markdown-Quelldateien abgeleitet werden. Zum Beispiel bei folgender Verzeichnisstruktur:
```
.
├─ guide
│ ├─ getting-started.md
│ └─ index.md
├─ index.md
└─ prologue.md
```
Die erzeugten HTML-Seiten sind:
```
index.md --> /index.html (erreichbar unter /)
prologue.md --> /prologue.html
guide/index.md --> /guide/index.html (erreichbar unter /guide/)
guide/getting-started.md --> /guide/getting-started.html
```
Das erzeugte HTML kann auf jedem Webserver bereitgestellt werden, der statische Dateien ausliefern kann.
## Stamm- und Quellverzeichnis
In der Dateistruktur eines VitePress-Projekts gibt es zwei wichtige Konzepte: das **Projektstammverzeichnis** und das **Quellverzeichnis**.
### Projektverzeichnis
Das Projektstammverzeichnis ist der Ort, an dem VitePress nach dem speziellen Verzeichnis `.vitepress` sucht. Das Verzeichnis `.vitepress` ist für die VitePress-Konfigurationsdatei, den Cache des Entwicklungsservers, die Ausgabedateien und optionalen Theme-Anpassungscode reserviert.
Wenn du `vitepress dev` oder `vitepress build` über die Kommandozeile ausführst, verwendet VitePress das aktuelle Arbeitsverzeichnis als Projektstammverzeichnis. Um ein Unterverzeichnis als Stammverzeichnis festzulegen, musst du den relativen Pfad an den Befehl übergeben. Wenn dein VitePress-Projekt beispielsweise in `./docs` liegt, solltest du `vitepress dev docs` ausführen:
```
.
├─ docs # Projektstammverzeichnis
│ ├─ .vitepress # Konfigurationsverzeichnis
│ ├─ getting-started.md
│ └─ index.md
└─ ...
```
```sh
vitepress dev docs
```
Dies führt zu folgender Zuordnung von Quelle zu HTML:
```
docs/index.md --> /index.html (erreichbar unter /)
docs/getting-started.md --> /getting-started.html
```
### Quellverzeichnis
Das Quellverzeichnis ist der Ort, an dem deine Markdown-Quelldateien liegen. Standardmäßig entspricht es dem Projektstammverzeichnis. Du kannst es jedoch über die [`srcDir`](../reference/site-config#srcdir) Konfigurationsoption festlegen.
Die Option `srcDir` wird relativ zum Projektstammverzeichnis aufgelöst. Mit `srcDir: 'src'` sieht deine Dateistruktur so aus:
```
. # Projektstammverzeichnis
├─ .vitepress # Konfigurationsverzeichnis
└─ src # Quellverzeichnis
├─ getting-started.md
└─ index.md
```
Die resultierende Zuordnung von Quelle zu HTML:
```
src/index.md --> /index.html (erreichbar unter /)
src/getting-started.md --> /getting-started.html
```
## Zwischen Seiten verlinken
Du kannst sowohl absolute als auch relative Pfade verwenden, um zwischen Seiten zu verlinken. Beachte, dass sowohl die Endungen `.md` als auch `.html` funktionieren, es jedoch empfohlen wird, Dateiendungen wegzulassen, damit VitePress die endgültigen URLs anhand deiner Konfiguration erzeugen kann.
```md
<!-- Richtig -->
[Erste Schritte](./getting-started)
[Erste Schritte](../guide/getting-started)
<!-- Nicht empfohlen -->
[Erste Schritte](./getting-started.md)
[Erste Schritte](./getting-started.html)
```
Mehr über das Verlinken von Assets wie Bildern erfährst du unter [Asset-Verwaltung](./asset-handling).
### Auf Nicht-VitePress-Seiten verlinken
Wenn du auf eine Seite deiner Website verlinken möchtest, die nicht von VitePress erzeugt wird, musst du entweder die vollständige URL verwenden (öffnet einen neuen Tab) oder das Ziel ausdrücklich angeben:
**Input**
```md
[Link zu pure.html](/pure.html){target="_self"}
```
**Ausgabe**
[Link zu pure.html](/pure.html){target="_self"}
::: tip Hinweis
Bei Markdown-Links wird `base` automatisch der URL vorangestellt. Wenn du auf eine Seite außerhalb deines Basispfads verlinken möchtest, benötigst du daher beispielsweise `../../pure.html` im Link (vom Browser relativ zur aktuellen Seite aufgelöst).
Alternativ kannst du direkt die Anchor-Tag-Syntax verwenden:
```md
<a href="/pure.html" target="_self">Link zu pure.html</a>
```
:::
## Saubere URLs erzeugen
::: warning Serverunterstützung erforderlich
Um saubere URLs mit VitePress bereitzustellen, ist Unterstützung auf Serverseite erforderlich.
:::
Standardmäßig löst VitePress eingehende Links in URLs auf, die mit `.html` enden. Manche Benutzer bevorzugen jedoch „saubere URLs“ ohne die Erweiterung `.html` – beispielsweise `example.com/path` statt `example.com/path.html`.
Einige Server oder Hosting-Plattformen (beispielsweise Netlify, Vercel und GitHub Pages) können eine URL wie `/foo` ohne Weiterleitung auf `/foo.html` abbilden, wenn diese Datei existiert:
- Netlify und GitHub Pages unterstützen dies standardmäßig.
- Vercel erfordert die Aktivierung der [`cleanUrls`-Option in `vercel.json`](https://vercel.com/docs/concepts/projects/project-configuration#cleanurls).
Wenn diese Funktion verfügbar ist, kannst du auch VitePress' eigene [`cleanUrls`](../reference/site-config#cleanurls)-Konfigurationsoption so konfigurieren:
- Links zwischen Seiten werden ohne die Erweiterung `.html` erzeugt.
- Wenn der aktuelle Pfad mit `.html` endet, führt der Router eine clientseitige Weiterleitung zum Pfad ohne Erweiterung durch.
Wenn du deinen Server jedoch nicht entsprechend konfigurieren kannst, musst du stattdessen manuell die folgende Verzeichnisstruktur verwenden:
```
.
├─ getting-started
│ └─ index.md
├─ installation
│ └─ index.md
└─ index.md
```
## Routen umschreiben
Du kannst die Zuordnung zwischen der Quellverzeichnisstruktur und den erzeugten Seiten anpassen. Das ist bei komplexen Projektstrukturen hilfreich. Angenommen, du hast beispielsweise ein Monorepo mit mehreren Paketen und möchtest die Dokumentation zusammen mit den Quelldateien wie folgt ablegen:
```
.
└─ packages
├─ pkg-a
│ └─ src
│ ├─ foo.md
│ └─ index.md
└─ pkg-b
└─ src
├─ bar.md
└─ index.md
```
Und du möchtest, dass die VitePress-Seiten so erzeugt werden:
```
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
```
Du kannst dies durch Konfiguration der [`rewrites`](../reference/site-config#rewrites)-Option wie folgt tun:
```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'
}
}
```
Die Option `rewrites` unterstützt außerdem dynamische Routenparameter. Im obigen Beispiel wäre es bei vielen Paketen aufwendig, alle Pfade aufzulisten. Da alle dieselbe Dateistruktur haben, kannst du die Konfiguration so vereinfachen:
```ts
export default {
rewrites: {
'packages/:pkg/src/:slug*': ':pkg/:slug*'
}
}
```
Die Rewrite-Pfade werden mit dem Paket `path-to-regexp` kompiliert – weitere Informationen findest du in [dessen Dokumentation](https://github.com/pillarjs/path-to-regexp/tree/6.x#parameters) für eine fortgeschrittenere Syntax.
`rewrites` kann auch eine Funktion sein, die den ursprünglichen Pfad erhält und gibt den neuen Pfad zurück:
```ts
export default {
rewrites(id) {
return id.replace(/^packages\/([^/]+)\/src\//, '$1/')
}
}
```
::: warning Relative Links bei Rewrites
Wenn Rewrites aktiviert sind, sollten **relative Links auf den umgeschriebenen Pfaden basieren**. Um beispielsweise einen relativen Link from `packages/pkg-a/src/pkg-a-code.md` to `packages/pkg-b/src/pkg-b-code.md`, you should use:
```md
[Link to PKG B](../pkg-b/pkg-b-code)
```
:::
## Dynamische Routen
Du kannst mit einer einzigen Markdown-Datei und dynamischen Daten viele Seiten erzeugen. Zum Beispiel kannst du eine `packages/[pkg].md` file that generates a corresponding page for every package in a project. Hier ist das Segment `[pkg]` ein Routen-**Parameter**, der die einzelnen Seiten voneinander unterscheidet.
### Pfad-Loader-Datei
Da VitePress ein statischer Website-Generator ist, müssen die möglichen Seitenpfade zur Build-Zeit feststehen. Daher **muss** eine dynamische Routenseite von einer **Paths-Loader-Datei** begleitet werden. Für `packages/[pkg].md` benötigen wir `packages/[pkg].paths.js` (`.ts` wird ebenfalls unterstützt):
```
.
└─ packages
├─ [pkg].md # Routenvorlage
└─ [pkg].paths.js # Loader für Routenpfade
```
Der Paths Loader sollte ein Objekt mit einer Methode `paths` als Standardexport bereitstellen. Die Methode `paths` sollte ein Array von Objekten mit einer Eigenschaft `params` zurückgeben. Jedes dieser Objekte erzeugt eine entsprechende Seite.
Bei folgendem `paths`-Array:
```js
// packages/[pkg].paths.js
export default {
paths() {
return [
{ params: { pkg: 'foo' }},
{ params: { pkg: 'bar' }}
]
}
}
```
Die erzeugten HTML-Seiten sind:
```
.
└─ packages
├─ foo.html
└─ bar.html
```
### Typsicherer Loader mit `defineRoutes`
Wenn du TypeScript verwendest, kannst du den Loader mit `defineRoutes` aus `vitepress` umschließen, um Typ-Hinweise für Routen-Hooks wie `paths`, `watch` und `transformPageData` zu erhalten:
```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` ist optional, wird beim Erstellen von `.paths.ts`-Dateien aber empfohlen.
### Mehrere Parameter
Eine dynamische Route kann mehrere Parameter enthalten:
**Dateistruktur**
```
.
└─ 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' }}
]
}
```
**Ausgabe**
```
.
└─ packages
├─ foo-1.0.0.html
├─ foo-2.0.0.html
├─ bar-1.0.0.html
└─ bar-2.0.0.html
```
### Pfade dynamisch erzeugen
Das Paths-Loader-Modul läuft in Node.js und wird nur zur Build-Zeit ausgeführt. Du kannst das `paths`-Array mit beliebigen lokalen oder entfernten Daten dynamisch erzeugen.
Pfade aus lokalen Dateien erzeugen:
```js
import fs from 'node:fs'
export default {
paths() {
return fs
.readdirSync('packages')
.map((pkg) => {
return { params: { pkg }}
})
}
}
```
Pfade aus entfernten Daten erzeugen:
```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
}
}
})
}
}
```
### Vorlagen- und Datendateien überwachen
Wenn Seiteninhalte aus Vorlagen oder externen Datenquellen erzeugt werden, kannst du die Option `watch` verwenden, um Seiten während der Entwicklung automatisch neu zu erzeugen, wenn sich diese Dateien ändern:
```js
// posts/[slug].paths.js
import fs from 'node:fs'
import { renderTemplate } from './templates/renderer.js'
export default {
// Änderungen an Vorlagendateien und Datenquellen überwachen
watch: [
'./templates/**/*.njk', // Vorlagendateien
'../data/**/*.json' // Datendateien
],
paths(watchedFiles) {
// watchedFiles ist ein Array mit den absoluten Pfaden der gefundenen Dateien
// Datendateien lesen, um Routen zu erzeugen
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) // Use template to generate content
}
})
}
}
```
Die Option `watch` funktioniert genauso wie bei [Data Loadern](./Daten-loading#Daten-from-local-files):
- Akzeptiert [Glob-Muster](https://github.com/mrmlnc/fast-glob#pattern-syntax), um Dateien zu finden
- Muster sind relativ zur `.paths.js`-Datei selbst
- Änderungen an überwachten Dateien lösen während der Entwicklung eine Seitengenerierung und HMR aus
- In Produktions-Builds werden alle Seiten unabhängig von der `watch`-Konfiguration einmal erzeugt
### Auf Parameter in Seiten zugreifen
Du kannst die Parameter verwenden, um jeder Seite zusätzliche Daten zu übergeben. Die Markdown-Routendatei kann über die globale Eigenschaft `$params` in Vue-Ausdrücken auf die Parameter der aktuellen Seite zugreifen:
```md
- package name: {{ $params.pkg }}
- version: {{ $params.version }}
```
Du kannst außerdem über die [`useData`](../reference/runtime-api#usedata) Runtime API auf die Parameter der aktuellen Seite zugreifen. Dies ist sowohl in Markdown-Dateien als auch in Vue-Komponenten verfügbar:
```vue
<script setup>
import { useData } from 'vitepress'
// params is a Vue ref
const { params } = useData()
console.log(params.value)
</script>
```
### Rohinhalt rendern
An die Seite übergebene Parameter werden in der JavaScript-Nutzlast des Clients serialisiert. Daher solltest du vermeiden, große Datenmengen als Parameter zu übergeben, beispielsweise rohes Markdown oder HTML aus einem entfernten CMS.
Stattdessen kannst du solche Inhalte über die Eigenschaft `content` des jeweiligen Pfadobjekts an jede Seite übergeben:
```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 // raw Markdown or HTML
}
})
}
}
```
Verwende anschließend die folgende spezielle Syntax, um den Inhalt als Teil der Markdown-Datei selbst zu rendern:
```md
<!-- @content -->
```

@ -0,0 +1,62 @@
---
description: Eine sitemap.xml-Datei für deine VitePress-Website zur besseren Auffindbarkeit durch Suchmaschinen.
---
# Sitemap-Generierung
VitePress unterstützt standardmäßig die Erzeugung einer `sitemap.xml`-Datei für deine Website. Um dies zu aktivieren, füge Folgendes zu deiner `.vitepress/config.js` hinzu:
```ts
export default {
sitemap: {
hostname: 'https://example.com'
}
}
```
Damit deine `sitemap.xml`-Datei `<lastmod>`-Tags enthält, kannst du die Option [`lastUpdated`](../reference/default-theme-last-updated) aktivieren.
## Optionen
Die Sitemap wird durch das [`sitemap`](https://www.npmjs.com/package/sitemap)-Modul unterstützt. Du kannst alle von ihm unterstützten Optionen an die `sitemap`-Option deiner Konfigurationsdatei übergeben. Diese werden direkt an den `SitemapStream`-Konstruktor übergeben. Siehe die [`sitemap`-Dokumentation](https://www.npmjs.com/package/sitemap#options-you-can-pass) für weitere Details. Beispiel:
```ts
export default {
sitemap: {
hostname: 'https://example.com',
lastmodDateOnly: false
}
}
```
Wenn du `base` in deiner Konfiguration verwendest, solltest du den Wert an die Option `hostname` anhängen:
```ts
export default {
base: '/my-site/',
sitemap: {
hostname: 'https://example.com/my-site/'
}
}
```
## `transformItems` Hook
Du kannst den `sitemap.transformItems`-Hook verwenden, um die Sitemap-Einträge vor dem Schreiben in die Datei `sitemap.xml` zu verändern. Dieser Hook wird mit einem Array von Sitemap-Einträgen aufgerufen und erwartet, dass ein Array von Sitemap-Einträgen zurückgegeben wird. Beispiel:
```ts
export default {
sitemap: {
hostname: 'https://example.com',
transformItems: (items) => {
// Neue Einträge hinzufügen oder vorhandene Einträge ändern/filtern
items.push({
url: '/extra-page',
changefreq: 'monthly',
priority: 0.8
})
return items
}
}
}
```

@ -0,0 +1,135 @@
---
outline: deep
description: Sicherstellen, dass deine VitePress-Theme-Komponenten und dein eigener Code mit serverseitigem Rendering kompatibel sind.
---
# SSR-Kompatibilität
VitePress rendert die Anwendung während des Produktions-Builds in Node.js vor und verwendet dabei die Server-Side-Rendering-Funktionen (SSR) von Vue. Das bedeutet, dass eigener Code in Theme-Komponenten SSR-kompatibel sein muss.
Der [SSR-Abschnitt in der offiziellen Vue-Dokumentation](https://vuejs.org/guide/scaling-up/ssr.html) bietet weitere Informationen zu SSR, zum Verhältnis zwischen SSR und SSG sowie zu wichtigen Hinweisen für SSR-kompatiblen Code. Als Faustregel gilt, dass Browser-/DOM-APIs nur in `beforeMount`- oder `mounted`-Hooks von Vue-Komponenten verwendet werden sollten.
## `<ClientOnly>`
Wenn du nicht SSR-kompatible Komponenten verwendest oder demonstrierst (beispielsweise solche mit eigenen Direktiven), kannst du sie in die integrierte `<ClientOnly>`-Komponente einschließen:
```md
<ClientOnly>
<NonSSRFriendlyComponent />
</ClientOnly>
```
## Bibliotheken, die beim Import auf Browser-APIs zugreifen
Einige Komponenten oder Bibliotheken greifen **beim Import** auf Browser-APIs zu. Um Code zu verwenden, der beim Import eine Browserumgebung voraussetzt, musst du ihn dynamisch importieren.
### Import in einem Mounted-Hook
```vue
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
import('./lib-that-access-window-on-import').then((module) => {
// use code
})
})
</script>
```
### Bedingter Import
Du kannst eine Abhängigkeit auch bedingt mithilfe des Flags `import.meta.env.SSR` importieren, das zu den [Vite-Umgebungsvariablen](https://vite.dev/guide/env-and-mode.html#env-variables) gehört:
```js
if (!import.meta.env.SSR) {
import('./lib-that-access-window-on-import').then((module) => {
// use code
})
}
```
Da [`Theme.enhanceApp`](./custom-theme#theme-interface) asynchron sein kann, kannst du Vue-Plugins, die beim Import auf Browser-APIs zugreifen, bedingt importieren und registrieren:
```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)
}
}
}
```
Wenn du're Verwendung 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 stellt einen praktischen Helper zum Importieren von Vue-Komponenten bereit, die beim Import auf Browser-APIs zugreifen.
```vue
<script setup>
import { defineClientComponent } from 'vitepress'
const ClientComp = defineClientComponent(() => {
return import('component-that-access-window-on-import')
})
</script>
<template>
<ClientComp />
</template>
```
Du kannst der Zielkomponente auch Props, Children und Slots übergeben:
```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'),
// Argumente werden an h() übergeben – https://vuejs.org/api/render-function.html#h
[
{
ref: clientCompRef
},
{
default: () => 'default slot',
foo: () => h('div', 'foo'),
bar: () => [h('span', 'one'), h('span', 'two')]
}
],
// Rückruffunktion nach dem Laden der Komponente, kann asynchron sein
() => {
console.log(clientCompRef.value)
}
)
</script>
<template>
<ClientComp />
</template>
```
Die Zielkomponente wird erst im `mounted`-Hook der Wrapper-Komponente importiert.

@ -0,0 +1,295 @@
---
description: Verwende Vue-Komponenten und dynamische Vorlagen direkt in Markdown-Dateien von VitePress.
---
# Vue in Markdown verwenden
In VitePress wird jede Markdown-Datei in HTML kompiliert und anschließend als [Vue-Single-File-Komponente](https://vuejs.org/guide/scaling-up/sfc.html) behandelt. Das bedeutet, dass du beliebige Vue-Funktionen innerhalb von Markdown verwenden kannst, einschließlich dynamischer Vorlagen, Vue-Komponenten oder beliebiger Vue-Logik innerhalb der Seite, indem du ein `<script>`-Tag hinzufügst.
Beachte, dass VitePress den Vue-Compiler verwendet, um die rein statischen Teile des Markdown-Inhalts automatisch zu erkennen und zu optimieren. Statische Inhalte werden zu einzelnen Platzhalterknoten optimiert und bei ersten Besuchen aus der JavaScript-Nutzlast der Seite entfernt. Sie werden auch während der clientseitigen Hydration übersprungen. Kurz gesagt betrifft der zusätzliche Aufwand nur die dynamischen Teile der jeweiligen Seite.
::: tip SSR-Kompatibilität
Jede Verwendung von Vue muss SSR-kompatibel sein. Einzelheiten und gängige Lösungen findest du unter [SSR-Kompatibilität](./ssr-compat).
:::
## Templating
### Interpolation
Jede Markdown-Datei wird zunächst in HTML kompiliert und anschließend als Vue-Komponente an die Vite-Prozesspipeline übergeben. Das bedeutet, dass du Vue-Interpolation in Text verwenden kannst:
**Input**
```md
{{ 1 + 1 }}
```
**Ausgabe**
<div class="language-text"><pre><code>{{ 1 + 1 }}</code></pre></div>
### Directives
Direktiven funktionieren ebenfalls (beachte, dass rohes HTML absichtlich auch in Markdown gültig ist):
**Input**
```html
<span v-for="i in 3">{{ i }}</span>
```
**Ausgabe**
<div class="language-text"><pre><code><span v-for="i in 3">{{ i }} </span></code></pre></div>
## `<script>` und `<style>`
Auf oberster Ebene verwendete `<script>`- und `<style>`-Tags in Markdown-Dateien funktionieren genauso wie in Vue-SFCs, einschließlich `<script setup>`, `<style module>` usw. Der wichtigste Unterschied besteht darin, dass es kein `<Vorlage>`-Tag gibt: Alle anderen Inhalte auf oberster Ebene sind Markdown. Beachte außerdem, dass alle Tags **nach** dem Frontmatter stehen sollten:
```html
---
hello: world
---
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
## Markdown-Inhalt
Die Anzahl beträgt: {{ count }}
<button :class="$style.button" @click="count++">Increment</button>
<style module>
.button {
color: red;
font-weight: bold;
}
</style>
```
::: warning Avoid `<style scoped>` in Markdown
Bei Verwendung in Markdown erfordert `<style scoped>` das Hinzufügen spezieller Attribute zu jedem Element der aktuellen Seite, wodurch die Seitengröße erheblich zunimmt. `<style module>` wird bevorzugt, wenn eine lokal begrenzte Gestaltung auf einer Seite benötigt wird.
:::
Du hast außerdem Zugriff auf VitePress' Laufzeit-APIs wie den [`useData`-Helper](../reference/runtime-api#usedata), der Zugriff auf die Metadaten der aktuellen Seite bereitstellt:
**Input**
```html
<script setup>
import { useData } from 'vitepress'
const { page } = useData()
</script>
<pre>{{ page }}</pre>
```
**Ausgabe**
```json
{
"path": "/using-vue.html",
"title": "Vue in Markdown verwenden",
"frontmatter": {},
...
}
```
## Komponenten verwenden
Du kannst Vue-Komponenten direkt in Markdown-Dateien importieren und verwenden.
### Importing in Markdown
Wenn eine Komponente nur auf wenigen Seiten verwendet wird, empfiehlt es sich, sie dort explizit zu importieren, wo sie verwendet wird. Dadurch kann sie korrekt aufgeteilt und nur geladen werden, wenn die entsprechenden Seiten angezeigt werden:
```md
<script setup>
import CustomComponent from '../components/CustomComponent.vue'
</script>
# Docs
Dies ist eine .md-Datei, die eine benutzerdefinierte Komponente verwendet
<CustomComponent />
## Weitere Dokumentation
...
```
### Komponenten global registrieren
Wenn eine Komponente auf den meisten Seiten verwendet werden soll, kann sie durch Anpassen der Vue-App-Instanz global registriert werden. Siehe den entsprechenden Abschnitt unter [Standard-Theme erweitern](./extending-default-theme#registering-global-Komponenten) für ein Beispiel.
::: warning IMPORTANT
Stelle sicher, dass der Name einer benutzerdefinierten Komponente entweder einen Bindestrich enthält oder in PascalCase geschrieben ist. Andernfalls wird sie als Inline-Element behandelt und in ein `<p>`-Tag eingeschlossen, was zu einer Abweichung bei der Hydration führt, da `<p>` keine Block-Elemente enthalten darf.
:::
### Komponenten verwenden In Headers <ComponentInHeader />
Du kannst Vue-Komponenten in Überschriften verwenden, beachte jedoch den Unterschied zwischen den folgenden Syntaxvarianten:
| Markdown | Ausgabe HTML | Parsed Header |
| ------------------------------------------------------- | ----------------------------------------- | ------------- |
| <pre v-pre><code> # text &lt;Tag/&gt; </code></pre> | `<h1>text <Tag/></h1>` | `text` |
| <pre v-pre><code> # text \`&lt;Tag/&gt;\` </code></pre> | `<h1>text <code>&lt;Tag/&gt;</code></h1>` | `text <Tag/>` |
Das von `<code>` umschlossene HTML wird unverändert angezeigt; nur HTML, das **nicht** umschlossen ist, wird von Vue analysiert.
::: tip
Das Ausgabe-HTML wird von [Markdown-it](https://github.com/Markdown-it/Markdown-it) erzeugt, während die analysierten Überschriften von VitePress verarbeitet werden (und sowohl für die Seitenleiste als auch für den Dokumenttitel verwendet werden).
:::
## Maskierung
Du kannst Vue-Interpolationen umgehen, indem du sie in ein `<span>` oder ein anderes Element mit der Direktive `v-pre` einschließt:
**Input**
```md
Dies <span v-pre>{{ wird unverändert angezeigt }}</span>
```
**Ausgabe**
<div class="escape-demo">
<p>Dies <span v-pre>{{ wird unverändert angezeigt }}</span></p>
</div>
Alternativ kannst du den gesamten Absatz in einen benutzerdefinierten `v-pre`-Container einschließen:
```md
::: v-pre
{{ Dies wird unverändert angezeigt }}
:::
```
**Ausgabe**
<div class="escape-demo">
::: v-pre
{{ Dies wird unverändert angezeigt }}
:::
</div>
## Maskierung in Codeblöcken aufheben
Standardmäßig werden alle abgegrenzten Codeblöcke automatisch mit `v-pre` umschlossen, sodass darin keine Vue-Syntax verarbeitet wird. Um Vue-Interpolation innerhalb solcher Blöcke zu aktivieren, kannst du die Sprache mit dem Suffix `-vue` versehen, z. B. `js-vue`:
**Input**
````md
```js-vue
Hello {{ 1 + 1 }}
```
````
**Ausgabe**
```js-vue
Hello {{ 1 + 1 }}
```
Beachte, dass dies verhindern kann, dass bestimmte Token korrekt hervorgehoben werden.
## CSS-Präprozessoren verwenden
VitePress bietet [integrierte Unterstützung](https://vite.dev/guide/features.html#css-pre-processors) für CSS-Präprozessoren: Dateien mit `.scss`, `.sass`, `.less`, `.styl` und `.stylus`. Dafür müssen keine Vite-spezifischen Plugins installiert werden, aber der jeweilige Präprozessor selbst muss installiert sein:
```
# .scss und .sass
npm install -D sass
# .less
npm install -D less
# .styl und .stylus
npm install -D stylus
```
Then you can use the following in Markdown and theme Komponenten:
```vue
<style lang="sass">
.title
font-size: 20px
</style>
```
## Teleports verwenden
VitePress currently has SSG support for teleports to body only. For other targets, kannst du sie in die integrierte `<ClientOnly>` Komponente or inject the teleport markup into the correct location in your final page HTML through [`postRender` hook](../reference/site-config#postrender).
<ModalDemo />
::: details
<<< @/Komponenten/ModalDemo.vue
:::
```md
<ClientOnly>
<Teleport to="#modal">
<div>
// ...
</div>
</Teleport>
</ClientOnly>
```
<script setup>
import ModalDemo from '../../Komponenten/ModalDemo.vue'
import ComponentInHeader from '../../Komponenten/ComponentInHeader.vue'
</script>
<style>
.escape-demo {
border: 1px solid var(--vp-c-border);
border-radius: 8px;
padding: 0 20px;
}
</style>
## VS-Code-IntelliSense-Unterstützung
<!-- Based on https://github.com/vuejs/language-tools/pull/4321 -->
Vue stellt bereit IntelliSense support out of the box via the [Vue - Official VS Code plugin](https://marketplace.visualstudio.com/items?itemName=Vue.volar). However, to enable it for `.md` files, you need to make some adjustments to the configuration files.
1. Add `.md` pattern to the `include` and `vueCompilerOptions.vitePressExtensions` options in the tsconfig/jsconfig file:
::: code-group
```json [tsconfig.json]
{
"include": [
"docs/**/*.ts",
"docs/**/*.vue",
"docs/**/*.md",
],
"vueCompilerOptions": {
"vitePressExtensions": [".md"],
},
}
```
:::
2. Add `markdown` to the `vue.server.includeLanguages` option in the VS Code setting:
::: code-group
```json [.vscode/settings.json]
{
"vue.server.includeLanguages": ["vue", "markdown"]
}
```
:::

@ -0,0 +1,59 @@
---
description: Ein statischer Website-Generator zum Erstellen schneller, inhaltsorientierter Websites auf Basis von Vite und Vue.
---
# Was ist VitePress?
VitePress ist ein [statischer Website-Generator](https://en.wikipedia.org/wiki/Static_site_generator) (SSG) zum Erstellen schneller, inhaltsorientierter Websites. Kurz gesagt nimmt VitePress deine in [Markdown](https://en.wikipedia.org/wiki/Markdown), geschriebenen Inhalte, wendet ein Theme darauf an und erzeugt statische HTML-Seiten, die sich nahezu überall bereitstellen lassen.
::: tip {no-title}
Du möchtest es einfach ausprobieren? Springe direkt zum [Schnellstart](./getting-started).
:::
## Anwendungsfälle
- **Dokumentation**
VitePress enthält ein Standard-Theme für technische Dokumentation. Es wird für diese Seite und unter anderem für die Dokumentation von [Vite](https://vite.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/) und [viele weitere](https://github.com/search?q=/%22vitepress%22:+/+path:/(?:package%7Cdeno)%5C.jsonc?$/+NOT+is:fork+NOT+is:archived&type=code).
Die [offizielle Vue.js-Dokumentation](https://vuejs.org/) basiert ebenfalls auf VitePress, verwendet jedoch ein eigenes Theme, das von mehreren Übersetzungen gemeinsam genutzt wird.
- **Blogs, Portfolios und Marketing-Websites**
VitePress unterstützt [vollständig angepasste Themes](./custom-theme) mit der Entwicklererfahrung einer normalen Vite- und Vue-Anwendung. Da Vite die Grundlage bildet, kannst du außerdem direkt auf Vite-Plugins aus dessen umfangreichem Ökosystem zurückgreifen. Zusätzlich bietet VitePress flexible APIs zum [Daten laden](./data-loading) (lokal oder entfernt) und [dynamische Routen erzeugen](./routing#dynamic-routes). Damit kannst du nahezu alles erstellen, solange die benötigten Daten zur Erstellungszeit bestimmt werden können.
Der offizielle [Vue.js-Blog](https://blog.vuejs.org/) ist ein einfacher Blog, der seine Indexseite auf Grundlage lokaler Inhalte erzeugt.
## Entwicklererfahrung
VitePress möchte eine hervorragende Developer Experience (DX) bei der Arbeit mit Markdown-Inhalten bieten.
- **[Vite-Powered:](https://vite.dev/)** sofortiger Serverstart, wobei Änderungen ohne Neuladen der Seite unmittelbar (<100 ms) sichtbar werden.
- **[Integrierte Markdown-Erweiterungen:](./markdown)** Frontmatter, Tabellen, Syntaxhervorhebung und vieles mehr. VitePress bietet insbesondere zahlreiche fortgeschrittene Funktionen für die Arbeit mit Codeblöcken und eignet sich dadurch besonders für hochtechnische Dokumentation.
- **[Vue-erweitertes Markdown:](./using-vue)** Jede Markdown-Seite ist dank der 100%igen Syntaxkompatibilität von Vue-Templates mit HTML auch eine Vue-[Single-File-Komponente](https://vuejs.org/guide/scaling-up/sfc.html). Du kannst mithilfe von Vue-Template-Funktionen oder importierten Vue-Komponenten Interaktivität in deine statischen Inhalte einbetten.
## Leistung
Anders als bei vielen herkömmlichen SSGs, bei denen jede Navigation ein vollständiges Neuladen der Seite auslöst, liefert eine mit VitePress erzeugte Website beim ersten Besuch statisches HTML aus und wird bei weiterer Navigation innerhalb der Website zu einer [Single-Page-Anwendung](https://en.wikipedia.org/wiki/Single-page_application) (SPA). Dieses Modell bietet unserer Ansicht nach ein ausgewogenes Verhältnis zwischen Leistung und Benutzerfreundlichkeit:
- **Schnelles erstes Laden**
Beim ersten Aufruf einer beliebigen Seite wird statisches, vorgerendertes HTML ausgeliefert, um schnelle Ladezeiten und optimale SEO zu ermöglichen. Anschließend lädt die Seite ein JavaScript-Bundle, das die Seite in eine Vue-SPA („Hydration“) umwandelt. Entgegen der verbreiteten Annahme, dass die Hydration von SPAs langsam sei, ist dieser Vorgang dank der hohen Leistung von Vue 3 und der Compiler-Optimierungen sehr schnell. Auf [PageSpeed Insights](https://pagespeed.web.dev/report?url=https%3A%2F%2Fvitepress.dev%2F) erreichen typische VitePress-Websites selbst auf leistungsschwachen Mobilgeräten mit langsamer Verbindung nahezu perfekte Leistungswerte.
- **Schnelle Navigation nach dem Laden**
Noch wichtiger ist, dass das SPA-Modell **nach** dem ersten Laden zu einer besseren Benutzererfahrung führt. Bei der weiteren Navigation innerhalb der Website wird die Seite nicht mehr vollständig neu geladen. Stattdessen wird der Inhalt der Zielseite abgerufen und dynamisch aktualisiert. VitePress lädt außerdem automatisch Seitenabschnitte für Links vor, die sich im sichtbaren Bereich befinden. In den meisten Fällen fühlt sich die Navigation nach dem Laden sofort an.
- **Interaktivität ohne Nachteile**
Damit die in statisches Markdown eingebetteten dynamischen Vue-Teile hydratisiert werden können, wird jede Markdown-Seite als Vue-Komponente verarbeitet und in JavaScript kompiliert. Das mag ineffizient klingen, aber der Vue-Compiler kann statische und dynamische Teile voneinander trennen und dadurch sowohl die Kosten der Hydration als auch die Größe der Nutzlast minimieren. Beim ersten Laden der Seite werden die statischen Teile automatisch aus der JavaScript-Nutzlast entfernt und während der Hydration übersprungen.
## Und was ist mit VuePress?
VitePress ist der Nachfolger von VuePress 1. Das ursprüngliche VuePress 1 basierte auf Vue 2 und webpack. Mit Vue 3 und Vite im Hintergrund bietet VitePress eine deutlich bessere Entwicklererfahrung, bessere Leistung in der Produktion, ein ausgereifteres Standard-Theme und eine flexiblere API zur Anpassung.
Die API-Unterschiede zwischen VitePress und VuePress 1 liegen hauptsächlich beim Theming und bei der Anpassung. Wenn du VuePress 1 mit dem Standard-Theme verwendest, sollte die Migration zu VitePress relativ unkompliziert sein.
Die parallele Pflege zweier SSGs ist langfristig nicht sinnvoll. Daher hat das Vue-Team beschlossen, sich langfristig auf VitePress als empfohlenes SSG zu konzentrieren. VuePress 1 ist inzwischen veraltet, und VuePress 2 wurde zur weiteren Entwicklung und Pflege an das VuePress-Community-Team übergeben.

@ -0,0 +1,36 @@
---
description: VitePress ist ein auf Vite und Vue basierender Generator für statische Websites, mit dem du aus Markdown ansprechende Dokumentationen erstellen kannst.
layout: home
hero:
name: VitePress
text: Generator für statische Websites mit Vite & Vue
tagline: Von Markdown zu ansprechender Dokumentation in wenigen Minuten
actions:
- theme: brand
text: Was ist VitePress?
link: ./guide/what-is-vitepress
- theme: alt
text: Schnellstart
link: ./guide/getting-started
- theme: alt
text: GitHub
link: https://github.com/vuejs/vitepress
image:
src: /vitepress-logo-large.svg
alt: VitePress
features:
- icon: <span class="memo"></span>
title: Konzentriere dich auf deine Inhalte
details: Erstelle mühelos ansprechende Dokumentationsseiten mit einfachem Markdown.
- icon: <span class="vite"></span>
title: Die Vite-DX nutzen
details: Sofortiger Serverstart, blitzschnelle Hot-Updates und Zugriff auf Plugins aus dem Vite-Ökosystem.
- icon: <span class="vue"></span>
title: Mit Vue anpassen
details: Verwende Vue-Syntax und -Komponenten direkt in Markdown oder erstelle eigene Themes mit Vue.
- icon: <span class="rocket"></span>
title: Schnelle Websites ausliefern
details: Schneller initialer Ladevorgang mit statischem HTML und schnelle Navigation nach dem Laden dank clientseitigem Routing.
---

@ -0,0 +1,79 @@
---
description: Referenz der VitePress-CLI-Befehle einschließlich dev, build, preview und init.
---
# Kommandozeilenschnittstelle
## `vitepress dev`
Starte den VitePress-Entwicklungsserver mit dem angegebenen Verzeichnis als Stammverzeichnis. Standardmäßig wird das aktuelle Verzeichnis verwendet. Der Befehl `dev` kann beim Ausführen im aktuellen Verzeichnis weggelassen werden.
### Verwendung
```sh
# Start im aktuellen Verzeichnis, wobei `dev` weggelassen wird
vitepress
# Start in einem Unterverzeichnis
vitepress dev [root]
```
### Optionen
| Option | Beschreibung |
| --------------- | ----------------------------------------------------------------- |
| `--open [path]` | Browser beim Start öffnen (`boolean \| string`) |
| `--port <port>` | Port festlegen (`number`) |
| `--base <path>` | Öffentlicher Basispfad (Standard: `/`) (`string`) |
| `--cors` | CORS aktivieren |
| `--strictPort` | Beenden, wenn der angegebene Port bereits verwendet wird (`boolean`) |
| `--force` | Optimierer zwingen, den Cache zu ignorieren und erneut zu bündeln (`boolean`) |
## `vitepress build`
VitePress-Website für die Produktion erstellen.
### Verwendung
```sh
vitepress build [root]
```
### Optionen
| Option | Beschreibung |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| `--mpa` (experimentell) | Im [MPA-Modus erstellen](../guide/mpa-mode) ohne clientseitige Hydration (`boolean`) |
| `--base <path>` | Öffentlicher Basispfad (Standard: `/`) (`string`) |
| `--assetsBase <url>` | URL-Präfix, von dem die erzeugten Assets ausgeliefert werden, z. B. ein CDN (`string`) |
| `--target <target>` | Transpilierungsziel (Standard: `"modules"`) (`string`) |
| `--outDir <dir>` | Ausgabeverzeichnis relativ zu **cwd** (Standard: `<root>/.vitepress/dist`) (`string`) |
| `--assetsInlineLimit <number>` | Grenzwert für das Base64-Einbetten statischer Assets in Byte (Standard: `4096`) (`number`) |
## `vitepress preview`
Produktions-Build lokal in der Vorschau anzeigen.
### Verwendung
```sh
vitepress preview [root]
```
### Optionen
| Option | Beschreibung |
| --------------- | ------------------------------------------ |
| `--base <path>` | Öffentlicher Basispfad (Standard: `/`) (`string`) |
| `--assetsBase <url>` | URL-Präfix, von dem die erzeugten Assets ausgeliefert werden, z. B. ein CDN (`string`) |
| `--port <port>` | Port festlegen (`number`) |
## `vitepress init`
Starte den [Einrichtungsassistenten](../guide/getting-started#setup-wizard) im aktuellen Verzeichnis.
### Verwendung
```sh
vitepress init
```

@ -0,0 +1,85 @@
---
description: Verwende die Badge-Komponente, um Statusbezeichnungen zu Überschriften in der VitePress-Dokumentation hinzuzufügen.
---
# Badge
Mit dem Badge kannst du deinen Überschriften einen Status hinzufügen. Zum Beispiel kann damit der Typ eines Abschnitts oder die unterstützte Version angegeben werden.
## Verwendung
Du kannst die global verfügbare `Badge`-Komponente verwenden.
```html
### Titel <Badge type="info" text="default" />
### Titel <Badge type="tip" text="^1.9.0" />
### Titel <Badge type="warning" text="beta" />
### Titel <Badge type="danger" text="deprecated" />
```
Der obige Code wird folgendermaßen dargestellt:
### Titel <Badge type="info" text="Standard" />
### Titel <Badge type="tip" text="^1.9.0" />
### Titel <Badge type="warning" text="beta" />
### Titel <Badge type="danger" text="deprecated" />
## Eigenes Children
`<Badge>` akzeptiert `children`, die im Badge angezeigt werden.
```html
### Titel <Badge type="info">benutzerdefiniertes Element</Badge>
```
### Titel <Badge type="info">benutzerdefiniertes Element</Badge>
## Farbe und Typ anpassen
Du kannst das Erscheinungsbild der Badges durch Überschreiben der CSS-Variablen anpassen. Die folgenden Werte sind die Standardwerte:
```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-note-border: transparent;
--vp-badge-note-text: var(--vp-c-note-1);
--vp-badge-note-bg: var(--vp-c-note-soft);
--vp-badge-tip-border: transparent;
--vp-badge-tip-text: var(--vp-c-tip-1);
--vp-badge-tip-bg: var(--vp-c-tip-soft);
--vp-badge-important-border: transparent;
--vp-badge-important-text: var(--vp-c-important-1);
--vp-badge-important-bg: var(--vp-c-important-soft);
--vp-badge-caution-border: transparent;
--vp-badge-caution-text: var(--vp-c-caution-1);
--vp-badge-caution-bg: var(--vp-c-caution-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>`
Die Komponente `<Badge>` akzeptiert die folgenden Props:
```ts
interface Props {
// Wenn `<slot>` übergeben wird, wird dieser Wert ignoriert.
text?: string
// Defaults to `tip`. Matches markdown containers/alerts colors.
type?: 'info' | 'note' | 'tip' | 'important' | 'caution' | 'warning' | 'danger'
}
```

@ -0,0 +1,29 @@
---
description: Integriere Carbon Ads mithilfe der integrierten Unterstützung des Standard-Themes in deine VitePress-Website.
---
# Carbon Ads
VitePress bietet integrierte Unterstützung für [Carbon Ads](https://www.carbonads.net/). Wenn du die Carbon-Ads-Zugangsdaten in der Konfiguration definierst, zeigt VitePress Anzeigen auf der Seite an.
```js
export default {
themeConfig: {
carbonAds: {
code: 'your-carbon-code',
placement: 'your-carbon-placement',
format: 'classic'
}
}
}
```
Diese Werte werden verwendet, um das Carbon-CDN-Skript wie unten gezeigt aufzurufen.
Die Option `format` unterstützt `classic`, `responsive` und `cover`.
```js
`//cdn.carbonads.com/carbon.js?serve=${code}&placement=${placement}&format=${format}`
```
Weitere Informationen zur Konfiguration von Carbon Ads findest du auf der [Carbon-Ads-Website](https://www.carbonads.net/).

@ -0,0 +1,552 @@
---
description: Referenz aller für das VitePress-Standard-Theme verfügbaren Konfigurationsoptionen.
---
# Konfiguration des Standard-Themes
Mit der Theme-Konfiguration kannst du dein Theme anpassen. Du kannst sie über die Option `themeConfig` in der Konfigurationsdatei definieren:
```ts
export default {
lang: 'en-US',
title: 'VitePress',
description: 'Statischer Website-Generator auf Basis von Vite und Vue.',
// Konfigurationsoptionen für das Theme.
themeConfig: {
logo: '/logo.svg',
nav: [...],
sidebar: { ... }
}
}
```
**Die auf dieser Seite dokumentierten Optionen gelten nur für das Standard-Theme.** Andere Themes erwarten eine andere Theme-Konfiguration. Bei Verwendung eines eigenen Themes wird das Theme-Konfigurationsobjekt an das Theme übergeben, damit es davon abhängiges Verhalten definieren kann.
## i18nRouting
- Type: `boolean | ((data: VitePressData<DefaultTheme.Config>, route: Route, targetLocale: string) => string)`
Wenn du die Sprache beispielsweise auf `zh` änderst, ändert sich die URL von `/foo` (oder `/en/foo/`) zu `/zh/foo`. Du kannst dieses Verhalten deaktivieren, indem du `themeConfig.i18nRouting` auf `false` setzt.
Setze `themeConfig.i18nRouting` auf eine Funktion, um den Sprachlink anzupassen. Die Funktion erhält die aktuellen VitePress-Daten, die aktuelle Route und den Schlüssel der Zielsprache und gibt den Ziellink zurück.
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
i18nRouting(data, route, targetLocale) {
const target = data.site.value.locales[targetLocale]
const targetLink =
target.link || (targetLocale === 'root' ? '/' : `/${targetLocale}/`)
return `${targetLink}${route.data.relativePath.replace(/\.md$/, '')}${route.hash}`
}
}
})
```
## logo
- Type: `ThemeableImage`
Logo-Datei, die in der Navigationsleiste direkt vor dem Seitentitel angezeigt wird. Akzeptiert eine Pfadzeichenkette oder ein Objekt, um unterschiedliche Logos für den Hell-/Dunkelmodus festzulegen.
```ts
export default {
themeConfig: {
logo: '/logo.svg'
}
}
```
```ts
type ThemeableImage =
| string
| { src: string; alt?: string }
| { light: string; dark: string; alt?: string }
```
## siteTitle
- Type: `string | false`
Du kannst dieses Element anpassen, um den Standard-Seitentitel (`title` in der App-Konfiguration) in der Navigation zu ersetzen. Bei `false` wird der Titel in der Navigation deaktiviert. Dies ist nützlich, wenn dein `logo` den Seitentitel bereits enthält.
```ts
export default {
themeConfig: {
siteTitle: 'Hello World'
}
}
```
## nav
- Type: `NavItem`
Die Konfiguration für einen Navigationseintrag. Weitere Details findest du unter [Standard-Theme: Navigation](./Standard-theme-nav#navigation-links).
```ts
export default {
themeConfig: {
nav: [
{ text: 'Anleitung', link: '/guide' },
{
text: 'Dropdown-Menü',
items: [
{ text: 'Eintrag A', link: '/item-1' },
{ text: 'Eintrag B', link: '/item-2' },
{ text: 'Eintrag 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
- Type: `Sidebar`
Die Konfiguration für einen Seitenleisteneintrag. Weitere Details findest du unter [Standard-Theme: Seitenleiste](./Standard-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 = {
/**
* Die Textbeschriftung des Eintrags.
*/
text?: string
/**
* Der Link des Eintrags.
*/
link?: string
/**
* The children of the item.
*/
items?: SidebarItem[]
/**
* If not specified, group is not collapsible.
*
* If `true`, group is collapsible and collapsed by default
*
* If `false`, group is collapsible but expanded by default
*/
collapsed?: boolean
/**
* Base path for the children items.
*/
base?: string
/**
* Anpassen text that appears on the footer of previous/next page.
*/
docFooterText?: string
rel?: string
target?: string
}
```
## aside
- Type: `boolean | 'left'`
- Default: `true`
- Can be overridden per page via [frontmatter](./frontmatter-config#aside)
Setting this value to `false` prevents rendering of aside container.\
Setting this value to `true` renders the aside to the right.\
Wenn dieser Wert auf `left` gesetzt wird, wird der Aside-Container links gerendert.\
In Rechts-nach-Links-Layouts werden beide Seiten gespiegelt.
Wenn du es für alle Ansichtsgrößen deaktivieren möchtest, solltest du stattdessen `outline: false` verwenden.
## outline
- Type: `Outline | Outline['level'] | false`
- Die Ebene kann pro Seite über das [Frontmatter] überschrieben werden.(./frontmatter-config#outline)
Wenn dieser Wert auf `false` gesetzt wird, wird der Outline-Container nicht gerendert. Weitere Details findest du in diesem Interface:
```ts
interface Outline {
/**
* The levels of headings to be displayed in the outline.
* Single number means only headings of that level will be displayed.
* If a tuple is passed, the first number is the minimum level and the second number is the maximum level.
* `'deep'` is same as `[2, 6]`, which means all headings from `<h2>` to `<h6>` will be displayed.
*
* @default 2
*/
level?: number | [number, number] | 'deep'
/**
* The title to be displayed on the outline.
*
* @default 'On this page'
*/
label?: string
}
```
## socialLinks
- Type: `SocialLink[]`
Du kannst diese Option definieren, um Links zu deinen sozialen Konten mit Symbolen in der Navigation anzuzeigen.
```ts
export default {
themeConfig: {
socialLinks: [
// You can add any icon from simple-icons (https://simpleicons.org/):
{ icon: 'github', link: 'https://github.com/vuejs/vitepress' },
{ icon: 'twitter', link: '...' },
{ icon: 'discord', link: '/community', target: '_self' },
// You can use any other iconify collection installed in your project
// as `collection:name` (e.g. after `npm add -D @iconify-json/lucide`):
{ icon: 'lucide:rss', link: '/feed.rss' },
// You can also add custom icons by passing SVG as 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: '...',
// You can include a custom label for accessibility too (optional but recommended):
ariaLabel: 'cool link'
}
]
}
}
```
```ts
interface SocialLink {
icon: string | { svg: string }
link: string
ariaLabel?: string
target?: string
}
```
## footer
- Type: `Fußzeile`
- Can be overridden per page via [frontmatter](./frontmatter-config#footer)
Konfiguration der Fußzeile. Du kannst eine Nachricht oder einen Copyright-Text in der Fußzeile hinzufügen. Er wird jedoch nur angezeigt, wenn die Seite keine Seitenleiste enthält. Dies ist eine bewusste Designentscheidung.
```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
- Type: `EditLink`
- Can be overridden per page via [frontmatter](./frontmatter-config#editlink)
Bearbeitungslink lets you display a link to edit the page on Git management services such as GitHub, or GitLab. See [Standard-Theme: Bearbeitungslink](./Standard-theme-edit-link) for more details.
```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
- Type: `LastUpdatedOptions`
Ermöglicht die Anpassung des Textes und Datumsformats für die letzte Aktualisierung.
```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
- Type: `AlgoliaSearch`
An option to support searching your docs site using [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch). Learn more in [Standard-Theme: Suche](./Standard-theme-search)
```ts
export interface AlgoliaSearchOptions extends DocSearchProps {
locales?: Record<string, Partial<DocSearchProps>>
}
```
Eine vollständige Liste der Optionen findest du [hier](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts).
## carbonAds {#carbon-ads}
- Type: `CarbonAdsOptions`
An option to display [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'
}
```
Weitere Informationen findest du unter [Standard-Theme: Carbon Ads](./Standard-theme-carbon-ads)
## docFooter
- Type: `DocFooter`
Kann verwendet werden, um den Text über den Links zur vorherigen und nächsten Seite anzupassen. Dies ist hilfreich, wenn die Dokumentation nicht auf Englisch verfasst ist. Außerdem können die Links global deaktiviert werden. Wenn du die Links gezielt aktivieren oder deaktivieren möchtest, kannst du [frontmatter](./Standard-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
- Type: `string`
- Default: `Appearance`
Kann verwendet werden, um die Beschriftung des Dunkelmodus-Schalters anzupassen. Diese Beschriftung wird nur in der mobilen Ansicht angezeigt.
## lightModeSwitchTitle
- Type: `string`
- Default: `Switch to light theme`
Kann verwendet werden, um den Titel des Hellmodus-Schalters anzupassen, der beim Darüberfahren angezeigt wird.
## darkModeSwitchTitle
- Type: `string`
- Default: `Switch to dark theme`
Kann verwendet werden, um den Titel des Dunkelmodus-Schalters anzupassen, der beim Darüberfahren angezeigt wird.
## sidebarMenuLabel
- Type: `string`
- Default: `Menu`
Kann verwendet werden, um die Beschriftung des Seitenleistenmenüs anzupassen. Diese Beschriftung wird nur in der mobilen Ansicht angezeigt.
## returnToTopLabel
- Type: `string`
- Default: `Return to top`
Kann verwendet werden, um die Beschriftung der Schaltfläche zum Zurückkehren nach oben anzupassen. Diese Beschriftung wird nur in der mobilen Ansicht angezeigt.
## langMenuLabel
- Type: `string`
- Default: `Change language`
Kann verwendet werden, um das aria-label der Sprachumschalt-Schaltfläche in der Navigationsleiste anzupassen. Dies wird nur bei Verwendung von [i18n] genutzt.(../guide/i18n).
## navMenuLabel
- Type: `string`
- Default: `Main Navigation`
Can be used to customize the accessible label of the main navigation landmarks (the navbar menu and the mobile menu).
## mobileMenuLabel
- Type: `string`
- Default: `Menu`
Can be used to customize the aria-label of the mobile menu (hamburger) button.
## extraMenuLabel
- Type: `string`
- Default: `More options`
Can be used to customize the aria-label of the `⋯` menu button in the navbar. That menu collects the nav items and controls that don't fit in the bar at the current viewport size.
## skipToContentLabel
- Type: `string`
- Default: `Skip to content`
Can be used to customize the label of the skip to content link. Dies link is shown when the user is navigating the site using a keyboard.
## externalLinkIcon
- Type: `boolean`
- Default: `false`
Whether to show an external link icon next to external links in markdown.
## gradedContainers
- Type: `boolean`
- Default: `false`
Whether to color [custom containers](../guide/markdown#custom-containers), [GitHub-flavored alerts](../guide/markdown#github-flavored-alerts), and badges on a graded severity scale — danger red, warning orange, caution yellow. By Standard, colors match GitHub's alerts, where caution shares danger's red and warning is yellow.
## `useLayout` <Badge type="info" text="composable" />
Returns layout-related data. The returned object has the following type:
```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>
}
```
**Beispiel:**
```vue
<script setup>
import { useLayout } from 'vitepress/theme'
const { hasSidebar } = useLayout()
</script>
<template>
<div v-if="hasSidebar">Only show when sidebar exists</div>
</template>
```

@ -0,0 +1,64 @@
---
description: Zeige auf Dokumentationsseiten einen Bearbeitungslink an, über den Nutzer Änderungen auf GitHub oder GitLab vorschlagen können.
---
# Bearbeitungslink
## Websiteweite Konfiguration
Mit dem Bearbeitungslink kannst du einen Link zum Bearbeiten der Seite bei Git-Verwaltungsdiensten wie GitHub oder GitLab anzeigen. Füge zum Aktivieren die Optionen von `themeConfig.editLink` zu deiner Konfiguration hinzu.
```js
export default {
themeConfig: {
editLink: {
pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path'
}
}
}
```
Die Option `pattern` definiert die URL-Struktur des Links. `:path` wird durch den Seitenpfad ersetzt.
Du kannst auch eine reine Funktion angeben, die [`PageData`](./runtime-api#usedata) als Argument akzeptiert und die URL als Zeichenkette zurückgibt.
```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}`
}
}
}
}
}
```
Die Funktion sollte keine Seiteneffekte haben und nicht auf Dinge außerhalb ihres Gültigkeitsbereichs zugreifen, da sie serialisiert und im Browser ausgeführt wird.
Standardmäßig wird am unteren Rand der Dokumentationsseite der Linktext „Diese Seite bearbeiten“ hinzugefügt. Du kannst diesen Text über die Option `text` anpassen.
```js
export default {
themeConfig: {
editLink: {
pattern: 'https://github.com/vuejs/vitepress/edit/main/docs/:path',
text: 'Diese Seite auf GitHub bearbeiten'
}
}
}
```
## Frontmatter-Konfiguration
Dies kann pro Seite über die Option `editLink` im Frontmatter deaktiviert werden:
```yaml
---
editLink: false
---
```

@ -0,0 +1,57 @@
---
description: Konfiguriere die globale Fußzeile, die am unteren Rand von VitePress-Seiten angezeigt wird.
---
# Fußzeile
VitePress zeigt eine globale Fußzeile am unteren Rand der Seite an, wenn `themeConfig.footer` vorhanden ist.
```ts
export default {
themeConfig: {
footer: {
message: 'Veröffentlicht unter der MIT-Lizenz.',
copyright: 'Copyright © 2019-present Evan You'
}
}
}
```
```ts
export interface Fußzeile {
// Die Nachricht, die direkt vor dem Copyright angezeigt wird.
message?: string
// Der eigentliche Copyright-Text.
copyright?: string
}
```
Die obige Konfiguration unterstützt außerdem HTML-Zeichenketten. Wenn du beispielsweise Links in der Fußzeile anzeigen möchtest, kannst du die Konfiguration wie folgt anpassen:
```ts
export default {
themeConfig: {
footer: {
message: 'Veröffentlicht unter der <a href="https://github.com/vuejs/vitepress/blob/main/LICENSE">MIT-Lizenz</a>.',
copyright: 'Copyright © 2019-present <a href="https://github.com/yyx990803">Evan You</a>'
}
}
}
```
::: warning
In `message` und `copyright` können nur Inline-Elemente verwendet werden, da sie innerhalb eines `<p>`-Elements gerendert werden. Wenn du Block-Elemente hinzufügen möchtest, verwende stattdessen den Slot [`layout-bottom`](../guide/extending-Standard-theme#layout-slots).
:::
Beachte, dass die Fußzeile nicht angezeigt wird, wenn die [Seitenleiste](./Standard-theme-sidebar) sichtbar ist.
## Frontmatter-Konfiguration
Dies kann pro Seite über die `footer`-Option im Frontmatter deaktiviert werden:
```yaml
---
footer: false
---
```

@ -0,0 +1,199 @@
---
description: Konfiguriere das Startseitenlayout des VitePress-Standard-Themes mit Hero-Bereichen, Features und eigenen Inhalten.
---
# Startseite
Das VitePress-Standard-Theme stellt ein Startseitenlayout bereit, das du auch auf [der Startseite dieser Website](../) sehen kannst. Du kannst es auf jeder deiner Seiten verwenden, indem du `layout: home` im [Frontmatter](./frontmatter-config) angibst.
```yaml
---
layout: home
---
```
Diese Option allein bewirkt jedoch noch nicht viel. Du kannst der Startseite verschiedene vorgefertigte „Bereiche“ hinzufügen, indem du zusätzliche Optionen wie `hero` und `features` setzt.
## Hero-Bereich
Der Hero-Bereich befindet sich oben auf der Startseite. So kannst du ihn konfigurieren.
```yaml
---
layout: home
hero:
name: VitePress
text: Statischer Website-Generator auf Basis von Vite und Vue.
tagline: Lorem ipsum...
image:
src: /logo.png
alt: VitePress
actions:
- theme: brand
text: Erste Schritte
link: /guide/what-is-vitepress
- theme: alt
text: Auf GitHub ansehen
link: https://github.com/vuejs/vitepress
---
```
```ts
interface Hero {
// Die Zeichenkette, die oberhalb von `text` angezeigt wird. Verwendet die Markenfarbe
// Sie sollte kurz sein, beispielsweise der Produktname.
name?: string
// Der Haupttext des Hero-Bereichs. Dieser wird definiert
// as `h1` tag.
text: string
// Unter `text` angezeigter Untertitel.
tagline?: string
// Das Bild wird neben dem Text- und Untertitelbereich angezeigt.
image?: ThemeableImage
// Aktionsschaltflächen, die im Hero-Bereich der Startseite angezeigt werden.
actions?: HeroAction[]
}
type ThemeableImage =
| string
| { src: string; alt?: string }
| { light: string; dark: string; alt?: string }
interface HeroAction {
// Farbvariante der Schaltfläche. Standardmäßig `brand`.
theme?: 'brand' | 'alt'
// Beschriftung der Schaltfläche.
text: string
// Ziellink der Schaltfläche.
link: string
// Zielattribut des Links.
target?: string
// Link-rel-Attribut.
rel?: string
}
```
### Farbe des Namens anpassen
VitePress verwendet für `name` die Markenfarbe (`--vp-c-brand-1`). Du kannst diese Farbe jedoch durch Überschreiben der Variable `--vp-home-hero-name-color` anpassen.
```css
:root {
--vp-home-hero-name-color: blue;
}
```
Du kannst es außerdem weiter anpassen, indem du `--vp-home-hero-name-background` to give the `name` gradient color.
```css
:root {
--vp-home-hero-name-color: transparent;
--vp-home-hero-name-background: -webkit-linear-gradient(120deg, #bd34fe, #41d1ff);
}
```
## Feature-Bereich
Im Feature-Bereich kannst du beliebig viele Features auflisten, die direkt nach dem Hero-Bereich angezeigt werden sollen. Übergebe dazu die Option `features` im Frontmatter.
Du kannst für jedes Feature ein Symbol angeben, which can be an emoji or any type of image. When the configured icon is an image (svg, png, jpeg...), you must provide the icon with the proper width and height; you can also provide the description, its intrinsic size as well as its variants for dark and light theme wenn erforderlich.
```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 {
// Show icon on each feature box.
icon?: FeatureIcon
// Title of the feature.
title: string
// Details of the feature.
details: string
// Link when clicked on feature component. The link can
// be both internal or external.
//
// e.g. `guide/reference/default-theme-home-page` or `https://example.com`
link?: string
// Link text to be shown inside feature component. Best
// used with `link` option.
//
// e.g. `Learn more`, `Visit page`, etc.
linkText?: string
// Link rel attribute for the `link` option.
//
// e.g. `external`
rel?: string
// Link target attribute for the `link` option.
target?: string
}
type FeatureIcon =
| string
| { src: string; alt?: string; width?: string; height: string }
| {
light: string
dark: string
alt?: string
width?: string
height: string
}
```
## Markdown-Inhalt
Du kannst zusätzliche Inhalte zur Startseite deiner Website hinzufügen, indem du einfach unterhalb der `---`-Frontmatter-Trennlinie Markdown hinzufügst.
````md
---
layout: home
hero:
name: VitePress
text: Statischer Website-Generator auf Basis von Vite und Vue.
---
## Getting Started
You can get started using VitePress right away using `npx`!
```sh
npm init
npx vitepress init
```
````
::: info
VitePress hat zusätzliche Inhalte einer Seite mit `layout: home` nicht immer automatisch gestaltet. Um das frühere Verhalten wiederherzustellen, kannst du `markdownStyles: false` im Frontmatter setzen.
:::

@ -0,0 +1,50 @@
---
description: Zeige den Zeitpunkt der letzten Aktualisierung von VitePress-Seiten anhand der Git-Commit-Historie an.
---
# Letzte Aktualisierung
Der Aktualisierungszeitpunkt des letzten Inhalts wird unten rechts auf der Seite angezeigt. Füge zum Aktivieren die Option `lastUpdated` zu deiner Konfiguration hinzu.
::: info
VitePress zeigt den Zeitpunkt der letzten Aktualisierung anhand des Zeitstempels des neuesten Git-Commits für jede Datei an. Dafür muss die Markdown-Datei in Git committed sein.
Intern führt VitePress für jede Datei `git log -1 --pretty="%ai"` aus, um den Zeitstempel abzurufen. Wenn alle Seiten dieselbe Aktualisierungszeit anzeigen, liegt dies wahrscheinlich an einem flachen Klonen (häufig in CI-Umgebungen), das den Git-Verlauf begrenzt.
Um dies in **GitHub Actions** zu beheben, verwende Folgendes in deinem Workflow:
```yaml{4}
- name: Checkout
uses: actions/checkout@v5
with:
fetch-depth: 0
```
Andere CI/CD-Plattformen verfügen über ähnliche Einstellungen.
Wenn solche Optionen nicht verfügbar sind, kannst du dem Befehl `docs:build` in deiner `package.json` einen manuellen Abruf voranstellen:
```json
"docs:build": "git fetch --unshallow && vitepress build docs"
```
:::
## Websiteweite Konfiguration
```js
export default {
lastUpdated: true
}
```
## Frontmatter-Konfiguration
Dies kann pro Seite über die `lastUpdated`-Option im Frontmatter deaktiviert werden:
```yaml
---
lastUpdated: false
---
```
Weitere Informationen findest du unter [Standard-Theme: Letzte Aktualisierung](./Standard-theme-config#lastupdated). Jeder als wahr ausgewertete Wert auf Theme-Ebene aktiviert die Funktion ebenfalls, sofern sie nicht ausdrücklich auf Website- oder Seitenebene deaktiviert wird.

@ -0,0 +1,66 @@
---
description: Wähle zwischen den Layouts doc, page und home im VitePress-Standard-Theme.
---
# Layout
Du kannst das Seitenlayout auswählen, indem du die Option `layout` im [Frontmatter](./frontmatter-config) der Seite setzt. Es gibt drei Layoutoptionen: `doc`, `page` und `home`. Wenn nichts angegeben ist, wird die Seite als `doc`-Seite behandelt.
```yaml
---
layout: doc
---
```
## Doc Layout
Die Option `doc` ist das Standardlayout. Sie gestaltet den gesamten Markdown-Inhalt im Stil einer „Dokumentation“, indem der gesamte Inhalt in die CSS-Klasse `vp-doc` eingeschlossen und auf die darin enthaltenen Elemente entsprechende Stile angewendet werden.
Nahezu alle allgemeinen Elemente wie `p` oder `h2` erhalten eine spezielle Gestaltung. Beachte daher, dass auch benutzerdefiniertes HTML innerhalb eines Markdown-Inhalts von diesen Stilen betroffen ist.
Außerdem stellt dieses Layout die unten aufgeführten dokumentationsspezifischen Funktionen bereit. Diese Funktionen sind nur in diesem Layout aktiviert.
- Bearbeitungslink
- Prev Weiter Link
- Outline
- [Carbon Ads](./default-theme-carbon-ads)
## Seite Layout
Die Option `page` wird als „leere Seite“ behandelt. Das Markdown wird weiterhin analysiert und alle [Markdown-Erweiterungen](../guide/markdown) funktionieren wie beim `doc`-Layout, erhalten jedoch keine Standardgestaltung.
Mit dem Seitenlayout kannst du alles selbst gestalten, ohne dass das VitePress-Theme das Markup beeinflusst. Das ist nützlich, wenn du eine eigene Seite erstellen möchtest.
Beachte, dass auch in diesem Layout die Seitenleiste angezeigt wird, wenn für die Seite eine passende Seitenleistenkonfiguration vorhanden ist.
## Home Layout
Die Option `home` erzeugt eine vorgefertigte „Startseite“. In diesem Layout kannst du zusätzliche Optionen wie `hero` und `features` festlegen, um den Inhalt weiter anzupassen. Weitere Informationen findest du unter [Standard-Theme: Startseite](./default-theme-home-page).
## No Layout
Wenn du kein Layout möchtest, kannst du über das Frontmatter `layout: false` angeben. Diese Option ist hilfreich, wenn du eine vollständig anpassbare Einstiegsseite ohne standardmäßige Seitenleiste, Navigationsleiste oder Fußzeile erstellen möchtest.
## Eigenes Layout
Du kannst auch ein eigenes Layout verwenden:
```md
---
layout: foo
---
```
Dadurch wird nach einer im Kontext registrierten Komponente namens `foo` gesucht. Zum Beispiel kannst du deine Komponente global in `.vitepress/theme/index.ts` registrieren:
```ts
import DefaultTheme from 'vitepress/theme'
import Foo from './Foo.vue'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
app.component('foo', Foo)
}
}
```

@ -0,0 +1,221 @@
---
description: Konfiguriere die Navigationsleiste im VitePress-Standard-Theme einschließlich Seitentitel, Logo und Menülinks.
---
# Nav
Die Navigation ist die oben auf der Seite angezeigte Navigationsleiste. Sie enthält den Seitentitel, globale Menülinks usw.
## Seitentitel und Logo
Standardmäßig zeigt die Navigation den Titel der Website anhand des Werts [`config.title`](./site-config#title) an. Wenn du die Anzeige in der Navigation ändern möchtest, kannst du einen eigenen Text über die Option `themeConfig.siteTitle` festlegen.
```js
export default {
themeConfig: {
siteTitle: 'My Custom Title'
}
}
```
Wenn du ein Logo für deine Website hast, kannst du es über den Bildpfad anzeigen. Du solltest das Logo direkt in `public` ablegen und den absoluten Pfad dazu angeben.
```js
export default {
themeConfig: {
logo: '/my-logo.svg'
}
}
```
Beim Hinzufügen eines Logos wird es zusammen mit dem Seitentitel angezeigt. Wenn du nur das Logo benötigst und den Seitentitel ausblenden möchtest, setze die Option `siteTitle` auf `false`.
```js
export default {
themeConfig: {
logo: '/my-logo.svg',
siteTitle: false
}
}
```
Du kannst als Logo auch ein Objekt übergeben, wenn du ein `alt`-Attribut hinzufügen oder es abhängig vom Hell-/Dunkelmodus anpassen möchtest. Einzelheiten findest du unter [`themeConfig.logo`](./default-theme-config#logo).
## Navigation Links
Du kannst die Option `themeConfig.nav` definieren, um Links zur Navigation hinzuzufügen.
```js
export default {
themeConfig: {
nav: [
{ text: 'Guide', link: '/guide' },
{ text: 'Config', link: '/config' },
{ text: 'Changelog', link: 'https://github.com/...' }
]
}
}
```
`text` ist der tatsächlich angezeigte Text in der Navigation, und `link` ist das Ziel, das beim Anklicken des Textes geöffnet wird. Setze beim Link den Pfad zur tatsächlichen Datei ohne `.md` und beginne immer mit `/`.
Der `link` kann auch eine Funktion sein, die [`PageData`](./runtime-api#usedata) als Argument akzeptiert und den Pfad zurückgibt.
Navigationslinks können auch Dropdown-Menüs sein. Setze dazu den Schlüssel `items` in der Link-Option.
```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' }
]
}
]
}
}
```
Beachte, dass der Titel des Dropdown-Menüs (`Dropdown Menu` im obigen Beispiel) keine Eigenschaft `link` besitzen kann, da er zu einer Schaltfläche zum Öffnen des Dropdowns wird.
Du kannst den Dropdown-Menüeinträgen außerdem weitere „Abschnitte“ hinzufügen, indem du weitere verschachtelte Einträge angibst.
```js
export default {
themeConfig: {
nav: [
{ text: 'Guide', link: '/guide' },
{
text: 'Dropdown Menu',
items: [
{
// Title for the section.
text: 'Section A Title',
items: [
{ text: 'Section A Item A', link: '...' },
{ text: 'Section B Item B', link: '...' }
]
}
]
},
{
text: 'Dropdown Menu',
items: [
{
// You may also omit the title.
items: [
{ text: 'Section A Item A', link: '...' },
{ text: 'Section B Item B', link: '...' }
]
}
]
}
]
}
}
```
### Status des Links "active" state
Navigationseinträge werden hervorgehoben, wenn sich die aktuelle Seite unter dem passenden Pfad befindet. Wenn du den abzugleichenden Pfad anpassen möchtest, definiere die Eigenschaft `activeMatch` als Zeichenkette mit einem regulären Ausdruck.
```js
export default {
themeConfig: {
nav: [
// This link gets active state when the user is
// on `/config/` path.
{
text: 'Guide',
link: '/guide',
activeMatch: '/config/'
}
]
}
}
```
::: warning
`activeMatch` is expected to be a regex string, but you must define it as a string. We can't use actual RegExp object here because it isn't serializable during the build time.
:::
### Status des Links "target" and "rel" attributes
Standardmäßig bestimmt VitePress automatisch `target` and `rel` attributes abhängig davon, ob der Link extern ist. But if you want, you can customize them too.
```js
export default {
themeConfig: {
nav: [
{
text: 'Merchandise',
link: 'https://www.thegithubshop.com/',
target: '_self',
rel: 'sponsored'
}
]
}
}
```
## Social Links
Refer [`socialLinks`](./default-theme-config#sociallinks).
## Eigene Komponenten
Du kannst eigene Komponenten mithilfe der Option `component` in die Navigationsleiste aufnehmen. by using the `component` option. The `component` key should be the Vue component name, and must be registered globally using [Theme.enhanceApp](../guide/custom-theme#theme-interface).
```js [.vitepress/config.js]
export default {
themeConfig: {
nav: [
{
text: 'My Menu',
items: [
{
component: 'MyCustomComponent',
// Optional props to pass to the component
props: {
title: 'My Custom Component'
}
}
]
},
{
component: 'AnotherCustomComponent'
}
]
}
}
```
Anschließend musst du die Komponente global registrieren:
```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)
}
}
```
Deine Komponente wird in der Navigationsleiste gerendert. VitePress will provide the following additional props to the component:
- `screenMenu`: ein optionaler Boolean, der angibt, ob sich die Komponente im mobilen Navigationsmenü befindet
- `menu`: ein optionaler Boolean, der angibt, ob sich die Komponente in einem Dropdown-Bereich befindet — for example, the `⋯` menu that nav items collapse into when they don't fit the bar. In both these contexts, render a flat list instead of a floating flyout, which would end up nested inside the panel
Du kannst check an example in the e2e tests [here](https://github.com/vuejs/vitepress/tree/main/__tests__/e2e/.vitepress).

@ -0,0 +1,47 @@
---
description: Passe die am unteren Rand von Dokumentationsseiten in VitePress angezeigten Links zur vorherigen und nächsten Seite an.
---
# Prev Weiter Links
Du kannst Text und Link für die vorherige und nächste Seite anpassen (sie werden am Ende der Dokumentationsseite angezeigt). Das ist hilfreich, wenn du dort einen anderen Text als in deiner Seitenleiste verwenden möchtest. Außerdem kann es nützlich sein, die Fußzeile zu deaktivieren oder auf eine Seite zu verlinken, die nicht in deiner Seitenleiste enthalten ist.
## prev
- Type: `string | false | { text?: string; link?: string }`
- Details:
Legt den Text/Link fest, der für den Link zur vorherigen Seite angezeigt wird. Wenn du dies im Frontmatter nicht festlegst, werden Text und Link aus der Seitenleistenkonfiguration abgeleitet.
- Beispiele:
- Nur den Text anpassen:
```yaml
---
prev: 'Get Started | Markdown'
---
```
- Text und Link anpassen:
```yaml
---
prev:
text: 'Markdown'
link: '/guide/markdown'
---
```
- Vorherige Seite ausblenden:
```yaml
---
prev: false
---
```
## next
Wie `prev`, aber für die nächste Seite.

@ -0,0 +1,371 @@
---
outline: deep
description: Richte eine lokale oder von Algolia bereitgestellte Suche für deine VitePress-Website ein.
---
# Suche
## Lokale Suche
VitePress unterstützt eine unscharfe Volltextsuche mithilfe eines Index im Browser dank [minisearch](https://github.com/lucaong/minisearch/). Um diese Funktion zu aktivieren, setze einfach die Option `themeConfig.search.provider` in deiner Datei `.vitepress/config.ts` auf `'local'`:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local'
}
}
})
```
Beispielergebnis:
![Screenshot des Suchfensters](/search.png)
Alternativ kannst du [Algolia DocSearch](#algolia-search) oder Community-Plugins verwenden, zum Beispiel:
- <https://npmx.dev/package/vitepress-plugin-pagefind>
- <https://npmx.dev/package/vitepress-plugin-typesense>
- <https://npmx.dev/package/vitepress-plugin-cloudflare-ai-search>
<!-- - <https://npmx.dev/package/@orama/plugin-vitepress> -- durch zbsearch ersetzen, sobald veröffentlicht -->
### Internationalisierung {#local-search-i18n}
Du kannst eine Konfiguration wie diese verwenden, um eine mehrsprachige Suche einzurichten:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
locales: {
zh: { // auf `root` setzen, wenn die Standardsprache übersetzt werden soll
translations: {
button: {
buttonText: '搜索',
buttonAriaLabel: '搜索'
},
modal: {
displayDetails: '显示详细列表',
resetButtonTitle: '重置搜索',
backButtonTitle: '关闭搜索',
noResultsText: '没有结果',
footer: {
selectText: '选择',
selectKeyAriaLabel: '输入',
navigateText: '导航',
navigateUpKeyAriaLabel: '上箭头',
navigateDownKeyAriaLabel: '下箭头',
closeText: '关闭',
closeKeyAriaLabel: 'esc'
}
}
}
}
}
}
}
}
})
```
### MiniSearch-Optionen
Du kannst MiniSearch folgendermaßen konfigurieren:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
miniSearch: {
/**
* @type {Pick<import('minisearch').Optionen, 'extractField' | 'tokenize' | 'processTerm'>}
*/
options: {
/* ... */
},
/**
* @type {import('minisearch').SearchOptions}
* @default
* { fuzzy: 0.2, prefix: true, boost: { title: 4, text: 2, titles: 1 } }
*/
searchOptions: {
/* ... */
}
}
}
}
}
})
```
Weitere Informationen findest du in der [MiniSearch-Dokumentation](https://lucaong.github.io/minisearch/classes/MiniSearch.MiniSearch.html).
::: info Document IDs
Die Dokument-IDs der Suche (wie sie von `searchOptions.filter`, `boostDocument` und im rohen Index verwendet werden) sind relative Pfade innerhalb der Website wie `/guide/page.html#section` – sie enthalten nicht [`base`](../reference/site-config#base). Das Theme löst sie beim Rendern der Ergebnisse gegen `base` auf.
:::
### Eigenen Inhalts-Renderer
Du kannst die Funktion anpassen, mit der der Markdown-Inhalt vor der Indizierung gerendert wird:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
/**
* @param {string} src
* @param {import('vitepress').MarkdownEnv} env
* @param {import('markdown-it-async')} md
*/
async _render(src, env, md) {
// return html string
}
}
}
}
})
```
Diese Funktion wird aus den clientseitigen Websitedaten entfernt, sodass du darin Node.js-APIs verwenden kannst.
#### Beispiel: Seiten aus der Suche ausschließen
Du kannst Seiten aus der Suche ausschließen, indem du `search: false` in das Frontmatter der Seite einfügst. Alternativ:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
async _render(src, env, md) {
const html = await md.renderAsync(src, env)
if (env.frontmatter?.search === false) return ''
if (env.relativePath.startsWith('some/path')) return ''
return html
}
}
}
}
})
```
::: warning Note
Wenn eine eigene `_render`-Funktion bereitgestellt wird, musst du das Frontmatter `search: false` selbst behandeln. Also, das `env`-Objekt ist vor dem Aufruf von `md.renderAsync` is called, so any checks on optional `env` properties like `frontmatter` should be done after that.
:::
#### Beispiel: Transforming content - adding anchors
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'local',
options: {
async _render(src, env, md) {
const html = await md.renderAsync(src, env)
if (env.frontmatter?.title)
return (await md.renderAsync(`# ${env.frontmatter.title}`)) + html
return html
}
}
}
}
})
```
## Algolia-Suche
VitePress unterstützt die Suche in deiner Dokumentation mit [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch). Siehe die entsprechende Einstiegsanleitung. In your `.vitepress/config.ts` you'll need to provide at least the following to make it work:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'algolia',
options: {
appId: '...',
apiKey: '...',
indexName: '...'
}
}
}
})
```
### i18n {#algolia-search-i18n}
Du kannst eine Konfiguration wie diese verwenden, um eine mehrsprachige Suche einzurichten:
<details>
<summary>Vollständiges Beispiel anzeigen</summary>
<<< @/snippets/algolia-i18n.ts
</details>
Refer [official Algolia docs](https://docsearch.algolia.com/docs/api#translations) to learn more about them. Für einen schnellen Einstieg kannst du auch the translations used by this site from [our GitHub repo](https://github.com/search?q=repo:vuejs/vitepress+%22function+searchOptions%22&type=code).
### Algolia Ask AI Support {#ask-ai}
Wenn du **Ask AI** einbinden möchtest, pass the `askAi` option (or any of the partial fields) inside `options`:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'algolia',
options: {
appId: '...',
apiKey: '...',
indexName: '...',
// askAi: "YOUR-ASSISTANT-ID"
// OR
askAi: {
// at minimum you must provide the assistantId you received from Algolia
assistantId: 'XXXYYY',
// optional overrides – if omitted, the top-level appId/apiKey/indexName values are reused
// apiKey: '...',
// appId: '...',
// indexName: '...'
}
}
}
}
})
```
::: warning Note
Wenn du standardmäßig die Stichwortsuche verwenden und Ask AI nicht nutzen möchtest, lasse the `askAi` property.
:::
### Ask AI Side Panel {#ask-ai-side-panel}
DocSearch v4.5+ unterstützt an optional **Ask-AI-Seitenleiste**. Wenn sie aktiviert ist, kann sie with **Ctrl/Cmd+I** by default. The [Sidepanel API Reference](https://docsearch.algolia.com/docs/sidepanel/api-reference) contains the full list of options.
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'algolia',
options: {
appId: '...',
apiKey: '...',
indexName: '...',
askAi: {
assistantId: 'XXXYYY',
sidePanel: {
panel: {
variant: 'floating', // or 'inline'
side: 'right',
width: '360px',
expandedWidth: '580px',
suggestedQuestions: true
}
}
}
}
}
}
})
```
Use `askAi.sidePanel.panel.suggestedQuestions` for side panel suggested
questions. Algolia's standalone Ask AI examples also mention
`askAi.suggestedQuestions`, but that top-level option is not enough for
VitePress side panel mode and does not make the integrated keyword-search
modal display suggested questions on first open.
Wenn du die Tastenkombination deaktivieren möchtest, verwende the `keyboardShortcuts` option at the sidepanel root level:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'algolia',
options: {
appId: '...',
apiKey: '...',
indexName: '...',
askAi: {
assistantId: 'XXXYYY',
sidePanel: {
keyboardShortcuts: {
'Ctrl/Cmd+I': false
}
}
}
}
}
}
})
```
#### Mode (auto / sidePanel / hybrid / modal) {#ask-ai-mode}
Du kannst optional festlegen, wie VitePress Stichwortsuche und Ask AI integriert:
- `mode: 'auto'` (default): infer `hybrid` when keyword search is configured, otherwise `sidePanel` when Ask-AI-Seitenleiste is configured.
- `mode: 'sidePanel'`: force side panel only (hides the keyword search button).
- `mode: 'hybrid'`: enable keyword search modal + Ask-AI-Seitenleiste (requires keyword search configuration).
- `mode: 'modal'`: keep Ask AI inside the DocSearch modal (even if you configured the side panel).
#### Ask AI only (no keyword search) {#ask-ai-only}
Wenn du want to use **Ask-AI-Seitenleiste only**, you can omit top-level keyword search config and provide credentials under `askAi`:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
search: {
provider: 'algolia',
options: {
mode: 'sidePanel',
askAi: {
assistantId: 'XXXYYY',
appId: '...',
apiKey: '...',
indexName: '...',
sidePanel: true
}
}
}
}
})
```
### Crawler Config
Here is an example config based on what this site uses:
<<< @/snippets/algolia-crawler.js

@ -0,0 +1,246 @@
---
description: Konfiguriere die Seitenleistennavigation im VitePress-Standard-Theme mit Gruppen, einklappbaren Abschnitten und mehreren Seitenleisten.
---
# Seitenleiste
Die Seitenleiste ist der zentrale Navigationsbereich deiner Dokumentation. Du kannst das Seitenleistenmenü unter [`themeConfig.sidebar`](./default-theme-config#sidebar) konfigurieren.
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Guide',
items: [
{ text: 'Introduction', link: '/introduction' },
{ text: 'Getting Started', link: '/getting-started' },
...
]
}
]
}
}
```
## Grundlagen
Die einfachste Form des Seitenleistenmenüs besteht aus einem einzelnen Array von Links. Das Element der ersten Ebene definiert den „Abschnitt“ der Seitenleiste. Es sollte `text`, den Titel des Abschnitts, und `items`, die eigentlichen Navigationslinks, enthalten.
```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' },
...
]
}
]
}
}
```
Jeder `link` sollte den Pfad zur tatsächlichen Datei angeben und mit `/` beginnen. Wenn du am Ende des Links einen abschließenden Schrägstrich hinzufügst, wird `index.md` des entsprechenden Verzeichnisses angezeigt.
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Guide',
items: [
// This shows `/guide/index.md` page.
{ text: 'Introduction', link: '/guide/' }
]
}
]
}
}
```
Du kannst die Seitenleisteneinträge bis zu sechs Ebenen tief verschachteln, ausgehend von der obersten Ebene. Beachte, dass Verschachtelungen mit mehr als sechs Ebenen ignoriert und nicht in der Seitenleiste angezeigt werden.
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Level 1',
items: [
{
text: 'Level 2',
items: [
{
text: 'Level 3',
items: [
...
]
}
]
}
]
}
]
}
}
```
## Multiple Sidebars
Du kannst abhängig vom Seitenpfad unterschiedliche Seitenleisten anzeigen. Zum Beispiel möchtest du in deiner Dokumentation möglicherweise separate Inhaltsbereiche wie eine „Anleitung“-Seite und eine „Konfiguration“-Seite erstellen.
Ordne dazu zunächst deine Seiten in Verzeichnissen für die gewünschten Abschnitte an:
```
.
├─ guide/
│ ├─ index.md
│ ├─ one.md
│ └─ two.md
└─ config/
├─ index.md
├─ three.md
└─ four.md
```
Then, update your configuration to define your sidebar for each section. This time, you should pass an object instead of an array.
```js
export default {
themeConfig: {
sidebar: {
// This sidebar gets displayed when a user
// is on `guide` directory.
'/guide/': [
{
text: 'Guide',
items: [
{ text: 'Index', link: '/guide/' },
{ text: 'One', link: '/guide/one' },
{ text: 'Two', link: '/guide/two' }
]
}
],
// This sidebar gets displayed when a user
// is on `config` directory.
'/config/': [
{
text: 'Config',
items: [
{ text: 'Index', link: '/config/' },
{ text: 'Three', link: '/config/three' },
{ text: 'Four', link: '/config/four' }
]
}
]
}
}
}
```
## Collapsible Seitenleiste Groups
By adding `collapsed` option to the sidebar group, it shows a toggle button to hide/show each section.
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Section Title A',
collapsed: false,
items: [...]
}
]
}
}
```
All sections are "open" by default. Wenn du would like them to be "closed" on initial page load, set `collapsed` option to `true`.
```js
export default {
themeConfig: {
sidebar: [
{
text: 'Section Title A',
collapsed: true,
items: [...]
}
]
}
}
```
## Path Prefix
When your documentation structure has deep directories or groups located under the same subdirectory, you can use the `base` option to automatisch prepend a path prefix to all nested `items` inside that group. This avoids repeating the same path prefix for every `link`.
The `base` option is supported in both multiple sidebar configurations and nested sidebar groups.
### In Multiple Sidebars
Du kannst define `base` at the root of a sidebar section configuration:
```js {5}
export default {
themeConfig: {
sidebar: {
'/guide/': {
base: '/guide/',
items: [
// This link is resolved to `/guide/introduction`
{ text: 'Introduction', link: 'introduction' },
// This link is resolved to `/guide/getting-started`
{ text: 'Getting Started', link: 'getting-started' }
]
}
}
}
}
```
### In Nested Groups
Du kannst also use `base` inside nested sidebar groups. It will apply to the immediate children of that group:
```js{6,13}
export default {
themeConfig: {
sidebar: [
{
text: 'Reference',
base: '/reference/',
items: [
// This link is resolved to `/reference/site-config`
{ text: 'Site-Konfiguration', link: 'site-config' },
{
text: 'Standard-Theme',
// Nested base overrides the parent path prefix
base: '/reference/default-theme-',
items: [
// This link is resolved to `/reference/default-theme-nav`
{ text: 'Nav', link: 'nav' },
// This link is resolved to `/reference/default-theme-sidebar`
{ text: 'Seitenleiste', link: 'sidebar' }
]
}
]
}
]
}
}
```

@ -0,0 +1,260 @@
---
description: Erstelle Teamseiten mit Mitgliederprofilen mithilfe der integrierten Team-Komponenten von 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>
# Teamseite
Wenn du dein Team vorstellen möchtest, kannst du Team-Komponenten verwenden, um eine Teamseite zu erstellen. Es gibt zwei Möglichkeiten: Du kannst sie in eine Dokumentationsseite einbetten oder eine vollständige Teamseite erstellen.
## Teammitglieder auf einer Seite anzeigen
Du kannst die von `vitepress/theme` bereitgestellte Komponente `<VPTeamMembers>` verwenden, um auf jeder Seite eine Liste von Teammitgliedern anzuzeigen.
```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>
# Our Team
Lerne unser großartiges Team kennen.
<VPTeamMembers size="small" :members />
```
Der obige Code zeigt ein Teammitglied in einem kartenähnlichen Element an. Das Ergebnis sollte ungefähr wie folgt aussehen.
<VPTeamMembers size="small" :members />
Die Komponente `<VPTeamMembers>` gibt es in zwei Größen: `small` und `medium`. Welche du verwendest, hängt von deinen Anforderungen ab; auf Dokumentationsseiten passt `small` normalerweise besser. Du kannst jedem Mitglied außerdem weitere Eigenschaften wie eine `description` oder eine `sponsor`-Schaltfläche hinzufügen. Weitere Informationen findest du unter [`<VPTeamMembers>`](#vpteammembers).
Das Einbetten von Teammitgliedern in eine Dokumentationsseite eignet sich für kleine Teams oder wenn nur einzelne Mitglieder im Zusammenhang mit der Dokumentation vorgestellt werden sollen.
Wenn du viele Mitglieder hast oder einfach mehr Platz für ihre Darstellung benötigst, kannst du [eine vollständige Teamseite erstellen](#create-a-full-team-page).
## Create a full Teamseite
Statt Teammitglieder in eine Dokumentationsseite einzubetten, kannst du auch eine vollständige Teamseite erstellen, ähnlich wie bei einer eigenen [Startseite](./default-theme-home-page).
Erstelle zunächst eine neue Markdown-Datei. Der Dateiname spielt keine Rolle; hier nennen wir sie `team.md`. Setze darin die Frontmatter-Option `layout: page` und baue anschließend die Seitenstruktur mit `TeamPage`-Komponenten auf.
```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>
Our Team
</template>
<template #lead>
The development of VitePress is guided by an international
team, some of whom have chosen to be featured below.
</template>
</VPTeamPageTitle>
<VPTeamMembers :members />
</VPTeamPage>
```
Bei einer vollständigen Teamseite musst du alle Komponenten mit der Komponente `<VPTeamPage>` umschließen. Sie sorgt dafür, dass alle verschachtelten Team-Komponenten die passende Layout-Struktur und Abstände erhalten.
Die Komponente `<VPPageTitle>` fügt den Seitentitelbereich hinzu. Der Titel ist eine `<h1>`-Überschrift. Verwende die Slots `#title` und `#lead`, um dein Team vorzustellen.
`<VPMembers>` funktioniert genauso wie auf einer Dokumentationsseite und zeigt eine Liste von Mitgliedern an.
### Abschnitte zur Aufteilung der Teammitglieder hinzufügen
Du kannst der Teamseite „Abschnitte“ hinzufügen. Zum Beispiel kannst du verschiedene Arten von Teammitgliedern wie Kernteammitglieder und Community-Partner haben. Mit Abschnitten kannst du die Rollen der einzelnen Gruppen besser erläutern.
Füge dazu die Komponente `<VPTeamPageSection>` in die zuvor erstellte Datei `team.md` ein.
```html
---
layout: page
---
<script setup>
import {
VPTeamPage,
VPTeamPageTitle,
VPTeamMembers,
VPTeamPageSection
} from 'vitepress/theme'
const coreMembers = [...]
const partners = [...]
</script>
<VPTeamPage>
<VPTeamPageTitle>
<template #title>Our Team</template>
<template #lead>...</template>
</VPTeamPageTitle>
<VPTeamMembers size="medium" :members="coreMembers" />
<VPTeamPageSection>
<template #title>Partners</template>
<template #lead>...</template>
<template #members>
<VPTeamMembers size="small" :members="partners" />
</template>
</VPTeamPageSection>
</VPTeamPage>
```
Die Komponente `<VPTeamPageSection>` kann wie `VPTeamPageTitle` die Slots `#title` und `#lead` sowie zusätzlich den Slot `#members` zur Anzeige von Teammitgliedern enthalten.
Denke daran, die Komponente `<VPTeamMembers>` innerhalb des Slots `#members` einzufügen.
## `<VPTeamMembers>`
Die Komponente `<VPTeamMembers>` zeigt eine übergebene Liste von Mitgliedern an.
```html
<VPTeamMembers
size="medium"
:members="[
{ avatar: '...', name: '...' },
{ avatar: '...', name: '...' },
...
]"
/>
```
```ts
interface Props {
// Size of each members. Defaults to `medium`.
size?: 'small' | 'medium'
// List of members to display.
members: TeamMember[]
}
interface TeamMember {
// Avatar image for the member.
avatar: string
// Name of the member.
name: string
// Title to be shown below member's name.
// e.g. Developer, Software Engineer, etc.
title?: string
// Organization that the member belongs.
org?: string
// URL for the organization.
orgLink?: string
// Description for the member.
desc?: string
// Social links. e.g. GitHub, Twitter, etc. You may pass in
// the Social Links object here.
// See: https://vitepress.dev/reference/default-theme-config.html#sociallinks
links?: SocialLink[]
// URL for the sponsor page for the member.
sponsor?: string
// Text for the sponsor link. Defaults to 'Sponsor'.
actionText?: string
}
```
## `<VPTeamPage>`
The root component when creating a full team page. It only accepts a single slot. It will style all passed in team related components.
## `<VPTeamPageTitle>`
Adds "title" section of the page. Best use at the very beginning under `<VPTeamPage>`. It accepts `#title` and `#lead` slot.
```html
<VPTeamPage>
<VPTeamPageTitle>
<template #title>
Our Team
</template>
<template #lead>
The development of VitePress is guided by an international
team, some of whom have chosen to be featured below.
</template>
</VPTeamPageTitle>
</VPTeamPage>
```
## `<VPTeamPageSection>`
Creates a "section" with in team page. It accepts `#title`, `#lead`, and `#members` slot. Du kannst add as many sections as you like inside `<VPTeamPage>`.
```html
<VPTeamPage>
...
<VPTeamPageSection>
<template #title>Partners</template>
<template #lead>Lorem ipsum...</template>
<template #members>
<VPTeamMembers :members="data" />
</template>
</VPTeamPageSection>
</VPTeamPage>
```

@ -0,0 +1,253 @@
---
outline: deep
description: Referenz aller verfügbaren Frontmatter-Konfigurationsoptionen für VitePress-Markdown-Seiten.
---
# Frontmatter-Konfiguration
Frontmatter ermöglicht die Konfiguration einzelner Seiten. In jeder Markdown-Datei kannst du Frontmatter verwenden, um Konfigurationsoptionen auf Website- oder Theme-Ebene zu überschreiben. Außerdem gibt es Optionen, die nur im Frontmatter definiert werden können.
Beispiel usage:
```md
---
title: Dokumentation mit VitePress
editLink: true
---
```
Du kannst über das globale `$frontmatter` in Vue-Ausdrücken auf Frontmatter-Daten zugreifen:
```md
{{ $frontmatter.title }}
```
## title
- Type: `string`
Titel der Seite. Entspricht [config.title](./site-config#title) und überschreibt die Konfiguration auf Websiteebene.
```yaml
---
title: VitePress
---
```
## titleTemplate
- Type: `string | boolean`
Suffix für den Titel. Entspricht [config.titleTemplate](./site-config#titletemplate) und überschreibt die Konfiguration auf Websiteebene.
```yaml
---
title: VitePress
titleTemplate: Statischer Website-Generator auf Basis von Vite und Vue
---
```
## description
- Type: `string`
Beschreibung der Seite. Entspricht [config.description](./site-config#description) und überschreibt die Konfiguration auf Websiteebene.
```yaml
---
description: VitePress
---
```
## head
- Type: `HeadConfig[]`
Gibt zusätzliche Head-Tags an, die für die aktuelle Seite eingefügt werden. Sie werden mit den über die Konfiguration auf Websiteebene eingefügten Head-Tags [zusammengeführt](./site-config#head).
```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]
```
## dir
- Type: `'ltr' | 'rtl' | 'auto'`
Überschreibt die [Schreibrichtung](./site-config#dir) der Website für die aktuelle Seite.
```yaml
---
dir: rtl
---
```
## Standard-Theme Only
Die folgenden Frontmatter-Optionen gelten nur bei Verwendung des Standard-Themes.
### layout
- Type: `doc | home | page`
- Default: `doc`
Legt das Layout der Seite fest.
- `doc` - Wendet die standardmäßigen Dokumentationsstile auf den Markdown-Inhalt an.
- `home` - Spezielles Layout für die „Startseite“. Du kannst zusätzliche Optionen wie `hero` und `features` hinzufügen, um schnell ansprechende Startseiten zu erstellen.
- `page` - Verhält sich ähnlich wie `doc`, wendet jedoch keine Stile auf den Inhalt an. Nützlich, wenn du eine vollständig eigene Seite erstellen möchtest.
```yaml
---
layout: doc
---
```
### hero <Badge type="info" text="home page only" />
Definiert den Inhalt des Hero-Bereichs der Startseite, wenn `layout` auf `home` gesetzt ist. Weitere Details findest du unter [Standard-Theme: Startseite](./default-theme-home-page).
### features <Badge type="info" text="home page only" />
Definiert die im Feature-Bereich anzuzeigenden Elemente, wenn `layout` auf `home` gesetzt ist. Weitere Details findest du unter [Standard-Theme: Startseite](./default-theme-home-page).
### navbar
- Type: `boolean`
- Default: `true`
Ob [navbar](./default-theme-nav).
```yaml
---
navbar: false
---
```
### sidebar
- Type: `boolean`
- Default: `true`
Ob [sidebar](./default-theme-sidebar).
```yaml
---
sidebar: false
---
```
### aside
- Type: `boolean | 'left'`
- Default: `true`
Definiert die Position der Aside-Komponente im `doc`-Layout.
Bei `false` wird der Aside-Container nicht gerendert.\
Bei `true` wird der Aside-Container rechts gerendert.\
Bei `'left'` wird der Aside-Container links gerendert.
```yaml
---
aside: false
---
```
### outline
- Type: `number | [number, number] | 'deep' | false`
- Default: `2`
Die Überschriftenebenen, die in der Seitenübersicht für die Seite angezeigt werden. Entspricht [config.themeConfig.outline.level](./default-theme-config#outline) und überschreibt den Wert der Konfiguration auf Websiteebene.
```yaml
---
outline: [2, 4]
---
```
### lastUpdated
- Type: `boolean | Date`
- Default: `true`
Ob der Text für die [letzte Aktualisierung](./default-theme-last-updated) in der Fußzeile der aktuellen Seite angezeigt wird. Wenn ein Zeitpunkt angegeben ist, wird dieser anstelle des letzten Änderungszeitpunkts aus Git angezeigt.
```yaml
---
lastUpdated: false
---
```
### editLink
- Type: `boolean`
- Default: `true`
Ob ein [Bearbeitungslink](./default-theme-edit-link) in der Fußzeile der aktuellen Seite angezeigt wird.
```yaml
---
editLink: false
---
```
### footer
- Type: `boolean`
- Default: `true`
Ob die [Fußzeile](./default-theme-footer) angezeigt wird.
```yaml
---
footer: false
---
```
### pageClass
- Type: `string`
Füge einer bestimmten Seite einen zusätzlichen Klassennamen hinzu.
```yaml
---
pageClass: custom-page-class
---
```
Anschließend kannst du die Stile dieser bestimmten Seite in der Datei `.vitepress/theme/custom.css` anpassen:
```css
.custom-page-class {
/* page-specific styles */
}
```
### isHome
- Type: `boolean`
Das Standard-Theme verwendet Prüfungen wie `frontmatter.layout === 'home'`, um festzustellen, ob die aktuelle Seite die Startseite ist.\
Dies ist nützlich, wenn du die Startseitenelemente in einem eigenen Layout erzwingen möchtest.
```yaml
---
isHome: true
---
```

@ -0,0 +1,223 @@
---
description: Referenz der VitePress-Runtime-APIs einschließlich Composables, Hilfsfunktionen und integrierter Komponenten.
---
# Runtime API
VitePress bietet außerdem einige integrierte Komponenten, die global verwendet werden können.
Die Hilfsmethoden können global aus `vitepress` importiert werden und werden normalerweise in Vue-Komponenten eigener Themes verwendet. Sie können jedoch auch innerhalb von `.md`-Seiten verwendet werden, da Markdown-Dateien in Vue-[Single-File-Komponenten](https://vuejs.org/guide/scaling-up/sfc.html) kompiliert werden.
Methoden, die mit `use*` beginnen, sind [Vue-3-Composition-API](https://vuejs.org/guide/introduction.html#composition-api)-Funktionen („Composables“), die nur innerhalb von `setup()` oder `<script setup>` verwendet werden können.
## `useData` <Badge type="info" text="composable" />
Gibt seitenspezifische Daten zurück. Das zurückgegebene Objekt hat folgenden Typ:
```ts
interface VitePressData<T = any> {
/**
* Metadaten auf Websiteebene
*/
site: Ref<SiteData<T>>
/**
* themeConfig aus .vitepress/config.js
*/
theme: Ref<T>
/**
* Metadaten auf Seitenebene
*/
page: Ref<PageData>
/**
* Frontmatter der Seite
*/
frontmatter: Ref<PageData['frontmatter']>
/**
* Dynamic route params
*/
params: Ref<PageData['params']>
title: Ref<string>
description: Ref<string>
lang: Ref<string>
isDark: Ref<boolean>
dir: Ref<'ltr' | 'rtl' | 'auto'>
localeIndex: Ref<string>
/**
* Current location hash
*/
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
}
```
`page.headers` wird nur gefüllt, wenn [`markdown.headers`](./site-config#markdown) aktiviert ist. Ohne diese Option bleibt es ein leeres Array. Die Seitenübersicht des Standard-Themes liest gerenderte Überschriften aus dem Seiteninhalt, sodass sie auch bei leerem `page.headers` angezeigt werden kann.
**Beispiel:**
```vue
<script setup>
import { useData } from 'vitepress'
const { theme } = useData()
</script>
<template>
<h1>{{ theme.footer.copyright }}</h1>
</template>
```
## `useRoute` <Badge type="info" text="composable" />
Gibt das aktuelle Routenobjekt mit folgendem Typ zurück:
```ts
interface Route {
path: string
data: PageData
component: Component | null
}
```
## `useRouter` <Badge type="info" text="composable" />
Gibt die VitePress-Routerinstanz zurück, mit der du programmgesteuert zu einer anderen Seite navigieren kannst.
```ts
interface Router {
/**
* Current route.
*/
route: Route
/**
* Navigate to a new URL.
*/
go: (to?: string) => Promise<void>
/**
* Called before the route changes. Return `false` to cancel the navigation.
*/
onBeforeRouteChange?: (to: string) => Awaitable<void | boolean>
/**
* Called before the page component is loaded (after the history state is updated).
* Return `false` to cancel the navigation.
*/
onBeforePageLoad?: (to: string) => Awaitable<void | boolean>
/**
* Called after the page component is loaded (before the page component is updated).
*/
onAfterPageLoad?: (to: string) => Awaitable<void>
/**
* Called after the route changes.
*/
onAfterRouteChange?: (to: string) => Awaitable<void>
}
```
Weise der Routerinstanz Handler für Routenänderungen zu:
```ts
const router = useRouter()
router.onBeforeRouteChange = (to) => {
console.log('navigating to', to)
}
```
Bei eigenen Themes ist derselbe Router über [`enhanceApp`](../guide/custom-theme#theme-interface).
## `useIcon` <Badge type="info" text="composable" />
- **Type**: `(icon: MaybeRefOrGetter<string | { svg: string } | undefined>, el?: MaybeRefOrGetter<HTMLElement | null>) => ComputedRef<string | undefined>`
Rendert ein [Iconify](https://iconify.design/)-Symbol über die Icon-Pipeline von VitePress. Erwartet eine vollständig qualifizierte `collection:name` (aufgelöst anhand der `@iconify-json/*`-Pakete in den Abhängigkeiten deines Projekts) und gibt die Klasse zurück, die auf dem Element gesetzt werden soll — `vpi-<collection>-<name>`.
Während SSR wird der Name im [`SSGContext`](./site-config#postrender) registriert, sodass der Build die Symbolstile in das erzeugte Stylesheet schreibt. Im Entwicklungsmodus liefert der Entwicklungsserver Symbole bei Bedarf aus den lokal installierten Sammlungen. Kein Symbol wird jemals von einem externen Dienst geladen.
```vue
<script setup>
import { useIcon } from 'vitepress'
import { useTemplateRef } from 'vue'
const el = useTemplateRef('el')
const iconClass = useIcon('lucide:rocket', el)
</script>
<template>
<span ref="el" :class="iconClass" />
</template>
```
Übergebe die Template-Referenz des Elements, das die Klasse trägt, damit der Entwicklungsmodus das Symbol darauf auflösen kann. Das Element benötigt die Maskenregeln des Standard-Themes; bei einem eigenen Theme ohne diese Regeln verwendet der Entwicklungsmodus ein entsprechendes Inline-Äquivalent und das erzeugte Stylesheet enthält für die Produktion Basisregeln ohne Spezifität.
Bei Verwendung des Standard-Themes kapselt die Komponente `VPIcon` aus `vitepress/theme` dieses Composable (und akzeptiert auch eine rohe `{ svg }`-Zeichenkette):
```vue-html
<VPIcon icon="lucide:rocket" />
```
Symbole, die nur auf dem Client gerendert werden (z. B. innerhalb von `<ClientOnly />`), können während des Builds nicht erfasst werden. Liste sie stattdessen unter [`icons.include`](./site-config#icons) auf.
## `withBase` <Badge type="info" text="helper" />
- **Type**: `(path: string) => string`
Stellt das konfigurierte [`base`](./site-config#base) einem angegebenen URL-Pfad voran. Siehe auch [Basis-URL](../guide/asset-handling#base-url).
## `<Inhalt />` <Badge type="info" text="component" />
Die Komponente `<Content />` zeigt den gerenderten Markdown-Inhalt an. Nützlich [beim Erstellen eines eigenen Themes](../guide/custom-theme).
```vue
<template>
<h1>Custom Layout!</h1>
<Content />
</template>
```
## `<ClientOnly />` <Badge type="info" text="component" />
Die Komponente `<ClientOnly />` rendert ihren Slot nur auf der Clientseite.
Da VitePress-Anwendungen beim Erzeugen statischer Builds in Node.js serverseitig gerendert werden, muss jede Vue-Verwendung den Anforderungen an universellen Code entsprechen. Kurz gesagt: Greife nur in `beforeMount`- oder `mounted`-Hooks auf Browser-/DOM-APIs zu.
Wenn du nicht SSR-kompatible Komponenten verwendest oder demonstrierst (beispielsweise solche mit eigenen Direktiven), kannst du sie in die `ClientOnly`-Komponente einschließen.
```vue-html
<ClientOnly>
<NonSSRFriendlyComponent />
</ClientOnly>
```
- Related: [SSR Compatibility](../guide/ssr-compat)
## `$frontmatter` <Badge type="info" text="template global" />
Greife direkt auf die [Frontmatter](../guide/frontmatter)-Daten in Vue-Ausdrücken zu.
```md
---
title: Hello
---
# {{ $frontmatter.title }}
```
## `$params` <Badge type="info" text="template global" />
Greife direkt auf die [Parameter dynamischer Routen](../guide/routing#dynamic-routes) in Vue-Ausdrücken zu.
```md
- package name: {{ $params.pkg }}
- version: {{ $params.version }}
```

@ -0,0 +1,862 @@
---
outline: deep
description: Vollständige Referenz der VitePress-Website-Konfigurationsoptionen einschließlich Einstellungen auf Anwendungsebene, Theme-Konfiguration und Build-Optionen.
---
# Website-Konfiguration
In der Website-Konfiguration definierst du die globalen Einstellungen der Website. Konfigurationsoptionen auf Anwendungsebene gelten für jede VitePress-Website, unabhängig vom verwendeten Theme. Zum Beispiel das Basisverzeichnis oder den Titel der Website.
## Übersicht
### Auflösung der Konfiguration
Die Konfigurationsdatei wird immer aus `<root>/.vitepress/config.[ext]`, wobei `<root>` dein VitePress-[Projektstammverzeichnis](../guide/routing#root-and-source-directory) ist und `[ext]` eine der unterstützten Dateierweiterungen bezeichnet. TypeScript wird standardmäßig unterstützt. Unterstützte Erweiterungen sind `.js`, `.ts`, `.mjs` und `.mts`.
Es wird empfohlen, in Konfigurationsdateien die ES-Modul-Syntax zu verwenden. Die Konfigurationsdatei sollte standardmäßig ein Objekt exportieren:
```ts
export default {
// app level config options
lang: 'en-US',
title: 'VitePress',
description: 'Statischer Website-Generator auf Basis von Vite und Vue.',
...
}
```
::: details Dynamische (asynchrone) Konfiguration
Wenn du die Konfiguration dynamisch erzeugen musst, kannst du auch standardmäßig eine Funktion exportieren. Zum Beispiel:
```ts
import { defineConfig } from 'vitepress'
export default async () => {
const posts = await (await fetch('https://my-cms.com/blog-posts')).json()
return defineConfig({
// app level config options
lang: 'en-US',
title: 'VitePress',
description: 'Statischer Website-Generator auf Basis von Vite und Vue.',
// Konfigurationsoptionen auf Theme-Ebene
themeConfig: {
sidebar: [
...posts.map((post) => ({
text: post.name,
link: `/posts/${post.name}`
}))
]
}
})
}
```
Du kannst auch `await` auf oberster Ebene verwenden. Zum Beispiel:
```ts
import { defineConfig } from 'vitepress'
const posts = await (await fetch('https://my-cms.com/blog-posts')).json()
export default defineConfig({
// app level config options
lang: 'en-US',
title: 'VitePress',
description: 'Statischer Website-Generator auf Basis von Vite und Vue.',
// Konfigurationsoptionen auf Theme-Ebene
themeConfig: {
sidebar: [
...posts.map((post) => ({
text: post.name,
link: `/posts/${post.name}`
}))
]
}
})
```
:::
### Konfigurations-IntelliSense
Die Verwendung des Helpers `defineConfig` stellt TypeScript-basierte IntelliSense für Konfigurationsoptionen bereit. Sofern deine IDE dies unterstützt, sollte dies sowohl in JavaScript als auch in TypeScript funktionieren.
```js
import { defineConfig } from 'vitepress'
export default defineConfig({
// ...
})
```
### Typisierte Theme-Konfiguration
Standardmäßig erwartet der Helper `defineConfig` den Theme-Konfigurationstyp des Standard-Themes:
```ts
import { defineConfig } from 'vitepress'
export default defineConfig({
themeConfig: {
// Typ ist `DefaultTheme.Config`
}
})
```
Wenn du ein eigenes Theme verwendest und Typprüfungen für dessen Theme-Konfiguration möchtest, musst du stattdessen `defineConfigWithTheme` verwenden und den Konfigurationstyp deines eigenen Themes als generisches Argument übergeben:
```ts
import { defineConfigWithTheme } from 'vitepress'
import type { ThemeConfig } from 'your-theme'
export default defineConfigWithTheme<ThemeConfig>({
themeConfig: {
// Type is `ThemeConfig`
}
})
```
### Vite, Vue & Markdown Config
- **Vite**
Du kannst die zugrunde liegende Vite-Instanz über die Option [vite](#vite) in deiner VitePress-Konfiguration konfigurieren. Eine separate Vite-Konfigurationsdatei ist nicht erforderlich.
- **Vue**
VitePress enthält bereits das offizielle Vue-Plugin für Vite ([@vitejs/plugin-vue](https://github.com/vitejs/vite-plugin-vue)). Du kannst dessen Optionen über die Option [vue](#vue) in deiner VitePress-Konfiguration konfigurieren.
- **Markdown**
Du kannst die zugrunde liegende [Markdown-It](https://github.com/markdown-it/markdown-it)-Instanz über die Option [markdown](#markdown) in deiner VitePress-Konfiguration konfigurieren.
### Überschreibungen auf Seitenebene
Einige Einstellungen können für bestimmte Seiten über das Frontmatter überschrieben werden.
Weitere Informationen findest du unter [Frontmatter-Konfiguration](./frontmatter-config).
### Überschreibungen auf Verzeichnisebene
Einige Konfigurationseinstellungen können auf Verzeichnisebene überschrieben werden, sodass alle Seiten in diesem Verzeichnis dieselben Einstellungen verwenden können, ohne sie im Frontmatter jeder Seite wiederholen zu müssen.
Dies wird erreicht, indem im entsprechenden Verzeichnis eine Datei namens `config.ts` (oder `.js`, `.mjs` bzw. `.mts`) angelegt wird. Diese Datei sollte wie die Hauptkonfigurationsdatei ein Konfigurationsobjekt über `export default` exportieren.
Verschachtelte Verzeichnisse übernehmen die Einstellungen ihres übergeordneten Verzeichnisses; Überschreibungen werden entsprechend zusammengeführt.
Der Helper `defineAdditionalConfig` kann verwendet werden, um TypeScript-basierte IntelliSense für die verfügbaren Optionen zu erhalten. Wie bei `defineConfig` ist seine Verwendung optional.
Bei einer Website mit mehreren Sprachen möchten wir beispielsweise für jede Sprache eine andere `description` verwenden. Dazu können wir `es/config.ts` mit folgendem Inhalt anlegen:
```ts
import { defineAdditionalConfig } from 'vitepress'
export default defineAdditionalConfig({
description: 'Generador de Sitios Estáticos desarrollado con Vite y Vue.'
})
```
Diese `description` wird anschließend für alle Seiten im Verzeichnis `es` verwendet.
Alternativ können die Einstellungen eines Sprachverzeichnisses bei Verwendung der integrierten i18n-Funktionen über die `locales`-Einstellung in der Hauptkonfigurationsdatei überschrieben werden. Weitere Informationen findest du unter [Internationalisierung](../guide/i18n).
## Website-Metadaten
### title
- Type: `string`
- Default: `VitePress`
- Kann pro Seite über das [Frontmatter](./frontmatter-config#title) oder auf [Verzeichnisebene](#directory-level-overrides) überschrieben werden
Titel der Website. Bei Verwendung des Standard-Themes wird er in der Navigationsleiste angezeigt.
Er wird außerdem als Standardsuffix für alle einzelnen Seitentitel verwendet, sofern [`titleTemplate`](#titletemplate) nicht definiert ist. Der endgültige Titel einer einzelnen Seite besteht aus dem Text ihrer ersten `<h1>`-Überschrift und dem globalen `title` als Suffix. Zum Beispiel bei folgender Konfiguration und folgendem Seiteninhalt:
```ts
export default {
title: 'My Awesome Site'
}
```
```md
# Hello
```
Der Titel der Seite lautet `Hello | My Awesome Site`.
### titleTemplate
- Type: `string | boolean`
- Kann pro Seite über das [Frontmatter](./frontmatter-config#titletemplate) oder auf [Verzeichnisebene](#directory-level-overrides) überschrieben werden
Ermöglicht die Anpassung des Titelsuffixes jeder Seite oder des gesamten Titels. Zum Beispiel:
```ts
export default {
title: 'My Awesome Site',
titleTemplate: 'Custom Suffix'
}
```
```md
# Hello
```
Der Titel der Seite lautet `Hello | Eigenes Suffix`.
Um die Darstellung des Titels vollständig anzupassen, kannst du das Symbol `:title` in `titleTemplate` verwenden:
```ts
export default {
titleTemplate: ':title - Custom Suffix'
}
```
Hier wird `:title` durch den aus der ersten `<h1>`-Überschrift der Seite ermittelten Text ersetzt. Der Titel der vorherigen Beispielseite lautet `Hello - Eigenes Suffix`.
Die Option kann auf `false` gesetzt werden, um Titelsuffixe zu deaktivieren.
### description
- Type: `string`
- Standard: `Eine VitePress-Website`
- Can be overridden per page via [frontmatter](./frontmatter-config#description) or at the [directory level](#directory-level-overrides)
Beschreibung der Website. Sie wird als `<meta>`-Tag im HTML der Seite ausgegeben.
```ts
export default {
description: 'A VitePress site'
}
```
### head
- Type: `HeadConfig[]`
- Default: `[]`
- Can be appended per page via [frontmatter](./frontmatter-config#head) or at the [directory level](#directory-level-overrides)
Zusätzliche Elemente, die im `<head>`-Tag des Seiten-HTML gerendert werden. Vom Benutzer hinzugefügte Tags werden nach den VitePress-Tags und vor dem schließenden `head`-Tag gerendert.
```ts
type HeadConfig =
| [string, Record<string, string>]
| [string, Record<string, string>, string]
```
Head entries from the site config, [locale config](../guide/i18n), [directory-level config](#directory-level-overrides), [frontmatter](./frontmatter-config#head) and [`transformHead`](#transformhead) are merged in that order. A later entry replaces an earlier one with the same key instead of being appended:
- Any element with an `id` attribute is keyed by its `id`.
- A `meta` element without an `id` is keyed by its first attribute other than `content` (e.g. `name`, `property`, `http-equiv`) and that attribute's value.
Other elements are never deduplicated. To render multiple `meta` tags that would share a key, like several `<meta name="author">`, give each of them a unique `id`.
#### Beispiel: Adding a favicon
```ts
export default {
head: [['link', { rel: 'icon', href: '/favicon.ico' }]]
} // put favicon.ico in public directory, if base is set, use /base/favicon.ico
/* Would render:
<link rel="icon" href="/favicon.ico">
*/
```
#### Beispiel: Adding 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' }
]
]
}
/* Would render:
<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">
*/
```
#### Beispiel: Registering a service worker
```ts
export default {
head: [
[
'script',
{ id: 'register-sw' },
`;(() => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
}
})()`
]
]
}
/* Would render:
<script id="register-sw">
;(() => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js')
}
})()
</script>
*/
```
#### Beispiel: Using 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');`
]
]
}
/* Would render:
<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
- Type: `string`
- Default: `en-US`
- Can be overridden at the [directory level](#directory-level-overrides)
The lang attribute for the site. This will render as a `<html lang="en-US">` tag in the page HTML.
```ts
export default {
lang: 'en-US'
}
```
### dir
- Type: `'ltr' | 'rtl' | 'auto'`
- Default: `ltr`
- Can be overridden at the [directory level](#directory-level-overrides)
The text direction of the site. This will render as a `<html dir="rtl">` tag in the page HTML, and the default theme mirrors its layout for right-to-left languages. It can also be overridden per page via [frontmatter](./frontmatter-config#dir). See [RTL Support](../guide/i18n#rtl-support).
```ts
export default {
dir: 'rtl'
}
```
### base
- Type: `string`
- Default: `/`
The base URL the site will be deployed at. You will need to set this if you plan to deploy your site under a sub path, for example, GitHub pages. Wenn du plan to deploy your site to `https://foo.github.io/bar/`, then you should set base to `'/bar/'`. It should always start and end with a slash.
The one exception is `'./'`, which produces a [relocatable build](../guide/deploy#relocatable-builds-relative-base): pages reference everything relative to their own location, so the same output works from any sub path (IPFS gateways, archives) without rebuilding and stays browsable when opened directly from the file system.
The base is automatisch prepended to all the URLs that start with / in other options, so you only need to specify it once.
```ts
export default {
base: '/base/'
}
```
Can also be set per build with `vitepress build --base /base/`.
## Routing
### cleanUrls
- Type: `boolean`
- Default: `false`
When set to `true`, VitePress will remove the trailing `.html` from URLs. Also see [Generating Clean URLs](../guide/routing#generating-clean-urls).
::: warning Server Support Required
Enabling this may require additional configuration on your hosting platform. For it to work, your server must be able to serve `/foo.html` when visiting `/foo` **without a redirect**.
:::
### rewrites
- Type: `Record<string, string>`
Defines custom directory &lt;-&gt; URL mappings. See [Routing: Route Rewrites](../guide/routing#route-rewrites) for more details.
```ts
export default {
rewrites: {
'source/:page': 'destination/:page'
}
}
```
## Build
### srcDir
- Type: `string`
- Default: `.`
The directory where your markdown pages are stored, relative to project root. Also see [Root and Quelle Verzeichnis](../guide/routing#root-and-source-directory).
```ts
export default {
srcDir: './src'
}
```
### srcExclude
- Type: `string[]`
- Default: `undefined`
A [glob pattern](https://github.com/mrmlnc/fast-glob#pattern-syntax) for matching markdown files that should be excluded as source content.
```ts
export default {
srcExclude: ['**/README.md', '**/TODO.md']
}
```
### outDir
- Type: `string`
- Default: `./.vitepress/dist`
The build output location for the site, relative to [project root](../guide/routing#root-and-source-directory).
```ts
export default {
outDir: '../public'
}
```
### assetsDir
- Type: `string`
- Default: `assets`
Specify the directory to nest generated assets under. The path should be inside [`outDir`](#outdir) and is resolved relative to it.
```ts
export default {
assetsDir: 'static'
}
```
### assetsBase
- Type: `string`
- Default: `undefined`
URL prefix the generated assets (everything under [`assetsDir`](#assetsdir)) are served from — typically a CDN. Must be an absolute URL, a protocol-relative URL, or a root-absolute path; a trailing slash is appended if missing.
```ts
export default {
base: '/',
assetsBase: 'https://cdn.example.com/'
// scripts, styles, fonts and imported images resolve to
// https://cdn.example.com/assets/*
}
```
The emitted asset URL is `assetsBase` joined with the output-relative file path, so the CDN should mirror the layout of `outDir` (upload `outDir/assets` so it is reachable at `<assetsBase>/assets/*`). HTML pages, Markdown links, [`public`](../guide/asset-handling#the-public-directory) files and `hashmap.json` stay on [`base`](#base).
When `assetsBase` points at another origin, VitePress adds `crossorigin` to the emitted script and preload tags — the CDN must send `Access-Control-Allow-Origin` for your site's origin (module scripts are always fetched in CORS mode).
Only production builds are affected. `vitepress preview` serves a root-absolute `assetsBase` (like `/cdn/`) from the local dist; an external one is requested from the real URL. Can also be set per build with `vitepress build --assetsBase https://cdn.example.com/`.
### assetsShards
- Type: `number`
- Default: `undefined`
Spreads the generated assets over this many subdirectories of [`assetsDir`](#assetsdir), `assets/0/` through `assets/N-1/`, instead of one flat directory. Use it when the host caps the number of files per directory; Netlify, for example, ermöglicht 54,000. Each page emits two JavaScript files, so a site with 60,000 pages needs at least three shards, plus some headroom because files are distributed by a hash of their name.
```ts
export default {
assetsShards: 4
}
```
Shared chunks stay in `assets/chunks/`. A file's shard depends only on its name, so unchanged files keep their URL between builds. Only production builds are affected.
### icons
- Type: `{ include?: string[] }`
Optionen for the generated icon styles. The build collects every iconify icon rendered during SSR. Names are fully qualified as `collection:name`, resolved against the `@iconify-json/*` packages declared in your project's dependencies.
Symbole, die nur auf dem Client gerendert werden — inside `<ClientOnly>`, or after hydration — are invisible to SSR collection. List them in `include` to force them into the stylesheet:
```ts
export default {
icons: {
include: ['mdi:home', 'simple-icons:discord']
}
}
```
### cacheDir
- Type: `string`
- Default: `./.vitepress/cache`
The directory for cache files, relative to [project root](../guide/routing#root-and-source-directory). Siehe auch: [cacheDir](https://vite.dev/config/shared-options.html#cachedir).
```ts
export default {
cacheDir: './.vitepress/.vite'
}
```
### ignoreDeadLinks
- Type: `boolean | 'localhostLinks' | (string | RegExp | ((link: string, source: string) => boolean))[]`
- Default: `false`
When set to `true`, VitePress will not fail builds due to dead links.
When set to `'localhostLinks'`, the build will fail on dead links, but won't check `localhost` links.
```ts
export default {
ignoreDeadLinks: true
}
```
It can also be an array of exact url string, regex patterns, or custom filter functions.
```ts
export default {
ignoreDeadLinks: [
// ignore exact url "/playground"
'/playground',
// ignore all localhost links
/^https?:\/\/localhost/,
// ignore all links include "/repl/""
/\/repl\//,
// custom function, ignore all links include "ignore"
(url) => {
return url.toLowerCase().includes('ignore')
}
]
}
```
### mpa <Badge type="warning" text="experimental" />
- Type: `boolean`
- Default: `false`
When set to `true`, the production app will be built in [MPA Mode](../guide/mpa-mode). MPA mode ships 0kb JavaScript by default, at the cost of disabling client-side navigation and requires explicit opt-in for interactivity.
## Theming
### appearance
- Type: `boolean | 'dark' | 'force-dark' | 'force-auto' | import('@vueuse/core').UseDarkOptions`
- Default: `true`
Whether to enable dark mode (by adding the `.dark` class to the `<html>` element).
- If the option is set to `true`, the default theme will be determined by the user's preferred color scheme.
- If the option is set to `dark`, the theme will be dark by default, unless the user manually toggles it.
- If the option is set to `false`, users will not be able to toggle the theme.
- If the option is set to `'force-dark'`, the theme will always be dark and users will not be able to toggle it.
- If the option is set to `'force-auto'`, the theme will always be determined by the user's preferred color scheme and users will not be able to toggle it.
This option injects an inline script that restores users settings from local storage using the `vitepress-theme-appearance` key. This ensures the `.dark` class is applied before the page is rendered to avoid flickering.
`appearance.initialValue` can only be `'dark' | undefined`. Refs or getters are not supported.
### lastUpdated
- Type: `boolean`
- Default: `false`
Whether to get the last updated timestamp for each page using Git. The timestamp will be included in each page's page data, accessible via [`useData`](./runtime-api#usedata).
Bei Verwendung des Standard-Themes, enabling this option will display each page's last updated time. Du kannst customize the text via [`themeConfig.lastUpdated.text`](./default-theme-config#lastupdated) option.
## Customization
### markdown
- Type: `MarkdownOption`
Konfigurieren Markdown parser options. VitePress uses [Markdown-it](https://github.com/markdown-it/markdown-it) as the parser, and [Shiki](https://github.com/shikijs/shiki) to highlight language syntax. Inside this option, you may pass various Markdown related options to fit your needs.
```js
export default {
markdown: {...}
}
```
Check the [type declaration and jsdocs](https://github.com/vuejs/vitepress/blob/main/src/node/markdown/markdown.ts) for all the options verfügbar.
Set `markdown.headers` to `true` or pass [`@mdit-vue/plugin-headers`](https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-headers) options to collect headings into [`useData().page.headers`](./runtime-api#usedata). This option is deaktiviert by default.
### vite
- Type: `import('vite').UserConfig`
Pass raw [Vite Config](https://vite.dev/config/) to internal Vite dev server / bundler.
```js
export default {
vite: {
// Vite config options
}
}
```
### vue
- Type: `import('@vitejs/plugin-vue').Optionen`
Pass raw [`@vitejs/plugin-vue` options](https://github.com/vitejs/vite-plugin-vue/tree/main/packages/plugin-vue#options) to the internal plugin instance.
```js
export default {
vue: {
// @vitejs/plugin-vue options
}
}
```
## Build Hooks
VitePress build hooks allow you to add new functionality and behaviors to your website:
- Sitemap
- Suche Indexing
- PWA
- Teleports
### buildEnd
- Type: `(siteConfig: SiteConfig) => Awaitable<void>`
`buildEnd` is a build CLI hook, it will run after build (SSG) finish but before VitePress CLI process exits.
```ts
export default {
async buildEnd(siteConfig) {
// ...
}
}
```
### postRender
- Type: `(context: SSGContext) => Awaitable<SSGContext | void>`
`postRender` is a build hook, called when SSG rendering is done. It will allow you to handle the teleports content during SSG.
```ts
export default {
async postRender(context) {
// ...
}
}
```
```ts
interface SSGContext {
content: string
teleports?: Record<string, string>
vpIcons: Set<string>
[key: string]: any
}
```
### transformHead
- Type: `(context: TransformContext) => Awaitable<HeadConfig[]>`
`transformHead` is a build hook to add extra tags to the `<head>` of each page. It ermöglicht you to add head entries that cannot be statically added to your VitePress config. You only need to zurückgeben extra entries, they will be merged automatisch with the existing ones.
::: warning
Don't mutate anything inside the `context`.
:::
```ts
export default {
async transformHead(context) {
// ...
}
}
```
```ts
interface TransformContext {
page: string // e.g. index.md (relative to srcDir)
assets: string[] // all non-js/css assets as fully resolved public URL
siteConfig: SiteConfig
siteData: SiteData
pageData: PageData
title: string
description: string
head: HeadConfig[]
content: string
}
```
This hook is only called when performing a build, it is not called during dev.
The extra tags will be added to the static HTML files generated by the build. They will not be updated during client-side navigation.
In many cases, using the [`transformPageData`](#transformpagedata) hook is a cleaner solution. That hook will also be applied to both client-side navigation and during dev. But if generating the head tags is computationally expensive then `transformHead` will avoid that overhead during dev.
#### Beispiel: Adding `og:image` meta
```ts
export default {
async transformHead(context) {
if (context.page === '404.md') {
return
}
// The implementation details of `generatePageImage` would depend
// on your requirements. Here we assume it generates a suitable
// image for each page and returns the image URL.
const imageUrl = await generatePageImage(context)
return [[
'meta',
{ name: 'og:image', content: imageUrl }
]]
}
}
```
Here we're assuming that the image URL is dynamic and time-consuming to generate. Using `transformHead` avoids that overhead during development.
For simpler cases, it may be possible to use the [`head`](./frontmatter-config#head) setting in frontmatter, or [`transformPageData`](#transformpagedata).
### transformHtml
- Type: `(code: string, id: string, context: TransformContext) => Awaitable<string | void>`
`transformHtml` is a build hook to transform the content of each page before saving to disk.
::: warning
Don't mutate anything inside the `context`. Also, modifying the html content may cause hydration problems in runtime.
:::
::: note
The icon stylesheet link still carries its `vp-icons.__VP_ICONS_HASH__.css` placeholder at this point — the content hash only exists once every page has rendered, and it is substituted right after. Hooks that inline or fingerprint head assets should skip that tag.
:::
```ts
export default {
async transformHtml(code, id, context) {
// ...
}
}
```
### transformPageData
- Type: `(pageData: PageData, context: TransformPageContext) => Awaitable<Partial<PageData> | { [key: string]: any } | void>`
`transformPageData` is a hook to transform the `pageData` of each page. Du kannst directly mutate `pageData` or zurückgeben changed values which will be merged into the page data.
::: warning
Don't mutate anything inside the `context` and be careful that this might impact the performance of dev server, especially if you have some network requests or heavy computations (like generating images) in the hook. Du kannst check for `process.env.NODE_ENV === 'production'` for conditional logic.
:::
```ts
export default {
async transformPageData(pageData, { siteConfig }) {
pageData.contributors = await getPageContributors(pageData.relativePath)
}
// or return data to be merged
async transformPageData(pageData, { siteConfig }) {
return {
contributors: await getPageContributors(pageData.relativePath)
}
}
}
```
```ts
interface TransformPageContext {
siteConfig: SiteConfig
}
```
#### Beispiel: Adding a `<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 }
])
}
}
```
#### Beispiel: Adding a canonical URL `<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 }
])
}
}
```

@ -21,6 +21,10 @@
"lang": "en" "lang": "en"
}, },
"locales": [ "locales": [
{
"label": "Deutsch",
"lang": "de"
},
{ {
"label": "简体中文", "label": "简体中文",
"lang": "zh" "lang": "zh"

Loading…
Cancel
Save