Skip to content
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

fix: improved hybrid hook support #41611

Closed

Conversation

wyattjoh
Copy link
Member

@wyattjoh wyattjoh commented Oct 20, 2022

These hooks when accessed from different router context's in fact, return null. These new router hooks have been adapted to be backwards compatible with the pages router to ease the migration process.

Bug

  • Related issues linked using fixes #number
  • Integration tests added
  • Errors have a helpful link attached, see contributing.md

Feature

  • Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
  • Related issues linked using fixes #number
  • Integration tests added
  • Documentation added
  • Telemetry added. In case of a feature if it's used or not.
  • Errors have a helpful link attached, see contributing.md

Documentation / Examples

  • Make sure the linting passes by running pnpm lint
  • The "examples guidelines" are followed from our contributing doc

@wyattjoh wyattjoh force-pushed the wyattjoh/improved-hybrid-hook-support branch from 4e6c49e to 6a091a5 Compare October 21, 2022 20:14
@wyattjoh wyattjoh marked this pull request as ready for review October 21, 2022 20:16
@ijjk
Copy link
Member

ijjk commented Oct 21, 2022

Failing test suites

Commit: 6a091a5

pnpm testheadless test/integration/link-without-router/test/index.test.js

  • Link without a router > dev mode > should not throw when rendered
  • Link without a router > production mode > should not throw when rendered
Expand output

● Link without a router › dev mode › should not throw when rendered

invariant at least one router was expected

  141 |     }
  142 |
> 143 |     throw new Error('invariant at least one router was expected')
      |           ^
  144 |   }, [router, appRouter])
  145 | }
  146 |

  at ../packages/next/client/components/navigation.ts:143:11
  at mountMemo (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:17225:19)
  at Object.useMemo (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:17670:16)
  at Object.useMemo (../node_modules/.pnpm/react@18.2.0/node_modules/react/cjs/react.development.js:1650:21)
  at Object.HYBRID_ROUTER_TYPE [as useRouter] (../packages/next/client/components/navigation.ts:144:26)
  at LinkComponent (../packages/next/client/link.tsx:352:32)
  at renderWithHooks (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:16305:18)
  at updateForwardRef (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:19226:20)
  at beginWork (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:21636:16)
  at beginWork$1 (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:27426:14)
  at performUnitOfWork (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:26560:12)
  at workLoopSync (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:26466:5)
  at renderRootSync (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:26434:7)
  at performSyncWorkOnRoot (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:26085:20)
  at flushSyncCallbacks (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
  at flushSync (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:26201:7)
  at legacyCreateRootFromDOMContainer (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:29575:5)
  at legacyRenderSubtreeIntoContainer (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:29601:12)
  at render (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:29685:10)
  at integration/link-without-router/test/index.test.js:29:15
  at act (../node_modules/.pnpm/react@18.2.0/node_modules/react/cjs/react.development.js:2512:16)
  at Object.<anonymous> (integration/link-without-router/test/index.test.js:28:10)
  at TestScheduler.scheduleTests (../node_modules/.pnpm/@jest+core@27.0.6_node-notifier@8.0.1/node_modules/@jest/core/build/TestScheduler.js:333:13)
  at runJest (../node_modules/.pnpm/@jest+core@27.0.6_node-notifier@8.0.1/node_modules/@jest/core/build/runJest.js:387:19)
  at _run10000 (../node_modules/.pnpm/@jest+core@27.0.6_node-notifier@8.0.1/node_modules/@jest/core/build/cli/index.js:408:7)
  at runCLI (../node_modules/.pnpm/@jest+core@27.0.6_node-notifier@8.0.1/node_modules/@jest/core/build/cli/index.js:261:3)

● Link without a router › production mode › should not throw when rendered

invariant at least one router was expected

  141 |     }
  142 |
