diff --git a/packages/next/src/pages/_document.tsx b/packages/next/src/pages/_document.tsx index 48a845299b10..5f61547a0036 100644 --- a/packages/next/src/pages/_document.tsx +++ b/packages/next/src/pages/_document.tsx @@ -1,4 +1,4 @@ -import React, { ReactElement, ReactNode, useContext } from 'react' +import React, { ReactElement, ReactNode } from 'react' import { OPTIMIZED_FONT_PROVIDERS, NEXT_BUILTIN_DOCUMENT, @@ -17,7 +17,7 @@ import { BuildManifest, getPageFiles } from '../server/get-page-files' import { htmlEscapeJsonString } from '../server/htmlescape' import isError from '../lib/is-error' -import { HtmlContext } from '../shared/lib/html-context' +import { HtmlContext, useHtmlContext } from '../shared/lib/html-context' import type { HtmlProps } from '../shared/lib/html-context' export { DocumentContext, DocumentInitialProps, DocumentProps } @@ -424,7 +424,7 @@ function getNextFontLinkTags( export class Head extends React.Component { static contextType = HtmlContext - context!: React.ContextType + context!: HtmlProps getCssLinks(files: DocumentFiles): JSX.Element[] | null { const { @@ -995,7 +995,7 @@ function handleDocumentScriptLoaderItems( export class NextScript extends React.Component { static contextType = HtmlContext - context!: React.ContextType + context!: HtmlProps getDynamicChunks(files: DocumentFiles) { return getDynamicChunks(this.context, this.props, files) @@ -1174,7 +1174,7 @@ export function Html( locale, scriptLoader, __NEXT_DATA__, - } = useContext(HtmlContext) + } = useHtmlContext() docComponentsRendered.Html = true handleDocumentScriptLoaderItems(scriptLoader, __NEXT_DATA__, props) @@ -1196,7 +1196,7 @@ export function Html( } export function Main() { - const { docComponentsRendered } = useContext(HtmlContext) + const { docComponentsRendered } = useHtmlContext() docComponentsRendered.Main = true // @ts-ignore return diff --git a/packages/next/src/shared/lib/html-context.ts b/packages/next/src/shared/lib/html-context.ts index 064110d70175..33b2dce0f06b 100644 --- a/packages/next/src/shared/lib/html-context.ts +++ b/packages/next/src/shared/lib/html-context.ts @@ -4,7 +4,7 @@ import type { NEXT_DATA } from './utils' import type { FontConfig } from '../../server/font-utils' import type { NextFontManifest } from '../../build/webpack/plugins/next-font-manifest-plugin' -import { createContext } from 'react' +import { createContext, useContext } from 'react' export type HtmlProps = { __NEXT_DATA__: NEXT_DATA @@ -48,7 +48,20 @@ export type HtmlProps = { nextFontManifest?: NextFontManifest } -export const HtmlContext = createContext(null as any) +export const HtmlContext = createContext(undefined) if (process.env.NODE_ENV !== 'production') { HtmlContext.displayName = 'HtmlContext' } + +export function useHtmlContext() { + const context = useContext(HtmlContext) + + if (!context) { + throw new Error( + ` should not be imported outside of pages/_document.\n` + + 'Read more: https://nextjs.org/docs/messages/no-document-import-in-page' + ) + } + + return context +}