diff --git a/vtex/loaders/proxy.ts b/vtex/loaders/proxy.ts index 0a5263ac5..f1466d502 100644 --- a/vtex/loaders/proxy.ts +++ b/vtex/loaders/proxy.ts @@ -28,6 +28,7 @@ const buildProxyRoutes = ( generateDecoSiteMap, excludePathsFromDecoSiteMap, includeScriptsToHead, + includeScriptsToBody, }: { publicUrl?: string; extraPaths: string[]; @@ -37,6 +38,9 @@ const buildProxyRoutes = ( includeScriptsToHead?: { includes?: Script[]; }; + includeScriptsToBody?: { + includes?: Script[]; + }; }, ) => { if (!publicUrl) { @@ -65,6 +69,7 @@ const buildProxyRoutes = ( url: urlToProxy, host: hostToUse, includeScriptsToHead, + includeScriptsToBody, removeDirtyCookies: true, }; // we have this check because we need to add @@ -155,6 +160,12 @@ export interface Props { includeScriptsToHead?: { includes?: Script[]; }; + /** + * @title Scripts to include on Html body + */ + includeScriptsToBody?: { + includes?: Script[]; + }; } /** @@ -167,6 +178,7 @@ function loader( generateDecoSiteMap = true, excludePathsFromDecoSiteMap = [], includeScriptsToHead = { includes: [] }, + includeScriptsToBody = { includes: [] }, }: Props, _req: Request, ctx: AppContext, @@ -178,6 +190,7 @@ function loader( publicUrl: ctx.publicUrl, extraPaths: extraPathsToProxy, includeScriptsToHead, + includeScriptsToBody, }); } diff --git a/website/handlers/proxy.ts b/website/handlers/proxy.ts index 5bd6f538f..a3ad150a0 100644 --- a/website/handlers/proxy.ts +++ b/website/handlers/proxy.ts @@ -66,6 +66,12 @@ export interface Props { includeScriptsToHead?: { includes?: Script[]; }; + /** + * @description Scripts to be included in the body of the html + */ + includeScriptsToBody?: { + includes?: Script[]; + }; /** * @description follow redirects * @default 'manual' @@ -91,6 +97,7 @@ export default function Proxy({ customHeaders = [], excludeHeaders = [], includeScriptsToHead, + includeScriptsToBody, avoidAppendPath, redirect = "manual", replaces, @@ -145,28 +152,51 @@ export default function Proxy({ }); const contentType = response.headers.get("Content-Type"); let newBody: ReadableStream | string | null = response.body; - if ( - contentType?.includes("text/html") && - includeScriptsToHead?.includes && - includeScriptsToHead.includes.length > 0 - ) { - // Use a more efficient approach to insert scripts + if (contentType?.includes("text/html")) { newBody = await response.text(); - // Find the position of tag - const headEndPos = newBody.indexOf(""); - if (headEndPos !== -1) { - // Split the response body at position - const beforeHeadEnd = newBody.substring(0, headEndPos); - const afterHeadEnd = newBody.substring(headEndPos); - // Prepare scripts to insert - let scriptsInsert = ""; - for (const script of (includeScriptsToHead?.includes ?? [])) { - scriptsInsert += typeof script.src === "string" - ? script.src - : script.src(req); + + if ( + includeScriptsToHead?.includes && + includeScriptsToHead.includes.length > 0 + ) { + // Find the position of tag + const headEndPos = newBody.indexOf(""); + if (headEndPos !== -1) { + // Split the response body at position + const beforeHeadEnd = newBody.substring(0, headEndPos); + const afterHeadEnd = newBody.substring(headEndPos); + // Prepare scripts to insert + let scriptsInsert = ""; + for (const script of (includeScriptsToHead?.includes ?? [])) { + scriptsInsert += typeof script.src === "string" + ? script.src + : script.src(req); + } + // Combine the new response body + newBody = beforeHeadEnd + scriptsInsert + afterHeadEnd; + } + } + + if ( + includeScriptsToBody?.includes && + includeScriptsToBody.includes.length > 0 + ) { + // Find the position of tag + const bodyEndPos = newBody.indexOf(""); + if (bodyEndPos !== -1) { + // Split the response body at position + const beforeBodyEnd = newBody.substring(0, bodyEndPos); + const afterBodyEnd = newBody.substring(bodyEndPos); + // Prepare scripts to insert + let scriptsInsert = ""; + for (const script of (includeScriptsToBody?.includes ?? [])) { + scriptsInsert += typeof script.src === "string" + ? script.src + : script.src(req); + } + // Combine the new response body + newBody = beforeBodyEnd + scriptsInsert + afterBodyEnd; } - // Combine the new response body - newBody = beforeHeadEnd + scriptsInsert + afterHeadEnd; } } // Change cookies domain diff --git a/website/mod.ts b/website/mod.ts index 0460a1c1b..6637ce1d6 100644 --- a/website/mod.ts +++ b/website/mod.ts @@ -62,12 +62,19 @@ export interface AbTesting { */ replaces?: TextReplace[]; /** - * @title Scripts to include + * @title Scripts to include to the head * @description Scripts to include in the head of the page proxied */ includeScriptsToHead?: { includes?: Script[]; }; + /** + * @title Scripts to include to the body + * @description Scripts to include in the body of the page proxied + */ + includeScriptsToBody?: { + includes?: Script[]; + }; } /** @titleBy framework */ interface Fresh { @@ -176,6 +183,7 @@ const getAbTestAudience = (abTesting: AbTesting) => { __resolveType: "website/handlers/proxy.ts", customHeaders: [], includeScriptsToHead: abTesting.includeScriptsToHead, + includeScriptsToBody: abTesting.includeScriptsToBody, replaces: abTesting.replaces, }, };