> 143 |     throw new Error('invariant at least one router was expected')
      |           ^
  144 |   }, [router, appRouter])
  145 | }
  146 |

  at ../packages/next/client/components/navigation.ts:143:11
  at mountMemo (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:17225:19)
  at Object.useMemo (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:17670:16)
  at Object.useMemo (../node_modules/.pnpm/react@18.2.0/node_modules/react/cjs/react.development.js:1650:21)
  at Object.HYBRID_ROUTER_TYPE [as useRouter] (../packages/next/client/components/navigation.ts:144:26)
  at LinkComponent (../packages/next/client/link.tsx:352:32)
  at renderWithHooks (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:16305:18)
  at updateForwardRef (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:19226:20)
  at beginWork (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:21636:16)
  at beginWork$1 (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:27426:14)
  at performUnitOfWork (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:26560:12)
  at workLoopSync (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:26466:5)
  at renderRootSync (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:26434:7)
  at performSyncWorkOnRoot (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:26085:20)
  at flushSyncCallbacks (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:12042:22)
  at flushSync (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:26201:7)
  at legacyCreateRootFromDOMContainer (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:29575:5)
  at legacyRenderSubtreeIntoContainer (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:29601:12)
  at render (../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom/cjs/react-dom.development.js:29685:10)
  at integration/link-without-router/test/index.test.js:45:15
  at act (../node_modules/.pnpm/react@18.2.0/node_modules/react/cjs/react.development.js:2512:16)
  at Object.<anonymous> (integration/link-without-router/test/index.test.js:44:10)
  at TestScheduler.scheduleTests (../node_modules/.pnpm/@jest+core@27.0.6_node-notifier@8.0.1/node_modules/@jest/core/build/TestScheduler.js:333:13)
  at runJest (../node_modules/.pnpm/@jest+core@27.0.6_node-notifier@8.0.1/node_modules/@jest/core/build/runJest.js:387:19)
  at _run10000 (../node_modules/.pnpm/@jest+core@27.0.6_node-notifier@8.0.1/node_modules/@jest/core/build/cli/index.js:408:7)
  at runCLI (../node_modules/.pnpm/@jest+core@27.0.6_node-notifier@8.0.1/node_modules/@jest/core/build/cli/index.js:261:3)

Read more about building and testing Next.js in contributing.md.

pnpm testheadless test/production/jest/new-link-behavior.test.ts

  • next/jest newLinkBehavior > should use new link behavior
Expand output

● next/jest newLinkBehavior › should use new link behavior

next build failed with code/signal 1

  75 |         if (code || signal)
  76 |           reject(
> 77 |             new Error(`next build failed with code/signal ${code || signal}`)
     |             ^
  78 |           )
  79 |         else resolve()
  80 |       })

  at ChildProcess.<anonymous> (lib/next-modes/next-start.ts:77:13)

Read more about building and testing Next.js in contributing.md.

pnpm testheadless test/integration/typescript/test/index.test.js

  • TypeScript Features > should build the app
  • TypeScript Features > should build the app with functions in next.config.js
  • TypeScript Features > should compile with different types > should compile async getInitialProps for _error
  • TypeScript Features > should compile with different types > should compile sync getStaticPaths & getStaticProps
Expand output

● TypeScript Features › should build the app

expect(received).toMatch(expected)

Expected pattern: /Compiled successfully/
Received string:  "info  - Linting and checking validity of types...
"

  105 |   it('should build the app', async () => {
  106 |     const output = await nextBuild(appDir, [], { stdout: true })
> 107 |     expect(output.stdout).toMatch(/Compiled successfully/)
      |                           ^
  108 |     expect(output.code).toBe(0)
  109 |   })
  110 |

  at Object.<anonymous> (integration/typescript/test/index.test.js:107:27)

● TypeScript Features › should build the app with functions in next.config.js

expect(received).toMatch(expected)

Expected pattern: /Compiled successfully/
Received string:  "info  - Linting and checking validity of types...
"

  125 |       const output = await nextBuild(appDir, [], { stdout: true })
  126 |
> 127 |       expect(output.stdout).toMatch(/Compiled successfully/)
      |                             ^
  128 |       expect(output.code).toBe(0)
  129 |     } finally {
  130 |       nextConfig.restore()

  at Object.<anonymous> (integration/typescript/test/index.test.js:127:29)

● TypeScript Features › should compile with different types › should compile async getInitialProps for _error

expect(received).toMatch(expected)

Expected pattern: /Compiled successfully/
Received string:  "info  - Linting and checking validity of types...
"

  143 |         errorPage.replace('static ', 'static async ')
  144 |         const output = await nextBuild(appDir, [], { stdout: true })
> 145 |         expect(output.stdout).toMatch(/Compiled successfully/)
      |                               ^
  146 |       } finally {
  147 |         errorPage.restore()
  148 |       }

  at Object.<anonymous> (integration/typescript/test/index.test.js:145:31)

● TypeScript Features › should compile with different types › should compile sync getStaticPaths & getStaticProps

expect(received).toMatch(expected)

