diff --git a/.github/workflows/build_reusable.yml b/.github/workflows/build_reusable.yml index 81a2ffe05f618..6cc1bc92c6c82 100644 --- a/.github/workflows/build_reusable.yml +++ b/.github/workflows/build_reusable.yml @@ -175,7 +175,7 @@ jobs: - run: turbo run get-test-timings -- --build ${{ github.sha }} - run: /bin/bash -c "${{ inputs.afterBuild }}" - timeout-minutes: 15 + timeout-minutes: 30 - name: Upload artifact uses: actions/upload-artifact@v4 diff --git a/packages/next-swc/crates/next-custom-transforms/src/transforms/react_server_components.rs b/packages/next-swc/crates/next-custom-transforms/src/transforms/react_server_components.rs index 40eabd224da83..10f8ed5454468 100644 --- a/packages/next-swc/crates/next-custom-transforms/src/transforms/react_server_components.rs +++ b/packages/next-swc/crates/next-custom-transforms/src/transforms/react_server_components.rs @@ -257,9 +257,9 @@ fn report_error(app_dir: &Option, filepath: &str, error_kind: RSCErrorK .unwrap_or_default(); let msg = if !is_app_dir { - format!("You're importing a component that needs {}. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/react-essentials#server-components\n\n", source) + format!("You're importing a component that needs \"{}\". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/react-essentials#server-components\n\n", source) } else { - format!("You're importing a component that needs {}. That only works in a Server Component but one of its parents is marked with \"use client\", so it's a Client Component.\nLearn more: https://nextjs.org/docs/getting-started/react-essentials\n\n", source) + format!("You're importing a component that needs \"{}\". That only works in a Server Component but one of its parents is marked with \"use client\", so it's a Client Component.\nLearn more: https://nextjs.org/docs/getting-started/react-essentials\n\n", source) }; (msg, span) } @@ -267,7 +267,7 @@ fn report_error(app_dir: &Option, filepath: &str, error_kind: RSCErrorK let msg = if source == "Component" { "You’re importing a class component. It only works in a Client Component but none of its parents are marked with \"use client\", so they're Server Components by default.\nLearn more: https://nextjs.org/docs/getting-started/react-essentials#client-components\n\n".to_string() } else { - format!("You're importing a component that needs {}. It only works in a Client Component but none of its parents are marked with \"use client\", so they're Server Components by default.\nLearn more: https://nextjs.org/docs/getting-started/react-essentials\n\n", source) + format!("You're importing a component that needs `{}`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `\"use client\"` directive.\n\n Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components\n\n", source) }; (msg,span) diff --git a/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/server-only/output.stderr b/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/server-only/output.stderr index 7600cc6e60894..dd20fed59e9d6 100644 --- a/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/server-only/output.stderr +++ b/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/client-graph/server-only/output.stderr @@ -1,5 +1,5 @@ - x You're importing a component that needs server-only. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/ + x You're importing a component that needs "server-only". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/ | react-essentials#server-components | | diff --git a/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-api/output.stderr b/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-api/output.stderr index e2afe9d109abe..f92341603eb1b 100644 --- a/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-api/output.stderr +++ b/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-api/output.stderr @@ -1,6 +1,7 @@ - x You're importing a component that needs useState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useState`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:1:1] @@ -8,8 +9,9 @@ : ^^^^^^^^ `---- - x You're importing a component that needs createContext. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `createContext`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:2:1] @@ -18,8 +20,9 @@ : ^^^^^^^^^^^^^ `---- - x You're importing a component that needs useEffect. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useEffect`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:4:1] @@ -28,8 +31,9 @@ : ^^^^^^^^^ `---- - x You're importing a component that needs useImperativeHandle. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useImperativeHandle`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:4:1] @@ -49,8 +53,9 @@ 9 | createFactory, `---- - x You're importing a component that needs createFactory. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `createFactory`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:8:1] @@ -60,8 +65,9 @@ 10 | PureComponent, `---- - x You're importing a component that needs PureComponent. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `PureComponent`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:9:1] @@ -71,8 +77,9 @@ 11 | useDeferredValue, `---- - x You're importing a component that needs useDeferredValue. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useDeferredValue`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:10:1] @@ -82,8 +89,9 @@ 12 | useInsertionEffect, `---- - x You're importing a component that needs useInsertionEffect. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useInsertionEffect`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:11:1] @@ -93,8 +101,9 @@ 13 | useLayoutEffect, `---- - x You're importing a component that needs useLayoutEffect. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useLayoutEffect`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:12:1] @@ -104,8 +113,9 @@ 14 | useReducer, `---- - x You're importing a component that needs useReducer. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useReducer`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:13:1] @@ -115,8 +125,9 @@ 15 | useRef, `---- - x You're importing a component that needs useRef. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useRef`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:14:1] @@ -126,8 +137,9 @@ 16 | useSyncExternalStore, `---- - x You're importing a component that needs useSyncExternalStore. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useSyncExternalStore`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:15:1] diff --git a/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-dom-api/output.stderr b/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-dom-api/output.stderr index 4cd910c9da2ee..0f61e8ce4bb78 100644 --- a/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-dom-api/output.stderr +++ b/packages/next-swc/crates/next-custom-transforms/tests/errors/react-server-components/server-graph/react-dom-api/output.stderr @@ -1,6 +1,7 @@ - x You're importing a component that needs flushSync. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `flushSync`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:1:1] @@ -8,9 +9,9 @@ : ^^^^^^^^^ `---- - x You're importing a component that needs unstable_batchedUpdates. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by - | default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `unstable_batchedUpdates`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:1:1] @@ -18,8 +19,9 @@ : ^^^^^^^^^^^^^^^^^^^^^^^ `---- - x You're importing a component that needs useActionState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useActionState`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:2:1] @@ -28,8 +30,9 @@ : ^^^^^^^^^^^^^^ `---- - x You're importing a component that needs useFormStatus. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useFormStatus`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:4:1] @@ -38,8 +41,9 @@ : ^^^^^^^^^^^^^ `---- - x You're importing a component that needs useFormState. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default. - | Learn more: https://nextjs.org/docs/getting-started/react-essentials + x You're importing a component that needs `useFormState`. This React hook only works in a client component. To fix, mark the file (or its parent) with the `"use client"` directive. + | + | Learn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components | | ,-[input.js:4:1] diff --git a/packages/next/src/build/webpack/plugins/wellknown-errors-plugin/parseRSC.ts b/packages/next/src/build/webpack/plugins/wellknown-errors-plugin/parseRSC.ts index 8e135b5fa22e1..18062b553ee80 100644 --- a/packages/next/src/build/webpack/plugins/wellknown-errors-plugin/parseRSC.ts +++ b/packages/next/src/build/webpack/plugins/wellknown-errors-plugin/parseRSC.ts @@ -34,7 +34,7 @@ function formatRSCErrorMessage( } else { formattedMessage = message.replace( NEXT_RSC_ERR_REACT_API, - `\n\nYou're importing a component that needs $1. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.\nLearn more: https://nextjs.org/docs/getting-started/react-essentials\n\n` + `\n\nYou're importing a component that needs $1. This React hook only works in a client component. To fix, mark the file (or its parent) with the \`"use client"\` directive. \n\nLearn more: https://nextjs.org/docs/app/building-your-application/rendering/client-components\n\n` ) } formattedVerboseMessage = diff --git a/test/development/acceptance-app/rsc-build-errors.test.ts b/test/development/acceptance-app/rsc-build-errors.test.ts index 77ffd7f4dac50..7aec7c8d49b83 100644 --- a/test/development/acceptance-app/rsc-build-errors.test.ts +++ b/test/development/acceptance-app/rsc-build-errors.test.ts @@ -277,7 +277,7 @@ describe('Error overlay - RSC build errors', () => { // `Component` has a custom error message api === 'Component' ? `You’re importing a class component. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.` - : `You're importing a component that needs ${api}. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.` + : `You're importing a component that needs \`${api}\`. This React hook only works in a client component. To fix, mark the file (or its parent) with the \`"use client"\` directive.` ) await cleanup() @@ -300,7 +300,7 @@ describe('Error overlay - RSC build errors', () => { expect(await session.hasRedbox()).toBe(true) expect(await session.getRedboxSource()).toInclude( - `You're importing a component that needs ${api}. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components` + `You're importing a component that needs \`${api}\`. This React hook only works in a client component. To fix, mark the file (or its parent) with the \`"use client"\` directive.` ) await cleanup() @@ -326,7 +326,7 @@ describe('Error overlay - RSC build errors', () => { expect(await session.hasRedbox()).toBe(true) expect(await session.getRedboxSource()).toInclude( - `You're importing a component that needs server-only. That only works in a Server Component but one of its parents is marked with "use client", so it's a Client Component.` + `You're importing a component that needs "server-only". That only works in a Server Component but one of its parents is marked with "use client", so it's a Client Component.` ) await cleanup() diff --git a/test/development/acceptance-app/server-components.test.ts b/test/development/acceptance-app/server-components.test.ts index 691ad9e247de5..4a803e6a349aa 100644 --- a/test/development/acceptance-app/server-components.test.ts +++ b/test/development/acceptance-app/server-components.test.ts @@ -550,7 +550,7 @@ describe('Error Overlay for server components', () => { // So we need to check for the first part of the message. const normalizedSource = await session.getRedboxSource() expect(normalizedSource).toContain( - `You're importing a component that needs ${hook}. It only works in a Client Component but none of its parents are marked with "use client"` + `You're importing a component that needs \`${hook}\`. This React hook only works in a client component. To fix, mark the file (or its parent) with the \`"use client"\` directive.` ) expect(normalizedSource).toContain( `import { ${hook} } from 'next/navigation'` diff --git a/test/development/acceptance/server-component-compiler-errors-in-pages.test.ts b/test/development/acceptance/server-component-compiler-errors-in-pages.test.ts index 588b716e544a6..8d52ec887dde5 100644 --- a/test/development/acceptance/server-component-compiler-errors-in-pages.test.ts +++ b/test/development/acceptance/server-component-compiler-errors-in-pages.test.ts @@ -65,14 +65,14 @@ describe('Error Overlay for server components compiler errors in pages', () => { 3 | export default function Page() { 4 | return

hello world

- You're importing a component that needs next/headers. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/react-essentials#server-components" + You're importing a component that needs "next/headers". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/react-essentials#server-components" `) } else { expect(next.normalizeTestDirContent(await session.getRedboxSource())) .toMatchInlineSnapshot(` "./components/Comp.js Error: - x You're importing a component that needs next/headers. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/ + x You're importing a component that needs "next/headers". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/ | react-essentials#server-components | | @@ -124,14 +124,14 @@ describe('Error Overlay for server components compiler errors in pages', () => { 3 | export default function Page() { 4 | return 'hello world' - You're importing a component that needs server-only. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/react-essentials#server-components" + You're importing a component that needs "server-only". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/react-essentials#server-components" `) } else { expect(next.normalizeTestDirContent(await session.getRedboxSource())) .toMatchInlineSnapshot(` "./components/Comp.js Error: - x You're importing a component that needs server-only. That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/ + x You're importing a component that needs "server-only". That only works in a Server Component which is not supported in the pages/ directory. Read more: https://nextjs.org/docs/getting-started/ | react-essentials#server-components | |