diff --git a/packages/next/server/render.tsx b/packages/next/server/render.tsx
index 3dad4bbadc4908e..e21200e2a05e64d 100644
--- a/packages/next/server/render.tsx
+++ b/packages/next/server/render.tsx
@@ -934,6 +934,20 @@ export async function renderToHTML(
}
}
+ const appWrappers: Array<(content: JSX.Element) => JSX.Element> = []
+ const getWrappedApp = (app: JSX.Element) => {
+ // Prevent wrappers from reading/writing props by rendering inside an
+ // opaque component. Wrappers should use context instead.
+ const InnerApp = () => app
+ return (
+
+ {appWrappers.reduce((innerContent, fn) => {
+ return fn(innerContent)
+ }, )}
+
+ )
+ }
+
/**
* Rules of Static & Dynamic HTML:
*
@@ -976,11 +990,13 @@ export async function renderToHTML(
const html = ReactDOMServer.renderToString(
-
+ {getWrappedApp(
+
+ )}
)
return { html, head }
@@ -1019,19 +1035,15 @@ export async function renderToHTML(
styles: docProps.styles,
}
} else {
- const contentWrappers: Array<(content: JSX.Element) => JSX.Element> = []
const bodyResult = async () => {
- const initialContent =
+ const content =
ctx.err && ErrorDebug ? (
) : (
-
+ getWrappedApp(
-
+ )
)
- const content = contentWrappers.reduce((innerContent, fn) => {
- return fn(innerContent)
- }, initialContent)
return concurrentFeatures
? process.browser
@@ -1045,7 +1057,7 @@ export async function renderToHTML(
documentElement: () => (Document as any)(),
useMainContent: (fn?: (content: JSX.Element) => JSX.Element) => {
if (fn) {
- contentWrappers.push(fn)
+ appWrappers.push(fn)
}
// @ts-ignore
return