@@ -67,13 +67,83 @@ describe('build-output-tree-view', () => {
6767 ` )
6868 } )
6969 } )
70+
71+ describe ( 'with dynamic access and generateStaticParams' , ( ) => {
72+ describe . each ( [ true , false ] ) ( 'cache components: %s' , ( cacheComponents ) => {
73+ const { next } = nextTestSetup ( {
74+ files : path . join ( __dirname , 'fixtures/dynamic-generate-static-params' ) ,
75+ env : {
76+ __NEXT_PRIVATE_DETERMINISTIC_BUILD_OUTPUT : '1' ,
77+ } ,
78+ // We don't skip start in this test because we want to actually hit the
79+ // dynamic pages, and starting again would cause the current API to
80+ // re-build the app again.
81+ nextConfig : {
82+ experimental : {
83+ cacheComponents,
84+ } ,
85+ } ,
86+ } )
87+
88+ it ( 'should mark routes with connection() as dynamic, not SSG' , async ( ) => {
89+ if ( cacheComponents ) {
90+ // When cache components are enabled, routes with connection() should be
91+ // marked as partial prerendered.
92+ expect ( getTreeView ( next . cliOutput ) ) . toMatchInlineSnapshot ( `
93+ "Route (app)
94+ ┌ ○ /_not-found
95+ └ ◐ /dynamic/[slug]
96+ ├ /dynamic/[slug]
97+ ├ /dynamic/slug-01
98+ ├ /dynamic/slug-02
99+ └ /dynamic/slug-03
100+
101+
102+ ○ (Static) prerendered as static content
103+ ◐ (Partial Prerender) prerendered as static HTML with dynamic server-streamed content"
104+ ` )
105+ } else {
106+ // Routes with generateStaticParams that use connection() should be marked as dynamic
107+ // because connection() makes the page dynamic. This is a regression test for a bug
108+ // where pages with generateStaticParams were incorrectly marked as SSG even when
109+ // the individual routes used dynamic APIs.
110+ expect ( getTreeView ( next . cliOutput ) ) . toMatchInlineSnapshot ( `
111+ "Route (app)
112+ ┌ ○ /_not-found
113+ └ ƒ /dynamic/[slug]
114+ ├ /dynamic/slug-01
115+ ├ /dynamic/slug-02
116+ └ /dynamic/slug-03
117+
118+
119+ ○ (Static) prerendered as static content
120+ ƒ (Dynamic) server-rendered on demand"
121+ ` )
122+ }
123+ } )
124+
125+ it ( 'should render the dynamic pages correctly' , async ( ) => {
126+ // Test one of the generated routes. We expect it to render and not
127+ // error.
128+ const $ = await next . render$ ( '/dynamic/slug-01' )
129+ expect ( $ ( '#page' ) . text ( ) ) . toBe ( 'Page slug-01' )
130+ } )
131+ } )
132+ } )
70133} )
71134
72135function getTreeView ( cliOutput : string ) : string {
73136 let foundStart = false
137+ let cliHeader = 0
74138 const lines : string [ ] = [ ]
75139
76140 for ( const line of cliOutput . split ( '\n' ) ) {
141+ // Once we've seen the CLI header twice, we can stop reading the output,
142+ // as we've already collected the first command (the `next build` command)
143+ // and we can ignore the rest of the output.
144+ if ( line . includes ( '▲ Next.js' ) ) cliHeader ++
145+ if ( cliHeader === 2 ) break
146+
77147 foundStart ||= line . startsWith ( 'Route ' )
78148
79149 if ( foundStart ) {
0 commit comments