Expected pattern: /Compiled successfully/
Received string:  "info  - Linting and checking validity of types...
"

  154 |         page.replace(/async \(/g, '(')
  155 |         const output = await nextBuild(appDir, [], { stdout: true })
> 156 |         expect(output.stdout).toMatch(/Compiled successfully/)
      |                               ^
  157 |       } finally {
  158 |         page.restore()
  159 |       }

  at Object.<anonymous> (integration/typescript/test/index.test.js:156:31)

Read more about building and testing Next.js in contributing.md.

pnpm testheadless test/e2e/streaming-ssr/index.test.ts

  • react 18 streaming SSR with custom next configs > should redirect paths without trailing-slash and render when slash is appended
Expand output

● react 18 streaming SSR with custom next configs › should redirect paths without trailing-slash and render when slash is appended

expect(received).toBe(expected) // Object.is equality

Expected: 200
Received: 500

  61 |
  62 |     expect(redirectRes.status).toBe(308)
> 63 |     expect(res.status).toBe(200)
     |                        ^
  64 |     expect(html).toContain('hello nextjs')
  65 |     expect(html).toContain('home')
  66 |   })

  at Object.<anonymous> (e2e/streaming-ssr/index.test.ts:63:24)

Read more about building and testing Next.js in contributing.md.

pnpm testheadless test/e2e/switchable-runtime/index.test.ts

  • Switchable runtime > Switchable runtime (dev) > should sort edge SSR routes correctly
  • Switchable runtime > Switchable runtime (dev) > should be able to navigate between edge SSR routes without any errors
Expand output

● Switchable runtime › Switchable runtime (dev) › should sort edge SSR routes correctly

expect(received).toContain(expected) // indexOf

