@@ -22,6 +22,7 @@ import {
2222 partialEncodeURIPath ,
2323 processSrcSet ,
2424 removeLeadingSlash ,
25+ unique ,
2526 urlCanParse ,
2627} from '../utils'
2728import type { ResolvedConfig } from '../config'
@@ -1265,6 +1266,42 @@ export function resolveHtmlTransforms(
12651266 return [ preHooks , normalHooks , postHooks ]
12661267}
12671268
1269+ // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head#see_also
1270+ const elementsAllowedInHead = new Set ( [
1271+ 'title' ,
1272+ 'base' ,
1273+ 'link' ,
1274+ 'style' ,
1275+ 'meta' ,
1276+ 'script' ,
1277+ 'noscript' ,
1278+ 'template' ,
1279+ ] )
1280+
1281+ function headTagInsertCheck (
1282+ tags : HtmlTagDescriptor [ ] ,
1283+ ctx : IndexHtmlTransformContext ,
1284+ ) {
1285+ if ( ! tags . length ) return
1286+ const { logger } = ctx . server ?. config || { }
1287+ const disallowedTags = tags . filter (
1288+ ( tagDescriptor ) => ! elementsAllowedInHead . has ( tagDescriptor . tag ) ,
1289+ )
1290+
1291+ if ( disallowedTags . length ) {
1292+ const dedupedTags = unique (
1293+ disallowedTags . map ( ( tagDescriptor ) => `<${ tagDescriptor . tag } >` ) ,
1294+ )
1295+ logger ?. warn (
1296+ colors . yellow (
1297+ colors . bold (
1298+ `[${ dedupedTags . join ( ',' ) } ] can not be used inside the <head> Element, please check the 'injectTo' value` ,
1299+ ) ,
1300+ ) ,
1301+ )
1302+ }
1303+ }
1304+
12681305export async function applyHtmlTransforms (
12691306 html : string ,
12701307 hooks : IndexHtmlTransformHook [ ] ,
@@ -1306,7 +1343,7 @@ export async function applyHtmlTransforms(
13061343 ; ( headPrependTags ??= [ ] ) . push ( tag )
13071344 }
13081345 }
1309-
1346+ headTagInsertCheck ( [ ... ( headTags || [ ] ) , ... ( headPrependTags || [ ] ) ] , ctx )
13101347 if ( headPrependTags ) html = injectToHead ( html , headPrependTags , true )
13111348 if ( headTags ) html = injectToHead ( html , headTags )
13121349 if ( bodyPrependTags ) html = injectToBody ( html , bodyPrependTags , true )
0 commit comments