diff --git a/docs/02-app/02-api-reference/02-file-conventions/layout.mdx b/docs/02-app/02-api-reference/02-file-conventions/layout.mdx index 737d4baf1aac8..91e7805948f64 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/layout.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/layout.mdx @@ -116,7 +116,7 @@ This performance optimization allows navigation between pages that share a layou Because `dashboard/layout.tsx` doesn't re-render, the `searchParams` prop in the layout Server Component might become **stale** after navigation. -- Instead, use the Page [`searchParams`](/docs/app/api-reference/file-conventions/page) prop or the [`useSearchParams`](/docs/app/api-reference/functions/use-params) hook in a Client Component, which is re-rendered on the client with the latest `searchParams`. +- Instead, use the Page [`searchParams`](/docs/app/api-reference/file-conventions/page#searchparams-optional) prop or the [`useSearchParams`](/docs/app/api-reference/functions/use-search-params) hook in a Client Component, which is re-rendered on the client with the latest `searchParams`. ### Root Layouts diff --git a/packages/next-swc/crates/next-core/src/env.rs b/packages/next-swc/crates/next-core/src/env.rs index ccc8d6a42b60f..e020e8773ff1e 100644 --- a/packages/next-swc/crates/next-core/src/env.rs +++ b/packages/next-swc/crates/next-core/src/env.rs @@ -141,7 +141,6 @@ pub async fn env_for_js( map.insert( "__NEXT_I18N_SUPPORT".to_string(), - // How do I check if i18n exists in the config? if next_config.i18n.is_none() { "false".to_string() } else { @@ -161,6 +160,196 @@ pub async fn env_for_js( }, ); + map.insert( + "NEXT_MINIMAL".to_string(), + // Don't stringify undefined + "\"\"".to_string(), + ); + + map.insert( + "__NEXT_ACTIONS_DEPLOYMENT_ID".to_string(), + if next_config + .experimental + .use_deployment_id_server_actions + .unwrap_or(false) + { + "true".to_string() + } else { + "false".to_string() + }, + ); + + map.insert( + "NEXT_DEPLOYMENT_ID".to_string(), + // Don't stringify undefined + if let Some(deployment_id) = next_config.experimental.deployment_id.as_ref() { + serde_json::to_string(deployment_id)? + } else { + "undefined".to_string() + }, + ); + + map.insert( + "__NEXT_MANUAL_CLIENT_BASE_PATH".to_string(), + if next_config + .experimental + .manual_client_base_path + .unwrap_or(false) + { + "true".to_string() + } else { + "false".to_string() + }, + ); + + map.insert( + "__NEXT_OPTIMISTIC_CLIENT_CACHE".to_string(), + if next_config + .experimental + .optimistic_client_cache + .unwrap_or(false) + { + "true".to_string() + } else { + "false".to_string() + }, + ); + + map.insert( + "__NEXT_MIDDLEWARE_PREFETCH".to_string(), + // Don't stringify undefined + if let Some(middleware_prefetch) = next_config.experimental.middleware_prefetch.as_ref() { + serde_json::to_string(middleware_prefetch)? + } else { + "undefined".to_string() + }, + ); + + // TODO: Implement crossOrigin in Turbopack script injection + map.insert( + "__NEXT_CROSS_ORIGIN".to_string(), + // Don't stringify undefined + if let Some(cross_origin) = next_config.cross_origin.as_ref() { + serde_json::to_string(cross_origin)? + } else { + "undefined".to_string() + }, + ); + + map.insert( + "__NEXT_BUILD_INDICATOR".to_string(), + // Don't stringify undefined + match next_config.dev_indicators.as_ref() { + Some(dev_indicators) => match dev_indicators.build_activity.as_ref() { + Some(build_activity) => serde_json::to_string(build_activity)?, + None => "false".to_string(), + }, + None => "false".to_string(), + }, + ); + + map.insert( + "__NEXT_BUILD_INDICATOR_POSITION".to_string(), + // Don't stringify undefined + match next_config.dev_indicators.as_ref() { + Some(dev_indicators) => match dev_indicators.build_activity_position.as_ref() { + Some(build_activity_position) => serde_json::to_string(build_activity_position)?, + None => "undefined".to_string(), + }, + None => "undefined".to_string(), + }, + ); + + map.insert( + "__NEXT_OPTIMIZE_FONTS".to_string(), + if next_config.optimize_fonts.unwrap_or(true) { + "true".to_string() + } else { + "false".to_string() + }, + ); + + map.insert( + "__NEXT_OPTIMIZE_CSS".to_string(), + // Don't stringify undefined + if let Some(optimize_css) = next_config.experimental.optimize_css.as_ref() { + serde_json::to_string(optimize_css)? + } else { + "false".to_string() + }, + ); + + map.insert( + "__NEXT_SCRIPT_WORKERS".to_string(), + // TODO: This should be true in production mode + // if next_config + // .experimental + // .next_script_workers + // .unwrap_or(false) + // { + // "false".to_string() + // } else { + // "false".to_string() + // }, + "false".to_string(), + ); + + map.insert( + "__NEXT_CONFIG_OUTPUT".to_string(), + // Don't stringify undefined + if let Some(output) = next_config.output.as_ref() { + serde_json::to_string(output)? + } else { + "undefined".to_string() + }, + ); + + map.insert( + "__NEXT_ANALYTICS_ID".to_string(), + // Don't stringify undefined + if let Some(analytics_id) = next_config.analytics_id.as_ref() { + serde_json::to_string(analytics_id)? + } else { + "undefined".to_string() + }, + ); + + map.insert( + "__NEXT_HAS_WEB_VITALS_ATTRIBUTION".to_string(), + if next_config.experimental.web_vitals_attribution.is_none() { + "false".to_string() + } else { + "true".to_string() + }, + ); + + map.insert( + "__NEXT_WEB_VITALS_ATTRIBUTION".to_string(), + // Don't stringify undefined + if let Some(web_vitals_attribution) = + next_config.experimental.web_vitals_attribution.as_ref() + { + serde_json::to_string(web_vitals_attribution)? + } else { + "undefined".to_string() + }, + ); + + // TODO: Implement + // map.insert( + // "__NEXT_FETCH_CACHE_KEY_PREFIX".to_string(), + // ); + + // TODO: Implement + // map.insert( + // "__NEXT_HAS_REWRITES".to_string(), + // ); + + // TODO: Implement for node server only? + // map.insert( + // "__NEXT_EXPERIMENTAL_REACT".to_string(), + // ); + if !test_mode.is_empty() { map.insert("__NEXT_TEST_MODE".to_string(), "true".to_string()); } diff --git a/packages/next-swc/crates/next-core/src/next_config.rs b/packages/next-swc/crates/next-core/src/next_config.rs index 984cce223ed9d..94966c5458552 100644 --- a/packages/next-swc/crates/next-core/src/next_config.rs +++ b/packages/next-swc/crates/next-core/src/next_config.rs @@ -91,6 +91,10 @@ pub struct NextConfig { pub skip_middleware_url_normalize: Option, pub skip_trailing_slash_redirect: Option, pub i18n: Option, + pub cross_origin: Option, + pub dev_indicators: Option, + pub output: Option, + pub analytics_id: Option, /// #[serde(rename = "_originalRedirects")] @@ -99,15 +103,12 @@ pub struct NextConfig { // Partially supported pub compiler: Option, - pub output: Option, + pub optimize_fonts: Option, // unsupported - cross_origin: Option, amp: AmpConfig, - analytics_id: String, clean_dist_dir: bool, compress: bool, - dev_indicators: DevIndicatorsConfig, eslint: EslintConfig, exclude_default_moment_locales: bool, // this can be a function in js land @@ -117,7 +118,6 @@ pub struct NextConfig { generate_etags: bool, http_agent_options: HttpAgentConfig, on_demand_entries: OnDemandEntriesConfig, - optimize_fonts: bool, output_file_tracing: bool, powered_by_header: bool, production_browser_source_maps: bool, @@ -146,7 +146,7 @@ struct EslintConfig { #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, TraceRawVcs)] #[serde(rename_all = "kebab-case")] -enum BuildActivityPositions { +pub enum BuildActivityPositions { #[default] BottomRight, BottomLeft, @@ -156,9 +156,9 @@ enum BuildActivityPositions { #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, TraceRawVcs)] #[serde(rename_all = "camelCase")] -struct DevIndicatorsConfig { - build_activity: bool, - build_activity_position: BuildActivityPositions, +pub struct DevIndicatorsConfig { + pub build_activity: Option, + pub build_activity_position: Option, } #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, TraceRawVcs)] @@ -431,6 +431,18 @@ pub struct ExperimentalConfig { pub turbotrace: Option, pub external_middleware_rewrites_resolve: Option, pub scroll_restoration: Option, + pub use_deployment_id: Option, + pub use_deployment_id_server_actions: Option, + pub deployment_id: Option, + pub manual_client_base_path: Option, + pub optimistic_client_cache: Option, + pub middleware_prefetch: Option, + /// optimizeCss can be boolean or critters' option object + /// Use Record as critters doesn't export its Option type + /// https://github.com/GoogleChromeLabs/critters/blob/a590c05f9197b656d2aeaae9369df2483c26b072/packages/critters/src/index.d.ts + pub optimize_css: Option, + pub next_script_workers: Option, + pub web_vitals_attribution: Option>, // --- // UNSUPPORTED @@ -442,7 +454,6 @@ pub struct ExperimentalConfig { case_sensitive_routes: Option, cpus: Option, cra_compat: Option, - deployment_id: Option, disable_optimized_loading: Option, disable_postcss_preset_env: Option, esm_externals: Option, @@ -460,17 +471,9 @@ pub struct ExperimentalConfig { instrumentation_hook: Option, large_page_data_bytes: Option, logging: Option, - manual_client_base_path: Option, memory_based_workers_count: Option, - middleware_prefetch: Option, - next_script_workers: Option, - optimistic_client_cache: Option, /// Optimize React APIs for server builds. optimize_server_react: Option, - /// optimizeCss can be boolean or critters' option object - /// Use Record as critters doesn't export its Option type - /// https://github.com/GoogleChromeLabs/critters/blob/a590c05f9197b656d2aeaae9369df2483c26b072/packages/critters/src/index.d.ts - optimize_css: Option, /// Automatically apply the "modularize_imports" optimization to imports of /// the specified packages. optimize_package_imports: Option>, @@ -502,9 +505,6 @@ pub struct ExperimentalConfig { /// @see https://nextjs.org/docs/app/api-reference/next-config-js/typedRoutes typed_routes: Option, url_imports: Option, - use_deployment_id: Option, - use_deployment_id_server_actions: Option, - web_vitals_attribution: Option>, /// This option is to enable running the Webpack build in a worker thread /// (doesn't apply to Turbopack). webpack_build_worker: Option, @@ -520,7 +520,7 @@ enum SizeLimit { #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TraceRawVcs)] #[serde(rename_all = "kebab-case")] -enum MiddlewarePrefetchType { +pub enum MiddlewarePrefetchType { Strict, Flexible, }