Expected substring: "to /edge/[id]"
Received string:    "<!DOCTYPE html><html><head><link rel=\"preload\" href=\"/_next/static/chunks/webpack.js?ts=1666384327184\" as=\"script\"/><link rel=\"preload\" href=\"/_next/static/chunks/main.js?ts=1666384327184\" as=\"script\"/><link rel=\"preload\" href=\"/_next/static/chunks/pages/_app.js?ts=1666384327184\" as=\"script\"/><link rel=\"preload\" href=\"/_next/static/chunks/pages/_error.js?ts=1666384327184\" as=\"script\"/><style data-next-hide-fouc=\"true\">body{display:none}</style><noscript data-next-hide-fouc=\"true\"><style>body{display:block}</style></noscript><meta charSet=\"utf-8\"/><meta name=\"viewport\" content=\"width=device-width\"/><title>Application error: a client-side exception has occurred</title><meta name=\"next-head-count\" content=\"3\"/><meta name=\"next-font-preconnect\"/><noscript data-n-css=\"\"></noscript><noscript id=\"__next_css__DO_NOT_USE__\"></noscript></head><body><div id=\"__next\"><div style=\"font-family:-apple-system, BlinkMacSystemFont, Roboto, &quot;Segoe UI&quot;, &quot;Fira Sans&quot;, Avenir, &quot;Helvetica Neue&quot;, &quot;Lucida Grande&quot;, sans-serif;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center\"><div><style>
                body { margin: 0; color: #000; background: #fff; }
                .next-error-h1 {
                  border-right: 1px solid rgba(0, 0, 0, .3);
                }·
                @media (prefers-color-scheme: dark) {
                  body { color: #fff; background: #000; }
                  .next-error-h1 {
                    border-right: 1px solid rgba(255, 255, 255, .3);
                  }
                }</style><div style=\"display:inline-block;text-align:left;line-height:49px;height:49px;vertical-align:middle\"><h2 style=\"font-size:14px;font-weight:normal;line-height:49px;margin:0;padding:0\">Application error: a client-side exception has occurred (see the browser console for more information)<!-- -->.</h2></div></div></div></div><script src=\"/_next/static/chunks/react-refresh.js?ts=1666384327184\"></script><script id=\"__NEXT_DATA__\" type=\"application/json\">{\"props\":{\"pageProps\":{}},\"page\":\"/_error\",\"query\":{},\"buildId\":\"development\",\"isFallback\":false,\"err\":{\"name\":\"Error\",\"source\":\"server\",\"message\":\"invariant at least one router was expected\",\"stack\":\"Error: invariant at least one router was expected\\n    at eval (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/client/components/navigation.js:117:15)\\n    at Object.useMemo (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:6661:19)\\n    at Object.useMemo (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react/cjs/react.development.js:1703:21)\\n    at Object.useRouter (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/client/components/navigation.js:106:24)\\n    at LinkComponent (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/client/link.js:179:37)\\n    at renderWithHooks (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:7364:16)\\n    at renderForwardRef (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:7548:18)\\n    at renderElement (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:7728:11)\\n    at renderNodeDestructiveImpl (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:7829:11)\\n    at renderNodeDestructive (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:7801:14)\"},\"customServer\":true,\"gip\":true,\"scriptLoader\":[]}</script><script nomodule=\"\" src=\"/_next/static/chunks/polyfills.js?ts=1666384327184\"></script><script src=\"/_next/static/chunks/webpack.js?ts=1666384327184\"></script><script src=\"/_next/static/chunks/main.js?ts=1666384327184\"></script><script src=\"/_next/static/chunks/pages/_app.js?ts=1666384327184\"></script><script src=\"/_next/static/chunks/pages/_error.js?ts=1666384327184\"></script><script src=\"/_next/static/development/_buildManifest.js?ts=1666384327184\"></script><script src=\"/_next/static/development/_ssgManifest.js?ts=1666384327184\"></script></body></html>"

  82 |
  83 |         // /edge/foo should be caught before /edge/[id]
> 84 |         expect(html).toContain(`to /edge/[id]`)
     |                      ^
  85 |       })
  86 |
  87 |       it('should be able to navigate between edge SSR routes without any errors', async () => {

  at Object.<anonymous> (e2e/switchable-runtime/index.test.ts:84:22)

● Switchable runtime › Switchable runtime (dev) › should be able to navigate between edge SSR routes without any errors

expect(received).toContain(expected) // indexOf

Expected substring: "to /edge/[id]"
Received string:    "<!DOCTYPE html><html><head><link rel=\"preload\" href=\"/_next/static/chunks/webpack.js?ts=1666384327645\" as=\"script\"/><link rel=\"preload\" href=\"/_next/static/chunks/main.js?ts=1666384327645\" as=\"script\"/><link rel=\"preload\" href=\"/_next/static/chunks/pages/_app.js?ts=1666384327645\" as=\"script\"/><link rel=\"preload\" href=\"/_next/static/chunks/pages/_error.js?ts=1666384327645\" as=\"script\"/><style data-next-hide-fouc=\"true\">body{display:none}</style><noscript data-next-hide-fouc=\"true\"><style>body{display:block}</style></noscript><meta charSet=\"utf-8\"/><meta name=\"viewport\" content=\"width=device-width\"/><title>Application error: a client-side exception has occurred</title><meta name=\"next-head-count\" content=\"3\"/><meta name=\"next-font-preconnect\"/><noscript data-n-css=\"\"></noscript><noscript id=\"__next_css__DO_NOT_USE__\"></noscript></head><body><div id=\"__next\"><div style=\"font-family:-apple-system, BlinkMacSystemFont, Roboto, &quot;Segoe UI&quot;, &quot;Fira Sans&quot;, Avenir, &quot;Helvetica Neue&quot;, &quot;Lucida Grande&quot;, sans-serif;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center\"><div><style>
                body { margin: 0; color: #000; background: #fff; }
                .next-error-h1 {
                  border-right: 1px solid rgba(0, 0, 0, .3);
                }·
                @media (prefers-color-scheme: dark) {
                  body { color: #fff; background: #000; }
                  .next-error-h1 {
                    border-right: 1px solid rgba(255, 255, 255, .3);
                  }
                }</style><div style=\"display:inline-block;text-align:left;line-height:49px;height:49px;vertical-align:middle\"><h2 style=\"font-size:14px;font-weight:normal;line-height:49px;margin:0;padding:0\">Application error: a client-side exception has occurred (see the browser console for more information)<!-- -->.</h2></div></div></div></div><script src=\"/_next/static/chunks/react-refresh.js?ts=1666384327645\"></script><script id=\"__NEXT_DATA__\" type=\"application/json\">{\"props\":{\"pageProps\":{}},\"page\":\"/_error\",\"query\":{},\"buildId\":\"development\",\"isFallback\":false,\"err\":{\"name\":\"Error\",\"source\":\"server\",\"message\":\"invariant at least one router was expected\",\"stack\":\"Error: invariant at least one router was expected\\n    at eval (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/client/components/navigation.js:117:15)\\n    at Object.useMemo (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:6661:19)\\n    at Object.useMemo (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react/cjs/react.development.js:1703:21)\\n    at Object.useRouter (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/client/components/navigation.js:106:24)\\n    at LinkComponent (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/client/link.js:179:37)\\n    at renderWithHooks (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:7364:16)\\n    at renderForwardRef (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:7548:18)\\n    at renderElement (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:7728:11)\\n    at renderNodeDestructiveImpl (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:7829:11)\\n    at renderNodeDestructive (webpack-internal:///./node_modules/.pnpm/file+..+next-repo-283dde6f021ab33ee1ab8fa464a3663c_lbmvaaeaekcc3t7i6eymif5l7i/node_modules/next/dist/compiled/react-dom/cjs/react-dom-server.browser.development.js:7801:14)\"},\"customServer\":true,\"gip\":true,\"scriptLoader\":[]}</script><script nomodule=\"\" src=\"/_next/static/chunks/polyfills.js?ts=1666384327645\"></script><script src=\"/_next/static/chunks/webpack.js?ts=1666384327645\"></script><script src=\"/_next/static/chunks/main.js?ts=1666384327645\"></script><script src=\"/_next/static/chunks/pages/_app.js?ts=1666384327645\"></script><script src=\"/_next/static/chunks/pages/_error.js?ts=1666384327645\"></script><script src=\"/_next/static/development/_buildManifest.js?ts=1666384327645\"></script><script src=\"/_next/static/development/_ssgManifest.js?ts=1666384327645\"></script></body></html>"

  90 |
  91 |         // /edge/foo should be caught before /edge/[id]
> 92 |         expect(html).toContain(`to /edge/[id]`)
     |                      ^
  93 |
  94 |         const browser = await webdriver(context.appPort, '/edge/foo')
  95 |

  at Object.<anonymous> (e2e/switchable-runtime/index.test.ts:92:22)

Read more about building and testing Next.js in contributing.md.

pnpm testheadless test/e2e/app-dir/index.test.ts

  • app dir > nested navigation > should navigate to nested pages
Expand output

● app dir › nested navigation › should navigate to nested pages

page.waitForSelector: Timeout 30000ms exceeded.
=========================== logs ===========================
waiting for selector "#all-electronics"
============================================================

  329 |     return this.chain(() => {
  330 |       return page
> 331 |         .waitForSelector(selector, { timeout, state: 'attached' })
      |          ^
  332 |         .then(async (el) => {
  333 |           // it seems selenium waits longer and tests rely on this behavior
  334 |           // so we wait for the load event fire before returning

  at lib/browsers/playwright.ts:331:10
  at Object.<anonymous> (e2e/app-dir/index.test.ts:1907:13)

Read more about building and testing Next.js in contributing.md.

return readonlySearchParams
}

// TODO-APP: Move the other router context over to this one
/**
* Get the router methods. For example router.push('/dashboard')
*/
export function useRouter(): import('../../shared/lib/app-router-context').AppRouterInstance {
return useContext(AppRouterContext)
export function useRouter(): HybridRouter {
Copy link
Member

Choose a reason for hiding this comment

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

The way I was thinking about this is that this always returns a AppRouterInstance, we'd just set AppRouterContext for the pages router too with it's own AppRouterInstance object that under the hood calls the existing router. Does that make sense? It would keep the type the same regardless and makes migrating easier.

Copy link
Member Author

Choose a reason for hiding this comment

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

That makes sense! I can look into making these changes.

@@ -97,8 +152,19 @@ export function useRouter(): import('../../shared/lib/app-router-context').AppRo
/**
* Get the current pathname. For example usePathname() on /dashboard?foo=bar would return "/dashboard"
*/
export function usePathname(): string {
return useContext(PathnameContext)
export function usePathname(): string | null {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this should throw in the null case. I'd prefer it to always be a string as that's how it's supposed to be in the new router.

Copy link
Member Author

Choose a reason for hiding this comment

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

If we change it to throws then during migration, this would cause any component using it from pages to throw too. This sort of defeats the purpose for the hybrid approach.

@wyattjoh wyattjoh force-pushed the wyattjoh/improved-hybrid-hook-support branch from 6a091a5 to 8e1b754 Compare October 23, 2022 20:19
@wyattjoh wyattjoh closed this Oct 25, 2022
@wyattjoh wyattjoh deleted the wyattjoh/improved-hybrid-hook-support branch October 25, 2022 04:13
@wyattjoh
Copy link
Member Author

Closed in favor of #41767

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants