Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions crates/next-core/src/next_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,8 @@ pub struct ExperimentalConfig {
cache_components: Option<bool>,
use_cache: Option<bool>,
root_params: Option<bool>,
runtime_server_deployment_id: Option<bool>,

// ---
// UNSUPPORTED
// ---
Expand Down Expand Up @@ -1815,6 +1817,15 @@ impl NextConfig {
)
}

#[turbo_tasks::function]
pub fn runtime_server_deployment_id_available(&self) -> Vc<bool> {
Vc::cell(
self.experimental
.runtime_server_deployment_id
.unwrap_or(false),
)
}

#[turbo_tasks::function]
pub fn cache_kinds(&self) -> Vc<CacheKinds> {
let mut cache_kinds = CacheKinds::default();
Expand Down
36 changes: 26 additions & 10 deletions crates/next-core/src/next_manifests/client_reference_manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,12 +167,15 @@ async fn build_manifest(
async move {
let mut entry_manifest: SerializedClientReferenceManifest = Default::default();
let mut references = FxIndexSet::default();
let chunk_suffix_path = next_config.chunk_suffix_path().owned().await?;
let prefix_path = next_config.computed_asset_prefix().owned().await?;
let suffix_path = chunk_suffix_path.unwrap_or_default();

// TODO: Add `suffix` to the manifest for React to use.
// entry_manifest.module_loading.prefix = prefix_path;
let runtime_server_deployment_id_available =
*next_config.runtime_server_deployment_id_available().await?;
let suffix_path = if !runtime_server_deployment_id_available {
let chunk_suffix_path = next_config.chunk_suffix_path().owned().await?;
chunk_suffix_path.unwrap_or_default()
} else {
rcstr!("")
};

entry_manifest.module_loading.cross_origin = next_config.cross_origin().owned().await?;
let ClientReferencesChunks {
Expand Down Expand Up @@ -469,15 +472,28 @@ async fn build_manifest(
FileContent::Content(File::from(formatdoc! {
r#"
globalThis.__RSC_MANIFEST = globalThis.__RSC_MANIFEST || {{}};
globalThis.__RSC_MANIFEST[{entry_name}] = {manifest}
globalThis.__RSC_MANIFEST[{entry_name}] = {manifest};
{suffix}
"#,
entry_name = StringifyJs(&normalized_manifest_entry),
manifest = &client_reference_manifest_json
manifest = &client_reference_manifest_json,
suffix = if runtime_server_deployment_id_available {
formatdoc!{
r#"
for (const key in globalThis.__RSC_MANIFEST[{entry_name}].clientModules) {{
const val = {{ ...globalThis.__RSC_MANIFEST[{entry_name}].clientModules[key] }}
globalThis.__RSC_MANIFEST[{entry_name}].clientModules[key] = val
val.chunks = val.chunks.map((c) => `${{c}}?dpl=${{process.env.NEXT_DEPLOYMENT_ID}}`)
}}
"#,
entry_name = StringifyJs(&normalized_manifest_entry),
}
} else {
"".to_string()
}
}))
.cell(),
)
.to_resolved()
.await?,
).to_resolved().await?,
references: ResolvedVc::cell(references.into_iter().collect()),
}
.cell())
Expand Down
44 changes: 28 additions & 16 deletions packages/next/src/build/define-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,14 @@ export interface DefineEnvOptions {
}
}

const DEFINE_ENV_EXPRESSION = Symbol('DEFINE_ENV_EXPRESSION')

