Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Safely retrieve router, improve page reload logic #74209

Merged
merged 2 commits into from
Jan 2, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 41 additions & 10 deletions packages/next/src/client/dev/hot-middleware-client.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
import type {
NextRouter,
PrivateRouteInfo,
} from '../../shared/lib/router/router'
import connect from '../components/react-dev-overlay/pages/hot-reloader-client'
import { sendMessage } from '../components/react-dev-overlay/pages/websocket'

// Define a local type for the window.next object
interface NextWindow {
next?: {
router?: NextRouter & {
components: { [pathname: string]: PrivateRouteInfo }
}
}
__nextDevClientId?: string
location: Location
}

declare const window: NextWindow

let reloading = false

export default (mode: 'webpack' | 'turbopack') => {
const devClient = connect(mode)

devClient.subscribeToHmrEvent((obj: any) => {
if (reloading) return
// if we're on an error/404 page, we can't reliably tell if the newly added/removed page
// matches the current path. In that case, assume any added/removed entries should trigger a reload of the current page

// Retrieve the router if it's available
const router = window.next?.router

// Determine if we're on an error page or the router is not initialized
const isOnErrorPage =
window.next.router.pathname === '/404' ||
window.next.router.pathname === '/_error'
!router || router.pathname === '/404' || router.pathname === '/_error'
gurkerl83 marked this conversation as resolved.
Show resolved Hide resolved

switch (obj.action) {
case 'reloadPage': {
Expand All @@ -27,7 +46,13 @@ export default (mode: 'webpack' | 'turbopack') => {
}
case 'removedPage': {
const [page] = obj.data
if (page === window.next.router.pathname || isOnErrorPage) {

// Check if the removed page is the current page
const isCurrentPage = page === router?.pathname

// We enter here if the removed page is currently being viewed
// or if we happen to be on an error page.
if (isCurrentPage || isOnErrorPage) {
sendMessage(
JSON.stringify({
event: 'client-removed-page',
Expand All @@ -41,11 +66,17 @@ export default (mode: 'webpack' | 'turbopack') => {
}
case 'addedPage': {
const [page] = obj.data
if (
(page === window.next.router.pathname &&
typeof window.next.router.components[page] === 'undefined') ||
isOnErrorPage
) {

// Check if the added page is the current page
const isCurrentPage = page === router?.pathname

// Check if the page component is not yet loaded
const isPageNotLoaded =
typeof router?.components?.[page] === 'undefined'

// We enter this block if the newly added page is the one currently being viewed
// but hasn't been loaded yet, or if we're on an error page.
if ((isCurrentPage && isPageNotLoaded) || isOnErrorPage) {
sendMessage(
JSON.stringify({
event: 'client-added-page',
Expand Down
Loading