Skip to content

fix: ignore metadata from default.js #75669

New issue

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

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

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
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
12 changes: 11 additions & 1 deletion packages/next/src/lib/metadata/resolve-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import {
import { resolveIcons } from './resolvers/resolve-icons'
import { getTracer } from '../../server/lib/trace/tracer'
import { ResolveMetadataSpan } from '../../server/lib/trace/constants'
import { PAGE_SEGMENT_KEY } from '../../shared/lib/segment'
import { DEFAULT_SEGMENT_KEY, PAGE_SEGMENT_KEY } from '../../shared/lib/segment'
import * as Log from '../../build/output/log'
import type { WorkStore } from '../../server/app-render/work-async-storage.external'
import type {
Expand Down Expand Up @@ -443,6 +443,7 @@ async function collectMetadata({
const hasErrorConventionComponent = Boolean(
errorConvention && tree[2][errorConvention]
)

if (errorConvention) {
mod = await getComponentTypeModule(tree, 'layout')
modType = errorConvention
Expand Down Expand Up @@ -550,6 +551,15 @@ async function resolveMetadataItemsImpl(
}
}

const pageKey = tree[0]

// If it's default.js, ignore the metadata
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's possible that the default is the page though right? since the way resolution works is that page gets higher priority, but without a page, default is given priority.

ref:

page = segment === DEFAULT_SEGMENT_KEY ? modules.defaultPage : page

// webpack loader: pageKey of the default.js is DEFAULT_SEGMENT_KEY ('__DEFAULT__')
// turbopack loader: pageKey of the parallel route @bar is 'page$'
const isDefaultPage = pageKey === DEFAULT_SEGMENT_KEY || pageKey === 'page$'
if (isDefaultPage) {
return metadataItems
}
await collectMetadata({
tree,
metadataItems,
Expand Down
19 changes: 19 additions & 0 deletions test/e2e/app-dir/metadata-parallel-routes/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Link from 'next/link'
import React from 'react'

export default function Root({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<div>
<Link href="/nested">to nested</Link>
</div>
<div>
<Link href="/nested/subroute">to nested subroute</Link>
</div>
<h1>Root Layout</h1>
<div>{children}</div>
</body>
</html>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function Default() {
console.log(
'@bar default page',
typeof window !== 'undefined' ? 'client' : 'server'
)
return '@bar default'
}

export const metadata = {
title: '@bar - page',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default function Layout({ children }) {
return (
<div>
<h1>@bar Layout</h1>
<div id="bar-children">{children}</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Page() {
return <div>Bar Slot</div>
}

export const metadata = {
title: '@bar - page',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Page() {
return <div>Subroute</div>
}

export const metadata = {
title: 'subroute - page',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function Default() {
console.log(
'foo default default page',
typeof window !== 'undefined' ? 'client' : 'server'
)
return '@foo default'
}

export const metadata = {
title: '@foo - default',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default function Layout({ children }) {
return (
<div>
<h1>@foo Layout</h1>
<div id="foo-children">{children}</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Page() {
return <div>Foo Slot</div>
}

export const metadata = {
title: '@foo - page',
}
11 changes: 11 additions & 0 deletions test/e2e/app-dir/metadata-parallel-routes/app/nested/default.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function Page() {
console.log(
'nested default page',
typeof window !== 'undefined' ? 'client' : 'server'
)
return 'nested default page'
}

export const metadata = {
title: 'nested - default',
}
10 changes: 10 additions & 0 deletions test/e2e/app-dir/metadata-parallel-routes/app/nested/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default function Layout({ children, bar, foo }) {
return (
<div>
<h1>Nested Layout</h1>
<div id="nested-children">{children}</div>
<div id="foo-slot">{foo}</div>
<div id="bar-slot">{bar}</div>
</div>
)
}
7 changes: 7 additions & 0 deletions test/e2e/app-dir/metadata-parallel-routes/app/nested/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default function Page() {
return <div>Hello from Nested</div>
}

export const metadata = {
title: 'nested - page',
}
3 changes: 3 additions & 0 deletions test/e2e/app-dir/metadata-parallel-routes/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default async function Home() {
return <div>Hello World</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { nextTestSetup } from 'e2e-utils'

describe('metadata-parallel-routes', () => {
const { next } = nextTestSetup({
files: __dirname,
})

it('should ignore metadata from default.js in normal route', async () => {
const $ = await next.render$('/')
// When there's no title, parallel routes should not affect it
expect($('title').length).toBe(0)

// When there's defined title, parallel routes should not affect it
const $nested = await next.render$('/nested')
expect($nested('title').text()).toBe('nested - page')
})

it('should ignore metadata from default.js in parallel routes', async () => {
const $ = await next.render$('/nested/subroute')
expect($('title').text()).toBe('subroute - page')
})
})
6 changes: 6 additions & 0 deletions test/e2e/app-dir/metadata-parallel-routes/next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @type {import('next').NextConfig}
*/
const nextConfig = {}

module.exports = nextConfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export default function Page() {
return <div>Bar Slot</div>
}

export const metadata = {
title: 'nested - page',
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export default function Page() {
return <div>Subroute</div>
}

export const metadata = {
title: 'subroute - page',
}
Loading