interface DefineEnv {
[key: string]:
| string
| string[]
| boolean
| { [DEFINE_ENV_EXPRESSION]: string }
| ProxyMatcher[]
| BloomFilter
| Partial<NextConfigComplete['images']>
Expand All @@ -64,7 +67,9 @@ function serializeDefineEnv(defineEnv: DefineEnv): SerializedDefineEnv {
const defineEnvStringified: SerializedDefineEnv = Object.fromEntries(
Object.entries(defineEnv).map(([key, value]) => [
key,
JSON.stringify(value),
typeof value === 'object' && DEFINE_ENV_EXPRESSION in value
? value[DEFINE_ENV_EXPRESSION]
: JSON.stringify(value),
])
)
return defineEnvStringified
Expand Down Expand Up @@ -165,23 +170,30 @@ export function getDefineEnv({
'process.env.__NEXT_CACHE_COMPONENTS': isCacheComponentsEnabled,
'process.env.__NEXT_USE_CACHE': isUseCacheEnabled,

...(isClient
...(config.experimental?.useSkewCookie || !config.deploymentId
? {
// TODO use `globalThis.NEXT_DEPLOYMENT_ID` on client to still support accessing
// process.env.NEXT_DEPLOYMENT_ID in userland
'process.env.NEXT_DEPLOYMENT_ID': config.experimental?.useSkewCookie
? false
: config.deploymentId || false,
'process.env.NEXT_DEPLOYMENT_ID': false,
}
: config.experimental?.runtimeServerDeploymentId
? {
// Don't inline at all, keep process.env.NEXT_DEPLOYMENT_ID as is
}
: {
'process.env.NEXT_DEPLOYMENT_ID': config.experimental?.useSkewCookie
? false
: config.deploymentId || false,
}),
: isClient
? isTurbopack
? {
// This is set at runtime by packages/next/src/client/register-deployment-id-global.ts
'process.env.NEXT_DEPLOYMENT_ID': {
[DEFINE_ENV_EXPRESSION]: 'globalThis.NEXT_DEPLOYMENT_ID',
},
}
: {
// For Webpack, we currently don't use the non-inlining globalThis.NEXT_DEPLOYMENT_ID
// approach because we cannot forward this global variable to web workers easily.
'process.env.NEXT_DEPLOYMENT_ID': config.deploymentId || false,
}
: config.experimental?.runtimeServerDeploymentId
? {
// Don't inline at all, keep process.env.NEXT_DEPLOYMENT_ID as is
}
: {
'process.env.NEXT_DEPLOYMENT_ID': config.deploymentId || false,
}),

// Propagates the `__NEXT_EXPERIMENTAL_STATIC_SHELL_DEBUGGING` environment
// variable to the client.
Expand Down
2 changes: 0 additions & 2 deletions packages/next/src/build/templates/edge-ssr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ async function requestHandler(
buildManifest,
prerenderManifest,
reactLoadableManifest,
clientReferenceManifest,
subresourceIntegrityManifest,
dynamicCssManifest,
} = prepareResult
Expand Down Expand Up @@ -168,7 +167,6 @@ async function requestHandler(
buildManifest,
subresourceIntegrityManifest,
reactLoadableManifest,
clientReferenceManifest,
dynamicCssManifest,
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,7 @@ export class ClientReferenceManifestPlugin {
new sources.RawSource(
`globalThis.__RSC_MANIFEST=(globalThis.__RSC_MANIFEST||{});globalThis.__RSC_MANIFEST[${JSON.stringify(
pagePath.slice('app'.length)
)}]=${json}`
)}]=${json};`
) as unknown as webpack.sources.RawSource
)
}
Expand Down
1 change: 1 addition & 0 deletions packages/next/src/client/app-next-turbopack.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './register-deployment-id-global'
import { appBootstrap } from './app-bootstrap'
import { isRecoverableError } from './react-client-callbacks/on-recoverable-error'

Expand Down
8 changes: 6 additions & 2 deletions packages/next/src/client/app-webpack.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
// Override chunk URL mapping in the webpack runtime
// https://github.com/webpack/webpack/blob/2738eebc7880835d88c727d364ad37f3ec557593/lib/RuntimeGlobals.js#L204

import { getDeploymentIdQueryOrEmptyString } from '../shared/lib/deployment-id'
import './register-deployment-id-global'
import {
getDeploymentId,
getDeploymentIdQueryOrEmptyString,
} from '../shared/lib/deployment-id'
import { encodeURIPath } from '../shared/lib/encode-uri-path'

declare const __webpack_require__: any

// If we have a deployment ID, we need to append it to the webpack chunk names
// I am keeping the process check explicit so this can be statically optimized
if (process.env.NEXT_DEPLOYMENT_ID) {
if (getDeploymentId()) {
const suffix = getDeploymentIdQueryOrEmptyString()
const getChunkScriptFilename = __webpack_require__.u
__webpack_require__.u = (...args: any[]) =>
Expand Down
1 change: 1 addition & 0 deletions packages/next/src/client/next-dev-turbopack.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// TODO: Remove use of `any` type.
import './register-deployment-id-global'
import { initialize, version, router, emitter } from './'
import initHMR from './dev/hot-middleware-client'

Expand Down
1 change: 1 addition & 0 deletions packages/next/src/client/next-dev.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// TODO: Remove use of `any` type.
import './register-deployment-id-global'
import './webpack'
import { initialize, version, router, emitter } from './'
import initHMR from './dev/hot-middleware-client'
Expand Down
1 change: 1 addition & 0 deletions packages/next/src/client/next-turbopack.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// A client-side entry point for Turbopack builds. Includes logic to load chunks,
// but does not include development-time features like hot module reloading.

import './register-deployment-id-global'
import '../lib/require-instrumentation-client'

// TODO: Remove use of `any` type.
Expand Down
1 change: 1 addition & 0 deletions packages/next/src/client/next.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './register-deployment-id-global'
import './webpack'
import '../lib/require-instrumentation-client'

Expand Down
2 changes: 2 additions & 0 deletions packages/next/src/client/register-deployment-id-global.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { getDeploymentId } from '../shared/lib/deployment-id'
;(globalThis as any).NEXT_DEPLOYMENT_ID = getDeploymentId()
12 changes: 12 additions & 0 deletions packages/next/src/lib/metadata/resolve-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,18 @@ async function mergeMetadata(
newResolvedMetadata.other,
metadata.other
)
if (metadata.other) {
if ('apple-touch-fullscreen' in metadata.other) {
buildState.warnings.add(
`Use appleWebApp instead\nRead more: https://nextjs.org/docs/app/api-reference/functions/generate-metadata`
)
}
if ('apple-touch-icon-precomposed' in metadata.other) {
buildState.warnings.add(
`Use icons.apple instead\nRead more: https://nextjs.org/docs/app/api-reference/functions/generate-metadata`
)
}
}
break
case 'metadataBase':
newResolvedMetadata.metadataBase = metadataBase
Expand Down
4 changes: 2 additions & 2 deletions packages/next/src/lib/metadata/types/extra-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export type ResolvedAppleWebApp = {
statusBarStyle?: 'default' | 'black' | 'black-translucent' | undefined
}

export type Facebook = FacebookAppId | FacebookAdmins
export type Facebook = FacebookAppId | FacebookAdmins | ResolvedFacebook
export type FacebookAppId = {
appId: string
admins?: never | undefined
Expand All @@ -106,7 +106,7 @@ export type ResolvedFacebook = {
admins?: string[] | undefined
}

export type Pinterest = PinterestRichPin
export type Pinterest = PinterestRichPin | ResolvedPinterest
export type PinterestRichPin = {
richPin: string | boolean
}
Expand Down
14 changes: 6 additions & 8 deletions packages/next/src/lib/metadata/types/metadata-interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,17 +557,17 @@ interface Metadata extends DeprecatedMetadataFields {
* ```
*/
other?:
| ({
| {
[name: string]: string | number | Array<string | number>
} & DeprecatedMetadataFields)
}
| undefined
}

/**
* ResolvedMetadataWithURLs represents the fully processed metadata after
* defaults are applied and relative URLs are composed with `metadataBase`.
*/
interface ResolvedMetadataWithURLs extends DeprecatedMetadataFields {
interface ResolvedMetadataWithURLs {
// origin and base path for absolute urls for various metadata links such as
// opengraph-image
metadataBase: string | null | URL
Expand Down Expand Up @@ -657,11 +657,9 @@ interface ResolvedMetadataWithURLs extends DeprecatedMetadataFields {
// meta name properties
category: null | string
classification: null | string
other:
| null
| ({
[name: string]: string | number | Array<string | number>
} & DeprecatedMetadataFields)
other: null | {
[name: string]: string | number | Array<string | number>
}
}

export type WithStringifiedURLs<T> = T extends URL
Expand Down
2 changes: 1 addition & 1 deletion packages/next/src/lib/metadata/types/opengraph-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type OpenGraphMetadata = {
images?: OGImage | Array<OGImage> | undefined
audio?: OGAudio | Array<OGAudio> | undefined
videos?: OGVideo | Array<OGVideo> | undefined
url?: string | URL | undefined
url?: null | string | URL | undefined
countryName?: string | undefined
ttl?: number | undefined
}
Expand Down
10 changes: 5 additions & 5 deletions packages/next/src/lib/metadata/types/twitter-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ export type Twitter =

type TwitterMetadata = {
// defaults to card="summary"
site?: string | undefined // username for account associated to the site itself
siteId?: string | undefined // id for account associated to the site itself
creator?: string | undefined // username for the account associated to the creator of the content on the site
creatorId?: string | undefined // id for the account associated to the creator of the content on the site
description?: string | undefined
site?: null | string | undefined // username for account associated to the site itself
siteId?: null | string | undefined // id for account associated to the site itself
creator?: null | string | undefined // username for the account associated to the creator of the content on the site
creatorId?: null | string | undefined // id for the account associated to the creator of the content on the site
description?: null | string | undefined
title?: string | TemplateString | undefined
images?: TwitterImage | Array<TwitterImage> | undefined
}
Expand Down
17 changes: 14 additions & 3 deletions packages/next/src/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -928,13 +928,24 @@ export function Html(
HTMLHtmlElement
>
) {
const { docComponentsRendered, locale, scriptLoader, __NEXT_DATA__ } =
useHtmlContext()
const {
docComponentsRendered,
locale,
scriptLoader,
deploymentId,
__NEXT_DATA__,
} = useHtmlContext()

docComponentsRendered.Html = true
handleDocumentScriptLoaderItems(scriptLoader, __NEXT_DATA__, props)

return <html {...props} lang={props.lang || locale || undefined} />
return (
<html
{...props}
lang={props.lang || locale || undefined}
data-dpl-id={deploymentId || undefined}
/>
)
}

export function Main() {
Expand Down
Loading
Loading