File tree Expand file tree Collapse file tree 5 files changed +96
-3
lines changed
packages/next/src/build/templates
test/e2e/app-dir/cache-components-bot-ua Expand file tree Collapse file tree 5 files changed +96
-3
lines changed Original file line number Diff line number Diff line change @@ -653,11 +653,13 @@ export async function handler(
653653 fallbackMode = parseFallbackField ( prerenderInfo . fallback )
654654 }
655655
656- // When serving a bot request, we want to serve a blocking render and not
657- // the prerendered page. This ensures that the correct content is served
656+ // When serving a HTML bot request, we want to serve a blocking render and
657+ // not the prerendered page. This ensures that the correct content is served
658658 // to the bot in the head.
659659 if ( fallbackMode === FallbackMode . PRERENDER && isBot ( userAgent ) ) {
660- fallbackMode = FallbackMode . BLOCKING_STATIC_RENDER
660+ if ( ! isRoutePPREnabled || isHtmlBot ) {
661+ fallbackMode = FallbackMode . BLOCKING_STATIC_RENDER
662+ }
661663 }
662664
663665 if ( previousCacheEntry ?. isStale === - 1 ) {
Original file line number Diff line number Diff line change 1+ import React from 'react'
2+
3+ import type { Metadata } from 'next'
4+
5+ export async function generateMetadata ( ) : Promise < Metadata > {
6+ await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) // Simulate a delay
7+ return {
8+ title : 'Home' ,
9+ description : 'Welcome to the home page' ,
10+ }
11+ }
12+
13+ export default async function Home ( {
14+ params,
15+ } : {
16+ params : Promise < { slug : string } >
17+ } ) {
18+ const { slug } = await params
19+ // Math.random() will cause SSG_BAILOUT if static generation runs
20+ // Bots should bypass static generation in PPR to avoid this error
21+ const randomValue = Math . random ( )
22+
23+ return (
24+ < >
25+ < h1 > { slug } </ h1 >
26+ < p > { randomValue } </ p >
27+ </ >
28+ )
29+ }
Original file line number Diff line number Diff line change 1+ import React , { Suspense } from 'react'
2+ import type { Metadata } from 'next'
3+
4+ export const metadata : Metadata = {
5+ title : 'PPR Bot SSG Bypass Test' ,
6+ description :
7+ 'Test bot static generation bypass with PPR and cache components' ,
8+ }
9+
10+ export default function RootLayout ( {
11+ children,
12+ } : {
13+ children : React . ReactNode
14+ } ) {
15+ return (
16+ < html lang = "en" >
17+ < body >
18+ < Suspense > { children } </ Suspense >
19+ </ body >
20+ </ html >
21+ )
22+ }
Original file line number Diff line number Diff line change 1+ import { nextTestSetup } from 'e2e-utils'
2+
3+ describe ( 'cache-components PPR bot static generation bypass' , ( ) => {
4+ const { next } = nextTestSetup ( {
5+ files : __dirname ,
6+ } )
7+
8+ it ( 'should bypass static generation for DOM bot requests to avoid SSG_BAILOUT' , async ( ) => {
9+ const res = await next . fetch ( '/foo' , {
10+ headers : {
11+ 'user-agent' : 'Googlebot' ,
12+ } ,
13+ } )
14+ // With cache components + PPR enabled, DOM bots should behave like regular users
15+ // and use the fallback cache mechanism. This allows them to handle dynamic content
16+ // like Math.random() without triggering SSG_BAILOUT errors.
17+ expect ( res . status ) . toBe ( 200 )
18+
19+ // Verify that the response contains the page content
20+ const html = await res . text ( )
21+
22+ // Check that the page rendered successfully
23+ // With PPR, content is streamed via script tags
24+ expect ( html ) . toContain ( '\\"children\\":\\"foo\\"' )
25+
26+ // Verify Math.random() was executed (check for a decimal number in the streamed content)
27+ expect ( html ) . toMatch ( / \\ " c h i l d r e n \\ " : 0 \. \d + / )
28+
29+ // With PPR, content is streamed, but the important thing is that
30+ // the page rendered without a 500 error
31+ } )
32+ } )
Original file line number Diff line number Diff line change 1+ /** @type {import('next').NextConfig } */
2+ const nextConfig = {
3+ experimental : {
4+ cacheComponents : true ,
5+ } ,
6+ }
7+
8+ module . exports = nextConfig
You can’t perform that action at this time.
0 commit comments