Repository: vercel/next.js
Pull request #77890: Turbopack: handle removed routes
Author: login: sokra
Labels: name: Turbopack
description: Related to Turbopack with Next.js.
name: created-by: Turbopack team
description: PRs by the Turbopack team.
name: locked
name: tests
Created: 2025-04-07T10:16:04Z | Merged: 2025-04-08T08:55:28Z

### Why?

Before `get_endpoints` gives you a lot of `Vc<Endpoint>`, which we keep around and subscribe to. That is a problem as endpoint can also vanish at any time. e. g. when the folder is removed.
`Vc<Endpoint>` was not able to represent this state. The subscription throw an error as the Vc is no longer existant. So the error was technically correct here (not a bug in turbo-tasks).
But in practice we don't want to have this error. We want to have a clean end of the subscription without any error. That's why I change it to `Vc<Option<Endpoint>>`, which allows to represent the non-existance of an endpoint.
This can (resp. need to be) handled in subscriptions, which can report e. g. a `NotFound` result or a change event (for server_changed).

### What?

avoid having inactive Vcs when routes are removed.

instead use an `Option<Endpoint>` to allow respresenting removed endpoints and handle these in subscriptions correctly.

Closes PACK-4291


Diff:
diff --git a/crates/napi/src/next_api/endpoint.rs b/crates/napi/src/next_api/endpoint.rs
index 74712fa58589..9aa75aa661d6 100644
--- a/crates/napi/src/next_api/endpoint.rs
+++ b/crates/napi/src/next_api/endpoint.rs
@@ -3,10 +3,11 @@ use std::{ops::Deref, sync::Arc};
 use anyhow::Result;
 use napi::{bindgen_prelude::External, JsFunction};
 use next_api::{
+    operation::OptionEndpoint,
     paths::ServerPath,
     route::{
-        endpoint_server_changed_operation, endpoint_write_to_disk_operation, Endpoint,
-        EndpointOutputPaths,
+        endpoint_client_changed_operation, endpoint_server_changed_operation,
+        endpoint_write_to_disk_operation, EndpointOutputPaths,
     },
 };
 use tracing::Instrument;
@@ -71,7 +72,7 @@ impl From<Option<EndpointOutputPaths>> for NapiWrittenEndpoint {
                 server_paths: server_paths.into_iter().map(From::from).collect(),
                 ..Default::default()
             },
