(), {
- Sponsor
+ {{ member.actionText || 'Sponsor' }}
diff --git a/src/client/theme-default/support/translation.ts b/src/client/theme-default/support/translation.ts
index 607d5db3..12ade37b 100644
--- a/src/client/theme-default/support/translation.ts
+++ b/src/client/theme-default/support/translation.ts
@@ -3,14 +3,14 @@ import { useData } from '../composables/data'
/**
* @param themeObject Can be an object with `translations` and `locales` properties
*/
-export function createTranslate(
- themeObject: any,
+export function createSearchTranslate(
defaultTranslations: Record
): (key: string) => string {
- const { localeIndex } = useData()
+ const { localeIndex, theme } = useData()
function translate(key: string): string {
const keyPath = key.split('.')
+ const themeObject = theme.value.search?.options
const isObject = themeObject && typeof themeObject === 'object'
const locales =
diff --git a/src/node/build/build.ts b/src/node/build/build.ts
index b5c50978..7dca478a 100644
--- a/src/node/build/build.ts
+++ b/src/node/build/build.ts
@@ -1,12 +1,14 @@
import { createHash } from 'crypto'
import fs from 'fs-extra'
import { createRequire } from 'module'
+import pMap from 'p-map'
import path from 'path'
import { packageDirectorySync } from 'pkg-dir'
import { rimraf } from 'rimraf'
import { pathToFileURL } from 'url'
import type { BuildOptions, Rollup } from 'vite'
import { resolveConfig, type SiteConfig } from '../config'
+import { clearCache } from '../markdownToVue'
import { slash, type HeadConfig } from '../shared'
import { deserializeFunctions, serializeFunctions } from '../utils/fnSerialize'
import { task } from '../utils/task'
@@ -106,23 +108,23 @@ export async function build(
}
}
- await Promise.all(
- ['404.md', ...siteConfig.pages]
- .map((page) => siteConfig.rewrites.map[page] || page)
- .map((page) =>
- renderPage(
- render,
- siteConfig,
- page,
- clientResult,
- appChunk,
- cssChunk,
- assets,
- pageToHashMap,
- metadataScript,
- additionalHeadTags
- )
+ await pMap(
+ ['404.md', ...siteConfig.pages],
+ async (page) => {
+ await renderPage(
+ render,
+ siteConfig,
+ siteConfig.rewrites.map[page] || page,
+ clientResult,
+ appChunk,
+ cssChunk,
+ assets,
+ pageToHashMap,
+ metadataScript,
+ additionalHeadTags
)
+ },
+ { concurrency: siteConfig.buildConcurrency }
)
})
@@ -139,6 +141,7 @@ export async function build(
await generateSitemap(siteConfig)
await siteConfig.buildEnd?.(siteConfig)
+ clearCache()
siteConfig.logger.info(
`build complete in ${((Date.now() - start) / 1000).toFixed(2)}s.`
diff --git a/src/node/config.ts b/src/node/config.ts
index a67a7f2e..d4a76de6 100644
--- a/src/node/config.ts
+++ b/src/node/config.ts
@@ -104,7 +104,8 @@ export async function resolveConfig(
const { pages, dynamicRoutes, rewrites } = await resolvePages(
srcDir,
- userConfig
+ userConfig,
+ logger
)
const config: SiteConfig = {
@@ -141,7 +142,8 @@ export async function resolveConfig(
transformPageData: userConfig.transformPageData,
rewrites,
userConfig,
- sitemap: userConfig.sitemap
+ sitemap: userConfig.sitemap,
+ buildConcurrency: userConfig.buildConcurrency ?? 64
}
// to be shared with content loaders
diff --git a/src/node/plugin.ts b/src/node/plugin.ts
index 6cfc02f6..0c3daddc 100644
--- a/src/node/plugin.ts
+++ b/src/node/plugin.ts
@@ -152,7 +152,8 @@ export async function createVitePressPlugin(
site.themeConfig?.search?.provider === 'algolia' ||
!!site.themeConfig?.algolia, // legacy
__CARBON__: !!site.themeConfig?.carbonAds,
- __ASSETS_DIR__: JSON.stringify(siteConfig.assetsDir)
+ __ASSETS_DIR__: JSON.stringify(siteConfig.assetsDir),
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: !!process.env.DEBUG
},
optimizeDeps: {
// force include vue to avoid duplicated copies when linked + optimized
@@ -267,7 +268,11 @@ export async function createVitePressPlugin(
if (file.endsWith('.md')) {
Object.assign(
siteConfig,
- await resolvePages(siteConfig.srcDir, siteConfig.userConfig)
+ await resolvePages(
+ siteConfig.srcDir,
+ siteConfig.userConfig,
+ siteConfig.logger
+ )
)
}
diff --git a/src/node/plugins/dynamicRoutesPlugin.ts b/src/node/plugins/dynamicRoutesPlugin.ts
index e42e8c13..cf9576ae 100644
--- a/src/node/plugins/dynamicRoutesPlugin.ts
+++ b/src/node/plugins/dynamicRoutesPlugin.ts
@@ -1,6 +1,7 @@
import {
loadConfigFromFile,
normalizePath,
+ type Logger,
type Plugin,
type ViteDevServer
} from 'vite'
@@ -13,7 +14,11 @@ import { resolveRewrites } from './rewritesPlugin'
export const dynamicRouteRE = /\[(\w+?)\]/g
-export async function resolvePages(srcDir: string, userConfig: UserConfig) {
+export async function resolvePages(
+ srcDir: string,
+ userConfig: UserConfig,
+ logger: Logger
+) {
// Important: fast-glob doesn't guarantee order of the returned files.
// We must sort the pages so the input list to rollup is stable across
// builds - otherwise different input order could result in different exports
@@ -39,7 +44,11 @@ export async function resolvePages(srcDir: string, userConfig: UserConfig) {
;(dynamicRouteRE.test(file) ? dynamicRouteFiles : pages).push(file)
})
- const dynamicRoutes = await resolveDynamicRoutes(srcDir, dynamicRouteFiles)
+ const dynamicRoutes = await resolveDynamicRoutes(
+ srcDir,
+ dynamicRouteFiles,
+ logger
+ )
pages.push(...dynamicRoutes.routes.map((r) => r.path))
const rewrites = resolveRewrites(pages, userConfig.rewrites)
@@ -141,7 +150,7 @@ export const dynamicRoutesPlugin = async (
if (!/\.md$/.test(ctx.file)) {
Object.assign(
config,
- await resolvePages(config.srcDir, config.userConfig)
+ await resolvePages(config.srcDir, config.userConfig, config.logger)
)
}
for (const id of mods) {
@@ -154,7 +163,8 @@ export const dynamicRoutesPlugin = async (
export async function resolveDynamicRoutes(
srcDir: string,
- routes: string[]
+ routes: string[],
+ logger: Logger
): Promise {
const pendingResolveRoutes: Promise[] = []
const routeFileToModulesMap: Record> = {}
@@ -170,7 +180,7 @@ export async function resolveDynamicRoutes(
const pathsFile = paths.find((p) => fs.existsSync(p))
if (pathsFile == null) {
- console.warn(
+ logger.warn(
c.yellow(
`Missing paths file for dynamic route ${route}: ` +
`a corresponding ${paths[0]} (or .ts/.mjs/.mts) file is needed.`
@@ -183,15 +193,15 @@ export async function resolveDynamicRoutes(
let mod = routeModuleCache.get(pathsFile)
if (!mod) {
try {
- mod = (await loadConfigFromFile({} as any, pathsFile)) as RouteModule
+ mod = (await loadConfigFromFile(
+ {} as any,
+ pathsFile,
+ undefined,
+ 'silent'
+ )) as RouteModule
routeModuleCache.set(pathsFile, mod)
- } catch (e) {
- console.warn(
- c.yellow(
- `Invalid paths file export in ${pathsFile}. ` +
- `Expects default export of an object with a "paths" property.`
- )
- )
+ } catch (e: any) {
+ logger.warn(`${c.yellow(`Failed to load ${pathsFile}:`)}\n${e.stack}`)
continue
}
}
@@ -210,7 +220,7 @@ export async function resolveDynamicRoutes(
const loader = mod!.config.paths
if (!loader) {
- console.warn(
+ logger.warn(
c.yellow(
`Invalid paths file export in ${pathsFile}. ` +
`Missing "paths" property from default export.`
diff --git a/src/node/siteConfig.ts b/src/node/siteConfig.ts
index 56c0592c..74174280 100644
--- a/src/node/siteConfig.ts
+++ b/src/node/siteConfig.ts
@@ -147,6 +147,15 @@ export interface UserConfig
*/
useWebFonts?: boolean
+ /**
+ * This option allows you to configure the concurrency of the build.
+ * A lower number will reduce the memory usage but will increase the build time.
+ *
+ * @experimental
+ * @default 64
+ */
+ buildConcurrency?: number
+
/**
* @experimental
*
@@ -240,4 +249,5 @@ export interface SiteConfig
}
logger: Logger
userConfig: UserConfig
+ buildConcurrency: number
}
diff --git a/src/shared/shared.ts b/src/shared/shared.ts
index c69f7277..9dd05e34 100644
--- a/src/shared/shared.ts
+++ b/src/shared/shared.ts
@@ -113,6 +113,10 @@ export function createTitle(siteData: SiteData, pageData: PageData): string {
const templateString = createTitleTemplate(siteData.title, template)
+ if (title === templateString.slice(3)) {
+ return title
+ }
+
return `${title}${templateString}`
}
diff --git a/types/default-theme.d.ts b/types/default-theme.d.ts
index 94dfb95c..157faa00 100644
--- a/types/default-theme.d.ts
+++ b/types/default-theme.d.ts
@@ -96,6 +96,16 @@ export namespace DefaultTheme {
*/
darkModeSwitchLabel?: string
+ /**
+ * @default 'Switch to light theme'
+ */
+ lightModeSwitchTitle?: string
+
+ /**
+ * @default 'Switch to dark theme'
+ */
+ darkModeSwitchTitle?: string
+
/**
* @default 'Menu'
*/
@@ -345,6 +355,7 @@ export namespace DefaultTheme {
desc?: string
links?: SocialLink[]
sponsor?: string
+ actionText?: string
}
// outline -------------------------------------------------------------------