diff --git a/.alexrc b/.alexrc index 47862f2c80a1..1f1de4b4382a 100644 --- a/.alexrc +++ b/.alexrc @@ -17,6 +17,7 @@ "hooks", "host-hostess", "invalid", - "remains" + "remains", + "white" ] } diff --git a/.github/workflows/build_test_deploy.yml b/.github/workflows/build_test_deploy.yml index b22bb436c1c3..fd346920c8d6 100644 --- a/.github/workflows/build_test_deploy.yml +++ b/.github/workflows/build_test_deploy.yml @@ -1060,7 +1060,7 @@ jobs: build-native-test: name: Build native binary for tests and metrics - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: # https://github.com/actions/virtual-environments/issues/1187 - name: tune linux network @@ -1092,14 +1092,14 @@ jobs: if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }} with: path: ~/.cargo/registry - key: stable-ubuntu-18.04-cargo-registry + key: stable-ubuntu-latest-cargo-registry - name: Cache cargo index uses: actions/cache@v3 if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }} with: path: ~/.cargo/git - key: stable-ubuntu-18.04-cargo-index + key: stable-ubuntu-latest-cargo-index # We use week in the turbo cache key to keep the cache from infinitely growing - id: get-week @@ -1125,9 +1125,9 @@ jobs: uses: actions/cache@v3 with: path: ./packages/next-swc/target - key: next-swc-cargo-cache-dev-ubuntu-18.04-${{ hashFiles('**/Cargo.lock') }} + key: next-swc-cargo-cache-dev-ubuntu-latest-${{ hashFiles('**/Cargo.lock') }} restore-keys: | - next-swc-cargo-cache-dev-ubuntu-18.04 + next-swc-cargo-cache-dev-ubuntu-latest # since the repo's dependencies aren't installed we need # to install napi globally @@ -1152,7 +1152,7 @@ jobs: test-native: name: Unit Test Native Code - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -1176,7 +1176,7 @@ jobs: test-wasm: name: Test the wasm build - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest needs: [build, build-native-test, build-wasm-dev] steps: @@ -1294,7 +1294,7 @@ jobs: export CC_aarch64_unknown_linux_gnu=/usr/aarch64-unknown-linux-gnu/bin/aarch64-unknown-linux-gnu-gcc && turbo run build-native --cache-dir=".turbo" -- --release --target aarch64-unknown-linux-gnu && llvm-strip -x packages/next-swc/native/next-swc.*.node - - host: ubuntu-18.04 + - host: ubuntu-latest target: 'armv7-unknown-linux-gnueabihf' setup: | sudo apt-get update @@ -1357,7 +1357,7 @@ jobs: # https://github.com/actions/virtual-environments/issues/1187 - name: tune linux network run: sudo ethtool -K eth0 tx off rx off - if: ${{ matrix.settings.host == 'ubuntu-18.04' }} + if: ${{ matrix.settings.host == 'ubuntu-latest' }} - name: tune linux network run: sudo ethtool -K eth0 tx off rx off if: ${{ matrix.settings.host == 'ubuntu-latest' }} diff --git a/.github/workflows/pull_request_stats.yml b/.github/workflows/pull_request_stats.yml index 0971e1b6221e..5a9dc25f116d 100644 --- a/.github/workflows/pull_request_stats.yml +++ b/.github/workflows/pull_request_stats.yml @@ -13,7 +13,7 @@ env: jobs: build-native-dev: name: Build dev binary for tests - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest steps: # https://github.com/actions/virtual-environments/issues/1187 - name: tune linux network @@ -46,14 +46,14 @@ jobs: if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }} with: path: ~/.cargo/registry - key: stable-ubuntu-18.04-node@14-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }} + key: stable-ubuntu-latest-node@14-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }} - name: Cache cargo index uses: actions/cache@v1 if: ${{ steps.docs-change.outputs.DOCS_CHANGE == 'nope' }} with: path: ~/.cargo/git - key: stable-ubuntu-18.04-node@14-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }} + key: stable-ubuntu-latest-node@14-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }} # We use week in the turbo cache key to keep the cache from infinitely growing - id: get-week @@ -78,9 +78,9 @@ jobs: uses: actions/cache@v3 with: path: ./packages/next-target - key: next-swc-cargo-cache-ubuntu-18.04--${{ hashFiles('**/Cargo.lock') }} + key: next-swc-cargo-cache-ubuntu-latest--${{ hashFiles('**/Cargo.lock') }} restore-keys: | - next-swc-cargo-cache-ubuntu-18.04 + next-swc-cargo-cache-ubuntu-latest # since the repo's dependencies aren't installed we need # to install napi globally diff --git a/.prettierignore_staged b/.prettierignore_staged index 44fcc6dab75a..41755b6a33ae 100644 --- a/.prettierignore_staged +++ b/.prettierignore_staged @@ -7,5 +7,6 @@ packages/next/bundles/webpack/packages/*.runtime.js lerna.json packages/next-codemod/transforms/__testfixtures__/**/* packages/next-codemod/transforms/__tests__/**/* -pnpm-lock.yaml -.github/actions/issue-validator/index.mjs \ No newline at end of file +pnpm-lock.yam +.github/actions/issue-validator/index.mjs +**/convex/_generated/** \ No newline at end of file diff --git a/contributing.md b/contributing.md index 6238e972f4bf..b3ec843cf2e7 100644 --- a/contributing.md +++ b/contributing.md @@ -61,7 +61,7 @@ pnpm build pnpm prepublishOnly ``` -By default the latest canary of the next-swc binaries will be installed and used. If you are actively working on Rust code or you need to test out the most recent Rust code that hasn't been published as a canary yet you can [install Rust](https://www.rust-lang.org/tools/install) and run `pnpm --filter=@next/swc build-native`. +By default, the latest canary of the next-swc binaries will be installed and used. If you are actively working on Rust code or you need to test out the most recent Rust code that hasn't been published as a canary yet you can [install Rust](https://www.rust-lang.org/tools/install) and run `pnpm --filter=@next/swc build-native`. If you want to test out the wasm build locally, you will need to [install wasm-pack](https://rustwasm.github.io/wasm-pack/installer/). Run `pnpm --filter=@next/swc build-wasm --target ` to build and `node ./scripts/setup-wasm.mjs` to copy it into your `node_modules`. Run next with `NODE_OPTIONS='--no-addons'` to force it to use the wasm binary. @@ -164,7 +164,7 @@ There are two options to develop with your local version of the codebase: to re-install all of the dependencies. - Note that Next will be copied from the locally compiled version as opposed to from being downloaded from the NPM registry. + Note that Next will be copied from the locally compiled version as opposed to being downloaded from the NPM registry. 4. Run your application as you normally would. @@ -263,7 +263,7 @@ Below are the steps to add a new link: ## Adding examples -When you add an example to the [examples](examples) directory, please follow these guidelines to ensure high quality examples: +When you add an example to the [examples](examples) directory, please follow these guidelines to ensure high-quality examples: - TypeScript should be leveraged for new examples (no need for separate JavaScript and TypeScript examples, converting old JavaScript examples is preferred) - Examples should not add custom ESLint configuration (we have specific templates for ESLint) @@ -277,7 +277,7 @@ When you add an example to the [examples](examples) directory, please follow the - Example directories should not be prefixed with `with-` - Make sure linting passes (you can run `pnpm lint-fix`) -Also don’t forget to add a `README.md` file with the following format: +Also, don’t forget to add a `README.md` file with the following format: - Replace `DIRECTORY_NAME` with the directory name you’re adding. - Fill in `Example Name` and `Description`. @@ -333,7 +333,7 @@ Issues are opened with one of these labels: - `template: bug` - unverified issue with Next.js itself, or one of the examples in the [`examples`](https://github.com/vercel/next.js/tree/canary/examples) folder - `template: documentation` - feedback for improvement or an unverified issue with the Next.js documentation -In case of a bug report, a maintainer looks at the provided reproduction. If the reproduction is missing or insufficient, a `please add a complete reproduction` label is added. If a reproduction is not provided for more than 30 days, the issue becomes stale and will be automatically closed. If a reproduction is provided within 30 days, the `please add a complete reproduction` label is removed and the issue will not become stale anymore. +In the case of a bug report, a maintainer looks at the provided reproduction. If the reproduction is missing or insufficient, a `please add a complete reproduction` label is added. If a reproduction is not provided for more than 30 days, the issue becomes stale and will be automatically closed. If a reproduction is provided within 30 days, the `please add a complete reproduction` label is removed and the issue will not become stale anymore. Bug reports must be verified against the `next@canary` release. The canary version of Next.js ships daily and includes all features and fixes that have not been released to the stable version yet. Think of canary as a public beta. Some issues may already be fixed in the canary version, so please verify that your issue reproduces before opening a new issue. Issues not verified against `next@canary` will be closed after 30 days. @@ -341,6 +341,6 @@ If the issue is specific to the project and not to Next.js itself, it might be c If the bug is verified, it will receive the `kind: bug` label and will be tracked by the maintainers. An `area:` label can be added to indicate which part of Next.js is affected. -Confirmed issues never become stale or be closed before resolution. +Confirmed issues never become stale or are closed before resolution. All **closed** PRs and Issues will be locked after 30 days of inactivity (eg.: comment, referencing from elsewhere). diff --git a/docs/advanced-features/custom-error-page.md b/docs/advanced-features/custom-error-page.md index e3f4b2ddf79d..6b3a2b860b1b 100644 --- a/docs/advanced-features/custom-error-page.md +++ b/docs/advanced-features/custom-error-page.md @@ -98,3 +98,4 @@ If you have a custom `Error` component be sure to import that one instead. `next ### Caveats - `Error` does not currently support Next.js [Data Fetching methods](/docs/basic-features/data-fetching.md) like [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) or [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md). +- `_error`, like `_app`, is a reserved pathname. `_error` is used to define the customized layouts and behaviors of the error pages. `/_error` will render 404 when accessed directly via [routing](/docs/routing/introduction) or rendering in a [custom server](/docs/advanced-features/custom-server). diff --git a/docs/advanced-features/preview-mode.md b/docs/advanced-features/preview-mode.md index a6700718692d..e9cd56f40f61 100644 --- a/docs/advanced-features/preview-mode.md +++ b/docs/advanced-features/preview-mode.md @@ -173,6 +173,8 @@ https:///api/preview?secret=&slug= ## More Details +> **Note**: during rendering `next/router` exposes an `isPreview` flag, see the [router object docs](/docs/api-reference/next/router.md#router-object) for more info. + ### Clear the Preview Mode cookies By default, no expiration date is set for Preview Mode cookies, so the preview session ends when the browser is closed. diff --git a/docs/advanced-features/react-18/server-components.md b/docs/advanced-features/react-18/server-components.md index fb6699fba26c..839bda3274a3 100644 --- a/docs/advanced-features/react-18/server-components.md +++ b/docs/advanced-features/react-18/server-components.md @@ -1,30 +1,18 @@ -# React Server Components (Alpha) +# React Server Components (RFC) Server Components allow us to render React components on the server. This is fundamentally different from server-side rendering (SSR) where you're pre-generating HTML on the server. With Server Components, there's **zero client-side JavaScript needed,** making page rendering faster. This improves the user experience of your application, pairing the best parts of server-rendering with client-side interactivity. -### Enable React Server Components +### Next Router and Layouts RFC -To use React Server Components, ensure you have the latest React installed: +We are currently implementing the [Next.js Router and Layouts RFC](/blog/layouts-rfc). -```jsx -npm install next@canary react@latest react-dom@latest -``` - -Then, update your `next.config.js`: +The new Next.js router will be built on top of React 18 features, including React Server Components. -```jsx -// next.config.js -module.exports = { - experimental: { - runtime: 'nodejs', - serverComponents: true, - }, -} -``` +One of the biggest proposed changes is that, by default, files inside a new `app` directory will be rendered on the server as React Server Components. -Using `runtime` also enables [Streaming SSR](/docs/advanced-features/react-18/streaming). When setting `runtime` to `'experimental-edge'`, the server will be running entirely in the [Edge Runtime](https://nextjs.org/docs/api-reference/edge-runtime). +This will allow you to automatically adopt React Server Components when migrating from `pages` to `app`. -Now, you can start using React Server Components in Next.js. [See our example](https://github.com/vercel/next-rsc-demo) for more information. +You can find more information on the [RFC](/blog/layouts-rfc) and we welcome your feedback on [Github Discussions](https://github.com/vercel/next.js/discussions/37136). ### Server Components Conventions diff --git a/docs/advanced-features/static-html-export.md b/docs/advanced-features/static-html-export.md index a2a7a7f2b80a..107a348a4f3f 100644 --- a/docs/advanced-features/static-html-export.md +++ b/docs/advanced-features/static-html-export.md @@ -31,6 +31,8 @@ Running `npm run build` will generate an `out` directory. For more advanced scenarios, you can define a parameter called [`exportPathMap`](/docs/api-reference/next.config.js/exportPathMap.md) in your [`next.config.js`](/docs/api-reference/next.config.js/introduction.md) file to configure exactly which pages will be generated. +> **Warning**: Using `exportPathMap` for defining routes with any `getStaticPaths` powered page is now ignored and gets overridden. We recommend not to use them together. + ## Supported Features The majority of core Next.js features needed to build a static site are supported, including: diff --git a/docs/api-reference/next.config.js/exportPathMap.md b/docs/api-reference/next.config.js/exportPathMap.md index a1ef9f65021f..4180363e6dcf 100644 --- a/docs/api-reference/next.config.js/exportPathMap.md +++ b/docs/api-reference/next.config.js/exportPathMap.md @@ -40,7 +40,7 @@ module.exports = { } ``` -Note: the `query` field in `exportPathMap` cannot be used with [automatically statically optimized pages](/docs/advanced-features/automatic-static-optimization) or [`getStaticProps` pages](/docs/basic-features/data-fetching/get-static-props.md) as they are rendered to HTML files at build-time and additional query information cannot be provided during `next export`. +> Note: the `query` field in `exportPathMap` cannot be used with [automatically statically optimized pages](/docs/advanced-features/automatic-static-optimization) or [`getStaticProps` pages](/docs/basic-features/data-fetching/get-static-props.md) as they are rendered to HTML files at build-time and additional query information cannot be provided during `next export`. The pages will then be exported as HTML files, for example, `/about` will become `/about.html`. @@ -79,6 +79,8 @@ module.exports = { next export -o outdir ``` +> **Warning**: Using `exportPathMap` for defining routes with any `getStaticPaths` powered page is now ignored and gets overridden. We recommend not to use them together. + ## Related
diff --git a/docs/api-reference/next.config.js/introduction.md b/docs/api-reference/next.config.js/introduction.md index 994c5c78cfc5..e708004bd1a2 100644 --- a/docs/api-reference/next.config.js/introduction.md +++ b/docs/api-reference/next.config.js/introduction.md @@ -80,7 +80,7 @@ module.exports = (phase, { defaultConfig }) => { } ``` -The commented lines are the place where you can put the configs allowed by `next.config.js`, which are [defined in this file](https://github.com/vercel/next.js/blob/canary/packages/next/server/config-shared.ts#L137). +The commented lines are the place where you can put the configs allowed by `next.config.js`, which are [defined in this file](https://github.com/vercel/next.js/blob/canary/packages/next/server/config-shared.ts#L158). However, none of the configs are required, and it's not necessary to understand what each config does. Instead, search for the features you need to enable or modify in this section and they will show you what to do. diff --git a/docs/api-reference/next.config.js/redirects.md b/docs/api-reference/next.config.js/redirects.md index 988a5fa97522..05b50a62a3d7 100644 --- a/docs/api-reference/next.config.js/redirects.md +++ b/docs/api-reference/next.config.js/redirects.md @@ -300,4 +300,4 @@ In some rare cases, you might need to assign a custom status code for older HTTP ## Other Redirects - Inside [API Routes](/docs/api-routes/response-helpers.md), you can use `res.redirect()`. -- Inside [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) and [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md), you can redirect specific pages at request-time. +- Inside [`getStaticProps`](/docs/api-reference/data-fetching/get-static-props.md) and [`getServerSideProps`](/docs/api-reference/data-fetching/get-server-side-props.md), you can redirect specific pages at request-time. diff --git a/docs/api-reference/next/future/image.md b/docs/api-reference/next/future/image.md index f7909d6bcec6..aeeacf7eac26 100644 --- a/docs/api-reference/next/future/image.md +++ b/docs/api-reference/next/future/image.md @@ -16,7 +16,7 @@ description: Try the latest Image Optimization with the experimental `next/futur The `next/future/image` component is an experiment to improve both the performance and developer experience of `next/image` by using the native `` element with better default behavior. -This new component is considered experimental and therefore not covered by semver, and may cause unexpected or broken application behavior. This component uses browser native [lazy loading](https://caniuse.com/loading-lazy-attr), which may fallback to eager loading for older browsers before Safari 15.4. When using the blur-up placeholder, older browsers before Safari 12 will fallback to empty placeholder. When using styles with `width`/`height` of `auto`, it is possible to cause [Layout Shift](https://web.dev/cls/) on older browsers before [Chrome 79](https://chromestatus.com/feature/5695266130755584), [Firefox 69](https://bugzilla.mozilla.org/show_bug.cgi?id=1547231), and [Safari 14.2](https://bugs.webkit.org/show_bug.cgi?id=201641). For more details, see [this MDN video](https://www.youtube.com/watch?v=4-d_SoCHeWE). +This new component is considered experimental and therefore not covered by semver, and may cause unexpected or broken application behavior. This component uses browser native [lazy loading](https://caniuse.com/loading-lazy-attr), which may fallback to eager loading for older browsers before Safari 15.4. When using the blur-up placeholder, older browsers before Safari 12 will fallback to empty placeholder. When using styles with `width`/`height` of `auto`, it is possible to cause [Layout Shift](https://web.dev/cls/) on older browsers before Safari 15 that don't [preserve the aspect ratio](https://caniuse.com/mdn-html_elements_img_aspect_ratio_computed_from_attributes). For more details, see [this MDN video](https://www.youtube.com/watch?v=4-d_SoCHeWE). To use `next/future/image`, add the following to your `next.config.js` file: @@ -34,12 +34,24 @@ module.exports = { Compared to `next/image`, the new `next/future/image` component has the following changes: -- Renders a single `` without `
` or `` wrappers +- Removes `` wrapper around `` in favor of [native computed aspect ratio](https://caniuse.com/mdn-html_elements_img_aspect_ratio_computed_from_attributes) - Adds support for canonical `style` prop -- Removes `layout`, `objectFit`, and `objectPosition` props in favor of `style` or `className` + - Removes `layout` prop in favor of `style` or `className` + - Removes `objectFit` prop in favor of `style` or `className` + - Removes `objectPosition` prop in favor of `style` or `className` - Removes `IntersectionObserver` implementation in favor of [native lazy loading](https://caniuse.com/loading-lazy-attr) + - Removes `lazyBoundary` prop since there is no native equivalent + - Removes `lazyRoot` prop since there is no native equivalent - Removes `loader` config in favor of [`loader`](#loader) prop -- Note: the [`onError`](#onerror) prop might behave differently + +## Known Browser Bugs + +- [Safari 15+](https://bugs.webkit.org/show_bug.cgi?id=243601) displays a gray border while loading. Possible solutions: + - Use CSS `@media not all and (min-resolution:.001dpcm) { img[loading="lazy"] { clip-path: inset(0.5px) } }` + - Use [`priority`](#priority) if the image is above the fold +- [Firefox 67+](https://bugzilla.mozilla.org/show_bug.cgi?id=1556156) displays a white background while loading progressive jpeg. Possible solutions: + - Enable [AVIF `formats`](#acceptable-formats) + - Use [`placeholder="blur"`](#blur) ## Migration @@ -303,7 +315,7 @@ The callback function will be called with one argument, an object with the follo A callback function that is invoked when the image is loaded. -Note that the load event might occur before client-side hydration completes, so this callback might not be invoked in that case. +Note that the load event might occur before the placeholder is removed and the image is fully decoded. Instead, use [`onLoadingComplete`](#onloadingcomplete). @@ -311,8 +323,6 @@ Instead, use [`onLoadingComplete`](#onloadingcomplete). A callback function that is invoked if the image fails to load. -Note that the error might occur before client-side hydration completes, so this callback might not be invoked in that case. - ### loading > **Attention**: This property is only meant for advanced usage. Switching an diff --git a/docs/basic-features/font-optimization.md b/docs/basic-features/font-optimization.md index bcd1498072fa..139a09b32d5d 100644 --- a/docs/basic-features/font-optimization.md +++ b/docs/basic-features/font-optimization.md @@ -53,7 +53,13 @@ class MyDocument extends Document { export default MyDocument ``` -Note that we don't recommend adding fonts with `next/head`, as this only applies the font to the particular page and won't work with a streaming architecture. +Although it's possible to add fonts in a page with [`next/head`](/docs/api-reference/next/head) it comes with some drawbacks: + +- It only applies the font to that particular page. +- The font optimization will only work on page load, not on client side navigation. +- It won't work with a streaming architecture. + +Thus it's highly recommended to add the font in a [Custom `Document`](/docs/advanced-features/custom-document.md), like in the code snippet above. Automatic Webfont Optimization currently supports Google Fonts and Typekit with support for other font providers coming soon. We're also planning to add control over [loading strategies](https://github.com/vercel/next.js/issues/21555) and `font-display` values. diff --git a/docs/basic-features/layouts.md b/docs/basic-features/layouts.md index 5afa956ec29e..394169e9f0a6 100644 --- a/docs/basic-features/layouts.md +++ b/docs/basic-features/layouts.md @@ -128,7 +128,7 @@ import type { ReactElement, ReactNode } from 'react' import type { NextPage } from 'next' import type { AppProps } from 'next/app' -export type NextPageWithLayout = NextPage & { +export type NextPageWithLayout

= NextPage & { getLayout?: (page: ReactElement) => ReactNode } diff --git a/docs/basic-features/pages.md b/docs/basic-features/pages.md index 519e8a18bece..46314a3ac16c 100644 --- a/docs/basic-features/pages.md +++ b/docs/basic-features/pages.md @@ -41,7 +41,7 @@ Importantly, Next.js lets you **choose** which pre-rendering form you'd like to We **recommend** using **Static Generation** over Server-side Rendering for performance reasons. Statically generated pages can be cached by CDN with no extra configuration to boost performance. However, in some cases, Server-side Rendering might be the only option. -You can also use **Client-side Rendering** along with Static Generation or Server-side Rendering. That means some parts of a page can be rendered entirely by client side JavaScript. To learn more, take a look at the [Data Fetching](/docs/basic-features/data-fetching/client-side.md) documentation. +You can also use **Client-side data fetching** along with Static Generation or Server-side Rendering. That means some parts of a page can be rendered entirely by client side JavaScript. To learn more, take a look at the [Data Fetching](/docs/basic-features/data-fetching/client-side.md) documentation. ## Static Generation (Recommended) @@ -217,7 +217,7 @@ On the other hand, Static Generation is **not** a good idea if you cannot pre-re In cases like this, you can do one of the following: -- Use Static Generation with **Client-side Rendering:** You can skip pre-rendering some parts of a page and then use client-side JavaScript to populate them. To learn more about this approach, check out the [Data Fetching documentation](/docs/basic-features/data-fetching/client-side.md). +- Use Static Generation with **Client-side data fetching:** You can skip pre-rendering some parts of a page and then use client-side JavaScript to populate them. To learn more about this approach, check out the [Data Fetching documentation](/docs/basic-features/data-fetching/client-side.md). - Use **Server-Side Rendering:** Next.js pre-renders a page on each request. It will be slower because the page cannot be cached by a CDN, but the pre-rendered page will always be up-to-date. We'll talk about this approach below. ## Server-side Rendering diff --git a/docs/faq.md b/docs/faq.md index fe9ca6838034..216db88c40ce 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -14,7 +14,7 @@ description: Get to know more about Next.js with the frequently asked questions.

How do I fetch data in Next.js? Next.js provides a variety of methods depending on your use case. You can use:
    -
  • Client-side rendering: Fetch data with useEffect or SWR inside your React components
  • +
  • Client-side data fetching: Fetch data with useEffect or SWR inside your React components
  • Server-side rendering with getServerSideProps
  • Static-site generation with getStaticProps
  • Incremental Static Regeneration by adding the `revalidate` prop to getStaticProps
  • diff --git a/errors/invalid-dynamic-suspense.md b/errors/invalid-dynamic-suspense.md index 11e4d6134d73..f016eec897d4 100644 --- a/errors/invalid-dynamic-suspense.md +++ b/errors/invalid-dynamic-suspense.md @@ -2,11 +2,29 @@ #### Why This Error Occurred -`` is not allowed under legacy render mode when using React older than v18. +- You are using `{ suspense: true }` with React version older than 18. +- You are using `{ suspense: true, ssr: false }`. +- You are using `{ suspense: true, loading }`. #### Possible Ways to Fix It -Remove `suspense: true` option in `next/dynamic` usages. +**If you are using `{ suspense: true }` with React version older than 18** + +- You can try upgrading to React 18 or newer +- If upgrading React is not an option, remove `{ suspense: true }` from `next/dynamic` usages. + +**If you are using `{ suspense: true, ssr: false }`** + +Next.js will use `React.lazy` when `suspense` is set to true. React 18 or newer will always try to resolve the Suspense boundary on the server. This behavior can not be disabled, thus the `ssr: false` is ignored with `suspense: true`. + +- You should write code that works in both client-side and server-side. +- If rewriting the code is not an option, remove `{ suspense: true }` from `next/dynamic` usages. + +**If you are using `{ suspense: true, loading }`** + +Next.js will use `React.lazy` when `suspense` is set to true, when your dynamic-imported component is loading, React will use the closest suspense boundary's fallback. + +You should remove `loading` from `next/dynamic` usages, and use ``'s `fallback` prop. ### Useful Links diff --git a/examples/auth-with-stytch/pages/_document.tsx b/examples/auth-with-stytch/pages/_document.tsx index 83d9080a67d7..496f4c465e5c 100644 --- a/examples/auth-with-stytch/pages/_document.tsx +++ b/examples/auth-with-stytch/pages/_document.tsx @@ -1,33 +1,18 @@ -import Document, { - Html, - Head, - Main, - NextScript, - DocumentContext, -} from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -class MyDocument extends Document { - static async getInitialProps(ctx: DocumentContext) { - const initialProps = await Document.getInitialProps(ctx) - return { ...initialProps } - } - - render() { - return ( - - - - - -
    - - - - ) - } +export default function Document() { + return ( + + + + + +
    + + + + ) } - -export default MyDocument diff --git a/examples/blog-starter/pages/_document.tsx b/examples/blog-starter/pages/_document.tsx index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/blog-starter/pages/_document.tsx +++ b/examples/blog-starter/pages/_document.tsx @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/blog/pages/_document.tsx b/examples/blog/pages/_document.tsx index 40ab3703fb31..d480d60cc696 100644 --- a/examples/blog/pages/_document.tsx +++ b/examples/blog/pages/_document.tsx @@ -1,47 +1,31 @@ -import Document, { - Html, - Head, - Main, - NextScript, - DocumentContext, -} from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -class MyDocument extends Document { - static async getInitialProps(ctx: DocumentContext) { - const initialProps = await Document.getInitialProps(ctx) - return { ...initialProps } +export default function Document() { + const meta = { + title: 'Next.js Blog Starter Kit', + description: 'Clone and deploy your own Next.js portfolio in minutes.', + image: 'https://assets.vercel.com/image/upload/q_auto/front/vercel/dps.png', } - render() { - const meta = { - title: 'Next.js Blog Starter Kit', - description: 'Clone and deploy your own Next.js portfolio in minutes.', - image: - 'https://assets.vercel.com/image/upload/q_auto/front/vercel/dps.png', - } - - return ( - - - - - - - - - - - - - - - -
    - - - - ) - } + return ( + + + + + + + + + + + + + + + +
    + + + + ) } - -export default MyDocument diff --git a/examples/cms-contentful/pages/_document.js b/examples/cms-contentful/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-contentful/pages/_document.js +++ b/examples/cms-contentful/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-cosmic/pages/_document.js b/examples/cms-cosmic/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-cosmic/pages/_document.js +++ b/examples/cms-cosmic/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-datocms/pages/_document.js b/examples/cms-datocms/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-datocms/pages/_document.js +++ b/examples/cms-datocms/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-drupal/pages/_document.js b/examples/cms-drupal/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-drupal/pages/_document.js +++ b/examples/cms-drupal/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-ghost/pages/_document.js b/examples/cms-ghost/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-ghost/pages/_document.js +++ b/examples/cms-ghost/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-graphcms/pages/_document.js b/examples/cms-graphcms/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-graphcms/pages/_document.js +++ b/examples/cms-graphcms/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-kontent/pages/_document.js b/examples/cms-kontent/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-kontent/pages/_document.js +++ b/examples/cms-kontent/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-makeswift/.env.local.example b/examples/cms-makeswift/.env.local.example index 6d8f3c9ad0ed..3685b7a9930b 100644 --- a/examples/cms-makeswift/.env.local.example +++ b/examples/cms-makeswift/.env.local.example @@ -1,2 +1 @@ -MAKESWIFT_API_HOST=https://api.makeswift.com MAKESWIFT_SITE_API_KEY= diff --git a/examples/cms-makeswift/package.json b/examples/cms-makeswift/package.json index f3b32cf70fa4..eb27abb4320f 100644 --- a/examples/cms-makeswift/package.json +++ b/examples/cms-makeswift/package.json @@ -6,7 +6,7 @@ "start": "next start" }, "dependencies": { - "@makeswift/runtime": "0.1.2", + "@makeswift/runtime": "0.1.5", "next": "latest", "react": "18.2.0", "react-dom": "18.2.0" diff --git a/examples/cms-prepr/pages/_document.js b/examples/cms-prepr/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-prepr/pages/_document.js +++ b/examples/cms-prepr/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-prismic/pages/_document.js b/examples/cms-prismic/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-prismic/pages/_document.js +++ b/examples/cms-prismic/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-sanity/pages/_document.js b/examples/cms-sanity/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-sanity/pages/_document.js +++ b/examples/cms-sanity/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-storyblok/pages/_document.js b/examples/cms-storyblok/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-storyblok/pages/_document.js +++ b/examples/cms-storyblok/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-strapi/pages/_document.js b/examples/cms-strapi/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-strapi/pages/_document.js +++ b/examples/cms-strapi/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-takeshape/pages/_document.js b/examples/cms-takeshape/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-takeshape/pages/_document.js +++ b/examples/cms-takeshape/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-tina/pages/_document.js b/examples/cms-tina/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-tina/pages/_document.js +++ b/examples/cms-tina/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-umbraco-heartcore/pages/_document.js b/examples/cms-umbraco-heartcore/pages/_document.js index c55951c0d5da..54e8bf3e2a29 100755 --- a/examples/cms-umbraco-heartcore/pages/_document.js +++ b/examples/cms-umbraco-heartcore/pages/_document.js @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/cms-wordpress/pages/_document.tsx b/examples/cms-wordpress/pages/_document.tsx index c55951c0d5da..54e8bf3e2a29 100644 --- a/examples/cms-wordpress/pages/_document.tsx +++ b/examples/cms-wordpress/pages/_document.tsx @@ -1,15 +1,13 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
    - - - - ) - } +export default function Document() { + return ( + + + +
    + + + + ) } diff --git a/examples/convex/convex.json b/examples/convex/convex.json deleted file mode 100644 index 4f972abd4642..000000000000 --- a/examples/convex/convex.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "authInfo": [], - "functions": "convex/", - "instanceName": "handsome-turtle-915", - "origin": "https://handsome-turtle-915.convex.cloud" -} diff --git a/examples/convex/convex/_generated/dataModel.ts b/examples/convex/convex/_generated/dataModel.ts index 2f229880ec7c..87c7cb3c1fbe 100644 --- a/examples/convex/convex/_generated/dataModel.ts +++ b/examples/convex/convex/_generated/dataModel.ts @@ -9,8 +9,8 @@ * @module */ -import { AnyDataModel } from 'convex/server' -import { GenericId } from 'convex/values' +import { AnyDataModel } from "convex/server"; +import { GenericId } from "convex/values"; /** * No `schema.ts` file found! @@ -26,12 +26,12 @@ import { GenericId } from 'convex/values' /** * The names of all of your Convex tables. */ -export type TableNames = string +export type TableNames = string; /** * The type of a document stored in Convex. */ -export type Document = any +export type Document = any; /** * An identifier for a document in Convex. @@ -45,8 +45,8 @@ export type Document = any * Using `===` will not work because two different instances of `Id` can refer * to the same document. */ -export type Id = GenericId -export const Id = GenericId +export type Id = GenericId; +export const Id = GenericId; /** * A type describing your Convex data model. @@ -57,4 +57,4 @@ export const Id = GenericId * This type is used to parameterize methods like `queryGeneric` and * `mutationGeneric` to make them type-safe. */ -export type DataModel = AnyDataModel +export type DataModel = AnyDataModel; diff --git a/examples/convex/convex/_generated/react.ts b/examples/convex/convex/_generated/react.ts index 1859ea22336c..0ed0e5634a0c 100644 --- a/examples/convex/convex/_generated/react.ts +++ b/examples/convex/convex/_generated/react.ts @@ -9,10 +9,10 @@ * @module */ -import type getCounter from '../getCounter' -import type incrementCounter from '../incrementCounter' -import type { OptimisticLocalStore as GenericOptimisticLocalStore } from 'convex/browser' -import type { ClientMutation, ClientQuery } from 'convex/server' +import type getCounter from "../getCounter"; +import type incrementCounter from "../incrementCounter"; +import type { OptimisticLocalStore as GenericOptimisticLocalStore } from "convex/browser"; +import type { ClientMutation, ClientQuery } from "convex/server"; /** * A type describing your app's public Convex API. @@ -25,14 +25,14 @@ import type { ClientMutation, ClientQuery } from 'convex/server' */ export type ConvexAPI = { queries: { - getCounter: ClientQuery - } + getCounter: ClientQuery; + }; mutations: { - incrementCounter: ClientMutation - } -} + incrementCounter: ClientMutation; + }; +}; -import { makeUseQuery, makeUseMutation, makeUseConvex } from 'convex/react' +import { makeUseQuery, makeUseMutation, makeUseConvex } from "convex/react"; /** * Load a reactive query within a React component. @@ -46,7 +46,7 @@ import { makeUseQuery, makeUseMutation, makeUseConvex } from 'convex/react' * @param args - The arguments to the query function. * @returns `undefined` if loading and the query's return value otherwise. */ -export const useQuery = makeUseQuery() +export const useQuery = makeUseQuery(); /** * Construct a new {@link ReactMutation}. @@ -64,7 +64,7 @@ export const useQuery = makeUseQuery() * @param name - The name of the mutation. * @returns The {@link ReactMutation} object with that name. */ -export const useMutation = makeUseMutation() +export const useMutation = makeUseMutation(); /** * Get the {@link ConvexReactClient} within a React component. @@ -73,10 +73,10 @@ export const useMutation = makeUseMutation() * * @returns The active {@link ConvexReactClient} object, or `undefined`. */ -export const useConvex = makeUseConvex() +export const useConvex = makeUseConvex(); /** * A view of the query results currently in the Convex client for use within * optimistic updates. */ -export type OptimisticLocalStore = GenericOptimisticLocalStore +export type OptimisticLocalStore = GenericOptimisticLocalStore; diff --git a/examples/convex/convex/_generated/server.ts b/examples/convex/convex/_generated/server.ts index 833b51dcc8ef..0e8d913bbd0a 100644 --- a/examples/convex/convex/_generated/server.ts +++ b/examples/convex/convex/_generated/server.ts @@ -16,8 +16,8 @@ import { MutationCtx as GenericMutationCtx, DatabaseReader as GenericDatabaseReader, DatabaseWriter as GenericDatabaseWriter, -} from 'convex/server' -import { DataModel } from './dataModel.js' +} from "convex/server"; +import { DataModel } from "./dataModel.js"; /** * Define a query in this Convex app's public API. @@ -27,7 +27,7 @@ import { DataModel } from './dataModel.js' * @param func - The query function. It receives a {@link QueryCtx} as its first argument. * @returns The wrapped query. Include this as an `export` to name it and make it accessible. */ -export const query = makeQuery() +export const query = makeQuery(); /** * Define a mutation in this Convex app's public API. @@ -37,7 +37,7 @@ export const query = makeQuery() * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. */ -export const mutation = makeMutation() +export const mutation = makeMutation(); /** * A set of services for use within Convex query functions. @@ -48,7 +48,7 @@ export const mutation = makeMutation() * This differs from the {@link MutationCtx} because all of the services are * read-only. */ -export type QueryCtx = GenericQueryCtx +export type QueryCtx = GenericQueryCtx; /** * A set of services for use within Convex mutation functions. @@ -56,7 +56,7 @@ export type QueryCtx = GenericQueryCtx * The mutation context is passed as the first argument to any Convex mutation * function run on the server. */ -export type MutationCtx = GenericMutationCtx +export type MutationCtx = GenericMutationCtx; /** * An interface to read from the database within Convex query functions. @@ -65,7 +65,7 @@ export type MutationCtx = GenericMutationCtx * document by its {@link Id}, or {@link DatabaseReader.table}, which starts * building a query. */ -export type DatabaseReader = GenericDatabaseReader +export type DatabaseReader = GenericDatabaseReader; /** * An interface to read from and write to the database within Convex mutation @@ -76,4 +76,4 @@ export type DatabaseReader = GenericDatabaseReader * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control) * for the guarantees Convex provides your functions. */ -export type DatabaseWriter = GenericDatabaseWriter +export type DatabaseWriter = GenericDatabaseWriter; diff --git a/examples/convex/convex/incrementCounter.ts b/examples/convex/convex/incrementCounter.ts index 8e43836c7048..b7f6d035883d 100644 --- a/examples/convex/convex/incrementCounter.ts +++ b/examples/convex/convex/incrementCounter.ts @@ -2,7 +2,7 @@ import { mutation } from './_generated/server' export default mutation( async ({ db }, counterName: string, increment: number) => { - let counterDoc = await db + const counterDoc = await db .table('counter_table') .filter((q) => q.eq(q.field('name'), counterName)) .first() diff --git a/examples/convex/package.json b/examples/convex/package.json index 24cb00227708..2ad3f092106e 100644 --- a/examples/convex/package.json +++ b/examples/convex/package.json @@ -8,7 +8,6 @@ "dependencies": { "convex": "latest", "next": "latest", - "prettier": "^2.7.1", "react": "^18.2.0", "react-dom": "^18.2.0" }, @@ -16,6 +15,7 @@ "@types/node": "~16.11.12", "@types/react": "17.0.45", "@types/react-dom": "17.0.17", + "prettier": "^2.7.1", "typescript": "^4.7.3" } } diff --git a/examples/data-fetch/package.json b/examples/data-fetch/package.json index 349de02f4d84..6d7b78181046 100644 --- a/examples/data-fetch/package.json +++ b/examples/data-fetch/package.json @@ -6,8 +6,13 @@ "start": "next start" }, "dependencies": { - "next": "latest", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "next": "12.2.5", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/node": "18.7.11", + "@types/react": "18.0.17", + "typescript": "4.7.4" } } diff --git a/examples/data-fetch/pages/index.js b/examples/data-fetch/pages/index.tsx similarity index 52% rename from examples/data-fetch/pages/index.js rename to examples/data-fetch/pages/index.tsx index d668c07e8fd6..a85b350fab30 100644 --- a/examples/data-fetch/pages/index.js +++ b/examples/data-fetch/pages/index.tsx @@ -1,25 +1,26 @@ import Link from 'next/link' - -function Index({ stars }) { - return ( -
    -

    Next.js has {stars} ⭐️

    - - How about preact? - -
    - ) -} +import type { InferGetStaticPropsType } from 'next' +import type { Repository } from '../types/github' export async function getStaticProps() { const res = await fetch('https://api.github.com/repos/vercel/next.js') - const json = await res.json() - + const data: Repository = await res.json() return { props: { - stars: json.stargazers_count, + stars: data.stargazers_count, }, } } -export default Index +export default function IndexPage({ + stars, +}: InferGetStaticPropsType) { + return ( + <> +

    Next.js has {stars} ⭐️

    + + How about preact? + + + ) +} diff --git a/examples/data-fetch/pages/preact-stars.js b/examples/data-fetch/pages/preact-stars.tsx similarity index 57% rename from examples/data-fetch/pages/preact-stars.js rename to examples/data-fetch/pages/preact-stars.tsx index 9039129474ed..f7e7f70e3978 100644 --- a/examples/data-fetch/pages/preact-stars.js +++ b/examples/data-fetch/pages/preact-stars.tsx @@ -1,20 +1,10 @@ import Link from 'next/link' - -function PreactStars({ stars }) { - return ( -
    -

    Preact has {stars} ⭐

    - - I bet Next.js has more stars (?) - -
    - ) -} +import type { InferGetStaticPropsType } from 'next' +import type { Repository } from '../types/github' export async function getStaticProps() { const res = await fetch('https://api.github.com/repos/preactjs/preact') - const json = await res.json() - + const json: Repository = await res.json() return { props: { stars: json.stargazers_count, @@ -22,4 +12,15 @@ export async function getStaticProps() { } } -export default PreactStars +export default function PreactStarsPage({ + stars, +}: InferGetStaticPropsType) { + return ( + <> +

    Preact has {stars} ⭐

    + + I bet Next.js has more stars (?) + + + ) +} diff --git a/examples/data-fetch/tsconfig.json b/examples/data-fetch/tsconfig.json new file mode 100644 index 000000000000..93a83a407c40 --- /dev/null +++ b/examples/data-fetch/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve" + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/examples/data-fetch/types/github.d.ts b/examples/data-fetch/types/github.d.ts new file mode 100644 index 000000000000..1d373d98bc27 --- /dev/null +++ b/examples/data-fetch/types/github.d.ts @@ -0,0 +1,10 @@ +// For simplicity we are creating our own types here. +// If you want the full types check out: +// https://github.com/octokit/openapi-types.ts +export type Repository = { + id: number + name: string + full_name: string + stargazers_count: number + private: boolean +} & Record diff --git a/examples/dynamic-routing/components/header.js b/examples/dynamic-routing/components/header.js deleted file mode 100644 index e7349ba94d11..000000000000 --- a/examples/dynamic-routing/components/header.js +++ /dev/null @@ -1,30 +0,0 @@ -import Link from 'next/link' - -const Header = () => ( -
    - -
    -) - -export default Header diff --git a/examples/dynamic-routing/components/header.tsx b/examples/dynamic-routing/components/header.tsx new file mode 100644 index 000000000000..e71ccc603b93 --- /dev/null +++ b/examples/dynamic-routing/components/header.tsx @@ -0,0 +1,30 @@ +import Link from 'next/link' + +export default function Header() { + return ( +
    + +
    + ) +} diff --git a/examples/dynamic-routing/package.json b/examples/dynamic-routing/package.json index 349de02f4d84..6a0d14f6b52d 100644 --- a/examples/dynamic-routing/package.json +++ b/examples/dynamic-routing/package.json @@ -6,8 +6,13 @@ "start": "next start" }, "dependencies": { - "next": "latest", - "react": "^17.0.2", - "react-dom": "^17.0.2" + "next": "12.2.5", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/node": "18.7.9", + "@types/react": "18.0.17", + "typescript": "4.7.4" } } diff --git a/examples/dynamic-routing/pages/about.js b/examples/dynamic-routing/pages/about.js deleted file mode 100644 index 255d0764b446..000000000000 --- a/examples/dynamic-routing/pages/about.js +++ /dev/null @@ -1,10 +0,0 @@ -import Header from '../components/header' - -const About = () => ( - <> -
    -

    About page

    - -) - -export default About diff --git a/examples/dynamic-routing/pages/about.tsx b/examples/dynamic-routing/pages/about.tsx new file mode 100644 index 000000000000..d646cba7b626 --- /dev/null +++ b/examples/dynamic-routing/pages/about.tsx @@ -0,0 +1,10 @@ +import Header from '../components/header' + +export default function AboutPage() { + return ( + <> +
    +

    About page

    + + ) +} diff --git a/examples/dynamic-routing/pages/index.js b/examples/dynamic-routing/pages/index.js deleted file mode 100644 index 0f56525ada21..000000000000 --- a/examples/dynamic-routing/pages/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import Header from '../components/header' - -const Home = () => ( - <> -
    -

    Hello World!

    - -) - -export default Home diff --git a/examples/dynamic-routing/pages/index.tsx b/examples/dynamic-routing/pages/index.tsx new file mode 100644 index 000000000000..0280a6da7aa3 --- /dev/null +++ b/examples/dynamic-routing/pages/index.tsx @@ -0,0 +1,10 @@ +import Header from '../components/header' + +export default function IndexPage() { + return ( + <> +
    +

    Hello World!

    + + ) +} diff --git a/examples/dynamic-routing/pages/post/[id]/[comment].js b/examples/dynamic-routing/pages/post/[id]/[comment].tsx similarity index 64% rename from examples/dynamic-routing/pages/post/[id]/[comment].js rename to examples/dynamic-routing/pages/post/[id]/[comment].tsx index 6aa93ef597d2..1c33af5e0f24 100644 --- a/examples/dynamic-routing/pages/post/[id]/[comment].js +++ b/examples/dynamic-routing/pages/post/[id]/[comment].tsx @@ -1,9 +1,10 @@ import { useRouter } from 'next/router' import Header from '../../../components/header' -const Comment = () => { +export default function CommentPage() { const router = useRouter() - const { id, comment } = router.query + const id = router.query.id as string + const comment = router.query.comment as string return ( <> @@ -13,5 +14,3 @@ const Comment = () => { ) } - -export default Comment diff --git a/examples/dynamic-routing/pages/post/[id]/index.js b/examples/dynamic-routing/pages/post/[id]/index.tsx similarity index 63% rename from examples/dynamic-routing/pages/post/[id]/index.js rename to examples/dynamic-routing/pages/post/[id]/index.tsx index c8f4a77ca386..ffad6732b960 100644 --- a/examples/dynamic-routing/pages/post/[id]/index.js +++ b/examples/dynamic-routing/pages/post/[id]/index.tsx @@ -2,9 +2,9 @@ import { useRouter } from 'next/router' import Link from 'next/link' import Header from '../../../components/header' -const Post = () => { +export default function PostPage() { const router = useRouter() - const { id } = router.query + const id = router.query.id as string return ( <> @@ -12,12 +12,12 @@ const Post = () => {

    Post: {id}

    • - + First comment
    • - + Second comment
    • @@ -25,5 +25,3 @@ const Post = () => { ) } - -export default Post diff --git a/examples/dynamic-routing/tsconfig.json b/examples/dynamic-routing/tsconfig.json new file mode 100644 index 000000000000..50bcb22f653d --- /dev/null +++ b/examples/dynamic-routing/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es5", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "incremental": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve" + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/examples/with-babel-macros/pages/_document.js b/examples/with-babel-macros/pages/_document.js index dfbe440013fd..eb39cf4e4fda 100644 --- a/examples/with-babel-macros/pages/_document.js +++ b/examples/with-babel-macros/pages/_document.js @@ -1,17 +1,15 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - - - -
      - - - - ) - } + + +
      + + + + ) } diff --git a/examples/with-portals/pages/_document.js b/examples/with-portals/pages/_document.js index 9b7ed4536e34..980f43e2324d 100644 --- a/examples/with-portals/pages/_document.js +++ b/examples/with-portals/pages/_document.js @@ -1,17 +1,15 @@ -import Document, { Html, Head, Main, NextScript } from 'next/document' +import { Html, Head, Main, NextScript } from 'next/document' -export default class MyDocument extends Document { - render() { - return ( - - - -
      - {/* Here we will mount our modal portal */} -