-            None => Self {
+            Some(EndpointOutputPaths::NotFound) | None => Self {
                 r#type: "none".to_string(),
                 ..Default::default()
             },
@@ -85,10 +86,10 @@ impl From<Option<EndpointOutputPaths>> for NapiWrittenEndpoint {
 //    some async functions (in this case `endpoint_write_to_disk`) can cause
 //    higher-ranked lifetime errors. See https://github.com/rust-lang/rust/issues/102211
 // 2. the type_complexity clippy lint.
-pub struct ExternalEndpoint(pub VcArc<Box<dyn Endpoint>>);
+pub struct ExternalEndpoint(pub VcArc<OptionEndpoint>);
 
 impl Deref for ExternalEndpoint {
-    type Target = VcArc<Box<dyn Endpoint>>;
+    type Target = VcArc<OptionEndpoint>;
 
     fn deref(&self) -> &Self::Target {
         &self.0
@@ -105,7 +106,7 @@ struct WrittenEndpointWithIssues {
 
 #[turbo_tasks::function(operation)]
 async fn get_written_endpoint_with_issues_operation(
-    endpoint_op: OperationVc<Box<dyn Endpoint>>,
+    endpoint_op: OperationVc<OptionEndpoint>,
 ) -> Result<Vc<WrittenEndpointWithIssues>> {
     let write_to_disk_op = endpoint_write_to_disk_operation(endpoint_op);
     let (written, issues, diagnostics, effects) =
@@ -214,7 +215,7 @@ impl Eq for EndpointIssuesAndDiags {}
 
 #[turbo_tasks::function(operation)]
 async fn subscribe_issues_and_diags_operation(
-    endpoint_op: OperationVc<Box<dyn Endpoint>>,
+    endpoint_op: OperationVc<OptionEndpoint>,
     should_include_issues: bool,
 ) -> Result<Vc<EndpointIssuesAndDiags>> {
     let changed_op = endpoint_server_changed_operation(endpoint_op);
@@ -241,13 +242,6 @@ async fn subscribe_issues_and_diags_operation(
     }
 }
 
-#[turbo_tasks::function(operation)]
-fn endpoint_client_changed_operation(
-    endpoint_op: OperationVc<Box<dyn Endpoint>>,
-) -> Vc<Completion> {
-    endpoint_op.connect().client_changed()
-}
-
 #[napi(ts_return_type = "{ __napiType: \"RootTask\" }")]
 pub fn endpoint_client_changed_subscribe(
     #[napi(ts_arg_type = "{ __napiType: \"Endpoint\" }")] endpoint: External<ExternalEndpoint>,
diff --git a/crates/napi/src/next_api/project.rs b/crates/napi/src/next_api/project.rs
index 2dc4f553f953..155bbb70b583 100644
--- a/crates/napi/src/next_api/project.rs
+++ b/crates/napi/src/next_api/project.rs
@@ -9,7 +9,8 @@ use napi::{
 use next_api::{
     entrypoints::Entrypoints,
     operation::{
-        EntrypointsOperation, InstrumentationOperation, MiddlewareOperation, RouteOperation,
+        EntrypointsOperation, InstrumentationOperation, MiddlewareOperation, OptionEndpoint,
+        RouteOperation,
     },
     project::{
         DefineEnv, DraftModeOptions, PartialProjectOptions, Project, ProjectContainer,
@@ -580,7 +581,7 @@ pub struct NapiRoute {
 
 impl NapiRoute {
     fn from_route(pathname: String, value: RouteOperation, turbo_tasks: &NextTurboTasks) -> Self {
-        let convert_endpoint = |endpoint: OperationVc<Box<dyn Endpoint>>| {
+        let convert_endpoint = |endpoint: OperationVc<OptionEndpoint>| {
             Some(External::new(ExternalEndpoint(VcArc::new(
                 turbo_tasks.clone(),
                 endpoint,
diff --git a/crates/next-api/src/operation.rs b/crates/next-api/src/operation.rs
index db04f0928a69..ad9c28667d01 100644
--- a/crates/next-api/src/operation.rs
+++ b/crates/next-api/src/operation.rs
@@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
 use turbo_rcstr::RcStr;
 use turbo_tasks::{
     debug::ValueDebugFormat, get_effects, trace::TraceRawVcs, CollectiblesSource, FxIndexMap,
-    NonLocalValue, OperationVc, ResolvedVc, Vc,
+    NonLocalValue, OperationValue, OperationVc, ResolvedVc, TaskInput, Vc,
 };
 use turbopack_core::{diagnostics::Diagnostic, issue::IssueDescriptionExt};
 
@@ -25,9 +25,9 @@ pub struct EntrypointsOperation {
     pub routes: FxIndexMap<RcStr, RouteOperation>,
     pub middleware: Option<MiddlewareOperation>,
     pub instrumentation: Option<InstrumentationOperation>,
-    pub pages_document_endpoint: OperationVc<Box<dyn Endpoint>>,
-    pub pages_app_endpoint: OperationVc<Box<dyn Endpoint>>,
-    pub pages_error_endpoint: OperationVc<Box<dyn Endpoint>>,
+    pub pages_document_endpoint: OperationVc<OptionEndpoint>,
+    pub pages_app_endpoint: OperationVc<OptionEndpoint>,
+    pub pages_error_endpoint: OperationVc<OptionEndpoint>,
 }
 
 /// Removes diagnostics, issues, and effects from the top-level `entrypoints` operation so that
@@ -53,96 +53,181 @@ impl EntrypointsOperation {
             routes: e
                 .routes
                 .iter()
-                .map(|(k, v)| (k.clone(), wrap_route(v, entrypoints)))
+                .map(|(k, v)| (k.clone(), pick_route(entrypoints, k.clone(), v)))
                 .collect(),
-            middleware: e.middleware.as_ref().map(|m| MiddlewareOperation {
-                endpoint: wrap(m.endpoint, entrypoints),
+            middleware: e.middleware.as_ref().map(|_| MiddlewareOperation {
+                endpoint: pick_endpoint(entrypoints, EndpointSelector::Middleware),
             }),
             instrumentation: e
                 .instrumentation
                 .as_ref()
-                .map(|i| InstrumentationOperation {
-                    node_js: wrap(i.node_js, entrypoints),
-                    edge: wrap(i.edge, entrypoints),
+                .map(|_| InstrumentationOperation {
+                    node_js: pick_endpoint(entrypoints, EndpointSelector::InstrumentationNodeJs),
+                    edge: pick_endpoint(entrypoints, EndpointSelector::InstrumentationEdge),
                 }),
-            pages_document_endpoint: wrap(e.pages_document_endpoint, entrypoints),
-            pages_app_endpoint: wrap(e.pages_app_endpoint, entrypoints),
-            pages_error_endpoint: wrap(e.pages_error_endpoint, entrypoints),
+            pages_document_endpoint: pick_endpoint(entrypoints, EndpointSelector::PagesDocument),
+            pages_app_endpoint: pick_endpoint(entrypoints, EndpointSelector::PagesApp),
+            pages_error_endpoint: pick_endpoint(entrypoints, EndpointSelector::PagesError),
         }
         .cell())
     }
 }
 
-fn wrap_route(route: &Route, entrypoints: OperationVc<Entrypoints>) -> RouteOperation {
+fn pick_route(entrypoints: OperationVc<Entrypoints>, key: RcStr, route: &Route) -> RouteOperation {
     match route {
-        Route::Page {
-            html_endpoint,
-            data_endpoint,
-        } => RouteOperation::Page {
-            html_endpoint: wrap(*html_endpoint, entrypoints),
-            data_endpoint: wrap(*data_endpoint, entrypoints),
+        Route::Page { .. } => RouteOperation::Page {
+            html_endpoint: pick_endpoint(entrypoints, EndpointSelector::RoutePageHtml(key.clone())),
+            data_endpoint: pick_endpoint(entrypoints, EndpointSelector::RoutePageData(key)),
         },
-        Route::PageApi { endpoint } => RouteOperation::PageApi {
-            endpoint: wrap(*endpoint, entrypoints),
+        Route::PageApi { .. } => RouteOperation::PageApi {
+            endpoint: pick_endpoint(entrypoints, EndpointSelector::RoutePageApi(key)),
         },
         Route::AppPage(pages) => RouteOperation::AppPage(
             pages
                 .iter()
-                .map(|p| AppPageRouteOperation {
+                .enumerate()
+                .map(|(i, p)| AppPageRouteOperation {
                     original_name: p.original_name.clone(),
-                    html_endpoint: wrap(p.html_endpoint, entrypoints),
-                    rsc_endpoint: wrap(p.rsc_endpoint, entrypoints),
+                    html_endpoint: pick_endpoint(
+                        entrypoints,
+                        EndpointSelector::RouteAppPageHtml(key.clone(), i),
+                    ),
+                    rsc_endpoint: pick_endpoint(
+                        entrypoints,
+                        EndpointSelector::RouteAppPageRsc(key.clone(), i),
+                    ),
                 })
                 .collect(),
         ),
-        Route::AppRoute {
-            original_name,
-            endpoint,
-        } => RouteOperation::AppRoute {
+        Route::AppRoute { original_name, .. } => RouteOperation::AppRoute {
             original_name: original_name.clone(),
-            endpoint: wrap(*endpoint, entrypoints),
+            endpoint: pick_endpoint(entrypoints, EndpointSelector::RouteAppRoute(key)),
         },
         Route::Conflict => RouteOperation::Conflict,
     }
 }
 
-/// Given a resolved `Endpoint` and the `Entrypoints` operation that it comes from, connect the
-/// operation and return a `OperationVc` of the `Entrypoint`. This `Endpoint` operation will keep
-/// the entire `Entrypoints` operation alive.
+#[derive(
+    Debug,
+    Clone,
+    TaskInput,
+    Serialize,
+    Deserialize,
+    TraceRawVcs,
+    PartialEq,
+    Eq,
+    Hash,
+    ValueDebugFormat,
+    NonLocalValue,
+    OperationValue,
+)]
+enum EndpointSelector {
+    RoutePageHtml(RcStr),
+    RoutePageData(RcStr),
+    RoutePageApi(RcStr),
+    RouteAppPageHtml(RcStr, usize),
+    RouteAppPageRsc(RcStr, usize),
+    RouteAppRoute(RcStr),
+    InstrumentationNodeJs,
+    InstrumentationEdge,
+    Middleware,
+    PagesDocument,
+    PagesApp,
+    PagesError,
+}
+
+#[turbo_tasks::value(transparent)]
+pub struct OptionEndpoint(Option<ResolvedVc<Box<dyn Endpoint>>>);
+
+/// Given a selector and the `Entrypoints` operation that it comes from, connect the operation and
+/// return an `OperationVc` containing the selected value. The returned operation will keep the
+/// entire `Entrypoints` operation alive.
 #[turbo_tasks::function(operation)]
-fn wrap(
-    endpoint: ResolvedVc<Box<dyn Endpoint>>,
+async fn pick_endpoint(
     op: OperationVc<Entrypoints>,
-) -> Vc<Box<dyn Endpoint>> {
-    let _ = op.connect();
-    *endpoint
+    selector: EndpointSelector,
+) -> Result<Vc<OptionEndpoint>> {
+    let endpoints = op.connect().strongly_consistent().await?;
+    let endpoint = match selector {
+        EndpointSelector::InstrumentationNodeJs => {
+            endpoints.instrumentation.as_ref().map(|i| i.node_js)
+        }
+        EndpointSelector::InstrumentationEdge => endpoints.instrumentation.as_ref().map(|i| i.edge),
+        EndpointSelector::Middleware => endpoints.middleware.as_ref().map(|m| m.endpoint),
+        EndpointSelector::PagesDocument => Some(endpoints.pages_document_endpoint),
+        EndpointSelector::PagesApp => Some(endpoints.pages_app_endpoint),
+        EndpointSelector::PagesError => Some(endpoints.pages_error_endpoint),
+        EndpointSelector::RoutePageHtml(name) => {
+            if let Some(Route::Page { html_endpoint, .. }) = endpoints.routes.get(&name) {
+                Some(*html_endpoint)
+            } else {
+                None
+            }
+        }
+        EndpointSelector::RoutePageData(name) => {
+            if let Some(Route::Page { data_endpoint, .. }) = endpoints.routes.get(&name) {
+                Some(*data_endpoint)
+            } else {
+                None
+            }
+        }
+        EndpointSelector::RoutePageApi(name) => {
+            if let Some(Route::PageApi { endpoint }) = endpoints.routes.get(&name) {
+                Some(*endpoint)
+            } else {
+                None
+            }
+        }
+        EndpointSelector::RouteAppPageHtml(name, i) => {
+            if let Some(Route::AppPage(pages)) = endpoints.routes.get(&name) {
+                pages.get(i).as_ref().map(|p| p.html_endpoint)
+            } else {
+                None
+            }
+        }
+        EndpointSelector::RouteAppPageRsc(name, i) => {
+            if let Some(Route::AppPage(pages)) = endpoints.routes.get(&name) {
+                pages.get(i).as_ref().map(|p| p.rsc_endpoint)
+            } else {
+                None
+            }
+        }
+        EndpointSelector::RouteAppRoute(name) => {
+            if let Some(Route::AppRoute { endpoint, .. }) = endpoints.routes.get(&name) {
+                Some(*endpoint)
+            } else {
+                None
+            }
+        }
+    };
+    Ok(Vc::cell(endpoint))
 }
 
 #[derive(Serialize, Deserialize, TraceRawVcs, PartialEq, Eq, ValueDebugFormat, NonLocalValue)]
 pub struct InstrumentationOperation {
-    pub node_js: OperationVc<Box<dyn Endpoint>>,
-    pub edge: OperationVc<Box<dyn Endpoint>>,
+    pub node_js: OperationVc<OptionEndpoint>,
+    pub edge: OperationVc<OptionEndpoint>,
 }
 
 #[derive(Serialize, Deserialize, TraceRawVcs, PartialEq, Eq, ValueDebugFormat, NonLocalValue)]
 pub struct MiddlewareOperation {
-    pub endpoint: OperationVc<Box<dyn Endpoint>>,
+    pub endpoint: OperationVc<OptionEndpoint>,
 }
 
 #[turbo_tasks::value(shared)]
 #[derive(Clone, Debug)]
 pub enum RouteOperation {
     Page {
-        html_endpoint: OperationVc<Box<dyn Endpoint>>,
-        data_endpoint: OperationVc<Box<dyn Endpoint>>,
+        html_endpoint: OperationVc<OptionEndpoint>,
+        data_endpoint: OperationVc<OptionEndpoint>,
     },
     PageApi {
-        endpoint: OperationVc<Box<dyn Endpoint>>,
+        endpoint: OperationVc<OptionEndpoint>,
     },
     AppPage(Vec<AppPageRouteOperation>),
     AppRoute {
         original_name: RcStr,
-        endpoint: OperationVc<Box<dyn Endpoint>>,
+        endpoint: OperationVc<OptionEndpoint>,
     },
     Conflict,
 }
@@ -160,6 +245,6 @@ pub enum RouteOperation {
 )]
 pub struct AppPageRouteOperation {
     pub original_name: RcStr,
-    pub html_endpoint: OperationVc<Box<dyn Endpoint>>,
-    pub rsc_endpoint: OperationVc<Box<dyn Endpoint>>,
+    pub html_endpoint: OperationVc<OptionEndpoint>,
+    pub rsc_endpoint: OperationVc<OptionEndpoint>,
 }
diff --git a/crates/next-api/src/route.rs b/crates/next-api/src/route.rs
index 987e36a511ad..c6baa51efd46 100644
--- a/crates/next-api/src/route.rs
+++ b/crates/next-api/src/route.rs
@@ -10,7 +10,7 @@ use turbopack_core::{
     output::OutputAssets,
 };
 
-use crate::{paths::ServerPath, project::Project};
+use crate::{operation::OptionEndpoint, paths::ServerPath, project::Project};
 
 #[derive(
     TraceRawVcs,
@@ -97,17 +97,36 @@ async fn endpoint_output_assets_operation(
 }
 
 #[turbo_tasks::function(operation)]
-pub fn endpoint_write_to_disk_operation(
-    endpoint: OperationVc<Box<dyn Endpoint>>,
-) -> Vc<EndpointOutputPaths> {
-    endpoint_write_to_disk(endpoint.connect())
+pub async fn endpoint_write_to_disk_operation(
+    endpoint: OperationVc<OptionEndpoint>,
+) -> Result<Vc<EndpointOutputPaths>> {
+    Ok(if let Some(endpoint) = *endpoint.connect().await? {
+        endpoint_write_to_disk(*endpoint)
+    } else {
+        EndpointOutputPaths::NotFound.cell()
+    })
+}
+
+#[turbo_tasks::function(operation)]
+pub async fn endpoint_server_changed_operation(
+    endpoint: OperationVc<OptionEndpoint>,
+) -> Result<Vc<Completion>> {
+    Ok(if let Some(endpoint) = *endpoint.connect().await? {
+        endpoint.server_changed()
+    } else {
+        Completion::new()
+    })
 }
 
 #[turbo_tasks::function(operation)]
-pub fn endpoint_server_changed_operation(
-    endpoint: OperationVc<Box<dyn Endpoint>>,
-) -> Vc<Completion> {
-    endpoint.connect().server_changed()
+pub async fn endpoint_client_changed_operation(
+    endpoint: OperationVc<OptionEndpoint>,
+) -> Result<Vc<Completion>> {
+    Ok(if let Some(endpoint) = *endpoint.connect().await? {
+        endpoint.client_changed()
+    } else {
+        Completion::new()
+    })
 }
 
 #[turbo_tasks::value(shared)]
@@ -131,6 +150,7 @@ pub enum EndpointOutputPaths {
         server_paths: Vec<ServerPath>,
         client_paths: Vec<RcStr>,
     },
+    NotFound,
 }
 
 /// The routes as map from pathname to route. (pathname includes the leading
diff --git a/test/development/app-hmr/hmr.test.ts b/test/development/app-hmr/hmr.test.ts
index 63a4a99a2361..0da35d0bb65d 100644
--- a/test/development/app-hmr/hmr.test.ts
+++ b/test/development/app-hmr/hmr.test.ts
@@ -50,6 +50,8 @@ describe(`app-dir-hmr`, () => {
         // The new page should be rendered
         const newHTML = await next.render('/folder-renamed')
         expect(newHTML).toContain('Hello')
+
+        expect(next.cliOutput).not.toContain('FATAL')
       } finally {
         // Rename it back
         await next.renameFolder('app/folder-renamed', 'app/folder')
@@ -89,7 +91,6 @@ describe(`app-dir-hmr`, () => {
         // details are unimportant.
         expect(fastRefreshLogs).toEqual(
           expect.arrayContaining([
-            { source: 'log', message: '[Fast Refresh] rebuilding' },
             {
               source: 'log',
               message: expect.stringContaining('[Fast Refresh] done in '),
@@ -102,6 +103,8 @@ describe(`app-dir-hmr`, () => {
       await retry(async () => {
         expect(await browser.elementByCss('p').text()).toBe('mac')
       })
+
+      expect(next.cliOutput).not.toContain('FATAL')
     })
 
     it.each(['node', 'node-module-var', 'edge', 'edge-module-var'])(
@@ -118,7 +121,7 @@ describe(`app-dir-hmr`, () => {
             expect(logs).toEqual(
               expect.arrayContaining([
                 expect.objectContaining({
-                  message: '[Fast Refresh] rebuilding',
+                  message: expect.stringContaining('[Fast Refresh] done'),
                   source: 'log',
                 }),
               ])
@@ -143,6 +146,8 @@ describe(`app-dir-hmr`, () => {
         await retry(async () => {
           expect(await browser.elementByCss('p').text()).toBe('mac')
         })
+
+        expect(next.cliOutput).not.toContain('FATAL')
       }
     )
 
@@ -168,10 +173,6 @@ describe(`app-dir-hmr`, () => {
       // TODO: Should assert on all logs but these are cluttered with logs from our test utils (e.g. playwright tracing or webdriver)
       expect(logs).toEqual(
         expect.arrayContaining([
-          {
-            message: '[Fast Refresh] rebuilding',
-            source: 'log',
-          },
           {
             message: expect.stringContaining('[Fast Refresh] done in'),
             source: 'log',
@@ -187,6 +188,8 @@ describe(`app-dir-hmr`, () => {
       )
       // No MPA navigation triggered
       expect(await browser.eval('window.__TEST_NO_RELOAD')).toEqual(true)
+
+      expect(next.cliOutput).not.toContain('FATAL')
     })
   })
 })


Reviews:
user: login: greptile-apps[bot]
body: 
## PR Summary

This PR refactors endpoint handling by introducing `OptionEndpoint` to represent removed endpoints, thereby eliminating inactive Vcs and ensuring subscriptions handle missing routes correctly.

- Updated endpoint wrapping in `/crates/next-api/src/operation.rs` to use `OperationVc<OptionEndpoint>` with async handling.
- Revised conversion logic and type annotations in `/crates/napi/src/next_api/endpoint.rs` to account for NotFound cases.
- Transformed route endpoint conversion in `/crates/napi/src/next_api/project.rs` to integrate the new `OptionEndpoint`.
- Modified signature and async handling in `/crates/next-api/src/route.rs` for uniform endpoint state management.
- Adjusted HMR tests in `/test/development/app-hmr/hmr.test.ts` to validate changes without triggering fatal errors.

<sub>💡 (3/5) Reply to the bot's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>

<sub>5 file(s) reviewed, no comment(s)</sub>
<sub>[Edit PR Review Bot Settings](https://app.greptile.com/review/github) | [Greptile](https://greptile.com?utm_source=greptile_expert&utm_medium=github&utm_campaign=code_reviews&utm_content=next.js_77890)</sub>
state: COMMENTED
author_association: NONE
submitted_at: 2025-04-07T10:20:13Z
user: login: bgw
body: Nice! Is there a specific known issue this fixes, or is this just fixing a theoretical bug?
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-07T17:39:25Z
user: login: mischnic
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-08T06:24:26Z
user: login: sokra
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T07:59:14Z

Review comments:
diff_hunk: @@ -53,96 +53,181 @@ impl EntrypointsOperation {
             routes: e
                 .routes
                 .iter()
-                .map(|(k, v)| (k.clone(), wrap_route(v, entrypoints)))
+                .map(|(k, v)| (k.clone(), pick_route(entrypoints, k.clone(), v)))
                 .collect(),
-            middleware: e.middleware.as_ref().map(|m| MiddlewareOperation {
-                endpoint: wrap(m.endpoint, entrypoints),
+            middleware: e.middleware.as_ref().map(|_| MiddlewareOperation {
+                endpoint: pick_endpoint(entrypoints, EndpointSelector::Middleware),
             }),
             instrumentation: e
                 .instrumentation
                 .as_ref()
-                .map(|i| InstrumentationOperation {
-                    node_js: wrap(i.node_js, entrypoints),
-                    edge: wrap(i.edge, entrypoints),
+                .map(|_| InstrumentationOperation {
+                    node_js: pick_endpoint(entrypoints, EndpointSelector::InstrumentationNodeJs),
+                    edge: pick_endpoint(entrypoints, EndpointSelector::InstrumentationEdge),
                 }),
-            pages_document_endpoint: wrap(e.pages_document_endpoint, entrypoints),
-            pages_app_endpoint: wrap(e.pages_app_endpoint, entrypoints),
-            pages_error_endpoint: wrap(e.pages_error_endpoint, entrypoints),
+            pages_document_endpoint: pick_endpoint(entrypoints, EndpointSelector::PagesDocument),
+            pages_app_endpoint: pick_endpoint(entrypoints, EndpointSelector::PagesApp),
+            pages_error_endpoint: pick_endpoint(entrypoints, EndpointSelector::PagesError),
         }
         .cell())
     }
 }
 
-fn wrap_route(route: &Route, entrypoints: OperationVc<Entrypoints>) -> RouteOperation {
+fn pick_route(entrypoints: OperationVc<Entrypoints>, key: RcStr, route: &Route) -> RouteOperation {
     match route {
-        Route::Page {
-            html_endpoint,
-            data_endpoint,
-        } => RouteOperation::Page {
-            html_endpoint: wrap(*html_endpoint, entrypoints),
-            data_endpoint: wrap(*data_endpoint, entrypoints),
+        Route::Page { .. } => RouteOperation::Page {
+            html_endpoint: pick_endpoint(entrypoints, EndpointSelector::RoutePageHtml(key.clone())),
+            data_endpoint: pick_endpoint(entrypoints, EndpointSelector::RoutePageData(key)),
         },
-        Route::PageApi { endpoint } => RouteOperation::PageApi {
-            endpoint: wrap(*endpoint, entrypoints),
+        Route::PageApi { .. } => RouteOperation::PageApi {
+            endpoint: pick_endpoint(entrypoints, EndpointSelector::RoutePageApi(key)),
         },
         Route::AppPage(pages) => RouteOperation::AppPage(
             pages
                 .iter()
-                .map(|p| AppPageRouteOperation {
+                .enumerate()
+                .map(|(i, p)| AppPageRouteOperation {
                     original_name: p.original_name.clone(),
-                    html_endpoint: wrap(p.html_endpoint, entrypoints),
-                    rsc_endpoint: wrap(p.rsc_endpoint, entrypoints),
+                    html_endpoint: pick_endpoint(
+                        entrypoints,
+                        EndpointSelector::RouteAppPageHtml(key.clone(), i),
+                    ),
+                    rsc_endpoint: pick_endpoint(
+                        entrypoints,
+                        EndpointSelector::RouteAppPageRsc(key.clone(), i),
+                    ),
                 })
                 .collect(),
         ),
-        Route::AppRoute {
-            original_name,
-            endpoint,
-        } => RouteOperation::AppRoute {
+        Route::AppRoute { original_name, .. } => RouteOperation::AppRoute {
             original_name: original_name.clone(),
-            endpoint: wrap(*endpoint, entrypoints),
+            endpoint: pick_endpoint(entrypoints, EndpointSelector::RouteAppRoute(key)),
         },
         Route::Conflict => RouteOperation::Conflict,
     }
 }
 
+#[derive(
+    Debug,
+    Clone,
+    TaskInput,
+    Serialize,
+    Deserialize,
+    TraceRawVcs,
+    PartialEq,
+    Eq,
+    Hash,
+    ValueDebugFormat,
+    NonLocalValue,
+    OperationValue,
+)]
+enum EndpointSelector {
+    RoutePageHtml(RcStr),
+    RoutePageData(RcStr),
+    RoutePageApi(RcStr),
+    RouteAppPageHtml(RcStr, usize),
+    RouteAppPageRsc(RcStr, usize),
+    RouteAppRoute(RcStr),
+    InstrumentationNodeJs,
+    InstrumentationEdge,
+    Middleware,
+    PagesDocument,
+    PagesApp,
+    PagesError,
+}
+
+#[turbo_tasks::value(transparent)]
+pub struct OptionEndpoint(Option<ResolvedVc<Box<dyn Endpoint>>>);
+
 /// Given a resolved `Endpoint` and the `Entrypoints` operation that it comes from, connect the
 /// operation and return a `OperationVc` of the `Entrypoint`. This `Endpoint` operation will keep
 /// the entire `Entrypoints` operation alive.
path: crates/next-api/src/operation.rs
user: login: bgw
body: ```suggestion
/// Given a selector and the `Entrypoints` operation that it comes from, connect the operation and
/// return an `OperationVc` containing the selected value. The returned operation will keep the
/// entire `Entrypoints` operation alive.
```
created_at: 2025-04-07T17:38:37Z
author_association: MEMBER
diff_hunk: @@ -53,96 +53,181 @@ impl EntrypointsOperation {
             routes: e
                 .routes
                 .iter()
-                .map(|(k, v)| (k.clone(), wrap_route(v, entrypoints)))
+                .map(|(k, v)| (k.clone(), pick_route(entrypoints, k.clone(), v)))
                 .collect(),
-            middleware: e.middleware.as_ref().map(|m| MiddlewareOperation {
-                endpoint: wrap(m.endpoint, entrypoints),
+            middleware: e.middleware.as_ref().map(|_| MiddlewareOperation {
+                endpoint: pick_endpoint(entrypoints, EndpointSelector::Middleware),
             }),
             instrumentation: e
                 .instrumentation
                 .as_ref()
-                .map(|i| InstrumentationOperation {
-                    node_js: wrap(i.node_js, entrypoints),
-                    edge: wrap(i.edge, entrypoints),
+                .map(|_| InstrumentationOperation {
+                    node_js: pick_endpoint(entrypoints, EndpointSelector::InstrumentationNodeJs),
+                    edge: pick_endpoint(entrypoints, EndpointSelector::InstrumentationEdge),
                 }),
-            pages_document_endpoint: wrap(e.pages_document_endpoint, entrypoints),
-            pages_app_endpoint: wrap(e.pages_app_endpoint, entrypoints),
-            pages_error_endpoint: wrap(e.pages_error_endpoint, entrypoints),
+            pages_document_endpoint: pick_endpoint(entrypoints, EndpointSelector::PagesDocument),
+            pages_app_endpoint: pick_endpoint(entrypoints, EndpointSelector::PagesApp),
+            pages_error_endpoint: pick_endpoint(entrypoints, EndpointSelector::PagesError),
         }
         .cell())
     }
 }
 
-fn wrap_route(route: &Route, entrypoints: OperationVc<Entrypoints>) -> RouteOperation {
+fn pick_route(entrypoints: OperationVc<Entrypoints>, key: RcStr, route: &Route) -> RouteOperation {
     match route {
-        Route::Page {
-            html_endpoint,
-            data_endpoint,
-        } => RouteOperation::Page {
-            html_endpoint: wrap(*html_endpoint, entrypoints),
-            data_endpoint: wrap(*data_endpoint, entrypoints),
+        Route::Page { .. } => RouteOperation::Page {
+            html_endpoint: pick_endpoint(entrypoints, EndpointSelector::RoutePageHtml(key.clone())),
+            data_endpoint: pick_endpoint(entrypoints, EndpointSelector::RoutePageData(key)),
         },
-        Route::PageApi { endpoint } => RouteOperation::PageApi {
-            endpoint: wrap(*endpoint, entrypoints),
+        Route::PageApi { .. } => RouteOperation::PageApi {
+            endpoint: pick_endpoint(entrypoints, EndpointSelector::RoutePageApi(key)),
         },
         Route::AppPage(pages) => RouteOperation::AppPage(
             pages
                 .iter()
-                .map(|p| AppPageRouteOperation {
+                .enumerate()
+                .map(|(i, p)| AppPageRouteOperation {
                     original_name: p.original_name.clone(),
-                    html_endpoint: wrap(p.html_endpoint, entrypoints),
-                    rsc_endpoint: wrap(p.rsc_endpoint, entrypoints),
+                    html_endpoint: pick_endpoint(
+                        entrypoints,
+                        EndpointSelector::RouteAppPageHtml(key.clone(), i),
+                    ),
+                    rsc_endpoint: pick_endpoint(
+                        entrypoints,
+                        EndpointSelector::RouteAppPageRsc(key.clone(), i),
+                    ),
                 })
                 .collect(),
         ),
-        Route::AppRoute {
-            original_name,
-            endpoint,
-        } => RouteOperation::AppRoute {
+        Route::AppRoute { original_name, .. } => RouteOperation::AppRoute {
             original_name: original_name.clone(),
-            endpoint: wrap(*endpoint, entrypoints),
+            endpoint: pick_endpoint(entrypoints, EndpointSelector::RouteAppRoute(key)),
         },
         Route::Conflict => RouteOperation::Conflict,
     }
 }
 
-/// Given a resolved `Endpoint` and the `Entrypoints` operation that it comes from, connect the
-/// operation and return a `OperationVc` of the `Entrypoint`. This `Endpoint` operation will keep
-/// the entire `Entrypoints` operation alive.
+#[derive(
+    Debug,
+    Clone,
+    TaskInput,
+    Serialize,
+    Deserialize,
+    TraceRawVcs,
+    PartialEq,
+    Eq,
+    Hash,
+    ValueDebugFormat,
+    NonLocalValue,
+    OperationValue,
+)]
+enum EndpointSelector {
+    RoutePageHtml(RcStr),
+    RoutePageData(RcStr),
+    RoutePageApi(RcStr),
+    RouteAppPageHtml(RcStr, usize),
+    RouteAppPageRsc(RcStr, usize),
+    RouteAppRoute(RcStr),
+    InstrumentationNodeJs,
+    InstrumentationEdge,
+    Middleware,
+    PagesDocument,
+    PagesApp,
+    PagesError,
+}
+
+#[turbo_tasks::value(transparent)]
+pub struct OptionEndpoint(Option<ResolvedVc<Box<dyn Endpoint>>>);
+
+/// Given a selector and the `Entrypoints` operation that it comes from, connect the operation and
+/// return an `OperationVc` containing the selected value. The returned operation will keep the
+/// entire `Entrypoints` operation alive.
 #[turbo_tasks::function(operation)]
-fn wrap(
-    endpoint: ResolvedVc<Box<dyn Endpoint>>,
+async fn pick_endpoint(
     op: OperationVc<Entrypoints>,
-) -> Vc<Box<dyn Endpoint>> {
path: crates/next-api/src/operation.rs
user: login: sokra
body: @bgw `fn wrap(endpoint: ResolvedVc<Box<dyn Endpoint>>, op: OperationVc<Entrypoints>)` is a problem when `op` not consistently produces `endpoint`. Only `op` no longer produces `endpoint` we end up with a dangling `Vc`.
created_at: 2025-04-08T07:59:14Z
author_association: MEMBER

PR comments:
user: login: sokra
created_at: 2025-04-07T10:16:22Z
body: * **#77890** <a href="https://app.graphite.dev/github/pr/vercel/next.js/77890?utm_source=stack-comment-icon" target="_blank"><img src="https://static.graphite.dev/graphite-32x32-black.png" alt="Graphite" width="10px" height="10px"/></a> 👈 <a href="https://app.graphite.dev/github/pr/vercel/next.js/77890?utm_source=stack-comment-view-in-graphite" target="_blank">(View in Graphite)</a>
* `canary`


<h2></h2>

This stack of pull requests is managed by <a href="https://graphite.dev?utm-source=stack-comment"><b>Graphite</b></a>. Learn more about <a href="https://stacking.dev/?utm_source=stack-comment">stacking</a>.
<!-- Current dependencies on/for this PR: -->
author_association: MEMBER
user: login: ijjk
created_at: 2025-04-07T10:27:59Z
body: # Stats from current PR

<details open>
<summary><strong>Default Build</strong> (Increase detected ⚠️)</summary>

<br/>

<details>
<summary><strong>General</strong></summary>

|  | vercel/next.js canary  | vercel/next.js sokra/handle-removed-routes | Change |
| - | - | - | - |
| buildDuration | 20.3s | 20.5s | ⚠️ +231ms |
| buildDurationCached | 16.7s | 14s | N/A |
| nodeModulesSize | 427 MB | 423 MB | N/A |
| nextStartRea..uration (ms) | 466ms | 464ms | N/A |

</details>

<details>
<summary><strong>Client Bundles (main, webpack)</strong> Overall increase ⚠️</summary>

|  | vercel/next.js canary  | vercel/next.js sokra/handle-removed-routes | Change |
| - | - | - | - |
| 1733-HASH.js gzip | 46.1 kB | 46.6 kB | ⚠️ +564 B |
| 194b18f3-HASH.js gzip | 53.1 kB | 53.1 kB | N/A |
| 2192.HASH.js gzip | 169 B | 169 B | ✓ |
| 4719-HASH.js gzip | 5.47 kB | 5.44 kB | N/A |
| framework-HASH.js gzip | 57.4 kB | 57.4 kB | ✓ |
| main-app-HASH.js gzip | 248 B | 251 B | N/A |
| main-HASH.js gzip | 33.6 kB | 33.7 kB | N/A |
| webpack-HASH.js gzip | 1.71 kB | 1.71 kB | N/A |
| Overall change | 104 kB | 104 kB | ⚠️ +564 B |

</details>

<details>
<summary><strong>Legacy Client Bundles (polyfills)</strong></summary>

|  | vercel/next.js canary  | vercel/next.js sokra/handle-removed-routes | Change |
| - | - | - | - |
| polyfills-HASH.js gzip | 39.4 kB | 39.4 kB | ✓ |
| Overall change | 39.4 kB | 39.4 kB | ✓ |

</details>

<details>
<summary><strong>Client Pages</strong></summary>

|  | vercel/next.js canary  | vercel/next.js sokra/handle-removed-routes | Change |
| - | - | - | - |
| _app-HASH.js gzip | 193 B | 193 B | ✓ |
| _error-HASH.js gzip | 192 B | 192 B | ✓ |
| amp-HASH.js gzip | 510 B | 510 B | ✓ |
| css-HASH.js gzip | 344 B | 342 B | N/A |
| dynamic-HASH.js gzip | 1.84 kB | 1.83 kB | N/A |
| edge-ssr-HASH.js gzip | 265 B | 265 B | ✓ |
| head-HASH.js gzip | 363 B | 364 B | N/A |
| hooks-HASH.js gzip | 392 B | 391 B | N/A |
| image-HASH.js gzip | 4.69 kB | 4.67 kB | N/A |
| index-HASH.js gzip | 267 B | 267 B | ✓ |
| link-HASH.js gzip | 2.53 kB | 2.53 kB | N/A |
| routerDirect..HASH.js gzip | 328 B | 325 B | N/A |
| script-HASH.js gzip | 396 B | 396 B | ✓ |
| withRouter-HASH.js gzip | 325 B | 325 B | ✓ |
| 1afbb74e6ecf..834.css gzip | 106 B | 106 B | ✓ |
| Overall change | 2.25 kB | 2.25 kB | ✓ |

</details>

<details>
<summary><strong>Client Build Manifests</strong></summary>

|  | vercel/next.js canary  | vercel/next.js sokra/handle-removed-routes | Change |
| - | - | - | - |
| _buildManifest.js gzip | 750 B | 752 B | N/A |
| Overall change | 0 B | 0 B | ✓ |

</details>

<details>
<summary><strong>Rendered Page Sizes</strong></summary>

|  | vercel/next.js canary  | vercel/next.js sokra/handle-removed-routes | Change |
| - | - | - | - |
| index.html gzip | 524 B | 525 B | N/A |
| link.html gzip | 537 B | 539 B | N/A |
| withRouter.html gzip | 520 B | 520 B | ✓ |
| Overall change | 520 B | 520 B | ✓ |

</details>

<details>
<summary><strong>Edge SSR bundle Size</strong> Overall increase ⚠️</summary>

|  | vercel/next.js canary  | vercel/next.js sokra/handle-removed-routes | Change |
| - | - | - | - |
| edge-ssr.js gzip | 135 kB | 136 kB | ⚠️ +134 B |
| page.js gzip | 216 kB | 211 kB | N/A |
| Overall change | 135 kB | 136 kB | ⚠️ +134 B |

</details>

<details>
<summary><strong>Middleware size</strong> Overall increase ⚠️</summary>

|  | vercel/next.js canary  | vercel/next.js sokra/handle-removed-routes | Change |
| - | - | - | - |
| middleware-b..fest.js gzip | 678 B | 672 B | N/A |
| middleware-r..fest.js gzip | 155 B | 157 B | N/A |
| middleware.js gzip | 32.3 kB | 32.6 kB | ⚠️ +283 B |
| edge-runtime..pack.js gzip | 844 B | 844 B | ✓ |
| Overall change | 33.1 kB | 33.4 kB | ⚠️ +283 B |

</details>

<details>
<summary><strong>Next Runtimes</strong></summary>

|  | vercel/next.js canary  | vercel/next.js sokra/handle-removed-routes | Change |
| - | - | - | - |
| app-page-exp...dev.js gzip | 314 kB | 314 kB | N/A |
| app-page-exp..prod.js gzip | 143 kB | 143 kB | N/A |
| app-page-tur...dev.js gzip | 314 kB | 314 kB | N/A |
| app-page-tur..prod.js gzip | 143 kB | 143 kB | N/A |
| app-page-tur...dev.js gzip | 306 kB | 306 kB | N/A |
| app-page-tur..prod.js gzip | 140 kB | 140 kB | N/A |
| app-page.run...dev.js gzip | 306 kB | 306 kB | N/A |
| app-page.run..prod.js gzip | 140 kB | 140 kB | N/A |
| app-route-ex...dev.js gzip | 40.7 kB | 40.7 kB | N/A |
| app-route-ex..prod.js gzip | 26.3 kB | 26.3 kB | N/A |
| app-route-tu...dev.js gzip | 40.7 kB | 40.7 kB | N/A |
| app-route-tu..prod.js gzip | 26.4 kB | 26.3 kB | N/A |
| app-route-tu...dev.js gzip | 40 kB | 40 kB | N/A |
| app-route-tu..prod.js gzip | 26 kB | 26 kB | N/A |
| app-route.ru...dev.js gzip | 40 kB | 40 kB | N/A |
| app-route.ru..prod.js gzip | 26 kB | 26 kB | N/A |
| dist_client_...dev.js gzip | 356 B | 356 B | ✓ |
| dist_client_...dev.js gzip | 359 B | 359 B | ✓ |
| dist_client_...dev.js gzip | 351 B | 351 B | ✓ |
| dist_client_...dev.js gzip | 349 B | 349 B | ✓ |
| pages-api-tu...dev.js gzip | 11.9 kB | 11.9 kB | ✓ |
| pages-api-tu..prod.js gzip | 9.76 kB | 9.76 kB | ✓ |
| pages-api.ru...dev.js gzip | 11.9 kB | 11.9 kB | ✓ |
| pages-api.ru..prod.js gzip | 9.75 kB | 9.75 kB | ✓ |
| pages-turbo....dev.js gzip | 31.4 kB | 31.4 kB | ✓ |
| pages-turbo...prod.js gzip | 21.9 kB | 21.9 kB | ✓ |
| pages.runtim...dev.js gzip | 31.6 kB | 31.6 kB | ✓ |
| pages.runtim..prod.js gzip | 22 kB | 22 kB | ✓ |
| server.runti..prod.js gzip | 62.6 kB | 62.6 kB | N/A |
| Overall change | 152 kB | 152 kB | ✓ |

</details>

<details>
<summary><strong>build cache</strong> Overall increase ⚠️</summary>

|  | vercel/next.js canary  | vercel/next.js sokra/handle-removed-routes | Change |
| - | - | - | - |
| 0.pack gzip | 2.17 MB | 2.17 MB | ⚠️ +969 B |
| index.pack gzip | 76.6 kB | 76.9 kB | ⚠️ +278 B |
| Overall change | 2.24 MB | 2.24 MB | ⚠️ +1.25 kB |

</details>

<details>
<summary><strong>Diff details</strong></summary>

<details>
<summary>Diff for <strong>page.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>middleware.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>edge-ssr.js</strong></summary>

```diff
failed to diff
```
</details>
<details>
<summary>Diff for <strong>css-HASH.js</strong></summary>

```diff
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [9813],
   {
-    /***/ 1586: /***/ (
+    /***/ 2628: /***/ (
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -9,7 +9,7 @@
       (window.__NEXT_P = window.__NEXT_P || []).push([
         "/css",
         function () {
-          return __webpack_require__(4362);
+          return __webpack_require__(8707);
         },
       ]);
       if (false) {
@@ -18,14 +18,7 @@
       /***/
     },
 
-    /***/ 4350: /***/ (module) => {
-      // extracted by mini-css-extract-plugin
-      module.exports = { helloWorld: "css_helloWorld__aUdUq" };
-
-      /***/
-    },
-
-    /***/ 4362: /***/ (
+    /***/ 8707: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -39,7 +32,7 @@
       /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
         __webpack_require__(5640);
       /* harmony import */ var _css_module_css__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(4350);
+        __webpack_require__(9080);
       /* harmony import */ var _css_module_css__WEBPACK_IMPORTED_MODULE_1___default =
         /*#__PURE__*/ __webpack_require__.n(
           _css_module_css__WEBPACK_IMPORTED_MODULE_1__
@@ -58,13 +51,20 @@
 
       /***/
     },
+
+    /***/ 9080: /***/ (module) => {
+      // extracted by mini-css-extract-plugin
+      module.exports = { helloWorld: "css_helloWorld__aUdUq" };
+
+      /***/
+    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(1586)
+      __webpack_exec__(2628)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
```
</details>
<details>
<summary>Diff for <strong>dynamic-HASH.js</strong></summary>

```diff
@@ -1,17 +1,117 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [2291],
   {
-    /***/ 283: /***/ (
+    /***/ 2001: /***/ (
+      __unused_webpack_module,
+      __webpack_exports__,
+      __webpack_require__
+    ) => {
+      "use strict";
+      __webpack_require__.r(__webpack_exports__);
+      /* harmony export */ __webpack_require__.d(__webpack_exports__, {
+        /* harmony export */ __N_SSP: () => /* binding */ __N_SSP,
+        /* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
+        /* harmony export */
+      });
+      /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
+        __webpack_require__(5640);
+      /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1__ =
+        __webpack_require__(9553);
+      /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1___default =
+        /*#__PURE__*/ __webpack_require__.n(
+          next_dynamic__WEBPACK_IMPORTED_MODULE_1__
+        );
+
+      const DynamicHello = next_dynamic__WEBPACK_IMPORTED_MODULE_1___default()(
+        () =>
+          __webpack_require__
+            .e(/* import() */ 8042)
+            .then(__webpack_require__.bind(__webpack_require__, 8042))
+            .then((mod) => mod.Hello),
+        {
+          loadableGenerated: {
+            webpack: () => [/*require.resolve*/ 8042],
+          },
+        }
+      );
+      const Page = () =>
+        /*#__PURE__*/ (0, react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(
+          react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment,
+          {
+            children: [
+              /*#__PURE__*/ (0,
+              react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("p", {
+                children: "testing next/dynamic size",
+              }),
+              /*#__PURE__*/ (0,
+              react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(
+                DynamicHello,
+                {}
+              ),
+            ],
+          }
+        );
+      var __N_SSP = true;
+      /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = Page;
+
+      /***/
+    },
+
+    /***/ 2976: /***/ (
+      __unused_webpack_module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/dynamic",
+        function () {
+          return __webpack_require__(2001);
+        },
+      ]);
+      if (false) {
+      }
+
+      /***/
+    },
+
+    /***/ 7807: /***/ (
+      __unused_webpack_module,
+      exports,
+      __webpack_require__
+    ) => {
+      "use strict";
+      /* __next_internal_client_entry_do_not_use__  cjs */
+      Object.defineProperty(exports, "__esModule", {
+        value: true,
+      });
+      Object.defineProperty(exports, "LoadableContext", {
+        enumerable: true,
+        get: function () {
+          return LoadableContext;
+        },
+      });
+      const _interop_require_default = __webpack_require__(1532);
+      const _react = /*#__PURE__*/ _interop_require_default._(
+        __webpack_require__(148)
+      );
+      const LoadableContext = _react.default.createContext(null);
+      if (false) {
+      } //# sourceMappingURL=loadable-context.shared-runtime.js.map
+
+      /***/
+    },
+
+    /***/ 9553: /***/ (
       module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
-      module.exports = __webpack_require__(6990);
+      module.exports = __webpack_require__(9986);
 
       /***/
     },
 
-    /***/ 505: /***/ (
+    /***/ 9829: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -53,7 +153,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
       const _react = /*#__PURE__*/ _interop_require_default._(
         __webpack_require__(148)
       );
-      const _loadablecontextsharedruntime = __webpack_require__(6179);
+      const _loadablecontextsharedruntime = __webpack_require__(7807);
       function resolve(obj) {
         return obj && obj.default ? obj.default : obj;
       }
@@ -288,90 +388,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
       /***/
     },
 
-    /***/ 5703: /***/ (
-      __unused_webpack_module,
-      __webpack_exports__,
-      __webpack_require__
-    ) => {
-      "use strict";
-      __webpack_require__.r(__webpack_exports__);
-      /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-        /* harmony export */ __N_SSP: () => /* binding */ __N_SSP,
-        /* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
-        /* harmony export */
-      });
-      /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
-        __webpack_require__(5640);
-      /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(283);
-      /* harmony import */ var next_dynamic__WEBPACK_IMPORTED_MODULE_1___default =
-        /*#__PURE__*/ __webpack_require__.n(
-          next_dynamic__WEBPACK_IMPORTED_MODULE_1__
-        );
-
-      const DynamicHello = next_dynamic__WEBPACK_IMPORTED_MODULE_1___default()(
-        () =>
-          __webpack_require__
-            .e(/* import() */ 2192)
-            .then(__webpack_require__.bind(__webpack_require__, 2192))
-            .then((mod) => mod.Hello),
-        {
-          loadableGenerated: {
-            webpack: () => [/*require.resolve*/ 2192],
-          },
-        }
-      );
-      const Page = () =>
-        /*#__PURE__*/ (0, react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(
-          react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment,
-          {
-            children: [
-              /*#__PURE__*/ (0,
-              react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("p", {
-                children: "testing next/dynamic size",
-              }),
-              /*#__PURE__*/ (0,
-              react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(
-                DynamicHello,
-                {}
-              ),
-            ],
-          }
-        );
-      var __N_SSP = true;
-      /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = Page;
-
-      /***/
-    },
-
-    /***/ 6179: /***/ (
-      __unused_webpack_module,
-      exports,
-      __webpack_require__
-    ) => {
-      "use strict";
-      /* __next_internal_client_entry_do_not_use__  cjs */
-      Object.defineProperty(exports, "__esModule", {
-        value: true,
-      });
-      Object.defineProperty(exports, "LoadableContext", {
-        enumerable: true,
-        get: function () {
-          return LoadableContext;
-        },
-      });
-      const _interop_require_default = __webpack_require__(1532);
-      const _react = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(148)
-      );
-      const LoadableContext = _react.default.createContext(null);
-      if (false) {
-      } //# sourceMappingURL=loadable-context.shared-runtime.js.map
-
-      /***/
-    },
-
-    /***/ 6990: /***/ (module, exports, __webpack_require__) => {
+    /***/ 9986: /***/ (module, exports, __webpack_require__) => {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
@@ -404,7 +421,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
         __webpack_require__(148)
       );
       const _loadablesharedruntime = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(505)
+        __webpack_require__(9829)
       );
       const isServerSide = "object" === "undefined";
       // Normalize loader to return the module as form { default: Component } for `React.lazy`.
@@ -504,30 +521,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE
 
       /***/
     },
-
-    /***/ 9254: /***/ (
-      __unused_webpack_module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/dynamic",
-        function () {
-          return __webpack_require__(5703);
-        },
-      ]);
-      if (false) {
-      }
-
-      /***/
-    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(9254)
+      __webpack_exec__(2976)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
```
</details>
<details>
<summary>Diff for <strong>hooks-HASH.js</strong></summary>

```diff
@@ -1,24 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [9804],
   {
-    /***/ 1664: /***/ (
-      __unused_webpack_module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/hooks",
-        function () {
-          return __webpack_require__(6130);
-        },
-      ]);
-      if (false) {
-      }
-
-      /***/
-    },
-
-    /***/ 6130: /***/ (
+    /***/ 4756: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -76,13 +59,30 @@
 
       /***/
     },
+
+    /***/ 5426: /***/ (
+      __unused_webpack_module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/hooks",
+        function () {
+          return __webpack_require__(4756);
+        },
+      ]);
+      if (false) {
+      }
+
+      /***/
+    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(1664)
+      __webpack_exec__(5426)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
```
</details>
<details>
<summary>Diff for <strong>image-HASH.js</strong></summary>

```diff
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [2983],
   {
-    /***/ 2198: /***/ (
+    /***/ 264: /***/ (
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -9,7 +9,7 @@
       (window.__NEXT_P = window.__NEXT_P || []).push([
         "/image",
         function () {
-          return __webpack_require__(3444);
+          return __webpack_require__(3594);
         },
       ]);
       if (false) {
@@ -18,7 +18,190 @@
       /***/
     },
 
-    /***/ 2514: /***/ (
+    /***/ 1206: /***/ (__unused_webpack_module, exports) => {
+      "use strict";
+
+      Object.defineProperty(exports, "__esModule", {
+        value: true,
+      });
+      Object.defineProperty(exports, "default", {
+        enumerable: true,
+        get: function () {
+          return _default;
+        },
+      });
+      const DEFAULT_Q = 75;
+      function defaultLoader(param) {
+        let { config, src, width, quality } = param;
+        var _config_qualities;
+        if (false) {
+        }
+        const q =
+          quality ||
+          ((_config_qualities = config.qualities) == null
+            ? void 0
+            : _config_qualities.reduce((prev, cur) =>
+                Math.abs(cur - DEFAULT_Q) < Math.abs(prev - DEFAULT_Q)
+                  ? cur
+                  : prev
+              )) ||
+          DEFAULT_Q;
+        return (
+          config.path +
+          "?url=" +
+          encodeURIComponent(src) +
+          "&w=" +
+          width +
+          "&q=" +
+          q +
+          (src.startsWith("/_next/static/media/") && false ? 0 : "")
+        );
+      }
+      // We use this to determine if the import is the default loader
+      // or a custom loader defined by the user in next.config.js
+      defaultLoader.__next_img_default = true;
+      const _default = defaultLoader; //# sourceMappingURL=image-loader.js.map
+
+      /***/
+    },
+
+    /***/ 1765: /***/ (module, exports, __webpack_require__) => {
+      "use strict";
+
+      Object.defineProperty(exports, "__esModule", {
+        value: true,
+      });
+      Object.defineProperty(exports, "useMergedRef", {
+        enumerable: true,
+        get: function () {
+          return useMergedRef;
+        },
+      });
+      const _react = __webpack_require__(148);
+      function useMergedRef(refA, refB) {
+        const cleanupA = (0, _react.useRef)(null);
+        const cleanupB = (0, _react.useRef)(null);
+        // NOTE: In theory, we could skip the wrapping if only one of the refs is non-null.
+        // (this happens often if the user doesn't pass a ref to Link/Form/Image)
+        // But this can cause us to leak a cleanup-ref into user code (e.g. via `<Link legacyBehavior>`),
+        // and the user might pass that ref into ref-merging library that doesn't support cleanup refs
+        // (because it hasn't been updated for React 19)
+        // which can then cause things to blow up, because a cleanup-returning ref gets called with `null`.
+        // So in practice, it's safer to be defensive and always wrap the ref, even on React 19.
+        return (0, _react.useCallback)(
+          (current) => {
+            if (current === null) {
+              const cleanupFnA = cleanupA.current;
+              if (cleanupFnA) {
+                cleanupA.current = null;
+                cleanupFnA();
+              }
+              const cleanupFnB = cleanupB.current;
+              if (cleanupFnB) {
+                cleanupB.current = null;
+                cleanupFnB();
+              }
+            } else {
+              if (refA) {
+                cleanupA.current = applyRef(refA, current);
+              }
+              if (refB) {
+                cleanupB.current = applyRef(refB, current);
+              }
+            }
+          },
+          [refA, refB]
+        );
+      }
+      function applyRef(refA, current) {
+        if (typeof refA === "function") {
+          const cleanup = refA(current);
+          if (typeof cleanup === "function") {
+            return cleanup;
+          } else {
+            return () => refA(null);
+          }
+        } else {
+          refA.current = current;
+          return () => {
+            refA.current = null;
+          };
+        }
+      }
+      if (
+        (typeof exports.default === "function" ||
+          (typeof exports.default === "object" && exports.default !== null)) &&
+        typeof exports.default.__esModule === "undefined"
+      ) {
+        Object.defineProperty(exports.default, "__esModule", {
+          value: true,
+        });
+        Object.assign(exports.default, exports);
+        module.exports = exports.default;
+      } //# sourceMappingURL=use-merged-ref.js.map
+
+      /***/
+    },
+
+    /***/ 3353: /***/ (
+      module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      module.exports = __webpack_require__(5526);
+
+      /***/
+    },
+
+    /***/ 3594: /***/ (
+      __unused_webpack_module,
+      __webpack_exports__,
+      __webpack_require__
+    ) => {
+      "use strict";
+      // ESM COMPAT FLAG
+      __webpack_require__.r(__webpack_exports__);
+
+      // EXPORTS
+      __webpack_require__.d(__webpack_exports__, {
+        __N_SSP: () => /* binding */ __N_SSP,
+        default: () => /* binding */ pages_image,
+      });
+
+      // EXTERNAL MODULE: ./node_modules/.pnpm/react@19.1.0/node_modules/react/jsx-runtime.js
+      var jsx_runtime = __webpack_require__(5640);
+      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+diff-repo+packages+next+next-packed.tgz_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/image.js
+      var next_image = __webpack_require__(3353);
+      var image_default = /*#__PURE__*/ __webpack_require__.n(next_image); // ./pages/nextjs.png
+      /* harmony default export */ const nextjs = {
+        src: "/_next/static/media/nextjs.cae0b805.png",
+        height: 1347,
+        width: 1626,
+        blurDataURL:
+          "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAHCAMAAAACh/xsAAAAD1BMVEX////x8fH6+vrb29vo6Oh8o70bAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAH0lEQVR4nGNgwARMjIyMjCAGCzMzMwsTRISJCcRABwAEcAAkLCQfgAAAAABJRU5ErkJggg==",
+        blurWidth: 8,
+        blurHeight: 7,
+      }; // ./pages/image.js
+      function ImagePage(props) {
+        return /*#__PURE__*/ (0, jsx_runtime.jsxs)(jsx_runtime.Fragment, {
+          children: [
+            /*#__PURE__*/ (0, jsx_runtime.jsx)("h1", {
+              children: "next/image example",
+            }),
+            /*#__PURE__*/ (0, jsx_runtime.jsx)(image_default(), {
+              src: nextjs,
+              placeholder: "blur",
+            }),
+          ],
+        });
+      }
+      var __N_SSP = true;
+      /* harmony default export */ const pages_image = ImagePage;
+
+      /***/
+    },
+
+    /***/ 3854: /***/ (
       __unused_webpack_module,
       exports,
       __webpack_require__
@@ -34,9 +217,9 @@
           return getImgProps;
         },
       });
-      const _warnonce = __webpack_require__(5127);
-      const _imageblursvg = __webpack_require__(4287);
-      const _imageconfig = __webpack_require__(2795);
+      const _warnonce = __webpack_require__(3603);
+      const _imageblursvg = __webpack_require__(7835);
+      const _imageconfig = __webpack_require__(6799);
       const VALID_LOADING_VALUES =
         /* unused pure expression or super */ null && [
           "lazy",
@@ -463,55 +646,69 @@
       /***/
     },
 
-    /***/ 3444: /***/ (
+    /***/ 5526: /***/ (
       __unused_webpack_module,
-      __webpack_exports__,
+      exports,
       __webpack_require__
     ) => {
       "use strict";
-      // ESM COMPAT FLAG
-      __webpack_require__.r(__webpack_exports__);
 
-      // EXPORTS
-      __webpack_require__.d(__webpack_exports__, {
-        __N_SSP: () => /* binding */ __N_SSP,
-        default: () => /* binding */ pages_image,
+      Object.defineProperty(exports, "__esModule", {
+        value: true,
       });
-
-      // EXTERNAL MODULE: ./node_modules/.pnpm/react@19.1.0/node_modules/react/jsx-runtime.js
-      var jsx_runtime = __webpack_require__(5640);
-      // EXTERNAL MODULE: ./node_modules/.pnpm/next@file+..+main-repo+packages+next+next-packed.tgz_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/next/image.js
-      var next_image = __webpack_require__(6359);
-      var image_default = /*#__PURE__*/ __webpack_require__.n(next_image); // ./pages/nextjs.png
-      /* harmony default export */ const nextjs = {
-        src: "/_next/static/media/nextjs.cae0b805.png",
-        height: 1347,
-        width: 1626,
-        blurDataURL:
-          "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAHCAMAAAACh/xsAAAAD1BMVEX////x8fH6+vrb29vo6Oh8o70bAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAH0lEQVR4nGNgwARMjIyMjCAGCzMzMwsTRISJCcRABwAEcAAkLCQfgAAAAABJRU5ErkJggg==",
-        blurWidth: 8,
-        blurHeight: 7,
-      }; // ./pages/image.js
-      function ImagePage(props) {
-        return /*#__PURE__*/ (0, jsx_runtime.jsxs)(jsx_runtime.Fragment, {
-          children: [
-            /*#__PURE__*/ (0, jsx_runtime.jsx)("h1", {
-              children: "next/image example",
-            }),
-            /*#__PURE__*/ (0, jsx_runtime.jsx)(image_default(), {
-              src: nextjs,
-              placeholder: "blur",
-            }),
-          ],
+      0 && 0;
+      function _export(target, all) {
+        for (var name in all)
+          Object.defineProperty(target, name, {
+            enumerable: true,
+            get: all[name],
+          });
+      }
+      _export(exports, {
+        default: function () {
+          return _default;
+        },
+        getImageProps: function () {
+          return getImageProps;
+        },
+      });
+      const _interop_require_default = __webpack_require__(1532);
+      const _getimgprops = __webpack_require__(3854);
+      const _imagecomponent = __webpack_require__(8350);
+      const _imageloader = /*#__PURE__*/ _interop_require_default._(
+        __webpack_require__(1206)
+      );
+      function getImageProps(imgProps) {
+        const { props } = (0, _getimgprops.getImgProps)(imgProps, {
+          defaultLoader: _imageloader.default,
+          // This is replaced by webpack define plugin
+          imgConf: {
+            deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
+            imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
+            path: "/_next/image",
+            loader: "default",
+            dangerouslyAllowSVG: false,
+            unoptimized: false,
+          },
         });
+        // Normally we don't care about undefined props because we pass to JSX,
+        // but this exported function could be used by the end user for anything
+        // so we delete undefined props to clean it up a little.
+        for (const [key, value] of Object.entries(props)) {
+          if (value === undefined) {
+            delete props[key];
+          }
+        }
+        return {
+          props,
+        };
       }
-      var __N_SSP = true;
-      /* harmony default export */ const pages_image = ImagePage;
+      const _default = _imagecomponent.Image; //# sourceMappingURL=image-external.js.map
 
       /***/
     },
 
-    /***/ 4287: /***/ (__unused_webpack_module, exports) => {
+    /***/ 7835: /***/ (__unused_webpack_module, exports) => {
       "use strict";
       /**
        * A shared function, used on both client and server, to generate a SVG blur placeholder.
@@ -566,85 +763,7 @@
       /***/
     },
 
-    /***/ 4985: /***/ (module, exports, __webpack_require__) => {
-      "use strict";
-
-      Object.defineProperty(exports, "__esModule", {
-        value: true,
-      });
-      Object.defineProperty(exports, "useMergedRef", {
-        enumerable: true,
-        get: function () {
-          return useMergedRef;
-        },
-      });
-      const _react = __webpack_require__(148);
-      function useMergedRef(refA, refB) {
-        const cleanupA = (0, _react.useRef)(null);
-        const cleanupB = (0, _react.useRef)(null);
-        // NOTE: In theory, we could skip the wrapping if only one of the refs is non-null.
-        // (this happens often if the user doesn't pass a ref to Link/Form/Image)
-        // But this can cause us to leak a cleanup-ref into user code (e.g. via `<Link legacyBehavior>`),
-        // and the user might pass that ref into ref-merging library that doesn't support cleanup refs
-        // (because it hasn't been updated for React 19)
-        // which can then cause things to blow up, because a cleanup-returning ref gets called with `null`.
-        // So in practice, it's safer to be defensive and always wrap the ref, even on React 19.
-        return (0, _react.useCallback)(
-          (current) => {
-            if (current === null) {
-              const cleanupFnA = cleanupA.current;
-              if (cleanupFnA) {
-                cleanupA.current = null;
-                cleanupFnA();
-              }
-              const cleanupFnB = cleanupB.current;
-              if (cleanupFnB) {
-                cleanupB.current = null;
-                cleanupFnB();
-              }
-            } else {
-              if (refA) {
-                cleanupA.current = applyRef(refA, current);
-              }
-              if (refB) {
-                cleanupB.current = applyRef(refB, current);
-              }
-            }
-          },
-          [refA, refB]
-        );
-      }
-      function applyRef(refA, current) {
-        if (typeof refA === "function") {
-          const cleanup = refA(current);
-          if (typeof cleanup === "function") {
-            return cleanup;
-          } else {
-            return () => refA(null);
-          }
-        } else {
-          refA.current = current;
-          return () => {
-            refA.current = null;
-          };
-        }
-      }
-      if (
-        (typeof exports.default === "function" ||
-          (typeof exports.default === "object" && exports.default !== null)) &&
-        typeof exports.default.__esModule === "undefined"
-      ) {
-        Object.defineProperty(exports.default, "__esModule", {
-          value: true,
-        });
-        Object.assign(exports.default, exports);
-        module.exports = exports.default;
-      } //# sourceMappingURL=use-merged-ref.js.map
-
-      /***/
-    },
-
-    /***/ 5898: /***/ (module, exports, __webpack_require__) => {
+    /***/ 8350: /***/ (module, exports, __webpack_require__) => {
       "use strict";
       /* __next_internal_client_entry_do_not_use__  cjs */
       Object.defineProperty(exports, "__esModule", {
@@ -666,17 +785,17 @@
         __webpack_require__(7897)
       );
       const _head = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(5207)
+        __webpack_require__(8843)
       );
-      const _getimgprops = __webpack_require__(2514);
-      const _imageconfig = __webpack_require__(2795);
-      const _imageconfigcontextsharedruntime = __webpack_require__(2349);
-      const _warnonce = __webpack_require__(5127);
-      const _routercontextsharedruntime = __webpack_require__(3556);
+      const _getimgprops = __webpack_require__(3854);
+      const _imageconfig = __webpack_require__(6799);
+      const _imageconfigcontextsharedruntime = __webpack_require__(3905);
+      const _warnonce = __webpack_require__(3603);
+      const _routercontextsharedruntime = __webpack_require__(6712);
       const _imageloader = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(5970)
+        __webpack_require__(1206)
       );
-      const _usemergedref = __webpack_require__(4985);
+      const _usemergedref = __webpack_require__(1765);
       // This is replaced by webpack define plugin
       const configEnv = {
         deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
@@ -1002,132 +1121,13 @@
 
       /***/
     },
-
-    /***/ 5970: /***/ (__unused_webpack_module, exports) => {
-      "use strict";
-
-      Object.defineProperty(exports, "__esModule", {
-        value: true,
-      });
-      Object.defineProperty(exports, "default", {
-        enumerable: true,
-        get: function () {
-          return _default;
-        },
-      });
-      const DEFAULT_Q = 75;
-      function defaultLoader(param) {
-        let { config, src, width, quality } = param;
-        var _config_qualities;
-        if (false) {
-        }
-        const q =
-          quality ||
-          ((_config_qualities = config.qualities) == null
-            ? void 0
-            : _config_qualities.reduce((prev, cur) =>
-                Math.abs(cur - DEFAULT_Q) < Math.abs(prev - DEFAULT_Q)
-                  ? cur
-                  : prev
-              )) ||
-          DEFAULT_Q;
-        return (
-          config.path +
-          "?url=" +
-          encodeURIComponent(src) +
-          "&w=" +
-          width +
-          "&q=" +
-          q +
-          (src.startsWith("/_next/static/media/") && false ? 0 : "")
-        );
-      }
-      // We use this to determine if the import is the default loader
-      // or a custom loader defined by the user in next.config.js
-      defaultLoader.__next_img_default = true;
-      const _default = defaultLoader; //# sourceMappingURL=image-loader.js.map
-
-      /***/
-    },
-
-    /***/ 6359: /***/ (
-      module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      module.exports = __webpack_require__(8986);
-
-      /***/
-    },
-
-    /***/ 8986: /***/ (
-      __unused_webpack_module,
-      exports,
-      __webpack_require__
-    ) => {
-      "use strict";
-
-      Object.defineProperty(exports, "__esModule", {
-        value: true,
-      });
-      0 && 0;
-      function _export(target, all) {
-        for (var name in all)
-          Object.defineProperty(target, name, {
-            enumerable: true,
-            get: all[name],
-          });
-      }
-      _export(exports, {
-        default: function () {
-          return _default;
-        },
-        getImageProps: function () {
-          return getImageProps;
-        },
-      });
-      const _interop_require_default = __webpack_require__(1532);
-      const _getimgprops = __webpack_require__(2514);
-      const _imagecomponent = __webpack_require__(5898);
-      const _imageloader = /*#__PURE__*/ _interop_require_default._(
-        __webpack_require__(5970)
-      );
-      function getImageProps(imgProps) {
-        const { props } = (0, _getimgprops.getImgProps)(imgProps, {
-          defaultLoader: _imageloader.default,
-          // This is replaced by webpack define plugin
-          imgConf: {
-            deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
-            imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
-            path: "/_next/image",
-            loader: "default",
-            dangerouslyAllowSVG: false,
-            unoptimized: false,
-          },
-        });
-        // Normally we don't care about undefined props because we pass to JSX,
-        // but this exported function could be used by the end user for anything
-        // so we delete undefined props to clean it up a little.
-        for (const [key, value] of Object.entries(props)) {
-          if (value === undefined) {
-            delete props[key];
-          }
-        }
-        return {
-          props,
-        };
-      }
-      const _default = _imagecomponent.Image; //# sourceMappingURL=image-external.js.map
-
-      /***/
-    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(2198)
+      __webpack_exec__(264)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
```
</details>
<details>
<summary>Diff for <strong>index-HASH.js</strong></summary>

```diff
@@ -1,7 +1,24 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [3332],
   {
-    /***/ 9418: /***/ (
+    /***/ 8230: /***/ (
+      __unused_webpack_module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/",
+        function () {
+          return __webpack_require__(8696);
+        },
+      ]);
+      if (false) {
+      }
+
+      /***/
+    },
+
+    /***/ 8696: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -19,30 +36,13 @@
 
       /***/
     },
-
-    /***/ 9532: /***/ (
-      __unused_webpack_module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/",
-        function () {
-          return __webpack_require__(9418);
-        },
-      ]);
-      if (false) {
-      }
-
-      /***/
-    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(9532)
+      __webpack_exec__(8230)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
```
</details>
<details>
<summary>Diff for <strong>link-HASH.js</strong></summary>

```diff
@@ -1,125 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [4672],
   {
-    /***/ 1854: /***/ (
-      __unused_webpack_module,
-      __webpack_exports__,
-      __webpack_require__
-    ) => {
-      "use strict";
-      __webpack_require__.r(__webpack_exports__);
-      /* harmony export */ __webpack_require__.d(__webpack_exports__, {
-        /* harmony export */ __N_SSP: () => /* binding */ __N_SSP,
-        /* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
-        /* harmony export */
-      });
-      /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
-        __webpack_require__(5640);
-      /* harmony import */ var next_link__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(8770);
-      /* harmony import */ var next_link__WEBPACK_IMPORTED_MODULE_1___default =
-        /*#__PURE__*/ __webpack_require__.n(
-          next_link__WEBPACK_IMPORTED_MODULE_1__
-        );
-
-      function aLink(props) {
-        return /*#__PURE__*/ (0,
-        react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
-          children: [
-            /*#__PURE__*/ (0,
-            react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("h3", {
-              children: "A Link page!",
-            }),
-            /*#__PURE__*/ (0,
-            react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(
-              next_link__WEBPACK_IMPORTED_MODULE_1___default(),
-              {
-                href: "/",
-                children: "Go to /",
-              }
-            ),
-          ],
-        });
-      }
-      var __N_SSP = true;
-      /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = aLink;
-
-      /***/
-    },
-
-    /***/ 3199: /***/ (__unused_webpack_module, exports) => {
-      "use strict";
-
-      Object.defineProperty(exports, "__esModule", {
-        value: true,
-      });
-      Object.defineProperty(exports, "errorOnce", {
-        enumerable: true,
-        get: function () {
-          return errorOnce;
-        },
-      });
-      let errorOnce = (_) => {};
-      if (false) {
-      } //# sourceMappingURL=error-once.js.map
-
-      /***/
-    },
-
-    /***/ 3568: /***/ (
-      __unused_webpack_module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/link",
-        function () {
-          return __webpack_require__(1854);
-        },
-      ]);
-      if (false) {
-      }
-
-      /***/
-    },
-
-    /***/ 3857: /***/ (module, exports, __webpack_require__) => {
-      "use strict";
-
-      Object.defineProperty(exports, "__esModule", {
-        value: true,
-      });
-      Object.defineProperty(exports, "getDomainLocale", {
-        enumerable: true,
-        get: function () {
-          return getDomainLocale;
-        },
-      });
-      const _normalizetrailingslash = __webpack_require__(4869);
-      const basePath =
-        /* unused pure expression or super */ null && (false || "");
-      function getDomainLocale(path, locale, locales, domainLocales) {
-        if (false) {
-        } else {
-          return false;
-        }
-      }
-      if (
-        (typeof exports.default === "function" ||
-          (typeof exports.default === "object" && exports.default !== null)) &&
-        typeof exports.default.__esModule === "undefined"
-      ) {
-        Object.defineProperty(exports.default, "__esModule", {
-          value: true,
-        });
-        Object.assign(exports.default, exports);
-        module.exports = exports.default;
-      } //# sourceMappingURL=get-domain-locale.js.map
-
-      /***/
-    },
-
-    /***/ 3947: /***/ (module, exports, __webpack_require__) => {
+    /***/ 591: /***/ (module, exports, __webpack_require__) => {
       "use strict";
       /* __next_internal_client_entry_do_not_use__  cjs */
       Object.defineProperty(exports, "__esModule", {
@@ -146,17 +28,17 @@
       const _react = /*#__PURE__*/ _interop_require_wildcard._(
         __webpack_require__(148)
       );
-      const _resolvehref = __webpack_require__(3161);
-      const _islocalurl = __webpack_require__(2309);
-      const _formaturl = __webpack_require__(3768);
-      const _utils = __webpack_require__(5554);
-      const _addlocale = __webpack_require__(7591);
-      const _routercontextsharedruntime = __webpack_require__(3556);
-      const _useintersection = __webpack_require__(5624);
-      const _getdomainlocale = __webpack_require__(3857);
-      const _addbasepath = __webpack_require__(4356);
-      const _usemergedref = __webpack_require__(4985);
-      const _erroronce = __webpack_require__(3199);
+      const _resolvehref = __webpack_require__(5837);
+      const _islocalurl = __webpack_require__(5953);
+      const _formaturl = __webpack_require__(6212);
+      const _utils = __webpack_require__(6950);
+      const _addlocale = __webpack_require__(6467);
+      const _routercontextsharedruntime = __webpack_require__(6712);
+      const _useintersection = __webpack_require__(9692);
+      const _getdomainlocale = __webpack_require__(6850);
+      const _addbasepath = __webpack_require__(4928);
+      const _usemergedref = __webpack_require__(1765);
+      const _erroronce = __webpack_require__(8659);
       const prefetched = new Set();
       function prefetch(router, href, as, options) {
         if (false) {
@@ -545,7 +427,17 @@
       /***/
     },
 
-    /***/ 4985: /***/ (module, exports, __webpack_require__) => {
+    /***/ 1148: /***/ (
+      module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      module.exports = __webpack_require__(591);
+
+      /***/
+    },
+
+    /***/ 1765: /***/ (module, exports, __webpack_require__) => {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
@@ -623,7 +515,125 @@
       /***/
     },
 
-    /***/ 5624: /***/ (module, exports, __webpack_require__) => {
+    /***/ 5436: /***/ (
+      __unused_webpack_module,
+      __webpack_exports__,
+      __webpack_require__
+    ) => {
+      "use strict";
+      __webpack_require__.r(__webpack_exports__);
+      /* harmony export */ __webpack_require__.d(__webpack_exports__, {
+        /* harmony export */ __N_SSP: () => /* binding */ __N_SSP,
+        /* harmony export */ default: () => __WEBPACK_DEFAULT_EXPORT__,
+        /* harmony export */
+      });
+      /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
+        __webpack_require__(5640);
+      /* harmony import */ var next_link__WEBPACK_IMPORTED_MODULE_1__ =
+        __webpack_require__(1148);
+      /* harmony import */ var next_link__WEBPACK_IMPORTED_MODULE_1___default =
+        /*#__PURE__*/ __webpack_require__.n(
+          next_link__WEBPACK_IMPORTED_MODULE_1__
+        );
+
+      function aLink(props) {
+        return /*#__PURE__*/ (0,
+        react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
+          children: [
+            /*#__PURE__*/ (0,
+            react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("h3", {
+              children: "A Link page!",
+            }),
+            /*#__PURE__*/ (0,
+            react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(
+              next_link__WEBPACK_IMPORTED_MODULE_1___default(),
+              {
+                href: "/",
+                children: "Go to /",
+              }
+            ),
+          ],
+        });
+      }
+      var __N_SSP = true;
+      /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = aLink;
+
+      /***/
+    },
+
+    /***/ 6850: /***/ (module, exports, __webpack_require__) => {
+      "use strict";
+
+      Object.defineProperty(exports, "__esModule", {
+        value: true,
+      });
+      Object.defineProperty(exports, "getDomainLocale", {
+        enumerable: true,
+        get: function () {
+          return getDomainLocale;
+        },
+      });
+      const _normalizetrailingslash = __webpack_require__(6457);
+      const basePath =
+        /* unused pure expression or super */ null && (false || "");
+      function getDomainLocale(path, locale, locales, domainLocales) {
+        if (false) {
+        } else {
+          return false;
+        }
+      }
+      if (
+        (typeof exports.default === "function" ||
+          (typeof exports.default === "object" && exports.default !== null)) &&
+        typeof exports.default.__esModule === "undefined"
+      ) {
+        Object.defineProperty(exports.default, "__esModule", {
+          value: true,
+        });
+        Object.assign(exports.default, exports);
+        module.exports = exports.default;
+      } //# sourceMappingURL=get-domain-locale.js.map
+
+      /***/
+    },
+
+    /***/ 8659: /***/ (__unused_webpack_module, exports) => {
+      "use strict";
+
+      Object.defineProperty(exports, "__esModule", {
+        value: true,
+      });
+      Object.defineProperty(exports, "errorOnce", {
+        enumerable: true,
+        get: function () {
+          return errorOnce;
+        },
+      });
+      let errorOnce = (_) => {};
+      if (false) {
+      } //# sourceMappingURL=error-once.js.map
+
+      /***/
+    },
+
+    /***/ 9666: /***/ (
+      __unused_webpack_module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/link",
+        function () {
+          return __webpack_require__(5436);
+        },
+      ]);
+      if (false) {
+      }
+
+      /***/
+    },
+
+    /***/ 9692: /***/ (module, exports, __webpack_require__) => {
       "use strict";
 
       Object.defineProperty(exports, "__esModule", {
@@ -636,7 +646,7 @@
         },
       });
       const _react = __webpack_require__(148);
-      const _requestidlecallback = __webpack_require__(3543);
+      const _requestidlecallback = __webpack_require__(315);
       const hasIntersectionObserver =
         typeof IntersectionObserver === "function";
       const observers = new Map();
@@ -748,23 +758,13 @@
 
       /***/
     },
-
-    /***/ 8770: /***/ (
-      module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      module.exports = __webpack_require__(3947);
-
-      /***/
-    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(3568)
+      __webpack_exec__(9666)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
```
</details>
<details>
<summary>Diff for <strong>routerDirect-HASH.js</strong></summary>

```diff
@@ -1,7 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [188],
   {
-    /***/ 3618: /***/ (
+    /***/ 76: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -16,7 +16,7 @@
       /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
         __webpack_require__(5640);
       /* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(4631);
+        __webpack_require__(9413);
       /* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1___default =
         /*#__PURE__*/ __webpack_require__.n(
           next_router__WEBPACK_IMPORTED_MODULE_1__
@@ -36,17 +36,7 @@
       /***/
     },
 
-    /***/ 4631: /***/ (
-      module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      module.exports = __webpack_require__(7086);
-
-      /***/
-    },
-
-    /***/ 7824: /***/ (
+    /***/ 1810: /***/ (
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
@@ -54,7 +44,7 @@
       (window.__NEXT_P = window.__NEXT_P || []).push([
         "/routerDirect",
         function () {
-          return __webpack_require__(3618);
+          return __webpack_require__(76);
         },
       ]);
       if (false) {
@@ -62,13 +52,23 @@
 
       /***/
     },
+
+    /***/ 9413: /***/ (
+      module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      module.exports = __webpack_require__(5282);
+
+      /***/
+    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(7824)
+      __webpack_exec__(1810)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
```
</details>
<details>
<summary>Diff for <strong>script-HASH.js</strong></summary>

```diff
@@ -1,24 +1,17 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [1209],
   {
-    /***/ 1984: /***/ (
-      __unused_webpack_module,
+    /***/ 2227: /***/ (
+      module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/script",
-        function () {
-          return __webpack_require__(5769);
-        },
-      ]);
-      if (false) {
-      }
+      module.exports = __webpack_require__(5984);
 
       /***/
     },
 
-    /***/ 5769: /***/ (
+    /***/ 3043: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -33,7 +26,7 @@
       /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
         __webpack_require__(5640);
       /* harmony import */ var next_script__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(8293);
+        __webpack_require__(2227);
       /* harmony import */ var next_script__WEBPACK_IMPORTED_MODULE_1___default =
         /*#__PURE__*/ __webpack_require__.n(
           next_script__WEBPACK_IMPORTED_MODULE_1__
@@ -66,12 +59,19 @@
       /***/
     },
 
-    /***/ 8293: /***/ (
-      module,
+    /***/ 3642: /***/ (
+      __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
-      module.exports = __webpack_require__(900);
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/script",
+        function () {
+          return __webpack_require__(3043);
+        },
+      ]);
+      if (false) {
+      }
 
       /***/
     },
@@ -81,7 +81,7 @@
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(1984)
+      __webpack_exec__(3642)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
```
</details>
<details>
<summary>Diff for <strong>withRouter-HASH.js</strong></summary>

```diff
@@ -1,34 +1,7 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [3263],
   {
-    /***/ 4631: /***/ (
-      module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      module.exports = __webpack_require__(7086);
-
-      /***/
-    },
-
-    /***/ 9216: /***/ (
-      __unused_webpack_module,
-      __unused_webpack_exports,
-      __webpack_require__
-    ) => {
-      (window.__NEXT_P = window.__NEXT_P || []).push([
-        "/withRouter",
-        function () {
-          return __webpack_require__(9803);
-        },
-      ]);
-      if (false) {
-      }
-
-      /***/
-    },
-
-    /***/ 9803: /***/ (
+    /***/ 1089: /***/ (
       __unused_webpack_module,
       __webpack_exports__,
       __webpack_require__
@@ -43,7 +16,7 @@
       /* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ =
         __webpack_require__(5640);
       /* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1__ =
-        __webpack_require__(4631);
+        __webpack_require__(9413);
       /* harmony import */ var next_router__WEBPACK_IMPORTED_MODULE_1___default =
         /*#__PURE__*/ __webpack_require__.n(
           next_router__WEBPACK_IMPORTED_MODULE_1__
@@ -61,13 +34,40 @@
 
       /***/
     },
+
+    /***/ 3962: /***/ (
+      __unused_webpack_module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      (window.__NEXT_P = window.__NEXT_P || []).push([
+        "/withRouter",
+        function () {
+          return __webpack_require__(1089);
+        },
+      ]);
+      if (false) {
+      }
+
+      /***/
+    },
+
+    /***/ 9413: /***/ (
+      module,
+      __unused_webpack_exports,
+      __webpack_require__
+    ) => {
+      module.exports = __webpack_require__(5282);
+
+      /***/
+    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
     /******/ var __webpack_exec__ = (moduleId) =>
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(0, [636, 6593, 8792], () =>
-      __webpack_exec__(9216)
+      __webpack_exec__(3962)
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
```
</details>
<details>
<summary>Diff for <strong>1733-HASH.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>194b18f3-HASH.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>4719-HASH.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>main-HASH.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>main-app-HASH.js</strong></summary>

```diff
@@ -1,61 +1,61 @@
 (self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([
   [4977],
   {
-    /***/ 569: /***/ (
+    /***/ 3579: /***/ () => {
+      /* (ignored) */
+      /***/
+    },
+
+    /***/ 7191: /***/ (
       __unused_webpack_module,
       __unused_webpack_exports,
       __webpack_require__
     ) => {
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 8790, 23)
+        __webpack_require__.t.bind(__webpack_require__, 5356, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 7382, 23)
+        __webpack_require__.t.bind(__webpack_require__, 4304, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 9442, 23)
+        __webpack_require__.t.bind(__webpack_require__, 8390, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 94, 23)
+        __webpack_require__.t.bind(__webpack_require__, 9464, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 2439, 23)
+        __webpack_require__.t.bind(__webpack_require__, 7601, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 5083, 23)
+        __webpack_require__.t.bind(__webpack_require__, 2553, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 8103, 23)
+        __webpack_require__.t.bind(__webpack_require__, 1925, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 5625, 23)
+        __webpack_require__.t.bind(__webpack_require__, 959, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 4247, 23)
+        __webpack_require__.t.bind(__webpack_require__, 9389, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 5602, 23)
+        __webpack_require__.t.bind(__webpack_require__, 8628, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 227, 23)
+        __webpack_require__.t.bind(__webpack_require__, 3077, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 6734, 23)
+        __webpack_require__.t.bind(__webpack_require__, 7812, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.t.bind(__webpack_require__, 4120, 23)
+        __webpack_require__.t.bind(__webpack_require__, 5774, 23)
       );
       Promise.resolve(/* import() eager */).then(
-        __webpack_require__.bind(__webpack_require__, 6104)
+        __webpack_require__.bind(__webpack_require__, 750)
       );
 
       /***/
     },
-
-    /***/ 3505: /***/ () => {
-      /* (ignored) */
-      /***/
-    },
   },
   /******/ (__webpack_require__) => {
     // webpackRuntimeModules
@@ -63,8 +63,8 @@
       __webpack_require__((__webpack_require__.s = moduleId));
     /******/ __webpack_require__.O(
       0,
-      [1305, 1733],
-      () => (__webpack_exec__(9679), __webpack_exec__(569))
+      [9910, 965],
+      () => (__webpack_exec__(1389), __webpack_exec__(7191))
     );
     /******/ var __webpack_exports__ = __webpack_require__.O();
     /******/ _N_E = __webpack_exports__;
```
</details>
<details>
<summary>Diff for <strong>app-page-exp..ntime.dev.js</strong></summary>

```diff
failed to diff
```
</details>
<details>
<summary>Diff for <strong>app-page-exp..time.prod.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>app-page-tur..ntime.dev.js</strong></summary>

```diff
failed to diff
```
</details>
<details>
<summary>Diff for <strong>app-page-tur..time.prod.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>app-page-tur..ntime.dev.js</strong></summary>

```diff
failed to diff
```
</details>
<details>
<summary>Diff for <strong>app-page-tur..time.prod.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>app-page.runtime.dev.js</strong></summary>

```diff
failed to diff
```
</details>
<details>
<summary>Diff for <strong>app-page.runtime.prod.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>app-route-ex..ntime.dev.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>app-route-ex..time.prod.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>app-route-tu..ntime.dev.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>app-route-tu..time.prod.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>app-route-tu..ntime.dev.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>app-route-tu..time.prod.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>app-route.runtime.dev.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>app-route.ru..time.prod.js</strong></summary>

Diff too large to display
</details>
<details>
<summary>Diff for <strong>server.runtime.prod.js</strong></summary>

Diff too large to display
</details>

</details>

</details>
Commit: 89c91c7efb8ef0e0665f6ba4d7f2cfc00ff83333
author_association: MEMBER
user: login: ijjk
created_at: 2025-04-07T10:36:05Z
body: ## Failing test suites <!--36844652392-->
Commit: 89c91c7efb8ef0e0665f6ba4d7f2cfc00ff83333

`pnpm test-dev test/development/app-hmr/hmr.test.ts`
- app-dir-hmr > filesystem changes > should update server components after navigating to a page with a different runtime

<details>
<summary>Expand output</summary>

  ● app-dir-hmr › filesystem changes › should update server components after navigating to a page with a different runtime

    expect(received).toBe(expected) // Object.is equality

    Expected: "ipad"
    Received: "mac"

      74 |         // little slow (especially on overloaded CI servers)
      75 |         await retry(async () => {
    > 76 |           expect(await browser.elementByCss('p').text()).toBe('ipad')
         |                                                          ^
      77 |         }, 5000 /* ms */)
      78 |
      79 |         expect(

      at toBe (development/app-hmr/hmr.test.ts:76:58)
      at retry (lib/next-test-utils.ts:810:14)
      at development/app-hmr/hmr.test.ts:75:9
      at NextDevInstance.patchFile (lib/next-modes/base.ts:597:9)
      at NextDevInstance.patchFile (lib/next-modes/next-dev.ts:199:16)
      at Object.<anonymous> (development/app-hmr/hmr.test.ts:70:7)

</details>


Read more about building and testing Next.js in [contributing.md](https://github.com/vercel/next.js/blob/canary/contributing.md).

author_association: MEMBER
user: login: sokra
created_at: 2025-04-08T06:56:24Z
body: > Nice! Is there a specific known issue this fixes, or is this just fixing a theoretical bug?

test/development/app-hmr/hmr.test.ts reports this to console, but we weren't checking for that to the test was passing.
author_association: MEMBER