From 6b16dad22f944cb173dbf67ef04be5cb0d09279f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joaqu=C3=ADn=20S=C3=A1nchez?= Date: Mon, 12 Sep 2022 13:57:54 +0200 Subject: [PATCH] feat: add `transformHead` hook (#1323) Co-authored-by: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> --- .gitattributes | 1 + docs/config/app-configs.md | 41 ++++++++++++++++++++++++-------------- src/node/build/render.ts | 15 +++++++++++++- src/node/config.ts | 9 +++++++++ 4 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..6313b56c --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/docs/config/app-configs.md b/docs/config/app-configs.md index 89f9e378..b29950bf 100644 --- a/docs/config/app-configs.md +++ b/docs/config/app-configs.md @@ -255,24 +255,21 @@ VitePress build hooks allow you to add new functionality and behaviors to your w - Search Indexing - PWA -### transformHtml +### transformHead -- Type: `( code: string, id: string, ctx: TransformContext ) => Awaitable` +- Type: `(ctx: TransformContext) => Awaitable` -`transformHtml` is a build hook to transform the content of each page before saving to disk (SSG). +`transformHead` is a build hook to transform the head before generating each page. It will allow you to add head entries that cannot be statically added to your VitePress config. You only need to return extra entries, they will be merged automatically with the existing ones. ::: warning -Modifying the html content may cause hydration problems in runtime. +Don't mutate anything inside the `ctx`. ::: ```ts -import { defineConfig } from 'vitepress' - -export default defineConfig({ - /* other vitepress options */ - async transformHtml(code, id, context) { +export default { + async transformHead(ctx) { } -}) +} ``` ```ts @@ -287,6 +284,23 @@ interface TransformContext { } ``` +### transformHtml + +- Type: `(code: string, id: string, ctx: TransformContext) => Awaitable` + +`transformHtml` is a build hook to transform the content of each page before saving to disk. + +::: warning +Don't mutate anything inside the `ctx`. Also, modifying the html content may cause hydration problems in runtime. +::: + +```ts +export default { + async transformHtml(code, id, context) { + } +} +``` + ### buildEnd - Type: `(siteConfig: SiteConfig) => Awaitable` @@ -294,11 +308,8 @@ interface TransformContext { `buildEnd` is a build CLI hook, it will run after build (SSG) finish but before VitePress CLI process exits. ```ts -import { defineConfig } from 'vitepress' - -export default defineConfig({ - /* other vitepress options */ +export default { async buildEnd(siteConfig) { } -}) +} ``` diff --git a/src/node/build/render.ts b/src/node/build/render.ts index 55e1adf3..238bb0ff 100644 --- a/src/node/build/render.ts +++ b/src/node/build/render.ts @@ -106,11 +106,24 @@ export async function renderPage( const title: string = createTitle(siteData, pageData) const description: string = pageData.description || siteData.description - const head = mergeHead( + const headBeforeTransform = mergeHead( siteData.head, filterOutHeadDescription(pageData.frontmatter.head) ) + const head = mergeHead( + headBeforeTransform, + (await config.transformHead?.({ + siteConfig: config, + siteData, + pageData, + title, + description, + head: headBeforeTransform, + content + })) || [] + ) + let inlinedScript = '' if (config.mpa && result) { const matchingChunk = result.output.find( diff --git a/src/node/config.ts b/src/node/config.ts index d00499fa..8d1f73e1 100644 --- a/src/node/config.ts +++ b/src/node/config.ts @@ -93,6 +93,13 @@ export interface UserConfig { */ buildEnd?: (siteConfig: SiteConfig) => Awaitable + /** + * Head transform hook: runs before writing HTML to dist. + * + * This build hook will allow you to modify the head adding new entries that cannot be statically added. + */ + transformHead?: (ctx: TransformContext) => Awaitable + /** * HTML transform hook: runs before writing HTML to dist. */ @@ -129,6 +136,7 @@ export interface SiteConfig | 'ignoreDeadLinks' | 'cleanUrls' | 'buildEnd' + | 'transformHead' | 'transformHtml' > { root: string @@ -215,6 +223,7 @@ export async function resolveConfig( ignoreDeadLinks: userConfig.ignoreDeadLinks, cleanUrls: userConfig.cleanUrls || 'disabled', buildEnd: userConfig.buildEnd, + transformHead: userConfig.transformHead, transformHtml: userConfig.transformHtml }