{"version":3,"sources":["../../src/client/index.tsx"],"sourcesContent":["/* global location */\n// imports polyfill from `@next/polyfill-module` after build.\nimport '../build/polyfills/polyfill-module'\nimport type Router from '../shared/lib/router/router'\nimport type {\n AppComponent,\n AppProps,\n PrivateRouteInfo,\n} from '../shared/lib/router/router'\n\nimport React, { type JSX } from 'react'\nimport ReactDOM from 'react-dom/client'\nimport { HeadManagerContext } from '../shared/lib/head-manager-context.shared-runtime'\nimport mitt from '../shared/lib/mitt'\nimport type { MittEmitter } from '../shared/lib/mitt'\nimport { RouterContext } from '../shared/lib/router-context.shared-runtime'\nimport { disableSmoothScrollDuringRouteTransition } from '../shared/lib/router/utils/disable-smooth-scroll'\nimport { isDynamicRoute } from '../shared/lib/router/utils/is-dynamic'\nimport {\n urlQueryToSearchParams,\n assign,\n} from '../shared/lib/router/utils/querystring'\nimport { getURL, loadGetInitialProps, ST } from '../shared/lib/utils'\nimport type { NextWebVitalsMetric, NEXT_DATA } from '../shared/lib/utils'\nimport { Portal } from './portal'\nimport initHeadManager from './head-manager'\nimport PageLoader from './page-loader'\nimport type { StyleSheetTuple } from './page-loader'\nimport { RouteAnnouncer } from './route-announcer'\nimport { createRouter, makePublicRouterInstance } from './router'\nimport { getProperError } from '../lib/is-error'\nimport { ImageConfigContext } from '../shared/lib/image-config-context.shared-runtime'\nimport type { ImageConfigComplete } from '../shared/lib/image-config'\nimport { removeBasePath } from './remove-base-path'\nimport { hasBasePath } from './has-base-path'\nimport { AppRouterContext } from '../shared/lib/app-router-context.shared-runtime'\nimport {\n adaptForAppRouterInstance,\n adaptForPathParams,\n adaptForSearchParams,\n PathnameContextProviderAdapter,\n} from '../shared/lib/router/adapters'\nimport {\n SearchParamsContext,\n PathParamsContext,\n} from '../shared/lib/hooks-client-context.shared-runtime'\nimport { onRecoverableError } from './react-client-callbacks/on-recoverable-error'\nimport tracer from './tracing/tracer'\nimport { isNextRouterError } from './components/is-next-router-error'\n\n/// \n\ndeclare global {\n interface Window {\n /* test fns */\n __NEXT_HYDRATED?: boolean\n __NEXT_HYDRATED_AT?: number\n __NEXT_HYDRATED_CB?: () => void\n\n /* prod */\n __NEXT_DATA__: NEXT_DATA\n __NEXT_P: any[]\n }\n}\ntype RenderRouteInfo = PrivateRouteInfo & {\n App: AppComponent\n scroll?: { x: number; y: number } | null\n isHydratePass?: boolean\n}\ntype RenderErrorProps = Omit\ntype RegisterFn = (input: [string, () => void]) => void\n\nexport const version = process.env.__NEXT_VERSION\nexport let router: Router\nexport const emitter: MittEmitter = mitt()\n\nconst looseToArray = (input: any): T[] => [].slice.call(input)\n\nlet initialData: NEXT_DATA\nlet defaultLocale: string | undefined = undefined\nlet asPath: string\nlet pageLoader: PageLoader\nlet appElement: HTMLElement | null\nlet headManager: {\n mountedInstances: Set\n updateHead: (head: JSX.Element[]) => void\n getIsSsr?: () => boolean\n}\nlet initialMatchesMiddleware = false\nlet lastAppProps: AppProps\n\nlet lastRenderReject: (() => void) | null\nlet devClient: any\n\nlet CachedApp: AppComponent, onPerfEntry: (metric: any) => void\nlet CachedComponent: React.ComponentType\n\nclass Container extends React.Component<{\n children?: React.ReactNode\n fn: (err: Error, info?: any) => void\n}> {\n componentDidCatch(componentErr: Error, info: any) {\n this.props.fn(componentErr, info)\n }\n\n componentDidMount() {\n this.scrollToHash()\n\n // We need to replace the router state if:\n // - the page was (auto) exported and has a query string or search (hash)\n // - it was auto exported and is a dynamic route (to provide params)\n // - if it is a client-side skeleton (fallback render)\n // - if middleware matches the current page (may have rewrite params)\n // - if rewrites in next.config.js match (may have rewrite params)\n if (\n router.isSsr &&\n (initialData.isFallback ||\n (initialData.nextExport &&\n (isDynamicRoute(router.pathname) ||\n location.search ||\n process.env.__NEXT_HAS_REWRITES ||\n initialMatchesMiddleware)) ||\n (initialData.props &&\n initialData.props.__N_SSG &&\n (location.search ||\n process.env.__NEXT_HAS_REWRITES ||\n initialMatchesMiddleware)))\n ) {\n // update query on mount for exported pages\n router\n .replace(\n router.pathname +\n '?' +\n String(\n assign(\n urlQueryToSearchParams(router.query),\n new URLSearchParams(location.search)\n )\n ),\n asPath,\n {\n // @ts-ignore\n // WARNING: `_h` is an internal option for handing Next.js\n // client-side hydration. Your app should _never_ use this property.\n // It may change at any time without notice.\n _h: 1,\n // Fallback pages must trigger the data fetch, so the transition is\n // not shallow.\n // Other pages (strictly updating query) happens shallowly, as data\n // requirements would already be present.\n shallow: !initialData.isFallback && !initialMatchesMiddleware,\n }\n )\n .catch((err) => {\n if (!err.cancelled) throw err\n })\n }\n }\n\n componentDidUpdate() {\n this.scrollToHash()\n }\n\n scrollToHash() {\n let { hash } = location\n hash = hash && hash.substring(1)\n if (!hash) return\n\n const el: HTMLElement | null = document.getElementById(hash)\n if (!el) return\n\n // If we call scrollIntoView() in here without a setTimeout\n // it won't scroll properly.\n setTimeout(() => el.scrollIntoView(), 0)\n }\n\n render() {\n if (process.env.NODE_ENV === 'production') {\n return this.props.children\n } else {\n const { PagesDevOverlayBridge } =\n require('../next-devtools/userspace/pages/pages-dev-overlay-setup') as typeof import('../next-devtools/userspace/pages/pages-dev-overlay-setup')\n return (\n {this.props.children}\n )\n }\n }\n}\n\nexport async function initialize(opts: { devClient?: any } = {}): Promise<{\n assetPrefix: string\n}> {\n // This makes sure this specific lines are removed in production\n if (process.env.NODE_ENV === 'development') {\n tracer.onSpanEnd(\n (\n require('./tracing/report-to-socket') as typeof import('./tracing/report-to-socket')\n ).default\n )\n devClient = opts.devClient\n }\n\n initialData = JSON.parse(\n document.getElementById('__NEXT_DATA__')!.textContent!\n )\n window.__NEXT_DATA__ = initialData\n\n defaultLocale = initialData.defaultLocale\n const prefix: string = initialData.assetPrefix || ''\n // With dynamic assetPrefix it's no longer possible to set assetPrefix at the build time\n // So, this is how we do it in the client side at runtime\n ;(self as any).__next_set_public_path__(`${prefix}/_next/`)\n\n asPath = getURL()\n\n // make sure not to attempt stripping basePath for 404s\n if (hasBasePath(asPath)) {\n asPath = removeBasePath(asPath)\n }\n\n if (process.env.__NEXT_I18N_SUPPORT) {\n const { normalizeLocalePath } =\n require('../shared/lib/i18n/normalize-locale-path') as typeof import('../shared/lib/i18n/normalize-locale-path')\n\n const { detectDomainLocale } =\n require('../shared/lib/i18n/detect-domain-locale') as typeof import('../shared/lib/i18n/detect-domain-locale')\n\n const { parseRelativeUrl } =\n require('../shared/lib/router/utils/parse-relative-url') as typeof import('../shared/lib/router/utils/parse-relative-url')\n\n const { formatUrl } =\n require('../shared/lib/router/utils/format-url') as typeof import('../shared/lib/router/utils/format-url')\n\n if (initialData.locales) {\n const parsedAs = parseRelativeUrl(asPath)\n const localePathResult = normalizeLocalePath(\n parsedAs.pathname,\n initialData.locales\n )\n\n if (localePathResult.detectedLocale) {\n parsedAs.pathname = localePathResult.pathname\n asPath = formatUrl(parsedAs)\n } else {\n // derive the default locale if it wasn't detected in the asPath\n // since we don't prerender static pages with all possible default\n // locales\n defaultLocale = initialData.locale\n }\n\n // attempt detecting default locale based on hostname\n const detectedDomain = detectDomainLocale(\n process.env.__NEXT_I18N_DOMAINS as any,\n window.location.hostname\n )\n\n // TODO: investigate if defaultLocale needs to be populated after\n // hydration to prevent mismatched renders\n if (detectedDomain) {\n defaultLocale = detectedDomain.defaultLocale\n }\n }\n }\n\n if (initialData.scriptLoader) {\n const { initScriptLoader } =\n require('./script') as typeof import('./script')\n initScriptLoader(initialData.scriptLoader)\n }\n\n pageLoader = new PageLoader(initialData.buildId, prefix)\n\n const register: RegisterFn = ([r, f]) =>\n pageLoader.routeLoader.onEntrypoint(r, f)\n if (window.__NEXT_P) {\n // Defer page registration for another tick. This will increase the overall\n // latency in hydrating the page, but reduce the total blocking time.\n window.__NEXT_P.map((p) => setTimeout(() => register(p), 0))\n }\n window.__NEXT_P = []\n ;(window.__NEXT_P as any).push = register\n\n headManager = initHeadManager()\n headManager.getIsSsr = () => {\n return router.isSsr\n }\n\n appElement = document.getElementById('__next')\n return { assetPrefix: prefix }\n}\n\nfunction renderApp(App: AppComponent, appProps: AppProps) {\n return \n}\n\nfunction AppContainer({\n children,\n}: React.PropsWithChildren<{}>): React.ReactElement {\n // Create a memoized value for next/navigation router context.\n const adaptedForAppRouter = React.useMemo(() => {\n return adaptForAppRouterInstance(router)\n }, [])\n return (\n \n renderError({ App: CachedApp, err: error }).catch((err) =>\n console.error('Error rendering page: ', err)\n )\n }\n >\n \n \n \n \n \n \n \n {children}\n \n \n \n \n \n \n \n \n )\n}\n\nconst wrapApp =\n (App: AppComponent) =>\n (wrappedAppProps: Record): JSX.Element => {\n const appProps: AppProps = {\n ...wrappedAppProps,\n Component: CachedComponent,\n err: initialData.err,\n router,\n }\n return {renderApp(App, appProps)}\n }\n\n// This method handles all runtime and debug errors.\n// 404 and 500 errors are special kind of errors\n// and they are still handle via the main render method.\nfunction renderError(renderErrorProps: RenderErrorProps): Promise {\n let { App, err } = renderErrorProps\n\n // In development runtime errors are caught by our overlay\n // In production we catch runtime errors using componentDidCatch which will trigger renderError\n if (process.env.NODE_ENV !== 'production') {\n // A Next.js rendering runtime error is always unrecoverable\n // FIXME: let's make this recoverable (error in GIP client-transition)\n devClient.onUnrecoverableError()\n\n // We need to render an empty so that the `` can\n // render itself.\n return doRender({\n App: () => null,\n props: {},\n Component: () => null,\n styleSheets: [],\n })\n }\n\n // Make sure we log the error to the console, otherwise users can't track down issues.\n console.error(err)\n console.error(\n `A client-side exception has occurred, see here for more info: https://nextjs.org/docs/messages/client-side-exception-occurred`\n )\n\n return pageLoader\n .loadPage('/_error')\n .then(({ page: ErrorComponent, styleSheets }) => {\n return lastAppProps?.Component === ErrorComponent\n ? import('../pages/_error')\n .then((errorModule) => {\n return import('../pages/_app').then((appModule) => {\n App = appModule.default as any as AppComponent\n renderErrorProps.App = App\n return errorModule\n })\n })\n .then((m) => ({\n ErrorComponent: m.default as React.ComponentType<{}>,\n styleSheets: [],\n }))\n : { ErrorComponent, styleSheets }\n })\n .then(({ ErrorComponent, styleSheets }) => {\n // In production we do a normal render with the `ErrorComponent` as component.\n // If we've gotten here upon initial render, we can use the props from the server.\n // Otherwise, we need to call `getInitialProps` on `App` before mounting.\n const AppTree = wrapApp(App)\n const appCtx = {\n Component: ErrorComponent,\n AppTree,\n router,\n ctx: {\n err,\n pathname: initialData.page,\n query: initialData.query,\n asPath,\n AppTree,\n },\n }\n return Promise.resolve(\n renderErrorProps.props?.err\n ? renderErrorProps.props\n : loadGetInitialProps(App, appCtx)\n ).then((initProps) =>\n doRender({\n ...renderErrorProps,\n err,\n Component: ErrorComponent,\n styleSheets,\n props: initProps,\n })\n )\n })\n}\n\n// Dummy component that we render as a child of Root so that we can\n// toggle the correct styles before the page is rendered.\nfunction Head({ callback }: { callback: () => void }): null {\n // We use `useLayoutEffect` to guarantee the callback is executed\n // as soon as React flushes the update.\n React.useLayoutEffect(() => callback(), [callback])\n return null\n}\n\nconst performanceMarks = {\n navigationStart: 'navigationStart',\n beforeRender: 'beforeRender',\n afterRender: 'afterRender',\n afterHydrate: 'afterHydrate',\n routeChange: 'routeChange',\n} as const\n\nconst performanceMeasures = {\n hydration: 'Next.js-hydration',\n beforeHydration: 'Next.js-before-hydration',\n routeChangeToRender: 'Next.js-route-change-to-render',\n render: 'Next.js-render',\n} as const\n\nlet reactRoot: any = null\n// On initial render a hydrate should always happen\nlet shouldHydrate: boolean = true\n\nfunction clearMarks(): void {\n ;[\n performanceMarks.beforeRender,\n performanceMarks.afterHydrate,\n performanceMarks.afterRender,\n performanceMarks.routeChange,\n ].forEach((mark) => performance.clearMarks(mark))\n}\n\nfunction markHydrateComplete(): void {\n if (!ST) return\n\n performance.mark(performanceMarks.afterHydrate) // mark end of hydration\n\n const hasBeforeRenderMark = performance.getEntriesByName(\n performanceMarks.beforeRender,\n 'mark'\n ).length\n if (hasBeforeRenderMark) {\n const beforeHydrationMeasure = performance.measure(\n performanceMeasures.beforeHydration,\n performanceMarks.navigationStart,\n performanceMarks.beforeRender\n )\n\n const hydrationMeasure = performance.measure(\n performanceMeasures.hydration,\n performanceMarks.beforeRender,\n performanceMarks.afterHydrate\n )\n\n if (\n process.env.NODE_ENV === 'development' &&\n // Old versions of Safari don't return `PerformanceMeasure`s from `performance.measure()`\n beforeHydrationMeasure &&\n hydrationMeasure\n ) {\n tracer\n .startSpan('navigation-to-hydration', {\n startTime: performance.timeOrigin + beforeHydrationMeasure.startTime,\n attributes: {\n pathname: location.pathname,\n query: location.search,\n },\n })\n .end(\n performance.timeOrigin +\n hydrationMeasure.startTime +\n hydrationMeasure.duration\n )\n }\n }\n\n if (onPerfEntry) {\n performance\n .getEntriesByName(performanceMeasures.hydration)\n .forEach(onPerfEntry)\n }\n clearMarks()\n}\n\nfunction markRenderComplete(): void {\n if (!ST) return\n\n performance.mark(performanceMarks.afterRender) // mark end of render\n const navStartEntries: PerformanceEntryList = performance.getEntriesByName(\n performanceMarks.routeChange,\n 'mark'\n )\n\n if (!navStartEntries.length) return\n\n const hasBeforeRenderMark = performance.getEntriesByName(\n performanceMarks.beforeRender,\n 'mark'\n ).length\n\n if (hasBeforeRenderMark) {\n performance.measure(\n performanceMeasures.routeChangeToRender,\n navStartEntries[0].name,\n performanceMarks.beforeRender\n )\n performance.measure(\n performanceMeasures.render,\n performanceMarks.beforeRender,\n performanceMarks.afterRender\n )\n if (onPerfEntry) {\n performance\n .getEntriesByName(performanceMeasures.render)\n .forEach(onPerfEntry)\n performance\n .getEntriesByName(performanceMeasures.routeChangeToRender)\n .forEach(onPerfEntry)\n }\n }\n\n clearMarks()\n ;[\n performanceMeasures.routeChangeToRender,\n performanceMeasures.render,\n ].forEach((measure) => performance.clearMeasures(measure))\n}\n\nfunction renderReactElement(\n domEl: HTMLElement,\n fn: (cb: () => void) => JSX.Element\n): void {\n // mark start of hydrate/render\n if (ST) {\n performance.mark(performanceMarks.beforeRender)\n }\n\n const reactEl = fn(shouldHydrate ? markHydrateComplete : markRenderComplete)\n if (!reactRoot) {\n // Unlike with createRoot, you don't need a separate root.render() call here\n reactRoot = ReactDOM.hydrateRoot(domEl, reactEl, {\n onRecoverableError,\n })\n // TODO: Remove shouldHydrate variable when React 18 is stable as it can depend on `reactRoot` existing\n shouldHydrate = false\n } else {\n const startTransition = (React as any).startTransition\n startTransition(() => {\n reactRoot.render(reactEl)\n })\n }\n}\n\nfunction Root({\n callbacks,\n children,\n}: React.PropsWithChildren<{\n callbacks: Array<() => void>\n}>): React.ReactElement {\n // We use `useLayoutEffect` to guarantee the callbacks are executed\n // as soon as React flushes the update\n React.useLayoutEffect(\n () => callbacks.forEach((callback) => callback()),\n [callbacks]\n )\n\n if (process.env.__NEXT_TEST_MODE) {\n // eslint-disable-next-line react-hooks/rules-of-hooks\n React.useEffect(() => {\n window.__NEXT_HYDRATED = true\n window.__NEXT_HYDRATED_AT = performance.now()\n\n if (window.__NEXT_HYDRATED_CB) {\n window.__NEXT_HYDRATED_CB()\n }\n }, [])\n }\n\n return children as React.ReactElement\n}\n\nfunction doRender(input: RenderRouteInfo): Promise {\n let { App, Component, props, err }: RenderRouteInfo = input\n let styleSheets: StyleSheetTuple[] | undefined =\n 'initial' in input ? undefined : input.styleSheets\n Component = Component || lastAppProps.Component\n props = props || lastAppProps.props\n\n const appProps: AppProps = {\n ...props,\n Component,\n err,\n router,\n }\n // lastAppProps has to be set before ReactDom.render to account for ReactDom throwing an error.\n lastAppProps = appProps\n\n let canceled: boolean = false\n let resolvePromise: () => void\n const renderPromise = new Promise((resolve, reject) => {\n if (lastRenderReject) {\n lastRenderReject()\n }\n resolvePromise = () => {\n lastRenderReject = null\n resolve()\n }\n lastRenderReject = () => {\n canceled = true\n lastRenderReject = null\n\n const error: any = new Error('Cancel rendering route')\n error.cancelled = true\n reject(error)\n }\n })\n\n // This function has a return type to ensure it doesn't start returning a\n // Promise. It should remain synchronous.\n function onStart(): boolean {\n if (\n !styleSheets ||\n // We use `style-loader` in development, so we don't need to do anything\n // unless we're in production:\n process.env.NODE_ENV !== 'production'\n ) {\n return false\n }\n\n const currentStyleTags: HTMLStyleElement[] = looseToArray(\n document.querySelectorAll('style[data-n-href]')\n )\n const currentHrefs: Set = new Set(\n currentStyleTags.map((tag) => tag.getAttribute('data-n-href'))\n )\n\n const noscript: Element | null = document.querySelector(\n 'noscript[data-n-css]'\n )\n const nonce: string | null | undefined =\n noscript?.getAttribute('data-n-css')\n\n styleSheets.forEach(({ href, text }: { href: string; text: any }) => {\n if (!currentHrefs.has(href)) {\n const styleTag = document.createElement('style')\n styleTag.setAttribute('data-n-href', href)\n styleTag.setAttribute('media', 'x')\n\n if (nonce) {\n styleTag.setAttribute('nonce', nonce)\n }\n\n document.head.appendChild(styleTag)\n styleTag.appendChild(document.createTextNode(text))\n }\n })\n return true\n }\n\n function onHeadCommit(): void {\n if (\n // Turbopack has it's own css injection handling, this code ends up removing the CSS.\n !process.env.TURBOPACK &&\n // We use `style-loader` in development, so we don't need to do anything\n // unless we're in production:\n process.env.NODE_ENV === 'production' &&\n // We can skip this during hydration. Running it wont cause any harm, but\n // we may as well save the CPU cycles:\n styleSheets &&\n // Ensure this render was not canceled\n !canceled\n ) {\n const desiredHrefs: Set = new Set(styleSheets.map((s) => s.href))\n const currentStyleTags: HTMLStyleElement[] =\n looseToArray(\n document.querySelectorAll('style[data-n-href]')\n )\n const currentHrefs: string[] = currentStyleTags.map(\n (tag) => tag.getAttribute('data-n-href')!\n )\n\n // Toggle `