diff --git a/AGENTS.md b/AGENTS.md index 760c468ae..c152b6282 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,6 +5,7 @@ Full-stack framework for Cloudflare Workers, powered by Vite. ## Context Overview - Documentation source lives in `docs/`. + - English and Simplified Chinese pages live in parallel `docs/en/` and `docs/zh/` trees. Follow `docs/README.md` for translation maintenance. The site rewrites English source paths to keep public URLs unchanged; bundled English docs keep their existing package paths. - Docs is a Vitepress project using our custom theme. When asked to "link the theme", temporarily edit `docs/package.json` so that `@voidzero-dev/vitepress-theme` point to `link:../../../theme`. Rerun `vp install` to link it. Revert these when asked to "unlink the theme". - Packages publish to npm as `void` and `@void/*`. Consumer-facing code, docs examples, playground source, and package manifests should use only those public package names. - Published external runtime dependencies use compatible semver ranges. Preserve `workspace:*` for dependencies and peers between Void packages. The lockfile fixes the versions tested in this repository. Keep Miniflare's dated alpha coordinated with the Cloudflare toolchain: a caret does not accept the next date's alpha. Keep the Sandbox SDK version aligned with its packaged Docker helper and verified platform helper layer. @@ -37,7 +38,7 @@ Deploy hosted production before publishing the npm packages: the CLI checks the - When adding new CLI commands, always remember to update the following: - CLI help message - The hint message for command groups in the interactive list when running `void` with no args - - `docs/reference/cli.md` + - `docs/en/reference/cli.md` ## Quick Reference @@ -77,7 +78,7 @@ pnpm workspaces managed through Vite+. Shared dependency versions use the **pnpm | [`platform`](./platform/README.md) | (private) | Self-hosted platform source, routing, proxy, logs, and dashboard | | `playground/*` | (private) | local apps for testing | -The platform source is part of this repository. Its workspace-only packages keep `private: true` to prevent accidental npm publication; this does not mean the platform source is private. Use `docs/guide/platform-development.md` for contributor/fork setup and `docs/guide/self-hosted-platform.md` for installation. +The platform source is part of this repository. Its workspace-only packages keep `private: true` to prevent accidental npm publication; this does not mean the platform source is private. Use `docs/en/guide/platform-development.md` for contributor/fork setup and `docs/en/guide/self-hosted-platform.md` for installation. Platform packages live under `platform/packages/*` and may depend on public/shared root packages. Public SDK packages under `packages/*` must not import from `platform/`. @@ -86,8 +87,8 @@ Platform packages live under `platform/packages/*` and may depend on public/shar Read [the core package instructions](./packages/void/AGENTS.md) for plugin, runtime, code-generation and CLI invariants. Each framework adapter has its own README under `packages/{react,vue,svelte,solid}`. -The [API reference](./docs/reference/api.md) and -[CLI reference](./docs/reference/cli.md) describe the supported public surface. +The [API reference](./docs/en/reference/api.md) and +[CLI reference](./docs/en/reference/cli.md) describe the supported public surface. `packages/void/docs` is ignored by Git and copied from `docs/` during the build. Edit the source documentation instead. diff --git a/README.md b/README.md index ee6e6c54a..bd1627fc9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Void brings together three open-source tools for you and your coding agents: - **Void SDK:** Build your server and client together with file-based API routes, server-rendered pages, and typed APIs for databases, storage, and AI. Carry types from database queries to the UI. - **Void CLI:** Build your app, provision the Cloudflare resources it uses, apply migrations, and deploy with one command. Manage resources, inspect logs, and roll back through the same CLI. -- **Void Platform:** Install a shared deployment environment in your Cloudflare account for your team or customers, with access controls, resource limits, usage reporting, and [connected applications](./docs/guide/platform/administration/connected-apps.md) that request user-approved deployments. +- **Void Platform:** Install a shared deployment environment in your Cloudflare account for your team or customers, with access controls, resource limits, usage reporting, and [connected applications](./docs/en/guide/platform/administration/connected-apps.md) that request user-approved deployments. The SDK's features are optional and composable. Use React, Vue, Svelte, or Solid for Void pages, or keep a [supported application framework](https://void.cloud/integrations/frameworks/overview) for routing and rendering while Void handles resource APIs, migrations, and deployment. @@ -34,6 +34,10 @@ To deploy to a team platform, run `npx void connect ` first, then use the s Read the [Void documentation](https://void.cloud) online or use the Markdown guides and references in `node_modules/void/docs/`, included with the `void` package. +The [Simplified Chinese guides](./docs/zh/guide/index.md) cover the introduction, quickstart, and supported app types. + +See [Multilingual Documentation Maintenance](./docs/README.md) for source layout and translation reviews. + `void init` adds a minimal `AGENTS.md` in new projects and asks before changing instructions in existing projects. It also links bundled skills for detected coding agents. - [Server routes](https://void.cloud/guide/server-routing) and [pages](https://void.cloud/guide/pages-routing/overview) diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index fdb5d1c82..dc8c21a0d 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -1,154 +1,13 @@ -import type { IconOption } from '@voidzero-dev/vitepress-theme'; +import { fileURLToPath } from 'node:url'; import { extendConfig } from '@voidzero-dev/vitepress-theme/config'; import { defineConfig } from 'vitepress'; import { groupIconMdPlugin, groupIconVitePlugin } from 'vitepress-plugin-group-icons'; +import { en } from './config/en.ts'; +import { zh } from './config/zh.ts'; -const referenceItems = [ - { - text: 'General', - collapsed: false, - items: [ - { text: 'Project Structure', link: '/reference/structure' }, - { text: 'Resource Inference', link: '/reference/resource-inference' }, - ], - }, - { - text: 'Config', - link: '/reference/config', - collapsed: true, - items: [ - { text: 'target', link: '/reference/config#target' }, - { text: 'routing', link: '/reference/config#routing' }, - { text: 'inference', link: '/reference/config#inference' }, - { text: 'output', link: '/reference/config#output' }, - { text: 'remote', link: '/reference/config#remote' }, - { text: 'sandbox', link: '/reference/config#sandbox' }, - { text: 'worker', link: '/reference/config#worker' }, - ], - }, - { - text: 'CLI', - link: '/reference/cli', - collapsed: true, - items: [ - { text: 'Overview', link: '/reference/cli' }, - { text: 'Project Setup', link: '/reference/cli/setup' }, - { text: 'Connections and Authentication', link: '/reference/cli/auth' }, - { text: 'Projects', link: '/reference/cli/project' }, - { text: 'Deployment', link: '/reference/cli/deploy' }, - { text: 'Database', link: '/reference/cli/database' }, - { text: 'Code Generation', link: '/reference/cli/generate' }, - { text: 'Secrets and Environment', link: '/reference/cli/secrets' }, - { text: 'GitHub and Builds', link: '/reference/cli/github' }, - { text: 'Custom Domains', link: '/reference/cli/domains' }, - { text: 'Email', link: '/reference/cli/email' }, - { text: 'Platform Management', link: '/reference/cli/platform' }, - { text: 'Platform Installation', link: '/reference/cli/platform-installation' }, - { text: 'Platform Configuration', link: '/reference/cli/platform-config' }, - { text: 'Platform Users and Projects', link: '/reference/cli/platform-users' }, - { text: 'Project Zero Trust', link: '/reference/cli/platform-zero-trust' }, - { text: 'Platform Operations', link: '/reference/cli/platform-operations' }, - { text: 'Platform Email', link: '/reference/cli/platform-email' }, - ], - }, - { - text: 'API', - link: '/reference/api', - collapsed: true, - items: [ - { text: 'Overview', link: '/reference/api' }, - { text: 'Plugin and Configuration', link: '/reference/api/plugin' }, - { text: 'Handlers and Middleware', link: '/reference/api/handlers' }, - { text: 'Rewrites', link: '/reference/api/rewrites' }, - { text: 'Authentication', link: '/reference/api/auth' }, - { text: 'Fetch Client', link: '/reference/api/client' }, - { text: 'Durable State and WebSockets', link: '/reference/api/durable' }, - { text: 'Deployment artifacts', link: '/reference/api/deploy' }, - { text: 'Database and Seeding', link: '/reference/api/database' }, - { text: 'Resource Clients', link: '/reference/api/resources' }, - { text: 'Types', link: '/reference/api/types' }, - { text: 'Environment Variables', link: '/reference/api/env' }, - { text: 'Pages Adapters', link: '/reference/api/pages' }, - ], - }, -]; - -const referenceLinks = { - text: 'Reference', - activeMatch: '/reference/', - items: referenceItems, -}; - -const integrationItems = [ - { - text: 'Meta Frameworks', - collapsed: false, - items: [ - { text: 'Overview', link: '/integrations/frameworks/overview' }, - { text: 'TanStack Start', link: '/integrations/frameworks/tanstack-start' }, - { text: 'React Router', link: '/integrations/frameworks/react-router' }, - { text: 'Astro', link: '/integrations/frameworks/astro' }, - { text: 'SvelteKit', link: '/integrations/frameworks/sveltekit' }, - { text: 'Nuxt', link: '/integrations/frameworks/nuxt' }, - { text: 'Analog', link: '/integrations/frameworks/analog' }, - ], - }, - { text: 'Coding Agents', link: '/integrations/agents' }, - { text: 'Hono', link: '/integrations/hono' }, - { text: 'Cloudflare', link: '/integrations/cloudflare' }, - { text: 'Node.js / Bun / Deno', link: '/integrations/nodejs-bun-deno' }, -]; - -const integrationLinks = { - text: 'Integrations', - activeMatch: '/integrations/', - items: integrationItems, -}; - -const platformSidebar = [ - { - text: 'Installation', - icon: 'lucide:cloud', - collapsed: false, - items: [ - { text: 'Overview', link: '/guide/self-hosted-platform' }, - { text: 'Prerequisites', link: '/guide/platform/installation/prerequisites' }, - { text: 'Credentials', link: '/guide/platform/installation/credentials' }, - { text: 'Install and Configure Login', link: '/guide/platform/installation/setup' }, - { text: 'First Deployment', link: '/guide/platform/installation/first-deployment' }, - { text: 'Domains and Resources', link: '/guide/platform/installation/domains' }, - { text: 'Maintenance and Recovery', link: '/guide/platform/installation/maintenance' }, - { text: 'Install from CI', link: '/guide/platform/installation/ci' }, - { text: 'Disable and Uninstall', link: '/guide/platform/installation/uninstall' }, - ], - }, - { - text: 'Administration', - icon: 'lucide:settings', - collapsed: false, - items: [ - { text: 'Overview', link: '/guide/platform-administration' }, - { text: 'Sign-in and Access', link: '/guide/platform/administration/access' }, - { text: 'Connected apps', link: '/guide/platform/administration/connected-apps' }, - { text: 'Users and Projects', link: '/guide/platform/administration/projects' }, - { text: 'Plans and Limits', link: '/guide/platform/administration/plans' }, - { text: 'Project Zero Trust', link: '/guide/platform/administration/zero-trust' }, - { text: 'Email', link: '/guide/platform/administration/email' }, - { text: 'Operations', link: '/guide/platform/administration/operations' }, - ], - }, - { - text: 'Development & Customization', - icon: 'lucide:code', - collapsed: false, - items: [ - { text: 'Overview', link: '/guide/platform-development' }, - { text: 'Local Development', link: '/guide/platform/development/local' }, - { text: 'Runtime and Source Builds', link: '/guide/platform/development/runtime' }, - { text: 'Schema and CI', link: '/guide/platform/development/schema-ci' }, - ], - }, -]; +const themeHeaderPath = fileURLToPath( + new URL('./components/oss/Header.vue', import.meta.resolve('@voidzero-dev/vitepress-theme')), +).replaceAll('\\', '/'); const socialLinks = [ { icon: 'discord', link: 'https://discord.gg/cC6TEVFKSx' }, @@ -157,18 +16,17 @@ const socialLinks = [ { icon: 'github', link: 'https://github.com/voidzero-dev' }, ]; -const companyLinks = { - text: 'VoidZero', - items: [ - { text: 'VoidZero', link: 'https://voidzero.dev' }, - { text: 'Blog', link: 'https://voidzero.dev/blog' }, - ], -}; - export default extendConfig( defineConfig({ title: 'Void', - description: 'Build with Vite. Deploy with Void.', + rewrites: { + 'en/:rest*': ':rest*', + }, + locales: { + root: en, + zh, + }, + srcExclude: ['README.md'], cleanUrls: true, head: [['link', { rel: 'icon', type: 'image/svg+xml', href: '/icon.svg' }]], appearance: 'dark', @@ -183,222 +41,56 @@ export default extendConfig( }, vite: { - plugins: [groupIconVitePlugin()], + plugins: [ + groupIconVitePlugin(), + { + name: 'void:locale-logo-links', + enforce: 'pre', + // shortcut: localize hard-coded logo links until the shared theme supports locale homes. + transform(source, id) { + if (id !== themeHeaderPath) return; + if (source.match(/href="\/"/g)?.length !== 2) { + this.error('The shared theme header changed; review its localized logo links.'); + } + return { code: source.replaceAll('href="/"', ':href="currentLang.link"'), map: null }; + }, + }, + ], }, themeConfig: { + i18nRouting: true, search: { provider: 'local', - }, - - nav: [ - { - text: 'Guide', - link: '/guide/', - activeMatch: - '^/guide/(?!platform/|self-hosted-platform|platform-administration|platform-development)', - }, - { - text: 'Platform', - link: '/guide/self-hosted-platform', - activeMatch: - '^/guide/(platform/|self-hosted-platform|platform-administration|platform-development)', - }, - referenceLinks, - integrationLinks, - ], - - socialLinks, - - sidebar: { - '/guide/platform/': platformSidebar, - '/guide/self-hosted-platform': platformSidebar, - '/guide/platform-administration': platformSidebar, - '/guide/platform-development': platformSidebar, - '/guide/': [ - { - text: 'Getting Started', - icon: 'lucide:rocket', - collapsed: false, - items: [ - { text: 'Introduction', link: '/guide/' }, - { text: 'Quickstart', link: '/guide/quickstart' }, - { text: 'Supported App Types', link: '/guide/app-types' }, - ], - }, - { - text: 'Routing & Rendering', - // @ts-expect-error - icon: 'lucide:route', - collapsed: false, - items: [ - { text: 'Server Routing', link: '/guide/server-routing' }, - { - text: 'Pages Routing', - collapsed: true, - items: [ - { text: 'Overview', link: '/guide/pages-routing/overview' }, - { text: 'Layouts & Shared Data', link: '/guide/pages-routing/layouts' }, - { text: 'Loaders & Props', link: '/guide/pages-routing/loaders' }, - { text: 'Actions & Forms', link: '/guide/pages-routing/actions-and-forms' }, - { text: 'View Transitions', link: '/guide/pages-routing/view-transitions' }, - { text: 'Head Management', link: '/guide/pages-routing/head' }, - { text: 'Islands', link: '/guide/pages-routing/islands' }, - { text: 'Markdown', link: '/guide/pages-routing/markdown' }, - ], - }, - { - text: 'Edge Routing', - collapsed: true, - items: [ - { text: 'Static Assets Caching', link: '/guide/edge/static-assets' }, - { text: 'Revalidation (ISR)', link: '/guide/edge/revalidation' }, - { text: 'Edge Prerendering', link: '/guide/edge/prerendering' }, - { text: 'Custom Headers', link: '/guide/edge/headers' }, - { text: 'Redirects', link: '/guide/edge/redirects' }, - { text: 'Rewrites', link: '/guide/edge/rewrites' }, - ], + options: { + locales: { + zh: { + translations: { + button: { buttonText: '搜索文档', buttonAriaLabel: '搜索文档' }, + modal: { + noResultsText: '未找到相关结果', + resetButtonTitle: '清除搜索', + backButtonTitle: '返回', + displayDetails: '显示详细内容', + footer: { + selectText: '选择', + selectKeyAriaLabel: '回车键', + navigateText: '切换', + navigateUpKeyAriaLabel: '向上方向键', + navigateDownKeyAriaLabel: '向下方向键', + closeText: '关闭', + closeKeyAriaLabel: 'Esc 键', + }, + }, }, - { text: 'Custom SSR', link: '/guide/ssr' }, - { text: 'SSG', link: '/guide/ssg' }, - ], - }, - { - text: 'Data', - icon: 'lucide:database', - collapsed: false, - items: [ - { text: 'Type Safety', link: '/guide/type-safety' }, - { - text: 'Database', - collapsed: true, - items: [ - { text: 'Overview', link: '/guide/database' }, - { text: 'D1 (SQLite)', link: '/guide/database/d1' }, - { text: 'PostgreSQL', link: '/guide/database/postgresql' }, - { text: 'MySQL', link: '/guide/database/mysql' }, - ], - }, - { text: 'Typed Fetch', link: '/guide/typed-fetch' }, - { text: 'Key-Value Storage', link: '/guide/kv' }, - { text: 'Object Storage', link: '/guide/storage' }, - { text: 'Durable State', link: '/guide/durable-state' }, - { text: 'Environment Variables', link: '/guide/env-vars' }, - ], - }, - { - text: 'Backend Features', - icon: 'lucide:blocks', - collapsed: false, - items: [ - { text: 'Authentication', link: '/guide/auth' }, - { text: 'AI', link: '/guide/ai' }, - { - text: 'Email', - link: '/guide/email', - collapsed: true, - items: [ - { text: 'Sending Email', link: '/guide/email/sending' }, - { text: 'Receiving Email', link: '/guide/email/receiving' }, - { text: 'Domains and Setup', link: '/guide/email/domains' }, - ], - }, - { text: 'Sandboxes', link: '/guide/sandboxes' }, - { text: 'Cron Jobs', link: '/guide/jobs' }, - { text: 'Queues', link: '/guide/queues' }, - { text: 'WebSockets', link: '/guide/websockets' }, - { text: 'Server-Sent Events', link: '/guide/sse' }, - { text: 'Live Event Streams', link: '/guide/live' }, - ], - }, - { - text: 'Development & Deployment', - icon: 'lucide:rocket', - collapsed: false, - items: [ - { text: 'Remote Development', link: '/guide/remote-dev' }, - { text: 'Deploying Your App', link: '/guide/deployment' }, - { text: 'Project Collaboration', link: '/guide/project-collaboration' }, - ], - }, - ], - '/integrations/': (() => { - const frameworkIcons: Record = { - 'TanStack Start': 'simple-icons:tanstack', - 'React Router': { - light: 'logos:react-router', - dark: 'vscode-icons:file-type-reactrouter', }, - Astro: { light: 'logos:astro-icon', dark: 'simple-icons:astro' }, - SvelteKit: 'logos:svelte-icon', - Nuxt: 'logos:nuxt-icon', - Analog: 'logos:analog', - }; - const itemIcons: Record = { - 'Coding Agents': 'lucide:bot', - Hono: 'logos:hono', - Cloudflare: 'devicon:cloudflare', - 'Node.js / Bun / Deno': 'material-icon-theme:nodejs-alt', - }; - return integrationItems.map((item) => - item.text === 'Meta Frameworks' - ? { - ...item, - icon: 'lucide:blocks', - items: item.items?.map((child) => ({ - ...child, - icon: frameworkIcons[child.text], - })), - } - : { ...item, icon: itemIcons[item.text] }, - ); - })(), - '/reference/': (() => { - const icons: Record = { - General: 'lucide:book-open', - 'Project Structure': 'lucide:folder-tree', - 'Resource Inference': 'lucide:scan-search', - Config: 'lucide:settings', - API: 'lucide:code', - CLI: 'lucide:terminal', - }; - return referenceItems.map((item) => ({ - ...item, - icon: icons[item.text], - items: item.items?.map((child) => ({ - ...child, - icon: icons[child.text] ?? child.icon, - })), - })); - })(), + }, + }, }, + socialLinks, footer: { copyright: `© ${new Date().getFullYear()} Cloudflare Inc. All Rights Reserved.`, - nav: [ - { - title: 'Docs', - items: [ - { text: 'Guide', link: '/guide/' }, - { text: 'Integrations', link: '/integrations/frameworks/overview' }, - { text: 'Reference', link: '/reference/structure' }, - ], - }, - { - title: 'Open Source', - items: [ - { text: 'Vite+', link: 'https://viteplus.dev' }, - { text: 'Vite', link: 'https://vite.dev' }, - { text: 'Vitest', link: 'https://vitest.dev' }, - { text: 'Rolldown', link: 'https://rolldown.rs' }, - { text: 'Oxc', link: 'https://oxc.rs' }, - ], - }, - { - title: companyLinks.text, - items: companyLinks.items, - }, - ], social: socialLinks, }, }, diff --git a/docs/.vitepress/config/en.ts b/docs/.vitepress/config/en.ts new file mode 100644 index 000000000..86853c666 --- /dev/null +++ b/docs/.vitepress/config/en.ts @@ -0,0 +1,369 @@ +import type { IconOption } from '@voidzero-dev/vitepress-theme'; + +const referenceItems = [ + { + text: 'General', + collapsed: false, + items: [ + { text: 'Project Structure', link: '/reference/structure' }, + { text: 'Resource Inference', link: '/reference/resource-inference' }, + ], + }, + { + text: 'Config', + link: '/reference/config', + collapsed: true, + items: [ + { text: 'target', link: '/reference/config#target' }, + { text: 'routing', link: '/reference/config#routing' }, + { text: 'inference', link: '/reference/config#inference' }, + { text: 'output', link: '/reference/config#output' }, + { text: 'remote', link: '/reference/config#remote' }, + { text: 'sandbox', link: '/reference/config#sandbox' }, + { text: 'worker', link: '/reference/config#worker' }, + ], + }, + { + text: 'CLI', + link: '/reference/cli', + collapsed: true, + items: [ + { text: 'Overview', link: '/reference/cli' }, + { text: 'Project Setup', link: '/reference/cli/setup' }, + { text: 'Connections and Authentication', link: '/reference/cli/auth' }, + { text: 'Projects', link: '/reference/cli/project' }, + { text: 'Deployment', link: '/reference/cli/deploy' }, + { text: 'Database', link: '/reference/cli/database' }, + { text: 'Code Generation', link: '/reference/cli/generate' }, + { text: 'Secrets and Environment', link: '/reference/cli/secrets' }, + { text: 'GitHub and Builds', link: '/reference/cli/github' }, + { text: 'Custom Domains', link: '/reference/cli/domains' }, + { text: 'Email', link: '/reference/cli/email' }, + { text: 'Platform Management', link: '/reference/cli/platform' }, + { text: 'Platform Installation', link: '/reference/cli/platform-installation' }, + { text: 'Platform Configuration', link: '/reference/cli/platform-config' }, + { text: 'Platform Users and Projects', link: '/reference/cli/platform-users' }, + { text: 'Project Zero Trust', link: '/reference/cli/platform-zero-trust' }, + { text: 'Platform Operations', link: '/reference/cli/platform-operations' }, + { text: 'Platform Email', link: '/reference/cli/platform-email' }, + ], + }, + { + text: 'API', + link: '/reference/api', + collapsed: true, + items: [ + { text: 'Overview', link: '/reference/api' }, + { text: 'Plugin and Configuration', link: '/reference/api/plugin' }, + { text: 'Handlers and Middleware', link: '/reference/api/handlers' }, + { text: 'Rewrites', link: '/reference/api/rewrites' }, + { text: 'Authentication', link: '/reference/api/auth' }, + { text: 'Fetch Client', link: '/reference/api/client' }, + { text: 'Durable State and WebSockets', link: '/reference/api/durable' }, + { text: 'Deployment artifacts', link: '/reference/api/deploy' }, + { text: 'Database and Seeding', link: '/reference/api/database' }, + { text: 'Resource Clients', link: '/reference/api/resources' }, + { text: 'Types', link: '/reference/api/types' }, + { text: 'Environment Variables', link: '/reference/api/env' }, + { text: 'Pages Adapters', link: '/reference/api/pages' }, + ], + }, +]; + +const referenceLinks = { + text: 'Reference', + activeMatch: '/reference/', + items: referenceItems, +}; + +const integrationItems = [ + { + text: 'Meta Frameworks', + collapsed: false, + items: [ + { text: 'Overview', link: '/integrations/frameworks/overview' }, + { text: 'TanStack Start', link: '/integrations/frameworks/tanstack-start' }, + { text: 'React Router', link: '/integrations/frameworks/react-router' }, + { text: 'Astro', link: '/integrations/frameworks/astro' }, + { text: 'SvelteKit', link: '/integrations/frameworks/sveltekit' }, + { text: 'Nuxt', link: '/integrations/frameworks/nuxt' }, + { text: 'Analog', link: '/integrations/frameworks/analog' }, + ], + }, + { text: 'Coding Agents', link: '/integrations/agents' }, + { text: 'Hono', link: '/integrations/hono' }, + { text: 'Cloudflare', link: '/integrations/cloudflare' }, + { text: 'Node.js / Bun / Deno', link: '/integrations/nodejs-bun-deno' }, +]; + +const integrationLinks = { + text: 'Integrations', + activeMatch: '/integrations/', + items: integrationItems, +}; + +const platformSidebar = [ + { + text: 'Installation', + icon: 'lucide:cloud', + collapsed: false, + items: [ + { text: 'Overview', link: '/guide/self-hosted-platform' }, + { text: 'Prerequisites', link: '/guide/platform/installation/prerequisites' }, + { text: 'Credentials', link: '/guide/platform/installation/credentials' }, + { text: 'Install and Configure Login', link: '/guide/platform/installation/setup' }, + { text: 'First Deployment', link: '/guide/platform/installation/first-deployment' }, + { text: 'Domains and Resources', link: '/guide/platform/installation/domains' }, + { text: 'Maintenance and Recovery', link: '/guide/platform/installation/maintenance' }, + { text: 'Install from CI', link: '/guide/platform/installation/ci' }, + { text: 'Disable and Uninstall', link: '/guide/platform/installation/uninstall' }, + ], + }, + { + text: 'Administration', + icon: 'lucide:settings', + collapsed: false, + items: [ + { text: 'Overview', link: '/guide/platform-administration' }, + { text: 'Sign-in and Access', link: '/guide/platform/administration/access' }, + { text: 'Connected apps', link: '/guide/platform/administration/connected-apps' }, + { text: 'Users and Projects', link: '/guide/platform/administration/projects' }, + { text: 'Plans and Limits', link: '/guide/platform/administration/plans' }, + { text: 'Project Zero Trust', link: '/guide/platform/administration/zero-trust' }, + { text: 'Email', link: '/guide/platform/administration/email' }, + { text: 'Operations', link: '/guide/platform/administration/operations' }, + ], + }, + { + text: 'Development & Customization', + icon: 'lucide:code', + collapsed: false, + items: [ + { text: 'Overview', link: '/guide/platform-development' }, + { text: 'Local Development', link: '/guide/platform/development/local' }, + { text: 'Runtime and Source Builds', link: '/guide/platform/development/runtime' }, + { text: 'Schema and CI', link: '/guide/platform/development/schema-ci' }, + ], + }, +]; + +const companyLinks = { + text: 'VoidZero', + items: [ + { text: 'VoidZero', link: 'https://voidzero.dev' }, + { text: 'Blog', link: 'https://voidzero.dev/blog' }, + ], +}; + +export const en = { + label: 'English', + lang: 'en-US', + description: 'Build with Vite. Deploy with Void.', + themeConfig: { + nav: [ + { + text: 'Guide', + link: '/guide/', + activeMatch: + '^/guide/(?!platform/|self-hosted-platform|platform-administration|platform-development)', + }, + { + text: 'Platform', + link: '/guide/self-hosted-platform', + activeMatch: + '^/guide/(platform/|self-hosted-platform|platform-administration|platform-development)', + }, + referenceLinks, + integrationLinks, + ], + + sidebar: { + '/guide/platform/': platformSidebar, + '/guide/self-hosted-platform': platformSidebar, + '/guide/platform-administration': platformSidebar, + '/guide/platform-development': platformSidebar, + '/guide/': [ + { + text: 'Getting Started', + icon: 'lucide:rocket', + collapsed: false, + items: [ + { text: 'Introduction', link: '/guide/' }, + { text: 'Quickstart', link: '/guide/quickstart' }, + { text: 'Supported App Types', link: '/guide/app-types' }, + ], + }, + { + text: 'Routing & Rendering', + icon: 'lucide:route', + collapsed: false, + items: [ + { text: 'Server Routing', link: '/guide/server-routing' }, + { + text: 'Pages Routing', + collapsed: true, + items: [ + { text: 'Overview', link: '/guide/pages-routing/overview' }, + { text: 'Layouts & Shared Data', link: '/guide/pages-routing/layouts' }, + { text: 'Loaders & Props', link: '/guide/pages-routing/loaders' }, + { text: 'Actions & Forms', link: '/guide/pages-routing/actions-and-forms' }, + { text: 'View Transitions', link: '/guide/pages-routing/view-transitions' }, + { text: 'Head Management', link: '/guide/pages-routing/head' }, + { text: 'Islands', link: '/guide/pages-routing/islands' }, + { text: 'Markdown', link: '/guide/pages-routing/markdown' }, + ], + }, + { + text: 'Edge Routing', + collapsed: true, + items: [ + { text: 'Static Assets Caching', link: '/guide/edge/static-assets' }, + { text: 'Revalidation (ISR)', link: '/guide/edge/revalidation' }, + { text: 'Edge Prerendering', link: '/guide/edge/prerendering' }, + { text: 'Custom Headers', link: '/guide/edge/headers' }, + { text: 'Redirects', link: '/guide/edge/redirects' }, + { text: 'Rewrites', link: '/guide/edge/rewrites' }, + ], + }, + { text: 'Custom SSR', link: '/guide/ssr' }, + { text: 'SSG', link: '/guide/ssg' }, + ], + }, + { + text: 'Data', + icon: 'lucide:database', + collapsed: false, + items: [ + { text: 'Type Safety', link: '/guide/type-safety' }, + { + text: 'Database', + collapsed: true, + items: [ + { text: 'Overview', link: '/guide/database' }, + { text: 'D1 (SQLite)', link: '/guide/database/d1' }, + { text: 'PostgreSQL', link: '/guide/database/postgresql' }, + { text: 'MySQL', link: '/guide/database/mysql' }, + ], + }, + { text: 'Typed Fetch', link: '/guide/typed-fetch' }, + { text: 'Key-Value Storage', link: '/guide/kv' }, + { text: 'Object Storage', link: '/guide/storage' }, + { text: 'Durable State', link: '/guide/durable-state' }, + { text: 'Environment Variables', link: '/guide/env-vars' }, + ], + }, + { + text: 'Backend Features', + icon: 'lucide:blocks', + collapsed: false, + items: [ + { text: 'Authentication', link: '/guide/auth' }, + { text: 'AI', link: '/guide/ai' }, + { + text: 'Email', + link: '/guide/email', + collapsed: true, + items: [ + { text: 'Sending Email', link: '/guide/email/sending' }, + { text: 'Receiving Email', link: '/guide/email/receiving' }, + { text: 'Domains and Setup', link: '/guide/email/domains' }, + ], + }, + { text: 'Sandboxes', link: '/guide/sandboxes' }, + { text: 'Cron Jobs', link: '/guide/jobs' }, + { text: 'Queues', link: '/guide/queues' }, + { text: 'WebSockets', link: '/guide/websockets' }, + { text: 'Server-Sent Events', link: '/guide/sse' }, + { text: 'Live Event Streams', link: '/guide/live' }, + ], + }, + { + text: 'Development & Deployment', + icon: 'lucide:rocket', + collapsed: false, + items: [ + { text: 'Remote Development', link: '/guide/remote-dev' }, + { text: 'Deploying Your App', link: '/guide/deployment' }, + { text: 'Project Collaboration', link: '/guide/project-collaboration' }, + ], + }, + ], + '/integrations/': (() => { + const frameworkIcons: Record = { + 'TanStack Start': 'simple-icons:tanstack', + 'React Router': { + light: 'logos:react-router', + dark: 'vscode-icons:file-type-reactrouter', + }, + Astro: { light: 'logos:astro-icon', dark: 'simple-icons:astro' }, + SvelteKit: 'logos:svelte-icon', + Nuxt: 'logos:nuxt-icon', + Analog: 'logos:analog', + }; + const itemIcons: Record = { + 'Coding Agents': 'lucide:bot', + Hono: 'logos:hono', + Cloudflare: 'devicon:cloudflare', + 'Node.js / Bun / Deno': 'material-icon-theme:nodejs-alt', + }; + return integrationItems.map((item) => + item.text === 'Meta Frameworks' + ? { + ...item, + icon: 'lucide:blocks', + items: item.items?.map((child) => ({ + ...child, + icon: frameworkIcons[child.text], + })), + } + : { ...item, icon: itemIcons[item.text] }, + ); + })(), + '/reference/': (() => { + const icons: Record = { + General: 'lucide:book-open', + 'Project Structure': 'lucide:folder-tree', + 'Resource Inference': 'lucide:scan-search', + Config: 'lucide:settings', + API: 'lucide:code', + CLI: 'lucide:terminal', + }; + return referenceItems.map((item) => ({ + ...item, + icon: icons[item.text], + items: item.items?.map((child) => ({ + ...child, + icon: icons[child.text] ?? child.icon, + })), + })); + })(), + }, + + footer: { + nav: [ + { + title: 'Docs', + items: [ + { text: 'Guide', link: '/guide/' }, + { text: 'Integrations', link: '/integrations/frameworks/overview' }, + { text: 'Reference', link: '/reference/structure' }, + ], + }, + { + title: 'Open Source', + items: [ + { text: 'Vite+', link: 'https://viteplus.dev' }, + { text: 'Vite', link: 'https://vite.dev' }, + { text: 'Vitest', link: 'https://vitest.dev' }, + { text: 'Rolldown', link: 'https://rolldown.rs' }, + { text: 'Oxc', link: 'https://oxc.rs' }, + ], + }, + { + title: companyLinks.text, + items: companyLinks.items, + }, + ], + }, + }, +}; diff --git a/docs/.vitepress/config/zh.ts b/docs/.vitepress/config/zh.ts new file mode 100644 index 000000000..ee8a13616 --- /dev/null +++ b/docs/.vitepress/config/zh.ts @@ -0,0 +1,323 @@ +import type { DefaultTheme } from 'vitepress'; +import { en } from './en.ts'; + +function localizeSidebar( + source: DefaultTheme.SidebarItem[], + translations: DefaultTheme.SidebarItem[], +): DefaultTheme.SidebarItem[] { + return source.map((item, index) => ({ + ...item, + text: translations[index].text, + ...(item.link ? { link: translations[index].link } : {}), + ...(item.items + ? { items: localizeSidebar(item.items, translations[index].items ?? []) } + : {}), + })); +} + +const referenceItems = [ + { + text: '通用', + collapsed: false, + items: [ + { text: '项目结构', link: '/zh/reference/structure' }, + { text: '资源推断', link: '/zh/reference/resource-inference' }, + ], + }, + { + text: '配置', + link: '/zh/reference/config', + collapsed: true, + items: [ + { text: 'target', link: '/zh/reference/config#target' }, + { text: 'routing', link: '/zh/reference/config#routing' }, + { text: 'inference', link: '/zh/reference/config#inference' }, + { text: 'output', link: '/zh/reference/config#output' }, + { text: 'remote', link: '/zh/reference/config#remote' }, + { text: 'sandbox', link: '/zh/reference/config#sandbox' }, + { text: 'worker', link: '/zh/reference/config#worker' }, + ], + }, + { + text: 'CLI', + link: '/zh/reference/cli', + collapsed: true, + items: [ + { text: '概览', link: '/zh/reference/cli' }, + { text: '项目设置', link: '/zh/reference/cli/setup' }, + { text: '连接与身份验证', link: '/zh/reference/cli/auth' }, + { text: '项目', link: '/zh/reference/cli/project' }, + { text: '部署', link: '/zh/reference/cli/deploy' }, + { text: '数据库', link: '/zh/reference/cli/database' }, + { text: '代码生成', link: '/zh/reference/cli/generate' }, + { text: '密钥与环境变量', link: '/zh/reference/cli/secrets' }, + { text: 'GitHub 与构建', link: '/zh/reference/cli/github' }, + { text: '自定义域名', link: '/zh/reference/cli/domains' }, + { text: '电子邮件', link: '/zh/reference/cli/email' }, + { text: '平台管理', link: '/zh/reference/cli/platform' }, + { text: '平台安装', link: '/zh/reference/cli/platform-installation' }, + { text: '平台配置', link: '/zh/reference/cli/platform-config' }, + { text: '平台用户与项目', link: '/zh/reference/cli/platform-users' }, + { text: '项目零信任访问', link: '/zh/reference/cli/platform-zero-trust' }, + { text: '平台运维', link: '/zh/reference/cli/platform-operations' }, + { text: '平台邮件', link: '/zh/reference/cli/platform-email' }, + ], + }, + { + text: 'API', + link: '/zh/reference/api', + collapsed: true, + items: [ + { text: '概览', link: '/zh/reference/api' }, + { text: '插件与配置', link: '/zh/reference/api/plugin' }, + { text: '处理函数与中间件', link: '/zh/reference/api/handlers' }, + { text: '重写', link: '/zh/reference/api/rewrites' }, + { text: '身份验证', link: '/zh/reference/api/auth' }, + { text: 'Fetch 客户端', link: '/zh/reference/api/client' }, + { text: '持久化状态与 WebSockets', link: '/zh/reference/api/durable' }, + { text: '部署产物', link: '/zh/reference/api/deploy' }, + { text: '数据库与初始数据', link: '/zh/reference/api/database' }, + { text: '资源客户端', link: '/zh/reference/api/resources' }, + { text: '类型', link: '/zh/reference/api/types' }, + { text: '环境变量', link: '/zh/reference/api/env' }, + { text: 'Pages 适配器', link: '/zh/reference/api/pages' }, + ], + }, +]; + +const integrationItems = [ + { + text: '元框架', + collapsed: false, + items: [ + { text: '概览', link: '/zh/integrations/frameworks/overview' }, + { text: 'TanStack Start', link: '/zh/integrations/frameworks/tanstack-start' }, + { text: 'React Router', link: '/zh/integrations/frameworks/react-router' }, + { text: 'Astro', link: '/zh/integrations/frameworks/astro' }, + { text: 'SvelteKit', link: '/zh/integrations/frameworks/sveltekit' }, + { text: 'Nuxt', link: '/zh/integrations/frameworks/nuxt' }, + { text: 'Analog', link: '/zh/integrations/frameworks/analog' }, + ], + }, + { text: '编程 Agent', link: '/zh/integrations/agents' }, + { text: 'Hono', link: '/zh/integrations/hono' }, + { text: 'Cloudflare', link: '/zh/integrations/cloudflare' }, + { text: 'Node.js / Bun / Deno', link: '/zh/integrations/nodejs-bun-deno' }, +]; + +const platformSidebar = localizeSidebar(en.themeConfig.sidebar['/guide/platform/'], [ + { + text: '安装', + collapsed: false, + items: [ + { text: '概览', link: '/zh/guide/self-hosted-platform' }, + { text: '准备工作', link: '/zh/guide/platform/installation/prerequisites' }, + { text: '凭据', link: '/zh/guide/platform/installation/credentials' }, + { text: '安装平台并配置登录', link: '/zh/guide/platform/installation/setup' }, + { text: '首次部署', link: '/zh/guide/platform/installation/first-deployment' }, + { text: '域名与资源', link: '/zh/guide/platform/installation/domains' }, + { text: '维护与恢复', link: '/zh/guide/platform/installation/maintenance' }, + { text: '通过 CI 安装', link: '/zh/guide/platform/installation/ci' }, + { text: '停用与卸载', link: '/zh/guide/platform/installation/uninstall' }, + ], + }, + { + text: '平台管理', + collapsed: false, + items: [ + { text: '概览', link: '/zh/guide/platform-administration' }, + { text: '登录与访问权限', link: '/zh/guide/platform/administration/access' }, + { text: '已连接应用', link: '/zh/guide/platform/administration/connected-apps' }, + { text: '用户与项目', link: '/zh/guide/platform/administration/projects' }, + { text: '套餐与限额', link: '/zh/guide/platform/administration/plans' }, + { text: '项目零信任访问', link: '/zh/guide/platform/administration/zero-trust' }, + { text: '电子邮件', link: '/zh/guide/platform/administration/email' }, + { text: '运维', link: '/zh/guide/platform/administration/operations' }, + ], + }, + { + text: '开发与定制', + collapsed: false, + items: [ + { text: '概览', link: '/zh/guide/platform-development' }, + { text: '本地开发', link: '/zh/guide/platform/development/local' }, + { text: '运行时与源码构建', link: '/zh/guide/platform/development/runtime' }, + { text: 'Schema 与 CI', link: '/zh/guide/platform/development/schema-ci' }, + ], + }, +]); + +export const zh = { + label: '简体中文', + lang: 'zh-CN', + description: '用 Vite 构建,用 Void 部署。', + themeConfig: { + nav: [ + { + text: '指南', + link: '/zh/guide/', + activeMatch: '^/zh/guide/(?!platform/|self-hosted-platform|platform-administration|platform-development)', + }, + { + text: '平台', + link: '/zh/guide/self-hosted-platform', + activeMatch: '^/zh/guide/(platform/|self-hosted-platform|platform-administration|platform-development)', + }, + { + text: '参考', + activeMatch: '^/zh/reference/', + items: referenceItems, + }, + { + text: '集成', + activeMatch: '^/zh/integrations/', + items: integrationItems, + }, + ], + sidebar: { + '/zh/guide/platform/': platformSidebar, + '/zh/guide/self-hosted-platform': platformSidebar, + '/zh/guide/platform-administration': platformSidebar, + '/zh/guide/platform-development': platformSidebar, + '/zh/integrations/': localizeSidebar(en.themeConfig.sidebar['/integrations/'], integrationItems), + '/zh/reference/': localizeSidebar(en.themeConfig.sidebar['/reference/'], referenceItems), + '/zh/guide/': localizeSidebar(en.themeConfig.sidebar['/guide/'], [ + { + text: '开始使用', + items: [ + { text: '什么是 Void?', link: '/zh/guide/' }, + { text: '快速开始', link: '/zh/guide/quickstart' }, + { text: '支持的应用类型', link: '/zh/guide/app-types' }, + ], + }, + { + text: '路由与渲染', + items: [ + { text: '服务端路由', link: '/zh/guide/server-routing' }, + { + text: '页面路由', + collapsed: true, + items: [ + { text: '概览', link: '/zh/guide/pages-routing/overview' }, + { text: '布局与共享数据', link: '/zh/guide/pages-routing/layouts' }, + { text: 'Loader 与 props', link: '/zh/guide/pages-routing/loaders' }, + { text: 'Action 与表单', link: '/zh/guide/pages-routing/actions-and-forms' }, + { text: '视图过渡', link: '/zh/guide/pages-routing/view-transitions' }, + { text: 'Head 管理', link: '/zh/guide/pages-routing/head' }, + { text: 'Islands', link: '/zh/guide/pages-routing/islands' }, + { text: 'Markdown', link: '/zh/guide/pages-routing/markdown' }, + ], + }, + { + text: '边缘路由', + collapsed: true, + items: [ + { text: '静态资源缓存', link: '/zh/guide/edge/static-assets' }, + { text: '缓存重新验证(ISR)', link: '/zh/guide/edge/revalidation' }, + { text: '边缘预渲染', link: '/zh/guide/edge/prerendering' }, + { text: '自定义响应头', link: '/zh/guide/edge/headers' }, + { text: '重定向', link: '/zh/guide/edge/redirects' }, + { text: '重写', link: '/zh/guide/edge/rewrites' }, + ], + }, + { text: '自定义 SSR', link: '/zh/guide/ssr' }, + { text: '静态站点生成(SSG)', link: '/zh/guide/ssg' }, + ], + }, + { + text: '数据访问', + items: [ + { text: '类型安全', link: '/zh/guide/type-safety' }, + { + text: '数据库', + collapsed: true, + items: [ + { text: '概览', link: '/zh/guide/database' }, + { text: 'D1 (SQLite)', link: '/zh/guide/database/d1' }, + { text: 'PostgreSQL', link: '/zh/guide/database/postgresql' }, + { text: 'MySQL', link: '/zh/guide/database/mysql' }, + ], + }, + { text: '类型化 Fetch', link: '/zh/guide/typed-fetch' }, + { text: '键值存储', link: '/zh/guide/kv' }, + { text: '对象存储', link: '/zh/guide/storage' }, + { text: '持久化状态', link: '/zh/guide/durable-state' }, + { text: '环境变量', link: '/zh/guide/env-vars' }, + ], + }, + { + text: '后端功能', + items: [ + { text: '身份验证', link: '/zh/guide/auth' }, + { text: 'AI', link: '/zh/guide/ai' }, + { + text: '电子邮件', + link: '/zh/guide/email', + collapsed: true, + items: [ + { text: '发送邮件', link: '/zh/guide/email/sending' }, + { text: '接收邮件', link: '/zh/guide/email/receiving' }, + { text: '域名与配置', link: '/zh/guide/email/domains' }, + ], + }, + { text: '沙箱', link: '/zh/guide/sandboxes' }, + { text: '定时任务', link: '/zh/guide/jobs' }, + { text: '队列', link: '/zh/guide/queues' }, + { text: 'WebSockets', link: '/zh/guide/websockets' }, + { text: '服务端发送事件(SSE)', link: '/zh/guide/sse' }, + { text: '实时事件流', link: '/zh/guide/live' }, + ], + }, + { + text: '开发与部署', + items: [ + { text: '远程开发', link: '/zh/guide/remote-dev' }, + { text: '部署应用', link: '/zh/guide/deployment' }, + { text: '项目协作', link: '/zh/guide/project-collaboration' }, + ], + }, + ]), + }, + outline: { label: '本页内容' }, + docFooter: { prev: '上一页', next: '下一页' }, + langMenuLabel: '选择语言', + navMenuLabel: '主导航', + sidebarMenuLabel: '目录', + mobileMenuLabel: '菜单', + extraMenuLabel: '更多选项', + returnToTopLabel: '返回顶部', + skipToContentLabel: '跳转到内容', + darkModeSwitchLabel: '外观', + lightModeSwitchTitle: '切换到浅色模式', + darkModeSwitchTitle: '切换到深色模式', + footer: { + nav: [ + { + title: '文档', + items: [ + { text: '指南', link: '/zh/guide/' }, + { text: '集成', link: '/zh/integrations/frameworks/overview' }, + { text: '参考', link: '/zh/reference/structure' }, + ], + }, + { + title: '开源项目', + items: [ + { text: 'Vite+', link: 'https://viteplus.dev' }, + { text: 'Vite', link: 'https://vite.dev' }, + { text: 'Vitest', link: 'https://vitest.dev' }, + { text: 'Rolldown', link: 'https://rolldown.rs' }, + { text: 'Oxc', link: 'https://oxc.rs' }, + ], + }, + { + title: 'VoidZero', + items: [ + { text: 'VoidZero', link: 'https://voidzero.dev' }, + { text: '博客', link: 'https://voidzero.dev/blog' }, + ], + }, + ], + }, + }, +}; diff --git a/docs/.vitepress/theme/Hero.vue b/docs/.vitepress/theme/Hero.vue index 13e2a2034..e93f59d62 100644 --- a/docs/.vitepress/theme/Hero.vue +++ b/docs/.vitepress/theme/Hero.vue @@ -23,7 +23,9 @@ const { frontmatter } = useData();
- By + {{ + frontmatter.homeI18n?.hero_by ?? 'By' + }} VoidZero

@@ -53,7 +55,10 @@ const { frontmatter } = useData();