diff --git a/packages/next/src/lib/metadata/metadata.tsx b/packages/next/src/lib/metadata/metadata.tsx index ff5ac93e5af74..96d847179c3b0 100644 --- a/packages/next/src/lib/metadata/metadata.tsx +++ b/packages/next/src/lib/metadata/metadata.tsx @@ -162,14 +162,14 @@ export function createMetadataComponents({ } catch (notFoundMetadataErr) { // In PPR rendering we still need to throw the postpone error. // If metadata is postponed, React needs to be aware of the location of error. - if (isPostpone(notFoundMetadataErr)) { + if (serveStreamingMetadata && isPostpone(notFoundMetadataErr)) { throw notFoundMetadataErr } } } // In PPR rendering we still need to throw the postpone error. // If metadata is postponed, React needs to be aware of the location of error. - if (isPostpone(metadataErr)) { + if (serveStreamingMetadata && isPostpone(metadataErr)) { throw metadataErr } // We don't actually want to error in this component. We will diff --git a/test/e2e/app-dir/metadata-static-generation/metadata-static-generation.test.ts b/test/e2e/app-dir/metadata-static-generation/metadata-static-generation.test.ts index 85af160aa6d77..d8c0dd6528921 100644 --- a/test/e2e/app-dir/metadata-static-generation/metadata-static-generation.test.ts +++ b/test/e2e/app-dir/metadata-static-generation/metadata-static-generation.test.ts @@ -2,42 +2,46 @@ import { nextTestSetup } from 'e2e-utils' const isPPREnabled = process.env.__NEXT_EXPERIMENTAL_PPR === 'true' -describe('app-dir - metadata-static-generation', () => { - const { next, isNextStart } = nextTestSetup({ - files: __dirname, - }) +// PPR tests are covered in test/e2e/app-dir/ppr-metadata-blocking +;(isPPREnabled ? describe.skip : describe)( + 'app-dir - metadata-static-generation', + () => { + const { next, isNextStart } = nextTestSetup({ + files: __dirname, + }) + + if (isNextStart) { + // Precondition for the following tests in build mode. + // This test is only useful for non-PPR mode as in PPR mode those routes + // are all listed in the prerender manifest. + it('should generate all pages static', async () => { + const prerenderManifest = JSON.parse( + await next.readFile('.next/prerender-manifest.json') + ) + const staticRoutes = prerenderManifest.routes + expect(Object.keys(staticRoutes).sort()).toEqual([ + '/', + '/suspenseful/static', + ]) + }) + } - if (isNextStart && !isPPREnabled) { - // Precondition for the following tests in build mode. - // This test is only useful for non-PPR mode as in PPR mode those routes - // are all listed in the prerender manifest. - it('should generate all pages static', async () => { - const prerenderManifest = JSON.parse( - await next.readFile('.next/prerender-manifest.json') + it('should contain async generated metadata in head for simple static page', async () => { + const $ = await next.render$('/') + expect($('head title').text()).toBe('index page') + expect($('head meta[name="description"]').attr('content')).toBe( + 'index page description' ) - const staticRoutes = prerenderManifest.routes - expect(Object.keys(staticRoutes).sort()).toEqual([ - '/', - '/suspenseful/static', - ]) }) - } - - it('should contain async generated metadata in head for simple static page', async () => { - const $ = await next.render$('/') - expect($('head title').text()).toBe('index page') - expect($('head meta[name="description"]').attr('content')).toBe( - 'index page description' - ) - }) - it('should contain async generated metadata in head static page with suspenseful content', async () => { - const $ = await next.render$('/suspenseful/static') - expect($('head title').text()).toBe('suspenseful page - static') - }) + it('should contain async generated metadata in head static page with suspenseful content', async () => { + const $ = await next.render$('/suspenseful/static') + expect($('head title').text()).toBe('suspenseful page - static') + }) - it('should contain async generated metadata in head for dynamic page', async () => { - const $ = await next.render$('/suspenseful/dynamic') - expect($('head title').text()).toBe('suspenseful page - dynamic') - }) -}) + it('should contain async generated metadata in head for dynamic page', async () => { + const $ = await next.render$('/suspenseful/dynamic') + expect($('head title').text()).toBe('suspenseful page - dynamic') + }) + } +) diff --git a/test/e2e/app-dir/ppr-metadata-blocking/ppr-metadata-blocking-ppr-fallback.test.ts b/test/e2e/app-dir/ppr-metadata-blocking/ppr-metadata-blocking-ppr-fallback.test.ts new file mode 100644 index 0000000000000..1ae5b7e2b4395 --- /dev/null +++ b/test/e2e/app-dir/ppr-metadata-blocking/ppr-metadata-blocking-ppr-fallback.test.ts @@ -0,0 +1,37 @@ +import { nextTestSetup } from 'e2e-utils' + +function countSubstring(str: string, substr: string): number { + return str.split(substr).length - 1 +} + +describe('ppr-metadata-blocking-ppr-fallback', () => { + const { next, skipped } = nextTestSetup({ + files: __dirname, + skipDeployment: true, + env: { + __NEXT_EXPERIMENTAL_STATIC_SHELL_DEBUGGING: '1', + }, + }) + + if (skipped) return + + it('should not include metadata in partial shell when page is fully dynamic', async () => { + const $ = await next.render$('/fully-dynamic?__nextppronly=fallback') + expect(countSubstring($.html(), '