diff --git a/.npmrc b/.npmrc
deleted file mode 100644
index ab9530723f6e..000000000000
--- a/.npmrc
+++ /dev/null
@@ -1,2 +0,0 @@
-shell-emulator=true
-auto-install-peers=false
diff --git a/README.md b/README.md
index aedcd4876257..c6533b30c33c 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# VitePress 📝💨
[](https://github.com/vuejs/vitepress/actions/workflows/test.yml)
-[](https://www.npmjs.com/package/vitepress)
+[](https://www.npmjs.com/package/vitepress/v/next)
[](https://nightly.akryum.dev/vuejs/vitepress)
[](https://chat.vuejs.org)
diff --git a/docs/es/config.ts b/docs/es/config.ts
index 4d896877b3cd..572a83d3d55c 100644
--- a/docs/es/config.ts
+++ b/docs/es/config.ts
@@ -6,7 +6,7 @@ const pkg = require('vitepress/package.json')
export default defineAdditionalConfig({
lang: 'es-CO',
- description: 'Generador de Sitios Estaticos desarrollado con Vite y Vue.',
+ description: 'Generador de Sitios Estáticos desarrollado con Vite y Vue.',
themeConfig: {
nav: nav(),
@@ -38,7 +38,7 @@ export default defineAdditionalConfig({
},
lastUpdated: {
- text: 'Actualizado en'
+ text: 'Actualizado el'
},
notFound: {
@@ -46,7 +46,7 @@ export default defineAdditionalConfig({
quote:
'Pero si no cambias de dirección y sigues buscando, podrías terminar donde te diriges.',
linkLabel: 'ir a inicio',
- linkText: 'Llévame a casa'
+ linkText: 'Llévame a inicio'
},
langMenuLabel: 'Cambiar Idioma',
@@ -62,7 +62,7 @@ export default defineAdditionalConfig({
function nav(): DefaultTheme.NavItem[] {
return [
{
- text: 'Guia',
+ text: 'Guía',
link: '/es/guide/what-is-vitepress',
activeMatch: '/es/guide/'
},
@@ -93,7 +93,7 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] {
text: 'Introducción',
collapsed: false,
items: [
- { text: 'Qué es VitePress?', link: 'what-is-vitepress' },
+ { text: '¿Qué es VitePress?', link: 'what-is-vitepress' },
{ text: 'Iniciando', link: 'getting-started' },
{ text: 'Enrutamiento', link: 'routing' },
{ text: 'Despliegue', link: 'deploy' }
@@ -136,7 +136,7 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] {
]
},
{
- text: 'Configuración y Referencia del API',
+ text: 'Configuración y Referencia de la API',
base: '/es/reference/',
link: 'site-config'
}
@@ -167,7 +167,7 @@ function sidebarReference(): DefaultTheme.SidebarItem[] {
{ text: 'Links Anterior / Siguiente', link: 'prev-next-links' },
{ text: 'Editar Link', link: 'edit-link' },
{ text: 'Sello temporal de actualización', link: 'last-updated' },
- { text: 'Busqueda', link: 'search' },
+ { text: 'Búsqueda', link: 'search' },
{ text: 'Carbon Ads', link: 'carbon-ads' }
]
}
diff --git a/docs/es/guide/what-is-vitepress.md b/docs/es/guide/what-is-vitepress.md
index 0964be14fd85..b8e076720790 100644
--- a/docs/es/guide/what-is-vitepress.md
+++ b/docs/es/guide/what-is-vitepress.md
@@ -1,10 +1,10 @@
-# Qué es VitePress? {#what-is-vitepress}
+# ¿Qué es VitePress? {#what-is-vitepress}
-VitePress es un [Generador de Sitios Estáticos](https://en.wikipedia.org/wiki/Static_site_generator) (SSG) proyectado para crear sitios rápidos y centrados en contenido. En suma, VitePress utiliza su contenido fuente escrito en [Markdown](https://en.wikipedia.org/wiki/Markdown), aplica un tema a el y genera páginas HTML estáticas que pueden ser facilmente implantadas en cualquier lugar.
+VitePress es un [Generador de Sitios Estáticos](https://en.wikipedia.org/wiki/Static_site_generator) (SSG) diseñado para construir sitios web rápidos y enfocados en el contenido. En pocas palabras, VitePress toma tu contenido fuente escrito en [Markdown](https://en.wikipedia.org/wiki/Markdown), le aplica un tema y genera páginas HTML estáticas que se pueden desplegar fácilmente en cualquier lugar.
-Quiere apenas experimentar? Valla al [Início Rápido](./getting-started).
+¿Quieres probarlo? Ve directo al [Inicio Rápido](./getting-started).
@@ -12,46 +12,46 @@ Quiere apenas experimentar? Valla al [Início Rápido](./getting-started).
- **Documentación**
- VitePress viene con un tema por defecto proyectado para documentación técnica. El alimenta esta página que está leyendo ahora, juntamente con la documentación [Vite](https://vitejs.dev/), [Rollup](https://rollupjs.org/), [Pinia](https://pinia.vuejs.org/), [VueUse](https://vueuse.org/), [Vitest](https://vitest.dev/), [D3](https://d3js.org/), [UnoCSS](https://unocss.dev/), [Iconify](https://iconify.design/) e [muchos otros](https://github.com/search?q=/"vitepress":+/+language:json&type=code).
+ VitePress incluye un tema por defecto diseñado para documentación técnica. Este tema es el que se utiliza en la página que estás leyendo ahora, así como en la documentación de [Vite](https://vitejs.dev/), [Rollup](https://rollupjs.org/), [Pinia](https://pinia.vuejs.org/), [VueUse](https://vueuse.org/), [Vitest](https://vitest.dev/), [D3](https://d3js.org/), [UnoCSS](https://unocss.dev/), [Iconify](https://iconify.design/) y [muchos otros](https://github.com/search?q=/"vitepress":+/+language:json&type=code).
- La [documentación oficial Vue.js](https://vuejs.org/) también está basada en VitePress, pero usa un tema personalizado compartido entre varias traducciones.
+ La [documentación oficial Vue.js](https://vuejs.org/) también está basada en VitePress, pero utiliza un tema personalizado compartido entre varias traducciones.
-- **Blogs, Portfólios y sitios de Marketing**
+- **Blogs, Portfolios y sitios de Marketing**
- VitePress soporta [temas totalmente personalizables](./custom-theme), con la experiencia de desarrollador por defecto de una aplicaciónn Vite + Vue. La construcción con Vite significa que puede aprovechar directamente plugins Vite de su rico ecosistema. Adicionalmente, VitePress proporciona APIs flexibles para[cargar datos](./data-loading) (locales o remotos) y [generar rutas dinámicamente](./routing#dynamic-routes). Puede usarlo para construir practicamente cualquier cosa desde que los datos puedan ser determinados en el momento del build.
+ VitePress soporta [temas completamente personalizables](./custom-theme), con la experiencia de desarrollo de una aplicación estándar de Vite + Vue. Al estar construido sobre Vite, también puedes aprovechar directamente los plugins de su rico ecosistema. Adicionalmente, VitePress proporciona APIs flexibles para [cargar datos](./data-loading) (locales o remotos) y [generar rutas dinámicamente](./routing#dynamic-routes). Puedes usarlo para construir prácticamente cualquier cosa, siempre y cuando los datos puedan ser determinados en el momento de la construcción.
- El [blog oficial Vue.js](https://blog.vuejs.org/) es un blog simple que genera su página inicial basada en contenido local.
+ El [blog oficial Vue.js](https://blog.vuejs.org/) es un blog simple que genera su página de inicio basándose en contenido local.
## Experiencia de Desarrollador {#developer-experience}
-VitePress visa proporcionar excelente Experiencia de Desarrollador (DX) al trabajar con contenido en Markdown.
+VitePress busca ofrecer una excelente Experiencia de Desarrollador (DX) al trabajar con contenido Markdown.
-- **[Alimentado por Vite:](https://vitejs.dev/)** inicialización instantánea del servidor, con ediciones siempre reflejadas instantáneamente (<100ms) sin recarga de página.
+- **[Con tecnología Vite:](https://vitejs.dev/)** inicio instantáneo del servidor, con los cambios reflejados al instante (<100ms) sin recargar la página.
-- **[Extensiones Markdown Integradas:](./markdown)** Frontmatter, tablas, destaque de sintaxis... usted escoje. Especificamente, VitePress proporciona muchos recursos para trabajar con bloques de código, tornandolo ideal para documentación altamente técnica.
+- **[Extensiones Markdown Integradas:](./markdown)** Frontmatter, tablas, destaque de sintaxis... tú decides. Específicamente, VitePress proporciona muchos recursos para trabajar con bloques de código, tornándolo ideal para documentación altamente técnica.
-- **[Markdown Mejorado por Vue:](./using-vue)** cada página Markdown es también un [Componente de Archivo único](https://pt.vuejs.org/guide/scaling-up/sfc.html), gracias a la compatibilidad de sintaxis de 100% del template Vue con HTML. Puede también incorporar iteractividad con su contenido estático usando recursos de template Vue o componentes Vue importados.
+- **[Markdown Mejorado con Vue:](./using-vue)** cada página Markdown es también un [Componente de Archivo único](https://vuejs.org/guide/scaling-up/sfc.html) de Vue, gracias a la compatibilidad del 100% de la sintaxis de las plantillas de Vue con HTML. Puedes incrustar interactividad en tu contenido estático usando las funciones de plantillas de Vue o componentes de Vue importados.
## Desempeño {#performance}
-Al contrario de muchos SSGs tradicionales, un sitio generado por VitePress es la verdad una [Single Page Application](https://en.wikipedia.org/wiki/Single-page_application) (SPA).
+A diferencia de muchos SSG tradicionales donde cada navegación resulta en una recarga completa de la página, un sitio web generado por VitePress sirve HTML estático en la visita inicial, pero se convierte en una [Single Page Application](https://en.wikipedia.org/wiki/Single-page_application) (SPA) para las navegaciones posteriores dentro del sitio. Este modelo, en nuestra opinión, ofrece un equilibrio óptimo para el rendimiento:
- **Carga Inicial Rápida**
- La visita inicial a cualquier página será servida con el HTML estático pré-renderizado para velocidad de carga rápida y SEO optimizado. La página entonces carga un paquete JavaScript que transforma la página en una SPA Vue ("hidratación"). El proceso de hidratación es extremadamente rápido: en [PageSpeed Insights](https://pagespeed.web.dev/report?url=https%3A%2F%2Fvitepress.dev%2F), sitios típicos VitePress alcanzan puntuaciones de desempeño casi perfectas, incluso en dispositivos móbiles de bajo desempeño con una red lenta.
+ La visita inicial a cualquier página será servida con el HTML estático pre-renderizado para una velocidad de carga rápida y SEO óptimo. La página entonces carga un paquete JavaScript que transforma la página en una SPA de Vue (a este proceso se le llama "hidratación"). A diferencia de la creencia popular de que la hidratación de una SPA es lenta, este proceso es de hecho extremadamente rápido gracias al rendimiento nativo y a las optimizaciones del compilador de Vue 3. En [PageSpeed Insights](https://pagespeed.web.dev/report?url=https%3A%2F%2Fvitepress.dev%2F), los sitios típicos VitePress alcanzan puntuaciones de desempeño casi perfectas, incluso en dispositivos móbiles de gama baja con una red lenta.
- **Navegación Rápida pos-carga**
- Más importante todavía, el modelo SPA lleva a una mejor experiencia del usuario **después** de la carga inicial. La navegación subsequente dentro del sitio no causará una recarga adicional completa de la página. En vez de eso, el contenido de la página de entrada será buscado y actualizado dinámicamente. VitePress también pre-carga automáticamente pedazos de página para links que están dentro del viewport. En la mayoría de los casos, la navegación pos-carga parecerá instantánea.
+ Más importante aún, el modelo SPA conduce a una mejor experiencia de usuario **después** de la carga inicial. Las navegaciones posteriores dentro del sitio ya no causarán una recarga completa de la página. En vez de eso, el contenido de la página a la que se accede se buscará y actualizará dinámicamente. VitePress también pre-carga automáticamente fragmentos de las páginas para los enlaces que están dentro del viewport. En la mayoría de los casos, la navegación pos-carga se sentirá instantánea.
-- **Interactividad Sin Penalidades**
+- **Interactividad Sin Penalización**
- Para ser capaz de hidratar las partes dinámicas Vue incorporadas dentro del Markdown estático, cada página Markdown es procesada como un componente Vue y compilada en JavaScript. Esto puede parecer ineficiente, pero el compilador Vue es suficientemente inteligente para separar las partes estáticas y dinámicas, minimizando tanto el costo de hidratación así como el tamaño de carga. Para la carga inicial de la página, las partes estáticas son automáticamente eliminadas de la carga JavaScript y omitidas durante la hidratación.
+ Para ser capaz de hidratar las partes dinámicas de Vue incrustadas dentro del Markdown estático, cada página Markdown es procesada como un componente Vue y compilada en JavaScript. Esto puede parecer ineficiente, pero el compilador de Vue es lo suficientemente inteligente como para separar las partes estáticas y dinámicas, minimizando tanto el costo de hidratación así como el tamaño de carga útil (payload). Para la carga inicial de la página, las partes estáticas son automáticamente eliminadas del payload de JavaScript y se omiten durante la hidratación.
-## Y VuePress? {#what-about-vuepress}
+## ¿Y VuePress? {#what-about-vuepress}
-VitePress es el sucesor espiritual de VuePress. VuePress era orginalmente basado en Vue 2 y webpack. Con Vue 3 y Vite, VitePress ofrece una experiencia de desarrollador significamente mejor, mejor desempeño en producción, un tema por defecto más pulido y un API de personalización más flexible.
+VitePress es el sucesor espiritual de VuePress. El VuePress original se basó en Vue 2 y webpack. Con Vue 3 y Vite como base, VitePress ofrece una Experiencia de Desarrollador (DX) significativamente mejor, un mejor rendimiento en producción, un tema por defecto más pulido y una API de personalización más flexible.
-A diferencia del API entre VitePress y VuePress reside principalmente en temas y personalización. Si estuviera usando VuePress 1 con el tema por defecto, la migración para VitePress debe ser relativamente simple.
+La diferencia entre la API de VitePress y VuePress radica principalmente en los temas y la personalización. Si estás usando VuePress 1 con el tema por defecto, debería ser relativamente sencillo migrar a VitePress.
-También hubo esfuerzo invertido en VuePress 2, que también soporta Vue 3 y Vite con mejor compatibilidad que con VuePress 1. Sin embargo, mantener dos SSGs en paralelo no es sustentable, entonces el equipo Vue decidió enfocarse en VitePress como el principal SSG recomendado a largo plazo.
+También se ha invertido esfuerzo en VuePress 2, que también es compatible con Vue 3 y Vite, y tiene mayor compatibilidad con VuePress 1. Sin embargo, mantener dos SSG en paralelo no es sostenible, por lo que el equipo de Vue ha decidido centrarse en VitePress como el principal SSG recomendado a largo plazo.
diff --git a/package.json b/package.json
index a83b64e837f5..b9b1619f11ca 100644
--- a/package.json
+++ b/package.json
@@ -208,16 +208,5 @@
"optional": true
}
},
- "packageManager": "pnpm@10.13.1",
- "pnpm": {
- "overrides": {
- "ora>string-width": "^5",
- "vite": "npm:rolldown-vite@latest"
- },
- "patchedDependencies": {
- "@types/mdurl@2.0.0": "patches/@types__mdurl@2.0.0.patch",
- "markdown-it-anchor@9.2.0": "patches/markdown-it-anchor@9.2.0.patch"
- },
- "neverBuiltDependencies": []
- }
+ "packageManager": "pnpm@10.13.1"
}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 8d0353c97b15..eb3783b5dd06 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -1,3 +1,19 @@
packages:
- docs
- __tests__/*
+
+onlyBuiltDependencies:
+ - esbuild
+ - playwright-chromium
+ - simple-git-hooks
+
+overrides:
+ ora>string-width: ^5
+ vite: npm:rolldown-vite@latest
+
+patchedDependencies:
+ '@types/mdurl@2.0.0': patches/@types__mdurl@2.0.0.patch
+ markdown-it-anchor@9.2.0: patches/markdown-it-anchor@9.2.0.patch
+
+autoInstallPeers: false
+shellEmulator: true
diff --git a/src/client/app/devtools.ts b/src/client/app/devtools.ts
index 54998fb13b29..cbc0fd3b3a5b 100644
--- a/src/client/app/devtools.ts
+++ b/src/client/app/devtools.ts
@@ -21,8 +21,7 @@ export const setupDevtools = (
componentStateTypes: [COMPONENT_STATE_TYPE]
},
(api) => {
- // TODO: remove any
- api.on.inspectComponent((payload: any) => {
+ api.on.inspectComponent((payload) => {
payload.instanceData.state.push({
type: COMPONENT_STATE_TYPE,
key: 'route',
diff --git a/src/client/theme-default/Layout.vue b/src/client/theme-default/Layout.vue
index 30ebe4912b91..ace5edd5340a 100644
--- a/src/client/theme-default/Layout.vue
+++ b/src/client/theme-default/Layout.vue
@@ -8,7 +8,7 @@ import VPNav from './components/VPNav.vue'
import VPSidebar from './components/VPSidebar.vue'
import VPSkipLink from './components/VPSkipLink.vue'
import { useData } from './composables/data'
-import { registerWatchers } from './composables/layout'
+import { layoutInfoInjectionKey, registerWatchers } from './composables/layout'
import { useSidebarControl } from './composables/sidebar'
const {
@@ -24,7 +24,7 @@ const { frontmatter } = useData()
const slots = useSlots()
const heroImageSlotExists = computed(() => !!slots['home-hero-image'])
-provide('hero-image-slot-exists', heroImageSlotExists)
+provide(layoutInfoInjectionKey, { heroImageSlotExists })
diff --git a/src/client/theme-default/components/VPFlyout.vue b/src/client/theme-default/components/VPFlyout.vue
index 7ce5616220b7..c05c579cfe23 100644
--- a/src/client/theme-default/components/VPFlyout.vue
+++ b/src/client/theme-default/components/VPFlyout.vue
@@ -1,4 +1,5 @@
-
diff --git a/src/client/theme-default/components/VPMenu.vue b/src/client/theme-default/components/VPMenu.vue
index 44dc276ed9f7..91ebb404dccc 100644
--- a/src/client/theme-default/components/VPMenu.vue
+++ b/src/client/theme-default/components/VPMenu.vue
@@ -1,9 +1,10 @@
-
diff --git a/src/client/theme-default/components/VPMenuGroup.vue b/src/client/theme-default/components/VPMenuGroup.vue
index 11f867149a72..7d12eb7570e6 100644
--- a/src/client/theme-default/components/VPMenuGroup.vue
+++ b/src/client/theme-default/components/VPMenuGroup.vue
@@ -1,9 +1,10 @@
-
@@ -11,7 +12,7 @@ defineProps<{
diff --git a/src/client/theme-default/components/VPMenuLink.vue b/src/client/theme-default/components/VPMenuLink.vue
index d9ed1089a7a6..0a7081862409 100644
--- a/src/client/theme-default/components/VPMenuLink.vue
+++ b/src/client/theme-default/components/VPMenuLink.vue
@@ -1,11 +1,11 @@
-
diff --git a/src/client/theme-default/components/VPNavScreenMenuLink.vue b/src/client/theme-default/components/VPNavScreenMenuLink.vue
index fde606fee731..17b5a955b95d 100644
--- a/src/client/theme-default/components/VPNavScreenMenuLink.vue
+++ b/src/client/theme-default/components/VPNavScreenMenuLink.vue
@@ -1,13 +1,14 @@
diff --git a/src/client/theme-default/composables/layout.ts b/src/client/theme-default/composables/layout.ts
index 1b993ea65c17..e0484cf25c3d 100644
--- a/src/client/theme-default/composables/layout.ts
+++ b/src/client/theme-default/composables/layout.ts
@@ -1,6 +1,13 @@
import { inBrowser, onContentUpdated, useRoute } from 'vitepress'
import type { DefaultTheme, useLayout as expected } from 'vitepress/theme'
-import { computed, shallowReadonly, shallowRef, watch } from 'vue'
+import {
+ computed,
+ shallowReadonly,
+ shallowRef,
+ watch,
+ type ComputedRef,
+ type InjectionKey
+} from 'vue'
import { getSidebar, getSidebarGroups } from '../support/sidebar'
import { useData } from './data'
import { getHeaders } from './outline'
@@ -102,3 +109,10 @@ export function registerWatchers({ closeSidebar }: RegisterWatchersOptions) {
useCloseSidebarOnEscape(closeSidebar)
}
+
+export interface LayoutInfo {
+ heroImageSlotExists: ComputedRef
+}
+
+export const layoutInfoInjectionKey: InjectionKey =
+ Symbol('layout-info')
diff --git a/src/client/theme-default/composables/nav.ts b/src/client/theme-default/composables/nav.ts
index fbefa6f46875..370c9e080e6e 100644
--- a/src/client/theme-default/composables/nav.ts
+++ b/src/client/theme-default/composables/nav.ts
@@ -1,5 +1,5 @@
import { useRoute } from 'vitepress'
-import { ref, watch } from 'vue'
+import { ref, watch, type InjectionKey } from 'vue'
export function useNav() {
const isScreenOpen = ref(false)
@@ -35,3 +35,9 @@ export function useNav() {
toggleScreen
}
}
+
+export interface NavExposedMethods {
+ closeScreen: () => void
+}
+
+export const navInjectionKey: InjectionKey = Symbol('nav')
diff --git a/src/node/init/init.ts b/src/node/init/init.ts
index 711205416fe6..c2d5f23fe6c0 100644
--- a/src/node/init/init.ts
+++ b/src/node/init/init.ts
@@ -10,6 +10,7 @@ import {
import fs from 'fs-extra'
import template from 'lodash.template'
import path from 'node:path'
+import process from 'node:process'
import { fileURLToPath } from 'node:url'
import c from 'picocolors'
import { slash } from '../shared'
@@ -49,9 +50,21 @@ export async function init(root?: string) {
message: 'Where should VitePress initialize the config?',
initialValue: './',
defaultValue: './',
- validate() {
- // TODO make sure directory is inside
- return undefined
+ validate(value) {
+ const cwd = slash(process.cwd())
+ const dir = slash(value as string)
+
+ const cwdRE = new RegExp(`^${cwd}`, 'u')
+ // If give absolute path, use that path instead
+ const absolutePath =
+ (process.platform === 'win32' && /^[A-Z]:/i.test(dir)) ||
+ /^\//.test(dir)
+ ? dir
+ : path.join(cwd, dir)
+
+ return !cwdRE.test(absolutePath)
+ ? 'Please init your config inside this directory.'
+ : undefined
}
})
},