Skip to content

Commit

Permalink
feat: allow tag injection after body open (body-prepend) (#1435)
Browse files Browse the repository at this point in the history
  • Loading branch information
stafyniaksacha committed Jan 9, 2021
1 parent 51a02ff commit 432487e
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 8 deletions.
2 changes: 1 addition & 1 deletion docs/guide/api-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ Vite plugins can also provide hooks that serve Vite-specific purposes. These hoo
/**
* default: 'head-prepend'
*/
injectTo?: 'head' | 'body' | 'head-prepend'
injectTo?: 'head' | 'body' | 'head-prepend' | 'body-prepend'
}
```

Expand Down
6 changes: 6 additions & 0 deletions packages/playground/html/__tests__/html.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ function testPage(isNested: boolean) {
}
})

test('body prepend/append transform', async () => {
expect(await page.innerHTML('body')).toMatch(
/prepended to body(.*)appended to body/s
)
})

test('css', async () => {
expect(await getColor('h1')).toBe(isNested ? 'red' : 'blue')
expect(await getColor('p')).toBe('grey')
Expand Down
17 changes: 17 additions & 0 deletions packages/playground/html/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,23 @@ module.exports = {
]
}
}
},
{
name: 'body-prepend-transform',
transformIndexHtml() {
return [
{
tag: 'noscript',
children: '<!-- this is appended to body -->',
injectTo: 'body'
},
{
tag: 'noscript',
children: '<!-- this is prepended to body -->',
injectTo: 'body-prepend'
}
]
}
}
]
}
36 changes: 29 additions & 7 deletions packages/vite/src/node/plugins/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ export interface HtmlTagDescriptor {
/**
* default: 'head-prepend'
*/
injectTo?: 'head' | 'body' | 'head-prepend'
injectTo?: 'head' | 'body' | 'head-prepend' | 'body-prepend'
}

export type IndexHtmlTransformResult =
Expand Down Expand Up @@ -408,6 +408,7 @@ export async function applyHtmlTransforms(
const headTags: HtmlTagDescriptor[] = []
const headPrependTags: HtmlTagDescriptor[] = []
const bodyTags: HtmlTagDescriptor[] = []
const bodyPrependTags: HtmlTagDescriptor[] = []

const ctx: IndexHtmlTransformContext = {
path,
Expand Down Expand Up @@ -435,6 +436,8 @@ export async function applyHtmlTransforms(
for (const tag of tags) {
if (tag.injectTo === 'body') {
bodyTags.push(tag)
} else if (tag.injectTo === 'body-prepend') {
bodyPrependTags.push(tag)
} else if (tag.injectTo === 'head') {
headTags.push(tag)
} else {
Expand All @@ -451,6 +454,9 @@ export async function applyHtmlTransforms(
if (headTags.length) {
html = injectToHead(html, headTags)
}
if (bodyPrependTags.length) {
html = injectToBody(html, bodyPrependTags, true)
}
if (bodyTags.length) {
html = injectToBody(html, bodyTags)
}
Expand Down Expand Up @@ -488,13 +494,29 @@ function injectToHead(
}

const bodyInjectRE = /<\/body>/
function injectToBody(html: string, tags: HtmlTagDescriptor[]) {
const tagsHtml = `\n` + serializeTags(tags)
if (bodyInjectRE.test(html)) {
return html.replace(bodyInjectRE, `${tagsHtml}\n$&`)
const bodyPrependInjectRE = /<body>/
function injectToBody(
html: string,
tags: HtmlTagDescriptor[],
prepend = false
) {
if (prepend) {
// inject after body open
const tagsHtml = `\n` + serializeTags(tags)
if (bodyPrependInjectRE.test(html)) {
return html.replace(bodyPrependInjectRE, `$&\n${tagsHtml}`)
}
// if no body, prepend
return tagsHtml + `\n` + html
} else {
// inject before body close
const tagsHtml = `\n` + serializeTags(tags)
if (bodyInjectRE.test(html)) {
return html.replace(bodyInjectRE, `${tagsHtml}\n$&`)
}
// if no body, append
return html + `\n` + tagsHtml
}
// if no body, append
return html + `\n` + tagsHtml
}

const unaryTags = new Set(['link', 'meta', 'base'])
Expand Down

0 comments on commit 432487e

Please sign in to comment.