diff --git a/docs/advanced-features/automatic-static-optimization.md b/docs/advanced-features/automatic-static-optimization.md index 17a3ea787c3b94f..abf202aacbd6747 100644 --- a/docs/advanced-features/automatic-static-optimization.md +++ b/docs/advanced-features/automatic-static-optimization.md @@ -20,7 +20,7 @@ If the above is not the case, Next.js will **statically optimize** your page aut During prerendering, the router's `query` object will be empty since we do not have `query` information to provide during this phase. After hydration, Next.js will trigger an update to your application to provide the route parameters in the `query` object. -> **Note:** Parameters added with [dynamic routes](/docs/routing/dynamic-routes.md) to a page that's using [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) will always be available inside the `query` object. +> **Note:** Parameters added with [dynamic routes](/docs/routing/dynamic-routes.md) to a page that's using [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) will always be available inside the `query` object. `next build` will emit `.html` files for statically optimized pages. For example, the result for the page `pages/about.js` would be: @@ -36,5 +36,5 @@ And if you add `getServerSideProps` to the page, it will then be JavaScript, lik ## Caveats -- If you have a [custom `App`](/docs/advanced-features/custom-app.md) with `getInitialProps` then this optimization will be turned off in pages without [Static Generation](/docs/basic-features/data-fetching.md#getstaticprops-static-generation). +- If you have a [custom `App`](/docs/advanced-features/custom-app.md) with `getInitialProps` then this optimization will be turned off in pages without [Static Generation](/docs/basic-features/data-fetching/get-static-props.md). - If you have a [custom `Document`](/docs/advanced-features/custom-document.md) with `getInitialProps` be sure you check if `ctx.req` is defined before assuming the page is server-side rendered. `ctx.req` will be `undefined` for pages that are prerendered. diff --git a/docs/advanced-features/custom-app.md b/docs/advanced-features/custom-app.md index 7add6c1d9b0c5b8..73d65f5666a9721 100644 --- a/docs/advanced-features/custom-app.md +++ b/docs/advanced-features/custom-app.md @@ -38,14 +38,14 @@ export default MyApp The `Component` prop is the active `page`, so whenever you navigate between routes, `Component` will change to the new `page`. Therefore, any props you send to `Component` will be received by the `page`. -`pageProps` is an object with the initial props that were preloaded for your page by one of our [data fetching methods](/docs/basic-features/data-fetching.md), otherwise it's an empty object. +`pageProps` is an object with the initial props that were preloaded for your page by one of our [data fetching methods](/docs/basic-features/data-fetching/index.md), otherwise it's an empty object. ### Caveats - If your app is running and you added a custom `App`, you'll need to restart the development server. Only required if `pages/_app.js` didn't exist before. -- Adding a custom [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md) in your `App` will disable [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) in pages without [Static Generation](/docs/basic-features/data-fetching.md#getstaticprops-static-generation). +- Adding a custom [`getInitialProps`](/docs/api-reference/data-fetching/get-initial-props.md) in your `App` will disable [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) in pages without [Static Generation](/docs/basic-features/data-fetching/get-static-props.md). - When you add `getInitialProps` in your custom app, you must `import App from "next/app"`, call `App.getInitialProps(appContext)` inside `getInitialProps` and merge the returned object into the return value. -- `App` currently does not support Next.js [Data Fetching methods](/docs/basic-features/data-fetching.md) like [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) or [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering). +- `App` currently does not support Next.js [Data Fetching methods](/docs/basic-features/data-fetching/index.md) like [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) or [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md). ### TypeScript diff --git a/docs/advanced-features/custom-document.md b/docs/advanced-features/custom-document.md index 2c75cca86b376e4..3ec0e856bee7b28 100644 --- a/docs/advanced-features/custom-document.md +++ b/docs/advanced-features/custom-document.md @@ -45,7 +45,7 @@ Custom attributes are allowed as props, like `lang`: The `` component used here is not the same one from [`next/head`](/docs/api-reference/next/head.md). The `` component used here should only be used for any `` code that is common for all pages. For all other cases, such as `` tags, we recommend using [`next/head`](/docs/api-reference/next/head.md) in your pages or components. -The `ctx` object is equivalent to the one received in [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md#context-object), with one addition: +The `ctx` object is equivalent to the one received in [`getInitialProps`](/docs/api-reference/data-fetching/get-initial-props.md#context-object), with one addition: - `renderPage`: `Function` - a callback that runs the actual React rendering logic (synchronously). It's useful to decorate this function in order to support server-rendering wrappers like Aphrodite's [`renderStatic`](https://github.com/Khan/aphrodite#server-side-rendering) @@ -54,7 +54,7 @@ The `ctx` object is equivalent to the one received in [`getInitialProps`](/docs/ - `Document` is only rendered in the server, event handlers like `onClick` won't work. - React components outside of `<Main />` will not be initialized by the browser. Do _not_ add application logic here or custom CSS (like `styled-jsx`). If you need shared components in all your pages (like a menu or a toolbar), take a look at the [`App`](/docs/advanced-features/custom-app.md) component instead. - `Document`'s `getInitialProps` function is not called during client-side transitions, nor when a page is [statically optimized](/docs/advanced-features/automatic-static-optimization.md). -- `Document` currently does not support Next.js [Data Fetching methods](/docs/basic-features/data-fetching.md) like [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) or [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering). +- `Document` currently does not support Next.js [Data Fetching methods](/docs/basic-features/data-fetching/index.md) like [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) or [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md). ## Customizing `renderPage` diff --git a/docs/advanced-features/custom-error-page.md b/docs/advanced-features/custom-error-page.md index 40913ed76eee11e..1f7913253773304 100644 --- a/docs/advanced-features/custom-error-page.md +++ b/docs/advanced-features/custom-error-page.md @@ -21,7 +21,7 @@ export default function Custom404() { } ``` -> **Note**: You can use [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) inside this page if you need to fetch data at build time. +> **Note**: You can use [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) inside this page if you need to fetch data at build time. ## 500 Page @@ -38,7 +38,7 @@ export default function Custom500() { } ``` -> **Note**: You can use [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) inside this page if you need to fetch data at build time. +> **Note**: You can use [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) inside this page if you need to fetch data at build time. ### More Advanced Error Page Customizing diff --git a/docs/advanced-features/i18n-routing.md b/docs/advanced-features/i18n-routing.md index 8272276b47418b7..6eb849294e06331 100644 --- a/docs/advanced-features/i18n-routing.md +++ b/docs/advanced-features/i18n-routing.md @@ -207,7 +207,7 @@ You can access the locale information via the Next.js router. For example, using - `locales` contains all configured locales. - `defaultLocale` contains the configured default locale. -When [pre-rendering](/docs/basic-features/pages.md#static-generation-recommended) pages with `getStaticProps` or `getServerSideProps`, the locale information is provided in [the context](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) provided to the function. +When [pre-rendering](/docs/basic-features/pages.md#static-generation-recommended) pages with `getStaticProps` or `getServerSideProps`, the locale information is provided in [the context](/docs/basic-features/data-fetching/get-static-props.md) provided to the function. When leveraging `getStaticPaths`, the configured locales are provided in the context parameter of the function under `locales` and the configured defaultLocale under `defaultLocale`. @@ -293,7 +293,7 @@ Next.js doesn't know about variants of a page so it's up to you to add the `href ### Dynamic Routes and `getStaticProps` Pages -For pages using `getStaticProps` with [Dynamic Routes](/docs/routing/dynamic-routes.md), all locale variants of the page desired to be prerendered need to be returned from [`getStaticPaths`](/docs/basic-features/data-fetching.md#getstaticpaths-static-generation). Along with the `params` object returned for `paths`, you can also return a `locale` field specifying which locale you want to render. For example: +For pages using `getStaticProps` with [Dynamic Routes](/docs/routing/dynamic-routes.md), all locale variants of the page desired to be prerendered need to be returned from [`getStaticPaths`](/docs/basic-features/data-fetching/get-static-paths.md). Along with the `params` object returned for `paths`, you can also return a `locale` field specifying which locale you want to render. For example: ```js // pages/blog/[slug].js diff --git a/docs/advanced-features/preview-mode.md b/docs/advanced-features/preview-mode.md index 511974bad4264ae..a5b7ac69c3e6594 100644 --- a/docs/advanced-features/preview-mode.md +++ b/docs/advanced-features/preview-mode.md @@ -27,7 +27,7 @@ description: Next.js has the preview mode for statically generated pages. You ca </ul> </details> -In the [Pages documentation](/docs/basic-features/pages.md) and the [Data Fetching documentation](/docs/basic-features/data-fetching.md), we talked about how to pre-render a page at build time (**Static Generation**) using `getStaticProps` and `getStaticPaths`. +In the [Pages documentation](/docs/basic-features/pages.md) and the [Data Fetching documentation](/docs/basic-features/data-fetching/index.md), we talked about how to pre-render a page at build time (**Static Generation**) using `getStaticProps` and `getStaticPaths`. Static Generation is useful when your pages fetch data from a headless CMS. However, it’s not ideal when you’re writing a draft on your headless CMS and want to **preview** the draft immediately on your page. You’d want Next.js to render these pages at **request time** instead of build time and fetch the draft content instead of the published content. You’d want Next.js to bypass Static Generation only for this specific case. @@ -230,7 +230,7 @@ This ensures that the bypass cookie can’t be guessed. The following pages might also be useful. <div class="card"> - <a href="/docs/basic-features/data-fetching.md"> + <a href="/docs/basic-features/data-fetching/index.md"> <b>Data Fetching:</b> <small>Learn more about data fetching in Next.js.</small> </a> diff --git a/docs/advanced-features/static-html-export.md b/docs/advanced-features/static-html-export.md index e37bd2ababcf487..6408adf0b7c68f7 100644 --- a/docs/advanced-features/static-html-export.md +++ b/docs/advanced-features/static-html-export.md @@ -13,7 +13,7 @@ description: Export your Next.js app to static HTML, and run it standalone witho `next export` allows you to export your Next.js application to static HTML, which can be run standalone without the need of a Node.js server. It is recommended to only use `next export` if you don't need any of the [unsupported features](#unsupported-features) requiring a server. -If you're looking to build a hybrid site where only _some_ pages are prerendered to static HTML, Next.js already does that automatically. Learn more about [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) and [Incremental Static Regeneration](/docs/basic-features/data-fetching.md#incremental-static-regeneration). +If you're looking to build a hybrid site where only _some_ pages are prerendered to static HTML, Next.js already does that automatically. Learn more about [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) and [Incremental Static Regeneration](/docs/basic-features/data-fetching/incremental-static-regeneration.md). ## `next export` @@ -27,7 +27,7 @@ Update your build script in `package.json` to use `next export`: Running `npm run build` will generate an `out` directory. -`next export` builds an HTML version of your app. During `next build`, [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) and [`getStaticPaths`](/docs/basic-features/data-fetching.md#getstaticpaths-static-generation) will generate an HTML file for each page in your `pages` directory (or more for [dynamic routes](/docs/routing/dynamic-routes.md). Then, `next export` will copy the already exported files into the correct directory. `getInitialProps` will generate the HTML files during `next export` instead of `next build`. +`next export` builds an HTML version of your app. During `next build`, [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) and [`getStaticPaths`](/docs/basic-features/data-fetching/get-static-paths.md) will generate an HTML file for each page in your `pages` directory (or more for [dynamic routes](/docs/routing/dynamic-routes.md). Then, `next export` will copy the already exported files into the correct directory. `getInitialProps` will generate the HTML files during `next export` instead of `next build`. 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. @@ -40,9 +40,9 @@ The majority of core Next.js features needed to build a static site are supporte - Preloading JavaScript - [Dynamic Imports](/docs/advanced-features/dynamic-import.md) - Any styling options (e.g. CSS Modules, styled-jsx) -- [Client-side data fetching](/docs/basic-features/data-fetching.md#fetching-data-on-the-client-side) -- [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) -- [`getStaticPaths`](/docs/basic-features/data-fetching.md#getstaticpaths-static-generation) +- [Client-side data fetching](/docs/basic-features/data-fetching/client-side.md) +- [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) +- [`getStaticPaths`](/docs/basic-features/data-fetching/get-static-paths.md) - [Image Optimization](/docs/basic-features/image-optimization.md) using a [custom loader](/docs/basic-features/image-optimization.md#loader) ## Unsupported Features @@ -56,16 +56,16 @@ Features that require a Node.js server, or dynamic logic that cannot be computed - [Redirects](/docs/api-reference/next.config.js/redirects.md) - [Headers](/docs/api-reference/next.config.js/headers.md) - [Middleware](/docs/middleware.md) -- [Incremental Static Regeneration](/docs/basic-features/data-fetching.md#incremental-static-regeneration) -- [`fallback: true`](/docs/basic-features/data-fetching.md#fallback-true) -- [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) +- [Incremental Static Regeneration](/docs/basic-features/data-fetching/incremental-static-regeneration.md) +- [`fallback: true`](/docs/api-reference/data-fetching/get-static-paths.md#fallback-true) +- [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md) ### `getInitialProps` -It's possible to use the [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md) API instead of `getStaticProps`, but it comes with a few caveats: +It's possible to use the [`getInitialProps`](/docs/api-reference/data-fetching/get-initial-props.md) API instead of `getStaticProps`, but it comes with a few caveats: - `getInitialProps` cannot be used alongside `getStaticProps` or `getStaticPaths` on any given page. If you have dynamic routes, instead of using `getStaticPaths` you'll need to configure the [`exportPathMap`](/docs/api-reference/next.config.js/exportPathMap.md) parameter in your [`next.config.js`](/docs/api-reference/next.config.js/introduction.md) file to let the exporter know which HTML files it should output. -- When `getInitialProps` is called during export, the `req` and `res` fields of its [`context`](/docs/api-reference/data-fetching/getInitialProps.md#context-object) parameter will be empty objects, since during export there is no server running. +- When `getInitialProps` is called during export, the `req` and `res` fields of its [`context`](/docs/api-reference/data-fetching/get-initial-props.md#context-object) parameter will be empty objects, since during export there is no server running. - `getInitialProps` **will be called on every client-side navigation**, if you'd like to only fetch data at build-time, switch to `getStaticProps`. - `getInitialProps` should fetch from an API and cannot use Node.js-specific libraries or the file system like `getStaticProps` can. diff --git a/docs/api-reference/data-fetching/getInitialProps.md b/docs/api-reference/data-fetching/get-initial-props.md similarity index 79% rename from docs/api-reference/data-fetching/getInitialProps.md rename to docs/api-reference/data-fetching/get-initial-props.md index 611533a9b3fc0e6..f8295dbda52c225 100644 --- a/docs/api-reference/data-fetching/getInitialProps.md +++ b/docs/api-reference/data-fetching/get-initial-props.md @@ -4,15 +4,11 @@ description: Enable Server-Side Rendering in a page and do initial data populati # getInitialProps -> **Recommended: [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) or [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering)**. -> -> If you're using Next.js 9.3 or newer, we recommend that you use `getStaticProps` or `getServerSideProps` instead of `getInitialProps`. -> -> These new data fetching methods allow you to have a granular choice between static generation and server-side rendering. Learn more on the documentation for [Pages](/docs/basic-features/pages.md) and [Data Fetching](/docs/basic-features/data-fetching.md). +**Recommended: [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) or [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md)** instead of `getInitialProps`. These data fetching methods allow you to have a granular choice between static generation and server-side rendering. `getInitialProps` enables [server-side rendering](/docs/basic-features/pages.md#server-side-rendering) in a page and allows you to do **initial data population**, it means sending the [page](/docs/basic-features/pages.md) with the data already populated from the server. This is especially useful for [SEO](https://en.wikipedia.org/wiki/Search_engine_optimization). -> `getInitialProps` will disable [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md). +`getInitialProps` will disable [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md). `getInitialProps` is an [`async`](https://vercel.com/blog/async-and-await) function that can be added to any page as a [`static method`](https://javascript.info/static-properties-methods). Take a look at the following example: @@ -123,22 +119,8 @@ export default class Page extends React.Component<Props> { For more information on what to do next, we recommend the following sections: <div class="card"> - <a href="/docs/basic-features/data-fetching.md"> + <a href="/docs/basic-features/data-fetching/index.md"> <b>Data Fetching:</b> <small>Learn more about data fetching in Next.js.</small> </a> </div> - -<div class="card"> - <a href="/docs/basic-features/pages.md"> - <b>Pages:</b> - <small>Learn more about what pages are in Next.js.</small> - </a> -</div> - -<div class="card"> - <a href="/docs/advanced-features/automatic-static-optimization.md"> - <b>Automatic Static Optimization:</b> - <small>Learn about how Next.js automatically optimizes your pages.</small> - </a> -</div> diff --git a/docs/api-reference/data-fetching/get-server-side-props.md b/docs/api-reference/data-fetching/get-server-side-props.md new file mode 100644 index 000000000000000..582b04db9e7b167 --- /dev/null +++ b/docs/api-reference/data-fetching/get-server-side-props.md @@ -0,0 +1,151 @@ +--- +description: API reference for `getServerSideProps`. Learn how to fetch data on each request with Next.js. +--- + +# `getServerSideProps` + +<details> + <summary><b>Version History</b></summary> + +| Version | Changes | +| --------- | ------------------------------------------------------------------- | +| `v10.0.0` | `locale`, `locales`, `defaultLocale`, and `notFound` options added. | +| `v9.3.0` | `getServerSideProps` introduced. | + +</details> + +When exporting a function called `getServerSideProps` (Server-Side Rendering) from a page, Next.js will pre-render this page on each request using the data returned by `getServerSideProps`. This is useful if you want to fetch data that changes often, and have the page update to show the most current data. + +```js +export async function getServerSideProps(context) { + return { + props: {}, // will be passed to the page component as props + } +} +``` + +You can import modules in top-level scope for use in `getServerSideProps`. Imports used will **not be bundled for the client-side**. This means you can write **server-side code directly in `getServerSideProps`**, including fetching data from your database. + +## Context parameter + +The `context` parameter is an object containing the following keys: + +- `params`: If this page uses a [dynamic route](/docs/routing/dynamic-routes.md), `params` contains the route parameters. If the page name is `[id].js` , then `params` will look like `{ id: ... }`. +- `req`: [The `HTTP` IncomingMessage object](https://nodejs.org/api/http.html#http_class_http_incomingmessage). +- `res`: [The `HTTP` response object](https://nodejs.org/api/http.html#http_class_http_serverresponse). +- `query`: An object representing the query string. +- `preview`: `preview` is `true` if the page is in the [Preview Mode](/docs/advanced-features/preview-mode.md) and `false` otherwise. +- `previewData`: The [preview](/docs/advanced-features/preview-mode.md) data set by `setPreviewData`. +- `resolvedUrl`: A normalized version of the request `URL` that strips the `_next/data` prefix for client transitions and includes original query values. +- `locale` contains the active locale (if enabled). +- `locales` contains all supported locales (if enabled). +- `defaultLocale` contains the configured default locale (if enabled). + +## `getServerSideProps` return values + +The `getServerSideProps` function should return an object with the following **optional** properties: + +### `props` + +The `props` object is a key-value pair, where each value is received by the page component. It should be a [serializable object](https://developer.mozilla.org/en-US/docs/Glossary/Serialization) so that any props passed, could be serialized with [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). + +```jsx +export async function getServerSideProps(context) { + return { + props: { message: `Next.js is awesome` }, // will be passed to the page component as props + } +} +``` + +### `notFound` + +The `notFound` boolean allows the page to return a `404` status and [404 Page](/docs/advanced-features/custom-error-page.md#404-page). With `notFound: true`, the page will return a `404` even if there was a successfully generated page before. This is meant to support use cases like user-generated content getting removed by its author. + +```js +export async function getServerSideProps(context) { + const res = await fetch(`https://.../data`) + const data = await res.json() + + if (!data) { + return { + notFound: true, + } + } + + return { + props: { data }, // will be passed to the page component as props + } +} +``` + +### `redirect` + +The `redirect` object allows redirecting to internal and external resources. It should match the shape of `{ destination: string, permanent: boolean }`. In some rare cases, you might need to assign a custom status code for older `HTTP` clients to properly redirect. In these cases, you can use the `statusCode` property instead of the `permanent` property, but not both. + +```js +export async function getServerSideProps(context) { + const res = await fetch(`https://.../data`) + const data = await res.json() + + if (!data) { + return { + redirect: { + destination: '/', + permanent: false, + }, + } + } + + return { + props: {}, // will be passed to the page component as props + } +} +``` + +### `getServerSideProps` with TypeScript + +For TypeScript, you can use the `GetServerSideProps` type from `next`: + +```ts +import { GetServerSideProps } from 'next' + +export const getServerSideProps: GetServerSideProps = async (context) => { + // ... +} +``` + +If you want to get inferred typings for your props, you can use `InferGetServerSidePropsType<typeof getServerSideProps>`: + +```tsx +import { InferGetServerSidePropsType } from 'next' + +type Data = { ... } + +export const getServerSideProps = async () => { + const res = await fetch('https://.../data') + const data: Data = await res.json() + + return { + props: { + data, + }, + } +} + +function Page({ data }: InferGetServerSidePropsType<typeof getServerSideProps>) { + // will resolve posts to type Data +} + +export default Page +``` + +## Related + +For more information on what to do next, we recommend the following sections: + +<div class="card"> + <a href="/docs/basic-features/data-fetching/index.md"> + <b>Data Fetching:</b> + <small>Learn more about data fetching in Next.js.</small> + </a> +</div> diff --git a/docs/api-reference/data-fetching/get-static-paths.md b/docs/api-reference/data-fetching/get-static-paths.md new file mode 100644 index 000000000000000..d185922fae93da7 --- /dev/null +++ b/docs/api-reference/data-fetching/get-static-paths.md @@ -0,0 +1,212 @@ +--- +description: API reference for `getStaticPaths`. Learn how to fetch data and generate static pages with `getStaticPaths`. +--- + +# `getStaticPaths` + +<details> + <summary><b>Version History</b></summary> + +| Version | Changes | +| -------- | --------------------------------------------------------------------------------------------------------------- | +| `v9.5.0` | Stable [Incremental Static Regeneration](/docs/basic-features/data-fetching/incremental-static-regeneration.md) | +| `v9.3.0` | `getStaticPaths` introduced. | + +</details> + +When exporting a function called `getStaticPaths` from a page that uses [Dynamic Routes](/docs/routing/dynamic-routes.md), Next.js will statically pre-render all the paths specified by `getStaticPaths`. + +```jsx +export async function getStaticPaths() { + return { + paths: [ + { params: { ... } } // See the "paths" section below + ], + fallback: true, false or "blocking" // See the "fallback" section below + }; +} +``` + +## `getStaticPaths` return values + +The `getStaticPaths` function should return an object with the following **required** properties: + +### `paths` + +The `paths` key determines which paths will be pre-rendered. For example, suppose that you have a page that uses [Dynamic Routes](/docs/routing/dynamic-routes.md) named `pages/posts/[id].js`. If you export `getStaticPaths` from this page and return the following for `paths`: + +```js +return { + paths: [ + { params: { id: '1' } }, + { params: { id: '2' } } + ], + fallback: ... +} +``` + +Then, Next.js will statically generate `/posts/1` and `/posts/2` during `next build` using the page component in `pages/posts/[id].js`. + +The value for each `params` object must match the parameters used in the page name: + +- If the page name is `pages/posts/[postId]/[commentId]`, then `params` should contain `postId` and `commentId`. +- If the page name uses [catch-all routes](/docs/routing/dynamic-routes.md#catch-all-routes) like `pages/[...slug]`, then `params` should contain `slug` (which is an array). If this array is `['hello', 'world']`, then Next.js will statically generate the page at `/hello/world`. +- If the page uses an [optional catch-all route](/docs/routing/dynamic-routes.md#optional-catch-all-routes), use `null`, `[]`, `undefined` or `false` to render the root-most route. For example, if you supply `slug: false` for `pages/[[...slug]]`, Next.js will statically generate the page `/`. + +### `fallback: false` + +If `fallback` is `false`, then any paths not returned by `getStaticPaths` will result in a **404 page**. + +When `next build` is run, Next.js will check if `getStaticPaths` returned `fallback: false`, it will then build **only** the paths returned by `getStaticPaths`. This option is useful if you have a small number of paths to create, or new page data is not added often. If you find that you need to add more paths, and you have `fallback: false`, you will need to run `next build` again so that the new paths can be generated. + +The following example pre-renders one blog post per page called `pages/posts/[id].js`. The list of blog posts will be fetched from a CMS and returned by `getStaticPaths`. Then, for each page, it fetches the post data from a CMS using [`getStaticProps`](/docs/api-reference/data-fetching/get-static-props.md). + +```jsx +// pages/posts/[id].js + +function Post({ post }) { + // Render post... +} + +// This function gets called at build time +export async function getStaticPaths() { + // Call an external API endpoint to get posts + const res = await fetch('https://.../posts') + const posts = await res.json() + + // Get the paths we want to pre-render based on posts + const paths = posts.map((post) => ({ + params: { id: post.id }, + })) + + // We'll pre-render only these paths at build time. + // { fallback: false } means other routes should 404. + return { paths, fallback: false } +} + +// This also gets called at build time +export async function getStaticProps({ params }) { + // params contains the post `id`. + // If the route is like /posts/1, then params.id is 1 + const res = await fetch(`https://.../posts/${params.id}`) + const post = await res.json() + + // Pass post data to the page via props + return { props: { post } } +} + +export default Post +``` + +### `fallback: true` + +<details> + <summary><b>Examples</b></summary> + <ul> + <li><a href="https://static-tweet.vercel.app">Static generation of a large number of pages</a></li> + </ul> +</details> + +If `fallback` is `true`, then the behavior of `getStaticProps` changes in the following ways: + +- The paths returned from `getStaticPaths` will be rendered to `HTML` at build time by `getStaticProps`. +- The paths that have not been generated at build time will **not** result in a 404 page. Instead, Next.js will serve a [“fallback”](#fallback-pages) version of the page on the first request to such a path. +- In the background, Next.js will statically generate the requested path `HTML` and `JSON`. This includes running `getStaticProps`. +- When complete, the browser receives the `JSON` for the generated path. This will be used to automatically render the page with the required props. From the user’s perspective, the page will be swapped from the fallback page to the full page. +- At the same time, Next.js adds this path to the list of pre-rendered pages. Subsequent requests to the same path will serve the generated page, like other pages pre-rendered at build time. + +> **Note:** `fallback: true` is not supported when using [`next export`](/docs/advanced-features/static-html-export.md). + +#### When is `fallback: true` useful? + +`fallback: true` is useful if your app has a very large number of static pages that depend on data (such as a very large e-commerce site). If you want to pre-render all product pages, the builds would take a very long time. + +Instead, you may statically generate a small subset of pages and use `fallback: true` for the rest. When someone requests a page that is not generated yet, the user will see the page with a loading indicator or skeleton component. + +Shortly after, `getStaticProps` finishes and the page will be rendered with the requested data. From now on, everyone who requests the same page will get the statically pre-rendered page. + +This ensures that users always have a fast experience while preserving fast builds and the benefits of Static Generation. + +`fallback: true` will not _update_ generated pages, for that take a look at [Incremental Static Regeneration](/docs/basic-features/data-fetching/incremental-static-regeneration.md). + +### `fallback: 'blocking'` + +If `fallback` is `'blocking'`, new paths not returned by `getStaticPaths` will wait for the `HTML` to be generated, identical to SSR (hence why _blocking_), and then be cached for future requests so it only happens once per path. + +`getStaticProps` will behave as follows: + +- The paths returned from `getStaticPaths` will be rendered to `HTML` at build time by `getStaticProps`. +- The paths that have not been generated at build time will **not** result in a 404 page. Instead, Next.js will SSR on the first request and return the generated `HTML`. +- When complete, the browser receives the `HTML` for the generated path. From the user’s perspective, it will transition from "the browser is requesting the page" to "the full page is loaded". There is no flash of loading/fallback state. +- At the same time, Next.js adds this path to the list of pre-rendered pages. Subsequent requests to the same path will serve the generated page, like other pages pre-rendered at build time. + +`fallback: 'blocking'` will not _update_ generated pages by default. To update generated pages, use [Incremental Static Regeneration](/docs/basic-features/data-fetching/incremental-static-regeneration.md) in conjunction with `fallback: 'blocking'`. + +> **Note:** `fallback: 'blocking'` is not supported when using [`next export`](/docs/advanced-features/static-html-export.md). + +### Fallback pages + +In the “fallback” version of a page: + +- The page’s props will be empty. +- Using the [router](/docs/api-reference/next/router.md), you can detect if the fallback is being rendered, `router.isFallback` will be `true`. + +The following example showcases using `isFallback`: + +```jsx +// pages/posts/[id].js +import { useRouter } from 'next/router' + +function Post({ post }) { + const router = useRouter() + + // If the page is not yet generated, this will be displayed + // initially until getStaticProps() finishes running + if (router.isFallback) { + return <div>Loading...</div> + } + + // Render post... +} + +// This function gets called at build time +export async function getStaticPaths() { + return { + // Only `/posts/1` and `/posts/2` are generated at build time + paths: [{ params: { id: '1' } }, { params: { id: '2' } }], + // Enable statically generating additional pages + // For example: `/posts/3` + fallback: true, + } +} + +// This also gets called at build time +export async function getStaticProps({ params }) { + // params contains the post `id`. + // If the route is like /posts/1, then params.id is 1 + const res = await fetch(`https://.../posts/${params.id}`) + const post = await res.json() + + // Pass post data to the page via props + return { + props: { post }, + // Re-generate the post at most once per second + // if a request comes in + revalidate: 1, + } +} + +export default Post +``` + +## `getStaticProps` with TypeScript + +For TypeScript, you can use the `GetStaticPaths` type from `next`: + +```ts +import { GetStaticPaths } from 'next' + +export const getStaticPaths: GetStaticPaths = async () => { + // ... +} +``` diff --git a/docs/api-reference/data-fetching/get-static-props.md b/docs/api-reference/data-fetching/get-static-props.md new file mode 100644 index 000000000000000..2ab5ddb9f262590 --- /dev/null +++ b/docs/api-reference/data-fetching/get-static-props.md @@ -0,0 +1,244 @@ +--- +description: API reference for `getStaticProps`. Learn how to use `getStaticProps` to generate static pages with Next.js. +--- + +# `getStaticProps` + +<details> + <summary><b>Version History</b></summary> + +| Version | Changes | +| --------- | ----------------------------------------------------------------------------------------------------------------- | +| `v10.0.0` | `locale`, `locales`, `defaultLocale`, and `notFound` options added. | +| `v9.5.0` | Stable [Incremental Static Regeneration](https://nextjs.org/blog/next-9-5#stable-incremental-static-regeneration) | +| `v9.3.0` | `getStaticProps` introduced. | +| `v10.0.0` | `fallback: 'blocking'` return option added. | + +</details> + +Exporting a function called `getStaticProps` will pre-render a page at build time using the props returned from the function: + +```jsx +export async function getStaticProps(context) { + return { + props: {}, // will be passed to the page component as props + } +} +``` + +You can import modules in top-level scope for use in `getStaticProps`. Imports used will **not be bundled for the client-side**. This means you can write **server-side code directly in `getStaticProps`**, including fetching data from your database. + +## Context parameter + +The `context` parameter is an object containing the following keys: + +- `params` contains the route parameters for pages using [dynamic routes](/docs/routing/dynamic-routes.md). For example, if the page name is `[id].js` , then `params` will look like `{ id: ... }`. You should use this together with `getStaticPaths`, which we’ll explain later. +- `preview` is `true` if the page is in the [Preview Mode](/docs/advanced-features/preview-mode.md) and `undefined` otherwise. +- `previewData` contains the [preview](/docs/advanced-features/preview-mode.md) data set by `setPreviewData`. +- `locale` contains the active locale (if enabled). +- `locales` contains all supported locales (if enabled). +- `defaultLocale` contains the configured default locale (if enabled). + +## `getStaticProps` return values + +The `getStaticProps` function should return an object with the following **optional** properties: + +### `props` + +The `props` object is a key-value pair, where each value is received by the page component. It should be a [serializable object](https://developer.mozilla.org/en-US/docs/Glossary/Serialization) so that any props passed, could be serialized with [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). + +```jsx +export async function getStaticProps(context) { + return { + props: { message: `Next.js is awesome` }, // will be passed to the page component as props + } +} +``` + +### `revalidate` + +The `revalidate` property is the amount in seconds after which a page re-generation can occur (defaults to `false` or no revalidation). + +```js +// This function gets called at build time on server-side. +// It may be called again, on a serverless function, if +// revalidation is enabled and a new request comes in +export async function getStaticProps() { + const res = await fetch('https://.../posts') + const posts = await res.json() + + return { + props: { + posts, + }, + // Next.js will attempt to re-generate the page: + // - When a request comes in + // - At most once every 10 seconds + revalidate: 10, // In seconds + } +} +``` + +Learn more about [Incremental Static Regeneration](/docs/basic-features/data-fetching/incremental-static-regeneration.md) + +### `notFound` + +The `notFound` boolean allows the page to return a `404` status and [404 Page](/docs/advanced-features/custom-error-page.md#404-page). With `notFound: true`, the page will return a `404` even if there was a successfully generated page before. This is meant to support use cases like user-generated content getting removed by its author. + +```js +export async function getStaticProps(context) { + const res = await fetch(`https://.../data`) + const data = await res.json() + + if (!data) { + return { + notFound: true, + } + } + + return { + props: { data }, // will be passed to the page component as props + } +} +``` + +> **Note**: `notFound` is not needed for [`fallback: false`](/docs/api-reference/data-fetching/get-static-paths#fallback-false) mode as only paths returned from `getStaticPaths` will be pre-rendered. + +### `redirect` + +The `redirect` object allows redirecting to internal or external resources. It should match the shape of `{ destination: string, permanent: boolean }`. + +In some rare cases, you might need to assign a custom status code for older `HTTP` clients to properly redirect. In these cases, you can use the `statusCode` property instead of the `permanent` property, **but not both**. You can also set `basePath: false` similar to redirects in `next.config.js`. + +```js +export async function getStaticProps(context) { + const res = await fetch(`https://...`) + const data = await res.json() + + if (!data) { + return { + redirect: { + destination: '/', + permanent: false, + // statusCode: 301 + }, + } + } + + return { + props: { data }, // will be passed to the page component as props + } +} +``` + +If the redirects are known at build-time, they should be added in [`next.config.js`](/docs/api-reference/next.config.js/redirects.md) instead. + +## Reading files: Use `process.cwd()` + +Files can be read directly from the filesystem in `getStaticProps`. + +In order to do so you have to get the full path to a file. + +Since Next.js compiles your code into a separate directory you can't use `__dirname` as the path it will return will be different from the pages directory. + +Instead you can use `process.cwd()` which gives you the directory where Next.js is being executed. + +```jsx +import { promises as fs } from 'fs' +import path from 'path' + +// posts will be populated at build time by getStaticProps() +function Blog({ posts }) { + return ( + <ul> + {posts.map((post) => ( + <li> + <h3>{post.filename}</h3> + <p>{post.content}</p> + </li> + ))} + </ul> + ) +} + +// This function gets called at build time on server-side. +// It won't be called on client-side, so you can even do +// direct database queries. +export async function getStaticProps() { + const postsDirectory = path.join(process.cwd(), 'posts') + const filenames = await fs.readdir(postsDirectory) + + const posts = filenames.map(async (filename) => { + const filePath = path.join(postsDirectory, filename) + const fileContents = await fs.readFile(filePath, 'utf8') + + // Generally you would parse/transform the contents + // For example you can transform markdown to HTML here + + return { + filename, + content: fileContents, + } + }) + // By returning { props: { posts } }, the Blog component + // will receive `posts` as a prop at build time + return { + props: { + posts: await Promise.all(posts), + }, + } +} + +export default Blog +``` + +## `getStaticProps` with TypeScript + +You can use the `GetStaticProps` type from `next` to type the function: + +```ts +import { GetStaticProps } from 'next' + +export const getStaticProps: GetStaticProps = async (context) => { + // ... +} +``` + +If you want to get inferred typings for your props, you can use `InferGetStaticPropsType<typeof getStaticProps>`: + +```tsx +import { InferGetStaticPropsType } from 'next' + +type Post = { + author: string + content: string +} + +export const getStaticProps = async () => { + const res = await fetch('https://.../posts') + const posts: Post[] = await res.json() + + return { + props: { + posts, + }, + } +} + +function Blog({ posts }: InferGetStaticPropsType<typeof getStaticProps>) { + // will resolve posts to type Post[] +} + +export default Blog +``` + +## Related + +For more information on what to do next, we recommend the following sections: + +<div class="card"> + <a href="/docs/basic-features/data-fetching/index.md"> + <b>Data Fetching:</b> + <small>Learn more about data fetching in Next.js.</small> + </a> +</div> diff --git a/docs/api-reference/next.config.js/cdn-support-with-asset-prefix.md b/docs/api-reference/next.config.js/cdn-support-with-asset-prefix.md index 20056521d6e784d..0383f6ee6e6d27a 100644 --- a/docs/api-reference/next.config.js/cdn-support-with-asset-prefix.md +++ b/docs/api-reference/next.config.js/cdn-support-with-asset-prefix.md @@ -42,7 +42,7 @@ While `assetPrefix` covers requests to `_next/static`, it does not influence the - Files in the [public](/docs/basic-features/static-file-serving.md) folder; if you want to serve those assets over a CDN, you'll have to introduce the prefix yourself - `/_next/data/` requests for `getServerSideProps` pages. These requests will always be made against the main domain since they're not static. -- `/_next/data/` requests for `getStaticProps` pages. These requests will always be made against the main domain to support [Incremental Static Generation](/docs/basic-features/data-fetching.md#incremental-static-regeneration), even if you're not using it (for consistency). +- `/_next/data/` requests for `getStaticProps` pages. These requests will always be made against the main domain to support [Incremental Static Generation](/docs/basic-features/data-fetching/incremental-static-regeneration.md), even if you're not using it (for consistency). ## Related diff --git a/docs/api-reference/next.config.js/redirects.md b/docs/api-reference/next.config.js/redirects.md index 6a8e110db82f4b9..15b370c42081495 100644 --- a/docs/api-reference/next.config.js/redirects.md +++ b/docs/api-reference/next.config.js/redirects.md @@ -292,4 +292,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.md#getstaticprops-static-generation) and [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering), you can redirect specific pages at request-time. +- 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. diff --git a/docs/api-reference/next.config.js/rewrites.md b/docs/api-reference/next.config.js/rewrites.md index 3a54cf4288ef926..16ae2b533df855f 100644 --- a/docs/api-reference/next.config.js/rewrites.md +++ b/docs/api-reference/next.config.js/rewrites.md @@ -148,7 +148,7 @@ module.exports = { } ``` -Note: for static pages from the [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) or [prerendering](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) params from rewrites will be parsed on the client after hydration and provided in the query. +Note: for static pages from the [Automatic Static Optimization](/docs/advanced-features/automatic-static-optimization.md) or [prerendering](/docs/basic-features/data-fetching/get-static-props.md) params from rewrites will be parsed on the client after hydration and provided in the query. ## Path Matching diff --git a/docs/api-reference/next/link.md b/docs/api-reference/next/link.md index a7ad63ca2704798..0525518af91f64e 100644 --- a/docs/api-reference/next/link.md +++ b/docs/api-reference/next/link.md @@ -57,10 +57,10 @@ export default Home - `href` - The path or URL to navigate to. This is the only required prop - `as` - Optional decorator for the path that will be shown in the browser URL bar. Before Next.js 9.5.3 this was used for dynamic routes, check our [previous docs](https://nextjs.org/docs/tag/v9.5.2/api-reference/next/link#dynamic-routes) to see how it worked. Note: when this path differs from the one provided in `href` the previous `href`/`as` behavior is used as shown in the [previous docs](https://nextjs.org/docs/tag/v9.5.2/api-reference/next/link#dynamic-routes). - [`passHref`](#if-the-child-is-a-custom-component-that-wraps-an-a-tag) - Forces `Link` to send the `href` property to its child. Defaults to `false` -- `prefetch` - Prefetch the page in the background. Defaults to `true`. Any `<Link />` that is in the viewport (initially or through scroll) will be preloaded. Prefetch can be disabled by passing `prefetch={false}`. When `prefetch` is set to `false`, prefetching will still occur on hover. Pages using [Static Generation](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) will preload `JSON` files with the data for faster page transitions. Prefetching is only enabled in production. +- `prefetch` - Prefetch the page in the background. Defaults to `true`. Any `<Link />` that is in the viewport (initially or through scroll) will be preloaded. Prefetch can be disabled by passing `prefetch={false}`. When `prefetch` is set to `false`, prefetching will still occur on hover. Pages using [Static Generation](/docs/basic-features/data-fetching/get-static-props.md) will preload `JSON` files with the data for faster page transitions. Prefetching is only enabled in production. - [`replace`](#replace-the-url-instead-of-push) - Replace the current `history` state instead of adding a new url into the stack. Defaults to `false` - [`scroll`](#disable-scrolling-to-the-top-of-the-page) - Scroll to the top of the page after a navigation. Defaults to `true` -- [`shallow`](/docs/routing/shallow-routing.md) - Update the path of the current page without rerunning [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation), [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) or [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md). Defaults to `false` +- [`shallow`](/docs/routing/shallow-routing.md) - Update the path of the current page without rerunning [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md), [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md) or [`getInitialProps`](/docs/api-reference/data-fetching/get-initial-props.md). Defaults to `false` - `locale` - The active locale is automatically prepended. `locale` allows for providing a different locale. When `false` `href` has to include the locale as the default behavior is disabled. ## If the route has dynamic segments diff --git a/docs/api-reference/next/router.md b/docs/api-reference/next/router.md index 4d5356842fa2578..d595c3ac54703ca 100644 --- a/docs/api-reference/next/router.md +++ b/docs/api-reference/next/router.md @@ -42,9 +42,9 @@ export default ActiveLink The following is the definition of the `router` object returned by both [`useRouter`](#useRouter) and [`withRouter`](#withRouter): - `pathname`: `String` - Current route. That is the path of the page in `/pages`, the configured `basePath` or `locale` is not included. -- `query`: `Object` - The query string parsed to an object. It will be an empty object during prerendering if the page doesn't have [data fetching requirements](/docs/basic-features/data-fetching.md). Defaults to `{}` +- `query`: `Object` - The query string parsed to an object. It will be an empty object during prerendering if the page doesn't have [data fetching requirements](/docs/basic-features/data-fetching/index.md). Defaults to `{}` - `asPath`: `String` - The path (including the query) shown in the browser without the configured `basePath` or `locale`. -- `isFallback`: `boolean` - Whether the current page is in [fallback mode](/docs/basic-features/data-fetching.md#fallback-pages). +- `isFallback`: `boolean` - Whether the current page is in [fallback mode](/docs/api-reference/data-fetching/get-static-paths.md#fallback-pages). - `basePath`: `String` - The active [basePath](/docs/api-reference/next.config.js/basepath.md) (if enabled). - `locale`: `String` - The active locale (if enabled). - `locales`: `String[]` - All supported locales (if enabled). @@ -74,7 +74,7 @@ router.push(url, as, options) - `as`: `UrlObject | String` - Optional decorator for the path that will be shown in the browser URL bar. Before Next.js 9.5.3 this was used for dynamic routes, check our [previous docs](https://nextjs.org/docs/tag/v9.5.2/api-reference/next/link#dynamic-routes) to see how it worked. Note: when this path differs from the one provided in `href` the previous `href`/`as` behavior is used as shown in the [previous docs](https://nextjs.org/docs/tag/v9.5.2/api-reference/next/link#dynamic-routes) - `options` - Optional object with the following configuration options: - `scroll` - Optional boolean, controls scrolling to the top of the page after navigation. Defaults to `true` - - [`shallow`](/docs/routing/shallow-routing.md): Update the path of the current page without rerunning [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation), [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) or [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md). Defaults to `false` + - [`shallow`](/docs/routing/shallow-routing.md): Update the path of the current page without rerunning [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md), [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md) or [`getInitialProps`](/docs/api-reference/data-fetching/get-initial-props.md). Defaults to `false` - `locale` - Optional string, indicates locale of the new page > You don't need to use `router.push` for external URLs. [window.location](https://developer.mozilla.org/en-US/docs/Web/API/Window/location) is better suited for those cases. diff --git a/docs/authentication.md b/docs/authentication.md index 2afc9a05f9cf71a..45dc5bbe185a421 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -8,14 +8,14 @@ Authentication verifies who a user is, while authorization controls what a user ## Authentication Patterns -The first step to identifying which authentication pattern you need is understanding the [data-fetching strategy](/docs/basic-features/data-fetching.md) you want. We can then determine which authentication providers support this strategy. There are two main patterns: +The first step to identifying which authentication pattern you need is understanding the [data-fetching strategy](/docs/basic-features/data-fetching/index.md) you want. We can then determine which authentication providers support this strategy. There are two main patterns: - Use [static generation](/docs/basic-features/pages.md#static-generation-recommended) to server-render a loading state, followed by fetching user data client-side. - Fetch user data [server-side](/docs/basic-features/pages.md#server-side-rendering) to eliminate a flash of unauthenticated content. ### Authenticating Statically Generated Pages -Next.js automatically determines that a page is static if there are no blocking data requirements. This means the absence of [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) and `getInitialProps` in the page. Instead, your page can render a loading state from the server, followed by fetching the user client-side. +Next.js automatically determines that a page is static if there are no blocking data requirements. This means the absence of [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md) and `getInitialProps` in the page. Instead, your page can render a loading state from the server, followed by fetching the user client-side. One advantage of this pattern is it allows pages to be served from a global CDN and preloaded using [`next/link`](/docs/api-reference/next/link.md). In practice, this results in a faster TTI ([Time to Interactive](https://web.dev/interactive/)). @@ -52,7 +52,7 @@ You can view this [example in action](https://iron-session-example.vercel.app/). ### Authenticating Server-Rendered Pages -If you export an `async` function called [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) from a page, Next.js will pre-render this page on each request using the data returned by `getServerSideProps`. +If you export an `async` function called [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md) from a page, Next.js will pre-render this page on each request using the data returned by `getServerSideProps`. ```jsx export async function getServerSideProps(context) { @@ -154,7 +154,7 @@ For more information on what to do next, we recommend the following sections: </div> <div class="card"> - <a href="/docs/basic-features/data-fetching.md"> + <a href="/docs/basic-features/data-fetching/index.md"> <b>Data Fetching:</b> <small>Learn more about data fetching in Next.js.</small> </a> diff --git a/docs/basic-features/data-fetching.md b/docs/basic-features/data-fetching.md deleted file mode 100644 index d7d2caaa5c1b88b..000000000000000 --- a/docs/basic-features/data-fetching.md +++ /dev/null @@ -1,882 +0,0 @@ ---- -description: 'Next.js has 2 pre-rendering modes: Static Generation and Server-side rendering. Learn how they work here.' ---- - -# Data Fetching - -> This document is for Next.js versions 9.3 and up. If you’re using older versions of Next.js, refer to our [previous documentation](https://nextjs.org/docs/tag/v9.2.2/basic-features/data-fetching). - -<details open> - <summary><b>Examples</b></summary> - <ul> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-wordpress">WordPress Example</a> (<a href="https://next-blog-wordpress.vercel.app">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/blog-starter">Blog Starter using markdown files</a> (<a href="https://next-blog-starter.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-datocms">DatoCMS Example</a> (<a href="https://next-blog-datocms.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-takeshape">TakeShape Example</a> (<a href="https://next-blog-takeshape.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-sanity">Sanity Example</a> (<a href="https://next-blog-sanity.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-prismic">Prismic Example</a> (<a href="https://next-blog-prismic.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-contentful">Contentful Example</a> (<a href="https://next-blog-contentful.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-strapi">Strapi Example</a> (<a href="https://next-blog-strapi.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-prepr">Prepr Example</a> (<a href="https://next-blog-prepr.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-agilitycms">Agility CMS Example</a> (<a href="https://next-blog-agilitycms.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-cosmic">Cosmic Example</a> (<a href="https://next-blog-cosmic.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-buttercms">ButterCMS Example</a> (<a href="https://next-blog-buttercms.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-storyblok">Storyblok Example</a> (<a href="https://next-blog-storyblok.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-graphcms">GraphCMS Example</a> (<a href="https://next-blog-graphcms.vercel.app/">Demo</a>)</li> - <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-kontent">Kontent Example</a> (<a href="https://next-blog-kontent.vercel.app/">Demo</a>)</li> - <li><a href="https://static-tweet.vercel.app/">Static Tweet Demo</a></li> - </ul> -</details> - -In the [Pages documentation](/docs/basic-features/pages.md), we’ve explained that Next.js has two forms of pre-rendering: **Static Generation** and **Server-side Rendering**. In this page, we’ll talk in depth about data fetching strategies for each case. We recommend you to [read through the Pages documentation](/docs/basic-features/pages.md) first if you haven’t done so. - -We’ll talk about the three unique Next.js functions you can use to fetch data for pre-rendering: - -- [`getStaticProps`](#getstaticprops-static-generation) (Static Generation): Fetch data at **build time**. -- [`getStaticPaths`](#getstaticpaths-static-generation) (Static Generation): Specify [dynamic routes](/docs/routing/dynamic-routes.md) to pre-render pages based on data. -- [`getServerSideProps`](#getserversideprops-server-side-rendering) (Server-side Rendering): Fetch data on **each request**. - -In addition, we’ll talk briefly about how to fetch data on the client side. - -## `getStaticProps` (Static Generation) - -<details> - <summary><b>Version History</b></summary> - -| Version | Changes | -| --------- | ----------------------------------------------------------------------------------------------------------------- | -| `v12.0.0` | `staticPageGenerationTimeout` added. | -| `v10.0.0` | `locale`, `locales`, `defaultLocale`, and `notFound` options added. | -| `v9.5.0` | Stable [Incremental Static Regeneration](https://nextjs.org/blog/next-9-5#stable-incremental-static-regeneration) | -| `v9.3.0` | `getStaticProps` introduced. | - -</details> - -If you export an `async` function called `getStaticProps` from a page, Next.js will pre-render this page at build time using the props returned by `getStaticProps`. - -```jsx -export async function getStaticProps(context) { - return { - props: {}, // will be passed to the page component as props - } -} -``` - -The `context` parameter is an object containing the following keys: - -- `params` contains the route parameters for pages using dynamic routes. For example, if the page name is `[id].js` , then `params` will look like `{ id: ... }`. To learn more, take a look at the [Dynamic Routing documentation](/docs/routing/dynamic-routes.md). You should use this together with `getStaticPaths`, which we’ll explain later. -- `preview` is `true` if the page is in the preview mode and `undefined` otherwise. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md). -- `previewData` contains the preview data set by `setPreviewData`. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md). -- `locale` contains the active locale (if you've enabled [Internationalized Routing](/docs/advanced-features/i18n-routing.md)). -- `locales` contains all supported locales (if you've enabled [Internationalized Routing](/docs/advanced-features/i18n-routing.md)). -- `defaultLocale` contains the configured default locale (if you've enabled [Internationalized Routing](/docs/advanced-features/i18n-routing.md)). - -`getStaticProps` should return an object with: - -- `props` - An **optional** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization) -- `revalidate` - An **optional** amount in seconds after which a page re-generation can occur. Defaults to `false`. When `revalidate` is `false` it means that there is no revalidation, so the page will be cached as built until your next build. More on [Incremental Static Regeneration](#incremental-static-regeneration) -- `notFound` - An **optional** boolean value to allow the page to return a 404 status and page. Below is an example of how it works: - - ```js - export async function getStaticProps(context) { - const res = await fetch(`https://.../data`) - const data = await res.json() - - if (!data) { - return { - notFound: true, - } - } - - return { - props: { data }, // will be passed to the page component as props - } - } - ``` - - > **Note**: `notFound` is not needed for [`fallback: false`](#fallback-false) mode as only paths returned from `getStaticPaths` will be pre-rendered. - - > **Note**: With `notFound: true` the page will return a 404 even if there was a successfully generated page before. This is meant to support use-cases like user generated content getting removed by its author. - -- `redirect` - An **optional** redirect value to allow redirecting to internal and external resources. It should match the shape of `{ destination: string, permanent: boolean }`. In some rare cases, you might need to assign a custom status code for older HTTP Clients to properly redirect. In these cases, you can use the `statusCode` property instead of the `permanent` property, but not both. You can also set `basePath: false` similar to redirects in `next.config.js`. Below is an example of how it works: - - ```js - export async function getStaticProps(context) { - const res = await fetch(`https://...`) - const data = await res.json() - - if (!data) { - return { - redirect: { - destination: '/', - permanent: false, - }, - } - } - - return { - props: { data }, // will be passed to the page component as props - } - } - ``` - - > **Note**: Redirecting at build-time is currently not allowed and if the redirects are known at build-time they should be added in [`next.config.js`](/docs/api-reference/next.config.js/redirects.md). - -> **Note**: You can import modules in top-level scope for use in `getStaticProps`. -> Imports used in `getStaticProps` will [not be bundled for the client-side](#write-server-side-code-directly). -> -> This means you can write **server-side code directly in `getStaticProps`**. -> This includes reading from the filesystem or a database. - -> **Note**: You should not use [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to -> call an API route in `getStaticProps`. -> Instead, directly import the logic used inside your API route. -> You may need to slightly refactor your code for this approach. -> -> Fetching from an external API is fine! - -### Example - -Here’s an example which uses `getStaticProps` to fetch a list of blog posts from a CMS (content management system). This example is also in the [Pages documentation](/docs/basic-features/pages.md). - -```jsx -// posts will be populated at build time by getStaticProps() -function Blog({ posts }) { - return ( - <ul> - {posts.map((post) => ( - <li>{post.title}</li> - ))} - </ul> - ) -} - -// This function gets called at build time on server-side. -// It won't be called on client-side, so you can even do -// direct database queries. See the "Technical details" section. -export async function getStaticProps() { - // Call an external API endpoint to get posts. - // You can use any data fetching library - const res = await fetch('https://.../posts') - const posts = await res.json() - - // By returning { props: { posts } }, the Blog component - // will receive `posts` as a prop at build time - return { - props: { - posts, - }, - } -} - -export default Blog -``` - -### When should I use `getStaticProps`? - -You should use `getStaticProps` if: - -- The data required to render the page is available at build time ahead of a user’s request. -- The data comes from a headless CMS. -- The data can be publicly cached (not user-specific). -- The page must be pre-rendered (for SEO) and be very fast — `getStaticProps` generates HTML and JSON files, both of which can be cached by a CDN for performance. - -### TypeScript: Use `GetStaticProps` - -For TypeScript, you can use the `GetStaticProps` type from `next`: - -```ts -import { GetStaticProps } from 'next' - -export const getStaticProps: GetStaticProps = async (context) => { - // ... -} -``` - -If you want to get inferred typings for your props, you can use `InferGetStaticPropsType<typeof getStaticProps>`, like this: - -```tsx -import { InferGetStaticPropsType } from 'next' - -type Post = { - author: string - content: string -} - -export const getStaticProps = async () => { - const res = await fetch('https://.../posts') - const posts: Post[] = await res.json() - - return { - props: { - posts, - }, - } -} - -function Blog({ posts }: InferGetStaticPropsType<typeof getStaticProps>) { - // will resolve posts to type Post[] -} - -export default Blog -``` - -Note: Next.js has a default static generation timeout of 60 seconds. If no new pages complete generating within the timeout, it will attempt generation three more times. If the fourth attempt fails, the build will fail. This timeout can be modified using the following configuration: - -```js -// next.config.js -module.exports = { - // time in seconds of no pages generating during static - // generation before timing out - staticPageGenerationTimeout: 90, -} -``` - -### Incremental Static Regeneration - -<details open> - <summary><b>Examples</b></summary> - <ul> - <li><a href="https://nextjs.org/commerce">Next.js Commerce</a></li> - <li><a href="https://reactions-demo.vercel.app/">GitHub Reactions Demo</a></li> - <li><a href="https://static-tweet.vercel.app/">Static Tweet Demo</a></li> - </ul> -</details> - -<details> - <summary><b>Version History</b></summary> - -| Version | Changes | -| -------- | ---------------- | -| `v9.5.0` | Base Path added. | - -</details> - -Next.js allows you to create or update static pages _after_ you’ve built your site. Incremental Static Regeneration (ISR) enables you to use static-generation on a per-page basis, **without needing to rebuild the entire site**. With ISR, you can retain the benefits of static while scaling to millions of pages. - -Consider our previous [`getStaticProps` example](#simple-example), but now with Incremental Static Regeneration enabled through the `revalidate` property: - -```jsx -function Blog({ posts }) { - return ( - <ul> - {posts.map((post) => ( - <li>{post.title}</li> - ))} - </ul> - ) -} - -// This function gets called at build time on server-side. -// It may be called again, on a serverless function, if -// revalidation is enabled and a new request comes in -export async function getStaticProps() { - const res = await fetch('https://.../posts') - const posts = await res.json() - - return { - props: { - posts, - }, - // Next.js will attempt to re-generate the page: - // - When a request comes in - // - At most once every 10 seconds - revalidate: 10, // In seconds - } -} - -// This function gets called at build time on server-side. -// It may be called again, on a serverless function, if -// the path has not been generated. -export async function getStaticPaths() { - const res = await fetch('https://.../posts') - const posts = await res.json() - - // Get the paths we want to pre-render based on posts - const paths = posts.map((post) => ({ - params: { id: post.id }, - })) - - // We'll pre-render only these paths at build time. - // { fallback: blocking } will server-render pages - // on-demand if the path doesn't exist. - return { paths, fallback: 'blocking' } -} - -export default Blog -``` - -When a request is made to a page that was pre-rendered at build time, it will initially show the cached page. - -- Any requests to the page after the initial request and before 10 seconds are also cached and instantaneous. -- After the 10-second window, the next request will still show the cached (stale) page -- Next.js triggers a regeneration of the page in the background. -- Once the page has been successfully generated, Next.js will invalidate the cache and show the updated product page. If the background regeneration fails, the old page will stay unaltered. - -When a request is made to a path that hasn’t been generated, Next.js will server-render the page on the first request. Future requests will serve the static file from the cache. - -To learn how to persist the cache globally and handle rollbacks, learn more about [Incremental Static Regeneration](https://vercel.com/docs/next.js/incremental-static-regeneration). - -### Reading files: Use `process.cwd()` - -Files can be read directly from the filesystem in `getStaticProps`. - -In order to do so you have to get the full path to a file. - -Since Next.js compiles your code into a separate directory you can't use `__dirname` as the path it will return will be different from the pages directory. - -Instead you can use `process.cwd()` which gives you the directory where Next.js is being executed. - -```jsx -import { promises as fs } from 'fs' -import path from 'path' - -// posts will be populated at build time by getStaticProps() -function Blog({ posts }) { - return ( - <ul> - {posts.map((post) => ( - <li> - <h3>{post.filename}</h3> - <p>{post.content}</p> - </li> - ))} - </ul> - ) -} - -// This function gets called at build time on server-side. -// It won't be called on client-side, so you can even do -// direct database queries. See the "Technical details" section. -export async function getStaticProps() { - const postsDirectory = path.join(process.cwd(), 'posts') - const filenames = await fs.readdir(postsDirectory) - - const posts = filenames.map(async (filename) => { - const filePath = path.join(postsDirectory, filename) - const fileContents = await fs.readFile(filePath, 'utf8') - - // Generally you would parse/transform the contents - // For example you can transform markdown to HTML here - - return { - filename, - content: fileContents, - } - }) - // By returning { props: { posts } }, the Blog component - // will receive `posts` as a prop at build time - return { - props: { - posts: await Promise.all(posts), - }, - } -} - -export default Blog -``` - -### Technical details - -#### Only runs at build time - -Because `getStaticProps` runs at build time, it does **not** receive data that’s only available during request time, such as query parameters or HTTP headers as it generates static HTML. - -#### Write server-side code directly - -Note that `getStaticProps` runs only on the server-side. It will never be run on the client-side. It won’t even be included in the JS bundle for the browser. That means you can write code such as direct database queries without them being sent to browsers. You should not fetch an **API route** from `getStaticProps` — instead, you can write the server-side code directly in `getStaticProps`. - -You can use [this tool](https://next-code-elimination.vercel.app/) to verify what Next.js eliminates from the client-side bundle. - -#### Statically Generates both HTML and JSON - -When a page with `getStaticProps` is pre-rendered at build time, in addition to the page HTML file, Next.js generates a JSON file holding the result of running `getStaticProps`. - -This JSON file will be used in client-side routing through `next/link` ([documentation](/docs/api-reference/next/link.md)) or `next/router` ([documentation](/docs/api-reference/next/router.md)). When you navigate to a page that’s pre-rendered using `getStaticProps`, Next.js fetches this JSON file (pre-computed at build time) and uses it as the props for the page component. This means that client-side page transitions will **not** call `getStaticProps` as only the exported JSON is used. - -When using Incremental Static Generation `getStaticProps` will be executed out of band to generate the JSON needed for client-side navigation. You may see this in the form of multiple requests being made for the same page, however, this is intended and has no impact on end-user performance. - -#### Only allowed in a page - -`getStaticProps` can only be exported from a **page**. You can’t export it from non-page files. - -One of the reasons for this restriction is that React needs to have all the required data before the page is rendered. - -Also, you must use `export async function getStaticProps() {}` — it will **not** work if you add `getStaticProps` as a property of the page component. - -#### Runs on every request in development - -In development (`next dev`), `getStaticProps` will be called on every request. - -#### Preview Mode - -In some cases, you might want to temporarily bypass Static Generation and render the page at **request time** instead of build time. For example, you might be using a headless CMS and want to preview drafts before they're published. - -This use case is supported by Next.js by the feature called **Preview Mode**. Learn more on the [Preview Mode documentation](/docs/advanced-features/preview-mode.md). - -## `getStaticPaths` (Static Generation) - -<details> - <summary><b>Version History</b></summary> - -| Version | Changes | -| -------- | ----------------------------------------------------------------------------------------------------------------- | -| `v9.5.0` | Stable [Incremental Static Regeneration](https://nextjs.org/blog/next-9-5#stable-incremental-static-regeneration) | -| `v9.3.0` | `getStaticPaths` introduced. | - -</details> - -If a page has dynamic routes ([documentation](/docs/routing/dynamic-routes.md)) and uses `getStaticProps` it needs to define a list of paths that have to be rendered to HTML at build time. - -If you export an `async` function called `getStaticPaths` from a page that uses dynamic routes, Next.js will statically pre-render all the paths specified by `getStaticPaths`. - -```jsx -export async function getStaticPaths() { - return { - paths: [ - { params: { ... } } // See the "paths" section below - ], - fallback: true, false, or 'blocking' // See the "fallback" section below - }; -} -``` - -#### The `paths` key (required) - -The `paths` key determines which paths will be pre-rendered. For example, suppose that you have a page that uses dynamic routes named `pages/posts/[id].js`. If you export `getStaticPaths` from this page and return the following for `paths`: - -```js -return { - paths: [ - { params: { id: '1' } }, - { params: { id: '2' } } - ], - fallback: ... -} -``` - -Then Next.js will statically generate `posts/1` and `posts/2` at build time using the page component in `pages/posts/[id].js`. - -Note that the value for each `params` must match the parameters used in the page name: - -- If the page name is `pages/posts/[postId]/[commentId]`, then `params` should contain `postId` and `commentId`. -- If the page name uses catch-all routes, for example `pages/[...slug]`, then `params` should contain `slug` which is an array. For example, if this array is `['foo', 'bar']`, then Next.js will statically generate the page at `/foo/bar`. -- If the page uses an optional catch-all route, supply `null`, `[]`, `undefined` or `false` to render the root-most route. For example, if you supply `slug: false` for `pages/[[...slug]]`, Next.js will statically generate the page `/`. - -#### The `fallback` key (required) - -The object returned by `getStaticPaths` must contain a boolean `fallback` key. - -#### `fallback: false` - -If `fallback` is `false`, then any paths not returned by `getStaticPaths` will result in a **404 page**. You can do this if you have a small number of paths to pre-render - so they are all statically generated during build time. It’s also useful when the new pages are not added often. If you add more items to the data source and need to render the new pages, you’d need to run the build again. - -Here’s an example which pre-renders one blog post per page called `pages/posts/[id].js`. The list of blog posts will be fetched from a CMS and returned by `getStaticPaths` . Then, for each page, it fetches the post data from a CMS using `getStaticProps`. This example is also in the [Pages documentation](/docs/basic-features/pages.md). - -```jsx -// pages/posts/[id].js - -function Post({ post }) { - // Render post... -} - -// This function gets called at build time -export async function getStaticPaths() { - // Call an external API endpoint to get posts - const res = await fetch('https://.../posts') - const posts = await res.json() - - // Get the paths we want to pre-render based on posts - const paths = posts.map((post) => ({ - params: { id: post.id }, - })) - - // We'll pre-render only these paths at build time. - // { fallback: false } means other routes should 404. - return { paths, fallback: false } -} - -// This also gets called at build time -export async function getStaticProps({ params }) { - // params contains the post `id`. - // If the route is like /posts/1, then params.id is 1 - const res = await fetch(`https://.../posts/${params.id}`) - const post = await res.json() - - // Pass post data to the page via props - return { props: { post } } -} - -export default Post -``` - -#### `fallback: true` - -<details> - <summary><b>Examples</b></summary> - <ul> - <li><a href="https://static-tweet.vercel.app">Static generation of a large number of pages</a></li> - </ul> -</details> - -If `fallback` is `true`, then the behavior of `getStaticProps` changes: - -- The paths returned from `getStaticPaths` will be rendered to HTML at build time by `getStaticProps`. -- The paths that have not been generated at build time will **not** result in a 404 page. Instead, Next.js will serve a “fallback” version of the page on the first request to such a path (see [“Fallback pages”](#fallback-pages) below for details). Note: this "fallback" version will not be served for crawlers like Google and instead will render the path in `blocking` mode. -- In the background, Next.js will statically generate the requested path HTML and JSON. This includes running `getStaticProps`. -- When that’s done, the browser receives the JSON for the generated path. This will be used to automatically render the page with the required props. From the user’s perspective, the page will be swapped from the fallback page to the full page. -- At the same time, Next.js adds this path to the list of pre-rendered pages. Subsequent requests to the same path will serve the generated page, like other pages pre-rendered at build time. - -> `fallback: true` is not supported when using [`next export`](/docs/advanced-features/static-html-export.md). - -#### Fallback pages - -In the “fallback” version of a page: - -- The page’s props will be empty. -- Using the [router](/docs/api-reference/next/router.md), you can detect if the fallback is being rendered, `router.isFallback` will be `true`. - -Here’s an example that uses `isFallback`: - -```jsx -// pages/posts/[id].js -import { useRouter } from 'next/router' - -function Post({ post }) { - const router = useRouter() - - // If the page is not yet generated, this will be displayed - // initially until getStaticProps() finishes running - if (router.isFallback) { - return <div>Loading...</div> - } - - // Render post... -} - -// This function gets called at build time -export async function getStaticPaths() { - return { - // Only `/posts/1` and `/posts/2` are generated at build time - paths: [{ params: { id: '1' } }, { params: { id: '2' } }], - // Enable statically generating additional pages - // For example: `/posts/3` - fallback: true, - } -} - -// This also gets called at build time -export async function getStaticProps({ params }) { - // params contains the post `id`. - // If the route is like /posts/1, then params.id is 1 - const res = await fetch(`https://.../posts/${params.id}`) - const post = await res.json() - - // Pass post data to the page via props - return { - props: { post }, - // Re-generate the post at most once per second - // if a request comes in - revalidate: 1, - } -} - -export default Post -``` - -#### When is `fallback: true` useful? - -`fallback: true` is useful if your app has a very large number of static pages that depend on data (think: a very large e-commerce site). You want to pre-render all product pages, but then your builds would take forever. - -Instead, you may statically generate a small subset of pages and use `fallback: true` for the rest. When someone requests a page that’s not generated yet, the user will see the page with a loading indicator. Shortly after, `getStaticProps` finishes and the page will be rendered with the requested data. From now on, everyone who requests the same page will get the statically pre-rendered page. - -This ensures that users always have a fast experience while preserving fast builds and the benefits of Static Generation. - -`fallback: true` will not _update_ generated pages, for that take a look at [Incremental Static Regeneration](#incremental-static-regeneration). - -#### `fallback: 'blocking'` - -If `fallback` is `'blocking'`, new paths not returned by `getStaticPaths` will wait for the HTML to be generated, identical to SSR (hence why _blocking_), and then be cached for future requests so it only happens once per path. - -`getStaticProps` will behave as follows: - -- The paths returned from `getStaticPaths` will be rendered to HTML at build time by `getStaticProps`. -- The paths that have not been generated at build time will **not** result in a 404 page. Instead, Next.js will SSR on the first request and return the generated HTML. -- When that’s done, the browser receives the HTML for the generated path. From the user’s perspective, it will transition from "the browser is requesting the page" to "the full page is loaded". There is no flash of loading/fallback state. -- At the same time, Next.js adds this path to the list of pre-rendered pages. Subsequent requests to the same path will serve the generated page, like other pages pre-rendered at build time. - -`fallback: 'blocking'` will not _update_ generated pages by default. To update generated pages, use [Incremental Static Regeneration](#incremental-static-regeneration) in conjunction with `fallback: 'blocking'`. - -> `fallback: 'blocking'` is not supported when using [`next export`](/docs/advanced-features/static-html-export.md). - -### When should I use `getStaticPaths`? - -You should use `getStaticPaths` if you’re statically pre-rendering pages that use dynamic routes. - -### TypeScript: Use `GetStaticPaths` - -For TypeScript, you can use the `GetStaticPaths` type from `next`: - -```ts -import { GetStaticPaths } from 'next' - -export const getStaticPaths: GetStaticPaths = async () => { - // ... -} -``` - -### Technical details - -#### Use together with `getStaticProps` - -When you use `getStaticProps` on a page with dynamic route parameters, you must use `getStaticPaths`. - -You cannot use `getStaticPaths` with `getServerSideProps`. - -#### Only runs at build time on server-side - -`getStaticPaths` only runs at build time on server-side. - -#### Only allowed in a page - -`getStaticPaths` can only be exported from a **page**. You can’t export it from non-page files. - -Also, you must use `export async function getStaticPaths() {}` — it will **not** work if you add `getStaticPaths` as a property of the page component. - -#### Runs on every request in development - -In development (`next dev`), `getStaticPaths` will be called on every request. - -## `getServerSideProps` (Server-side Rendering) - -<details> - <summary><b>Version History</b></summary> - -| Version | Changes | -| --------- | ------------------------------------------------------------------- | -| `v10.0.0` | `locale`, `locales`, `defaultLocale`, and `notFound` options added. | -| `v9.3.0` | `getServerSideProps` introduced. | - -</details> - -If you export an `async` function called `getServerSideProps` from a page, Next.js will pre-render this page on each request using the data returned by `getServerSideProps`. - -```js -export async function getServerSideProps(context) { - return { - props: {}, // will be passed to the page component as props - } -} -``` - -The `context` parameter is an object containing the following keys: - -- `params`: If this page uses a dynamic route, `params` contains the route parameters. If the page name is `[id].js` , then `params` will look like `{ id: ... }`. To learn more, take a look at the [Dynamic Routing documentation](/docs/routing/dynamic-routes.md). -- `req`: [The HTTP IncomingMessage object](https://nodejs.org/api/http.html#http_class_http_incomingmessage), plus additional [built-in parsing helpers](#provided-req-middleware-in-getserversideprops). -- `res`: [The HTTP response object](https://nodejs.org/api/http.html#http_class_http_serverresponse). -- `query`: An object representing the query string. -- `preview`: `preview` is `true` if the page is in the preview mode and `false` otherwise. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md). -- `previewData`: The preview data set by `setPreviewData`. See the [Preview Mode documentation](/docs/advanced-features/preview-mode.md). -- `resolvedUrl`: A normalized version of the request URL that strips the `_next/data` prefix for client transitions and includes original query values. -- `locale` contains the active locale (if you've enabled [Internationalized Routing](/docs/advanced-features/i18n-routing.md)). -- `locales` contains all supported locales (if you've enabled [Internationalized Routing](/docs/advanced-features/i18n-routing.md)). -- `defaultLocale` contains the configured default locale (if you've enabled [Internationalized Routing](/docs/advanced-features/i18n-routing.md)). - -`getServerSideProps` should return an object with: - -- `props` - An **optional** object with the props that will be received by the page component. It should be a [serializable object](https://en.wikipedia.org/wiki/Serialization) or a Promise that resolves to a serializable object. -- `notFound` - An **optional** boolean value to allow the page to return a 404 status and page. Below is an example of how it works: - - ```js - export async function getServerSideProps(context) { - const res = await fetch(`https://...`) - const data = await res.json() - - if (!data) { - return { - notFound: true, - } - } - - return { - props: {}, // will be passed to the page component as props - } - } - ``` - -- `redirect` - An **optional** redirect value to allow redirecting to internal and external resources. It should match the shape of `{ destination: string, permanent: boolean }`. In some rare cases, you might need to assign a custom status code for older HTTP Clients to properly redirect. In these cases, you can use the `statusCode` property instead of the `permanent` property, but not both. You can also set `basePath: false` similar to redirects in `next.config.js`. Below is an example of how it works: - - ```js - export async function getServerSideProps(context) { - const res = await fetch(`https://.../data`) - const data = await res.json() - - if (!data) { - return { - redirect: { - destination: '/', - permanent: false, - }, - } - } - - return { - props: {}, // will be passed to the page component as props - } - } - ``` - -> **Note**: You can import modules in top-level scope for use in `getServerSideProps`. -> Imports used in `getServerSideProps` will not be bundled for the client-side. -> -> This means you can write **server-side code directly in `getServerSideProps`**. -> This includes reading from the filesystem or a database. - -> **Note**: You should not use [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to -> call an API route in `getServerSideProps`. -> Instead, directly import the logic used inside your API route. -> You may need to slightly refactor your code for this approach. -> -> Fetching from an external API is fine! - -### Provided `req` middleware in `getServerSideProps` - -The `req` in the context passed to `getServerSideProps` provides built in middleware that parses the incoming request (req). That middleware is: - -- `req.cookies` - An object containing the cookies sent by the request. Defaults to `{}` - -### Example - -Here’s an example which uses `getServerSideProps` to fetch data at request time and pre-renders it. This example is also in the [Pages documentation](/docs/basic-features/pages.md). - -```jsx -function Page({ data }) { - // Render data... -} - -// This gets called on every request -export async function getServerSideProps() { - // Fetch data from external API - const res = await fetch(`https://.../data`) - const data = await res.json() - - // Pass data to the page via props - return { props: { data } } -} - -export default Page -``` - -### When should I use `getServerSideProps`? - -You should use `getServerSideProps` only if you need to pre-render a page whose data must be fetched at request time. Time to first byte (TTFB) will be slower than `getStaticProps` because the server must compute the result on every request, and the result cannot be cached by a CDN without extra configuration. - -If you don’t need to pre-render the data, then you should consider fetching data on the client side. [Click here to learn more](#fetching-data-on-the-client-side). - -### TypeScript: Use `GetServerSideProps` - -For TypeScript, you can use the `GetServerSideProps` type from `next`: - -```ts -import { GetServerSideProps } from 'next' - -export const getServerSideProps: GetServerSideProps = async (context) => { - // ... -} -``` - -If you want to get inferred typings for your props, you can use `InferGetServerSidePropsType<typeof getServerSideProps>`, like this: - -```tsx -import { InferGetServerSidePropsType } from 'next' - -type Data = { ... } - -export const getServerSideProps = async () => { - const res = await fetch('https://.../data') - const data: Data = await res.json() - - return { - props: { - data, - }, - } -} - -function Page({ data }: InferGetServerSidePropsType<typeof getServerSideProps>) { - // will resolve posts to type Data -} - -export default Page -``` - -### Technical details - -#### Only runs on server-side - -`getServerSideProps` only runs on server-side and never runs on the browser. If a page uses `getServerSideProps`, then: - -- When you request this page directly, `getServerSideProps` runs at the request time, and this page will be pre-rendered with the returned props. -- When you request this page on client-side page transitions through `next/link` ([documentation](/docs/api-reference/next/link.md)) or `next/router` ([documentation](/docs/api-reference/next/router.md)), Next.js sends an API request to the server, which runs `getServerSideProps`. It’ll return JSON that contains the result of running `getServerSideProps`, and the JSON will be used to render the page. All this work will be handled automatically by Next.js, so you don’t need to do anything extra as long as you have `getServerSideProps` defined. - -You can use [this tool](https://next-code-elimination.vercel.app/) to verify what Next.js eliminates from the client-side bundle. - -#### Only allowed in a page - -`getServerSideProps` can only be exported from a **page**. You can’t export it from non-page files. - -Also, you must use `export async function getServerSideProps() {}` — it will **not** work if you add `getServerSideProps` as a property of the page component. - -## Fetching data on the client side - -If your page contains frequently updating data, and you don’t need to pre-render the data, you can fetch the data on the client side. An example of this is user-specific data. Here’s how it works: - -- First, immediately show the page without data. Parts of the page can be pre-rendered using Static Generation. You can show loading states for missing data. -- Then, fetch the data on the client side and display it when ready. - -This approach works well for user dashboard pages, for example. Because a dashboard is a private, user-specific page, SEO is not relevant and the page doesn’t need to be pre-rendered. The data is frequently updated, which requires request-time data fetching. - -### SWR - -The team behind Next.js has created a React hook for data fetching called [**SWR**](https://swr.vercel.app/). We highly recommend it if you’re fetching data on the client side. It handles caching, revalidation, focus tracking, refetching on interval, and more. And you can use it like so: - -```jsx -import useSWR from 'swr' - -const fetcher = (url) => fetch(url).then((res) => res.json()) - -function Profile() { - const { data, error } = useSWR('/api/user', fetcher) - - if (error) return <div>failed to load</div> - if (!data) return <div>loading...</div> - return <div>hello {data.name}!</div> -} -``` - -[Check out the SWR documentation to learn more](https://swr.vercel.app/). - -## Learn more - -We recommend you to read the following sections next: - -<div class="card"> - <a href="/docs/advanced-features/preview-mode.md"> - <b>Preview Mode:</b> - <small>Learn more about the preview mode in Next.js.</small> - </a> -</div> - -<div class="card"> - <a href="/docs/routing/introduction.md"> - <b>Routing:</b> - <small>Learn more about routing in Next.js.</small> - </a> -</div> - -<div class="card"> - <a href="/docs/basic-features/typescript.md#pages"> - <b>TypeScript:</b> - <small>Add TypeScript to your pages.</small> - </a> -</div> diff --git a/docs/basic-features/data-fetching/client-side.md b/docs/basic-features/data-fetching/client-side.md new file mode 100644 index 000000000000000..6c0837e191d1209 --- /dev/null +++ b/docs/basic-features/data-fetching/client-side.md @@ -0,0 +1,70 @@ +--- +description: 'Learn about client-side data fetching, and how to use SWR, a data fetching React hook library that handles caching, revalidation, focus tracking, refetching on interval and more.' +--- + +# Client-side data fetching + +Client-side data fetching is useful when your page doesn't require SEO indexing, when you don't need to pre-render your data, or when the content of your pages needs to update frequently. Unlike the server-side rendering APIs, you can use client-side data fetching at the component level. + +If done at the page level, the data is fetched at runtime, and the content of the page is updated as the data changes. When used at the component level, the data is fetched at the time of the component mount, and the content of the component is updated as the data changes. + +It's important to note that using client-side data fetching can affect the performance of your application and the load speed of your pages. This is because the data fetching is done at the time of the component or pages mount, and the data is not cached. + +## Client-side data fetching with useEffect + +The following example shows how you can fetch data on the client side using the useEffect hook. + +```jsx +function Profile() { + const [data, setData] = useState(null) + const [isLoading, setLoading] = useState(false) + + useEffect(() => { + setLoading(true) + fetch('api/profile-data') + .then((res) => res.json()) + .then((data) => { + setData(data) + setLoading(false) + }) + }, []) + + if (isLoading) return <p>Loading...</p> + if (!profileData) return <p>No profile data</p> + + return ( + <div> + <h1>{data.name}</h1> + <p>{data.bio}</p> + </div> + ) +} +``` + +## Client-side data fetching with SWR + +The team behind Next.js has created a React hook library for data fetching called [**SWR**](https://swr.vercel.app/). It is **highly recommend** if you are fetching data on the client-side. It handles caching, revalidation, focus tracking, refetching on intervals, and more. + +Using the same example as above, we can now use SWR to fetch the profile data. SWR will automatically cache the data for us and will revalidate the data if it becomes stale. + +For more information on using SWR, check out the [SWR docs](https://swr.vercel.app/docs). + +```jsx +import useSWR from 'swr' + +const fetcher = (...args) => fetch(...args).then((res) => res.json()) + +function Profile() { + const { data, error } = useSWR('/api/profile-data', fetcher) + + if (error) return <div>Failed to load</div> + if (!data) return <div>Loading...</div> + + return ( + <div> + <h1>{data.name}</h1> + <p>{data.bio}</p> + </div> + ) +} +``` diff --git a/docs/basic-features/data-fetching/get-server-side-props.md b/docs/basic-features/data-fetching/get-server-side-props.md new file mode 100644 index 000000000000000..2e28a45cbb89d0c --- /dev/null +++ b/docs/basic-features/data-fetching/get-server-side-props.md @@ -0,0 +1,75 @@ +--- +description: Fetch data on each request with `getServerSideProps`. +--- + +# `getServerSideProps` + +If you export a function called `getServerSideProps` (Server-Side Rendering) from a page, Next.js will pre-render this page on each request using the data returned by `getServerSideProps`. + +```js +export async function getServerSideProps(context) { + return { + props: {}, // will be passed to the page component as props + } +} +``` + +## When does `getServerSideProps` run + +`getServerSideProps` only runs on server-side and never runs on the browser. If a page uses `getServerSideProps`, then: + +- When you request this page directly, `getServerSideProps` runs at request time, and this page will be pre-rendered with the returned props +- When you request this page on client-side page transitions through [`next/link`](/docs/api-reference/next/link.md) or [`next/router`](/docs/api-reference/next/router.md), Next.js sends an API request to the server, which runs `getServerSideProps`. + +It then returns `JSON` that contains the result of running `getServerSideProps`, that `JSON` will be used to render the page. All this work will be handled automatically by Next.js, so you don’t need to do anything extra as long as you have `getServerSideProps` defined. + +You can use the [next-code-elimination tool](https://next-code-elimination.vercel.app/) to verify what Next.js eliminates from the client-side bundle. + +`getServerSideProps` can only be exported from a **page**. You can’t export it from non-page files. + +Note that you must export `getServerSideProps` as a standalone function — it will **not** work if you add `getServerSideProps` as a property of the page component. + +The [`getServerSideProps` API reference](/docs/api-reference/data-fetching/get-server-side-props.md) covers all parameters and props that can be used with `getServerSideProps`. + +## When should I use `getServerSideProps`? + +You should use `getServerSideProps` only if you need to pre-render a page whose data must be fetched at request time. [Time to First Byte (TTFB)](/learn/seo/web-performance) will be higher than [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) because the server must compute the result on every request, and the result can only be cached by a CDN using `cache-control` headers (which could require extra configuration). + +If you do not need to pre-render the data, then you should consider fetching data on the [client side](#fetching-data-on-the-client-side). + +### `getServerSideProps` or API Routes + +It can be tempting to reach for an [API Route](/docs/api-routes/introduction.md) when you want to fetch data from the server, then call that API route from `getServerSideProps`. This is an unnecessary and inefficient approach, as it will cause an extra request to be made due to both `getServerSideProps` and API Routes running on the server. + +Take the following example. An API route is used to fetch some data from a CMS. That API route is then called directly from `getServerSideProps`. This produces an additional call, reducing performance. Instead, directly import the logic used inside your API Route into `getServerSideProps`. This could mean calling a CMS, database, or other API directly from inside `getServerSideProps`. + +## Fetching data on the client side + +If your page contains frequently updating data, and you don’t need to pre-render the data, you can fetch the data on the [client side](/docs/basic-features/client-side.md). An example of this is user-specific data: + +- First, immediately show the page without data. Parts of the page can be pre-rendered using Static Generation. You can show loading states for missing data. +- Then, fetch the data on the client side and display it when ready. + +This approach works well for user dashboard pages, for example. Because a dashboard is a private, user-specific page, SEO is not relevant and the page doesn’t need to be pre-rendered. The data is frequently updated, which requires request-time data fetching. + +## Using `getServerSideProps` to fetch data at request time + +The following example shows how to fetch data at request time and pre-render the result. + +```jsx +function Page({ data }) { + // Render data... +} + +// This gets called on every request +export async function getServerSideProps() { + // Fetch data from external API + const res = await fetch(`https://.../data`) + const data = await res.json() + + // Pass data to the page via props + return { props: { data } } +} + +export default Page +``` diff --git a/docs/basic-features/data-fetching/get-static-paths.md b/docs/basic-features/data-fetching/get-static-paths.md new file mode 100644 index 000000000000000..9ba7a450928f91b --- /dev/null +++ b/docs/basic-features/data-fetching/get-static-paths.md @@ -0,0 +1,48 @@ +--- +description: Fetch data and generate static pages with `getStaticProps`. Learn more about this API for data fetching in Next.js. +--- + +# `getStaticPaths` + +If a page has [Dynamic Routes](/docs/routing/dynamic-routes.md) and uses `getStaticProps`, it needs to define a list of paths to be statically generated. + +When you export a function called `getStaticPaths` (Static Site Generation) from a page that uses dynamic routes, Next.js will statically pre-render all the paths specified by `getStaticPaths`. + +```jsx +export async function getStaticPaths() { + return { + paths: [ + { params: { ... } } + ], + fallback: true // false or 'blocking' + }; +} +``` + +Note that`getStaticProps` **must** be used with `getStaticPaths`, and that you **cannot** use it with [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md). + +The [`getStaticPaths` API reference](/docs/api-reference/data-fetching/get-static-paths.md) covers all parameters and props that can be used with `getStaticPaths`. + +## When should I use `getStaticPaths`? + +You should use `getStaticPaths` if you’re statically pre-rendering pages that use dynamic routes and: + +- The data comes from a headless CMS +- The data comes from a database +- The data comes from the filesystem +- The data can be publicly cached (not user-specific) +- The page must be pre-rendered (for SEO) and be very fast — `getStaticProps` generates `HTML` and `JSON` files, both of which can be cached by a CDN for performance + +## When does `getStaticPaths` run + +`getStaticPaths` only runs at build time on server-side. If you're using [Incremental Static Regeneration](/docs/basic-features/data-fetching/incremental-static-regeneration.md), `getStaticPaths` can also be run on-demand _in the background_, but still only on the server-side. + +## Where can I use `getStaticPaths` + +`getStaticPaths` can only be exported from a **page**. You **cannot** export it from non-page files. + +Note that you must use export `getStaticPaths` as a standalone function — it will **not** work if you add `getStaticPaths` as a property of the page component. + +## Runs on every request in development + +In development (`next dev`), `getStaticPaths` will be called on every request. diff --git a/docs/basic-features/data-fetching/get-static-props.md b/docs/basic-features/data-fetching/get-static-props.md new file mode 100644 index 000000000000000..adb8427fab01c2c --- /dev/null +++ b/docs/basic-features/data-fetching/get-static-props.md @@ -0,0 +1,103 @@ +--- +description: Fetch data and generate static pages with `getStaticProps`. Learn more about this API for data fetching in Next.js. +--- + +# `getStaticProps` + +If you export a function called `getStaticProps` (Static Site Generation) from a page, Next.js will pre-render this page at build time using the props returned by `getStaticProps`. + +```jsx +export async function getStaticProps(context) { + return { + props: {}, // will be passed to the page component as props + } +} +``` + +## When should I use `getStaticProps`? + +You should use `getStaticProps` if: + +- The data required to render the page is available at build time ahead of a user’s request +- The data comes from a headless CMS +- The data can be publicly cached (not user-specific) +- The page must be pre-rendered (for SEO) and be very fast — `getStaticProps` generates `HTML` and `JSON` files, both of which can be cached by a CDN for performance + +Because `getStaticProps` runs at build time, it does **not** receive data that’s only available during request time, such as query parameters or `HTTP` headers, as it generates static `HTML`. When combined with [Incremental Static Regeneration](/docs/basic-features/data-fetching/incremental-static-regeneration.md) however, it will run in the background while the stale page is being revalidated, and the fresh page served to the browser. + +## Using `getStaticProps` to fetch data from a CMS + +The following example shows how you can fetch a list of blog posts from a CMS. + +```jsx +// posts will be populated at build time by getStaticProps() +function Blog({ posts }) { + return ( + <ul> + {posts.map((post) => ( + <li>{post.title}</li> + ))} + </ul> + ) +} + +// This function gets called at build time on server-side. +// It won't be called on client-side, so you can even do +// direct database queries. +export async function getStaticProps() { + // Call an external API endpoint to get posts. + // You can use any data fetching library + const res = await fetch('https://.../posts') + const posts = await res.json() + + // By returning { props: { posts } }, the Blog component + // will receive `posts` as a prop at build time + return { + props: { + posts, + }, + } +} + +export default Blog +``` + +The [`getStaticProps` API reference](/docs/api-reference/data-fetching/get-static-props.md) covers all parameters and props that can be used with `getStaticProps`. + +## Write server-side code directly + +As `getStaticProps` runs only on the server-side, it will never run on the client-side. It won’t even be included in the JS bundle for the browser, so you can write direct database queries without them being sent to browsers. + +This means that instead of fetching an **API route** from `getStaticProps` (that itself fetches data from an external source), you can write the server-side code directly in `getStaticProps`. + +Take the following example. An API route is used to fetch some data from a CMS. That API route is then called directly from `getStaticProps`. This produces an additional call, reducing performance. Instead, the logic for fetching the data from the CMS can be moved to `getStaticProps`. + +Alternatively, if you are **not** using API routes to fetch data, then the [`fetch()`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) API _can_ be used directly in `getStaticProps` to fetch data. + +To verify what Next.js eliminates from the client-side bundle, you can use the [next-code-elimination tool](https://next-code-elimination.vercel.app/). + +## Statically Generates both HTML and JSON + +When a page with `getStaticProps` is pre-rendered at build time, in addition to the page HTML file, Next.js generates a JSON file holding the result of running `getStaticProps`. + +This JSON file will be used in client-side routing through [`next/link`](/docs/api-reference/next/link.md) or [`next/router`](/docs/api-reference/next/router.md). When you navigate to a page that’s pre-rendered using `getStaticProps`, Next.js fetches this JSON file (pre-computed at build time) and uses it as the props for the page component. This means that client-side page transitions will **not** call `getStaticProps` as only the exported JSON is used. + +When using Incremental Static Generation `getStaticProps` will be executed out of band to generate the JSON needed for client-side navigation. You may see this in the form of multiple requests being made for the same page, however, this is intended and has no impact on end-user performance + +## Where can I use `getStaticProps` + +`getStaticProps` can only be exported from a **page**. You **cannot** export it from non-page files. + +One of the reasons for this restriction is that React needs to have all the required data before the page is rendered. + +Also, you must use export `getStaticProps` as a standalone function — it will **not** work if you add `getStaticProps` as a property of the page component. + +## Runs on every request in development + +In development (`next dev`), `getStaticProps` will be called on every request. + +## Preview Mode + +In some cases, you might want to temporarily bypass Static Generation and render the page at **request time** instead of build time. For example, you might be using a headless CMS and want to preview drafts before they're published. + +This use case is supported in Next.js by the [**Preview Mode**](/docs/advanced-features/preview-mode.md) feature. diff --git a/docs/basic-features/data-fetching/incremental-static-regeneration.md b/docs/basic-features/data-fetching/incremental-static-regeneration.md new file mode 100644 index 000000000000000..7a7d197c3d09c6d --- /dev/null +++ b/docs/basic-features/data-fetching/incremental-static-regeneration.md @@ -0,0 +1,88 @@ +--- +description: 'Learn how to create or update static pages at runtime with Incremental Static Regeneration.' +--- + +# Incremental Static Regeneration + +<details> + <summary><b>Examples</b></summary> + <ul> + <li><a href="https://nextjs.org/commerce">Next.js Commerce</a></li> + <li><a href="https://reactions-demo.vercel.app/">GitHub Reactions Demo</a></li> + <li><a href="https://static-tweet.vercel.app/">Static Tweet Demo</a></li> + </ul> +</details> + +<details> + <summary><b>Version History</b></summary> + +| Version | Changes | +| -------- | ---------------- | +| `v9.5.0` | Base Path added. | + +</details> + +Next.js allows you to create or update static pages _after_ you’ve built your site. Incremental Static Regeneration (ISR) enables you to use static-generation on a per-page basis, **without needing to rebuild the entire site**. With ISR, you can retain the benefits of static while scaling to millions of pages. + +To use ISR add the `revalidate` prop to `getStaticProps`: + +```jsx +function Blog({ posts }) { + return ( + <ul> + {posts.map((post) => ( + <li>{post.title}</li> + ))} + </ul> + ) +} + +// This function gets called at build time on server-side. +// It may be called again, on a serverless function, if +// revalidation is enabled and a new request comes in +export async function getStaticProps() { + const res = await fetch('https://.../posts') + const posts = await res.json() + + return { + props: { + posts, + }, + // Next.js will attempt to re-generate the page: + // - When a request comes in + // - At most once every 10 seconds + revalidate: 10, // In seconds + } +} + +// This function gets called at build time on server-side. +// It may be called again, on a serverless function, if +// the path has not been generated. +export async function getStaticPaths() { + const res = await fetch('https://.../posts') + const posts = await res.json() + + // Get the paths we want to pre-render based on posts + const paths = posts.map((post) => ({ + params: { id: post.id }, + })) + + // We'll pre-render only these paths at build time. + // { fallback: blocking } will server-render pages + // on-demand if the path doesn't exist. + return { paths, fallback: 'blocking' } +} + +export default Blog +``` + +When a request is made to a page that was pre-rendered at build time, it will initially show the cached page. + +- Any requests to the page after the initial request and before 10 seconds are also cached and instantaneous. +- After the 10-second window, the next request will still show the cached (stale) page +- Next.js triggers a regeneration of the page in the background. +- Once the page has been successfully generated, Next.js will invalidate the cache and show the updated page. If the background regeneration fails, the old page would still be unaltered. + +When a request is made to a path that hasn’t been generated, Next.js will server-render the page on the first request. Future requests will serve the static file from the cache. + +[Incremental Static Regeneration](https://vercel.com/docs/concepts/next.js/incremental-static-regeneration) covers how to persist the cache globally and handle rollbacks. diff --git a/docs/basic-features/data-fetching/index.md b/docs/basic-features/data-fetching/index.md new file mode 100644 index 000000000000000..d414515f11ad86c --- /dev/null +++ b/docs/basic-features/data-fetching/index.md @@ -0,0 +1,87 @@ +--- +description: 'Data fetching in Next.js allows you to render your content in different ways, depending on your applications use case. These include pre-rendering with server-side rendering or static-site generation, and incremental static regeneration. Learn how to manage your application data in Next.js.' +--- + +# Data Fetching Overview + +<details> + <summary><b>Examples</b></summary> + <ul> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-wordpress">WordPress Example</a> (<a href="https://next-blog-wordpress.vercel.app">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/blog-starter">Blog Starter using markdown files</a> (<a href="https://next-blog-starter.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-datocms">DatoCMS Example</a> (<a href="https://next-blog-datocms.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-takeshape">TakeShape Example</a> (<a href="https://next-blog-takeshape.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-sanity">Sanity Example</a> (<a href="https://next-blog-sanity.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-prismic">Prismic Example</a> (<a href="https://next-blog-prismic.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-contentful">Contentful Example</a> (<a href="https://next-blog-contentful.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-strapi">Strapi Example</a> (<a href="https://next-blog-strapi.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-prepr">Prepr Example</a> (<a href="https://next-blog-prepr.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-agilitycms">Agility CMS Example</a> (<a href="https://next-blog-agilitycms.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-cosmic">Cosmic Example</a> (<a href="https://next-blog-cosmic.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-buttercms">ButterCMS Example</a> (<a href="https://next-blog-buttercms.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-storyblok">Storyblok Example</a> (<a href="https://next-blog-storyblok.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-graphcms">GraphCMS Example</a> (<a href="https://next-blog-graphcms.vercel.app/">Demo</a>)</li> + <li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-kontent">Kontent Example</a> (<a href="https://next-blog-kontent.vercel.app/">Demo</a>)</li> + <li><a href="https://static-tweet.vercel.app/">Static Tweet Demo</a></li> + </ul> +</details> + +Data fetching in Next.js allows you to render your content in different ways, depending on your application's use case. These include pre-rendering with **Server-side Rendering** or **Static Generation**, and updating or creating content at runtime with **Incremental Static Regeneration**. + +<div class="card"> + <a href="/docs/basic-features/data-fetching/get-server-side-props.md"> + <b>SSR: Server-side rendering</b> + <small>Learn more about server-side rendering in Next.js with getServerSideProps.</small> + </a> +</div> + +<div class="card"> + <a href="/docs/basic-features/data-fetching/get-static-props.md"> + <b>SSG: Static-site generation</b> + <small>Learn more about static site generation in Next.js with getStaticProps.</small> + </a> +</div> + +<div class="card"> + <a href="/docs/basic-features/data-fetching/client-side.md"> + <b>CSR: Client-side rendering</b> + <small>Learn more about client side rendering in Next.js with SWR.</small> + </a> +</div> + +<div class="card"> + <a href="/docs/basic-features/data-fetching/get-static-paths.md"> + <b>Dynamic routing</b> + <small>Learn more about dynamic routing in Next.js with getStaticPaths.</small> + </a> +</div> + +<div class="card"> + <a href="/docs/basic-features/data-fetching/incremental-static-regeneration.md"> + <b>ISR: Incremental Static Regeneration</b> + <small>Learn more about Incremental Static Regeneration in Next.js.</small> + </a> +</div> + +## Learn more + +<div class="card"> + <a href="/docs/advanced-features/preview-mode.md"> + <b>Preview Mode:</b> + <small>Learn more about the preview mode in Next.js.</small> + </a> +</div> + +<div class="card"> + <a href="/docs/routing/introduction.md"> + <b>Routing:</b> + <small>Learn more about routing in Next.js.</small> + </a> +</div> + +<div class="card"> + <a href="/docs/basic-features/typescript.md#pages"> + <b>TypeScript:</b> + <small>Add TypeScript to your pages.</small> + </a> +</div> diff --git a/docs/basic-features/environment-variables.md b/docs/basic-features/environment-variables.md index 857f4f488dc0b53..4e9211bc2f9f353 100644 --- a/docs/basic-features/environment-variables.md +++ b/docs/basic-features/environment-variables.md @@ -30,9 +30,9 @@ DB_USER=myuser DB_PASS=mypassword ``` -This loads `process.env.DB_HOST`, `process.env.DB_USER`, and `process.env.DB_PASS` into the Node.js environment automatically allowing you to use them in [Next.js data fetching methods](/docs/basic-features/data-fetching.md) and [API routes](/docs/api-routes/introduction.md). +This loads `process.env.DB_HOST`, `process.env.DB_USER`, and `process.env.DB_PASS` into the Node.js environment automatically allowing you to use them in [Next.js data fetching methods](/docs/basic-features/data-fetching/index.md) and [API routes](/docs/api-routes/introduction.md). -For example, using [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation): +For example, using [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md): ```js // pages/index.js diff --git a/docs/basic-features/pages.md b/docs/basic-features/pages.md index c01b5f046ce210d..ad46f39e5913ae7 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.md#fetching-data-on-the-client-side) documentation. +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. ## Static Generation (Recommended) @@ -137,7 +137,7 @@ export async function getStaticProps() { export default Blog ``` -To learn more about how `getStaticProps` works, check out the [Data Fetching documentation](/docs/basic-features/data-fetching.md#getstaticprops-static-generation). +To learn more about how `getStaticProps` works, check out the [Data Fetching documentation](/docs/basic-features/data-fetching/get-static-props.md). #### Scenario 2: Your page paths depend on external data @@ -196,7 +196,7 @@ export async function getStaticProps({ params }) { export default Post ``` -To learn more about how `getStaticPaths` works, check out the [Data Fetching documentation](/docs/basic-features/data-fetching.md#getstaticpaths-static-generation). +To learn more about how `getStaticPaths` works, check out the [Data Fetching documentation](/docs/basic-features/data-fetching/get-static-paths.md). ### When should I use Static Generation? @@ -215,7 +215,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.md#fetching-data-on-the-client-side). +- 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 **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 @@ -248,7 +248,7 @@ export default Page As you can see, `getServerSideProps` is similar to `getStaticProps`, but the difference is that `getServerSideProps` is run on every request instead of on build time. -To learn more about how `getServerSideProps` works, check out our [Data Fetching documentation](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) +To learn more about how `getServerSideProps` works, check out our [Data Fetching documentation](/docs/basic-features/data-fetching/get-server-side-props.md) ## Summary @@ -262,7 +262,7 @@ We've discussed two forms of pre-rendering for Next.js. We recommend you to read the following sections next: <div class="card"> - <a href="/docs/basic-features/data-fetching.md"> + <a href="/docs/basic-features/data-fetching/index.md"> <b>Data Fetching:</b> <small>Learn more about data fetching in Next.js.</small> </a> diff --git a/docs/basic-features/typescript.md b/docs/basic-features/typescript.md index 3290a8477063ded..f56028f7fe5f557 100644 --- a/docs/basic-features/typescript.md +++ b/docs/basic-features/typescript.md @@ -85,7 +85,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => { } ``` -> If you're using `getInitialProps`, you can [follow the directions on this page](/docs/api-reference/data-fetching/getInitialProps.md#typescript). +> If you're using `getInitialProps`, you can [follow the directions on this page](/docs/api-reference/data-fetching/get-initial-props.md#typescript). ## API Routes diff --git a/docs/faq.md b/docs/faq.md index 8a1cec7254a91bb..187f8836762c33a 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -39,7 +39,7 @@ description: Get to know more about Next.js with the frequently asked questions. <details> <summary>How do I fetch data?</summary> - <p>It's up to you. You can use the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch">fetch API</a> or <a href="https://swr.vercel.app/">SWR</a> inside your React components for remote data fetching; or use our <a href="/docs/basic-features/data-fetching.md">data fetching methods</a> for initial data population.</p> + <p>It's up to you. You can use the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch">fetch API</a> or <a href="https://swr.vercel.app/">SWR</a> inside your React components for remote data fetching; or use our <a href="/docs/basic-features/data-fetching/index.md">data fetching methods</a> for initial data population.</p> </details> <details> diff --git a/docs/getting-started.md b/docs/getting-started.md index d037f7ed9e418bc..a9d0501b1941bef 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -91,7 +91,7 @@ So far, we get: - Automatic compilation and bundling (with webpack and babel) - [React Fast Refresh](https://nextjs.org/blog/next-9-4#fast-refresh) -- [Static generation and server-side rendering](/docs/basic-features/data-fetching.md) of [`./pages/`](/docs/basic-features/pages.md) +- [Static generation and server-side rendering](/docs/basic-features/data-fetching/index.md) of [`./pages/`](/docs/basic-features/pages.md) - [Static file serving](/docs/basic-features/static-file-serving.md). `./public/` is mapped to `/` In addition, any Next.js application is ready for production from the start, read more in our [Deployment documentation](/docs/deployment.md). diff --git a/docs/going-to-production.md b/docs/going-to-production.md index 55d94ef2b572800..aa713bf04577c1b 100644 --- a/docs/going-to-production.md +++ b/docs/going-to-production.md @@ -38,7 +38,7 @@ Caching improves response times and reduces the number of requests to external s Cache-Control: public, max-age=31536000, immutable ``` -`Cache-Control` headers set in `next.config.js` will be overwritten in production to ensure that static assets can be cached effectively. If you need to revalidate the cache of a page that has been [statically generated](/docs/basic-features/pages.md#static-generation-recommended), you can do so by setting `revalidate` in the page's [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation) function. If you're using `next/image`, there are also [specific caching rules](/docs/basic-features/image-optimization.md#caching) for the default Image Optimization loader. +`Cache-Control` headers set in `next.config.js` will be overwritten in production to ensure that static assets can be cached effectively. If you need to revalidate the cache of a page that has been [statically generated](/docs/basic-features/pages.md#static-generation-recommended), you can do so by setting `revalidate` in the page's [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md) function. If you're using `next/image`, there are also [specific caching rules](/docs/basic-features/image-optimization.md#caching) for the default Image Optimization loader. **Note:** When running your application locally with `next dev`, your headers are overwritten to prevent caching locally. diff --git a/docs/manifest.json b/docs/manifest.json index 340199c8ff9d728..9e2534b1baa3da1 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -15,7 +15,33 @@ }, { "title": "Data Fetching", - "path": "/docs/basic-features/data-fetching.md" + "path": "/docs/basic-features/data-fetching/index.md", + "routes": [ + { + "title": "Overview", + "path": "/docs/basic-features/data-fetching/index.md" + }, + { + "title": "getServerSideProps", + "path": "/docs/basic-features/data-fetching/get-server-side-props.md" + }, + { + "title": "getStaticPaths", + "path": "/docs/basic-features/data-fetching/get-static-paths.md" + }, + { + "title": "getStaticProps", + "path": "/docs/basic-features/data-fetching/get-static-props.md" + }, + { + "title": "Incremental Static Regeneration", + "path": "/docs/basic-features/data-fetching/incremental-static-regeneration.md" + }, + { + "title": "Client side", + "path": "/docs/basic-features/data-fetching/client-side.md" + } + ] }, { "title": "Built-in CSS Support", @@ -33,10 +59,6 @@ "title": "Font Optimization", "path": "/docs/basic-features/font-optimization.md" }, - { - "title": "Script Optimization", - "path": "/docs/basic-features/script.md" - }, { "title": "Static File Serving", "path": "/docs/basic-features/static-file-serving.md" @@ -60,6 +82,10 @@ { "title": "Supported Browsers and Features", "path": "/docs/basic-features/supported-browsers-features.md" + }, + { + "title": "Handling Scripts", + "path": "/docs/basic-features/script.md" } ] }, @@ -321,7 +347,19 @@ "routes": [ { "title": "getInitialProps", - "path": "/docs/api-reference/data-fetching/getInitialProps.md" + "path": "/docs/api-reference/data-fetching/get-initial-props.md" + }, + { + "title": "getServerSideProps", + "path": "/docs/api-reference/data-fetching/get-server-side-props.md" + }, + { + "title": "getStaticPaths", + "path": "/docs/api-reference/data-fetching/get-static-paths.md" + }, + { + "title": "getStaticProps", + "path": "/docs/api-reference/data-fetching/get-static-props.md" } ] }, diff --git a/docs/migrating/from-create-react-app.md b/docs/migrating/from-create-react-app.md index 93db9eddd3d88fb..77697644ec1c496 100644 --- a/docs/migrating/from-create-react-app.md +++ b/docs/migrating/from-create-react-app.md @@ -6,8 +6,8 @@ description: Learn how to transition an existing Create React App project to Nex This guide will help you understand how to transition from an existing non-ejected Create React App project to Next.js. Migrating to Next.js will allow you to: -- Choose which [data fetching](/docs/basic-features/data-fetching.md) strategy you want on a per-page basis. -- Use [Incremental Static Regeneration](/docs/basic-features/data-fetching.md#incremental-static-regeneration) to update _existing_ pages by re-rendering them in the background as traffic comes in. +- Choose which [data fetching](/docs/basic-features/data-fetching/index.md) strategy you want on a per-page basis. +- Use [Incremental Static Regeneration](/docs/basic-features/data-fetching/incremental-static-regeneration.md) to update _existing_ pages by re-rendering them in the background as traffic comes in. - Use [API Routes](/docs/api-routes/introduction.md). And more! Let’s walk through a series of steps to complete the migration. @@ -51,7 +51,7 @@ Create React App uses the `public` directory for the [entry HTML file](https://c With Create React App, you're likely using React Router. Instead of using a third-party library, Next.js includes its own [file-system based routing](/docs/routing/introduction.md). - Convert all `Route` components to new files in the `pages` directory. -- For routes that require dynamic content (e.g. `/blog/:slug`), you can use [Dynamic Routes](/docs/routing/dynamic-routes.md) with Next.js (e.g. `pages/blog/[slug].js`). The value of `slug` is accessible through a [query parameter](/docs/routing/dynamic-routes.md). For example, the route `/blog/first-post` would forward the query object `{ 'slug': 'first-post' }` to `pages/blog/[slug].js` ([learn more here](/docs/basic-features/data-fetching.md#getstaticpaths-static-generation)). +- For routes that require dynamic content (e.g. `/blog/:slug`), you can use [Dynamic Routes](/docs/routing/dynamic-routes.md) with Next.js (e.g. `pages/blog/[slug].js`). The value of `slug` is accessible through a [query parameter](/docs/routing/dynamic-routes.md). For example, the route `/blog/first-post` would forward the query object `{ 'slug': 'first-post' }` to `pages/blog/[slug].js` ([learn more here](/docs/basic-features/data-fetching/get-static-paths.md)). For more information, see [Migrating from React Router](/docs/migrating/from-react-router.md). diff --git a/docs/migrating/from-gatsby.md b/docs/migrating/from-gatsby.md index 8198ee0ce5c8a17..fa46c9819c22b71 100644 --- a/docs/migrating/from-gatsby.md +++ b/docs/migrating/from-gatsby.md @@ -6,8 +6,8 @@ description: Learn how to transition an existing Gatsby project to Next.js. This guide will help you understand how to transition from an existing Gatsby project to Next.js. Migrating to Next.js will allow you to: -- Choose which [data fetching](/docs/basic-features/data-fetching.md) strategy you want on a per-page basis. -- Use [Incremental Static Regeneration](/docs/basic-features/data-fetching.md#incremental-static-regeneration) to update _existing_ pages by re-rendering them in the background as traffic comes in. +- Choose which [data fetching](/docs/basic-features/data-fetching/index.md) strategy you want on a per-page basis. +- Use [Incremental Static Regeneration](/docs/basic-features/data-fetching/incremental-static-regeneration.md) to update _existing_ pages by re-rendering them in the background as traffic comes in. - Use [API Routes](/docs/api-routes/introduction.md). And more! Let’s walk through a series of steps to complete the migration. @@ -52,7 +52,7 @@ Both Gatsby and Next support a `pages` directory, which uses [file-system based Gatsby creates dynamic routes using the `createPages` API inside of `gatsby-node.js`. With Next, we can use [Dynamic Routes](/docs/routing/dynamic-routes.md) inside of `pages` to achieve the same effect. Rather than having a `template` directory, you can use the React component inside your dynamic route file. For example: - **Gatsby:** `createPages` API inside `gatsby-node.js` for each blog post, then have a template file at `src/templates/blog-post.js`. -- **Next:** Create `pages/blog/[slug].js` which contains the blog post template. The value of `slug` is accessible through a [query parameter](/docs/routing/dynamic-routes.md). For example, the route `/blog/first-post` would forward the query object `{ 'slug': 'first-post' }` to `pages/blog/[slug].js` ([learn more here](/docs/basic-features/data-fetching.md#getstaticpaths-static-generation)). +- **Next:** Create `pages/blog/[slug].js` which contains the blog post template. The value of `slug` is accessible through a [query parameter](/docs/routing/dynamic-routes.md). For example, the route `/blog/first-post` would forward the query object `{ 'slug': 'first-post' }` to `pages/blog/[slug].js` ([learn more here](/docs/basic-features/data-fetching/get-static-paths.md)). ## Styling @@ -92,7 +92,7 @@ Update any import statements, switch `to` to `href`, and add an `<a>` tag as a c The largest difference between Gatsby and Next.js is how data fetching is implemented. Gatsby is opinionated with GraphQL being the default strategy for retrieving data across your application. With Next.js, you get to choose which strategy you want (GraphQL is one supported option). -Gatsby uses the `graphql` tag to query data in the pages of your site. This may include local data, remote data, or information about your site configuration. Gatsby only allows the creation of static pages. With Next.js, you can choose on a [per-page basis](/docs/basic-features/pages.md) which [data fetching strategy](/docs/basic-features/data-fetching.md) you want. For example, `getServerSideProps` allows you to do server-side rendering. If you wanted to generate a static page, you'd export `getStaticProps` / `getStaticPaths` inside the page, rather than using `pageQuery`. For example: +Gatsby uses the `graphql` tag to query data in the pages of your site. This may include local data, remote data, or information about your site configuration. Gatsby only allows the creation of static pages. With Next.js, you can choose on a [per-page basis](/docs/basic-features/pages.md) which [data fetching strategy](/docs/basic-features/data-fetching/index.md) you want. For example, `getServerSideProps` allows you to do server-side rendering. If you wanted to generate a static page, you'd export `getStaticProps` / `getStaticPaths` inside the page, rather than using `pageQuery`. For example: ```js // src/pages/[slug].js diff --git a/docs/routing/introduction.md b/docs/routing/introduction.md index 2481440ff15cef4..6d165c22d6259fa 100644 --- a/docs/routing/introduction.md +++ b/docs/routing/introduction.md @@ -74,7 +74,7 @@ The example above uses multiple links. Each one maps a path (`href`) to a known - `/about` → `pages/about.js` - `/blog/hello-world` → `pages/blog/[slug].js` -Any `<Link />` in the viewport (initially or through scroll) will be prefetched by default (including the corresponding data) for pages using [Static Generation](/docs/basic-features/data-fetching.md#getstaticprops-static-generation). The corresponding data for [server-rendered](https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering) routes is _not_ prefetched. +Any `<Link />` in the viewport (initially or through scroll) will be prefetched by default (including the corresponding data) for pages using [Static Generation](/docs/basic-features/data-fetching/get-static-props.md). The corresponding data for [server-rendered](https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering) routes is _not_ prefetched. ### Linking to dynamic paths diff --git a/docs/routing/shallow-routing.md b/docs/routing/shallow-routing.md index caa9cf35138e1ce..d1703af6b6e1c22 100644 --- a/docs/routing/shallow-routing.md +++ b/docs/routing/shallow-routing.md @@ -11,7 +11,7 @@ description: You can use shallow routing to change the URL without triggering a </ul> </details> -Shallow routing allows you to change the URL without running data fetching methods again, that includes [`getServerSideProps`](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering), [`getStaticProps`](/docs/basic-features/data-fetching.md#getstaticprops-static-generation), and [`getInitialProps`](/docs/api-reference/data-fetching/getInitialProps.md). +Shallow routing allows you to change the URL without running data fetching methods again, that includes [`getServerSideProps`](/docs/basic-features/data-fetching/get-server-side-props.md), [`getStaticProps`](/docs/basic-features/data-fetching/get-static-props.md), and [`getInitialProps`](/docs/api-reference/data-fetching/get-initial-props.md). You'll receive the updated `pathname` and the `query` via the [`router` object](/docs/api-reference/next/router.md#router-object) (added by [`useRouter`](/docs/api-reference/next/router.md#useRouter) or [`withRouter`](/docs/api-reference/next/router.md#withRouter)), without losing state. diff --git a/errors/get-initial-props-as-an-instance-method.md b/errors/get-initial-props-as-an-instance-method.md index 26218c66e28eb65..805055202f40cf4 100644 --- a/errors/get-initial-props-as-an-instance-method.md +++ b/errors/get-initial-props-as-an-instance-method.md @@ -36,4 +36,4 @@ export default YourEntryComponent ### Useful Links -- [Fetching data and component lifecycle](https://nextjs.org/docs/api-reference/data-fetching/getInitialProps) +- [Fetching data and component lifecycle](https://nextjs.org/docs/api-reference/data-fetching/get-initial-props) diff --git a/examples/blog/pages/posts/pages.md b/examples/blog/pages/posts/pages.md index d97c0afefc3d89a..98d4c8333d21878 100644 --- a/examples/blog/pages/posts/pages.md +++ b/examples/blog/pages/posts/pages.md @@ -43,7 +43,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.md#fetching-data-on-the-client-side) documentation. +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. ## Static Generation (Recommended) @@ -117,7 +117,7 @@ export async function getStaticProps() { export default Blog ``` -To learn more about how `getStaticProps` works, check out the [Data Fetching documentation](/docs/basic-features/data-fetching.md#getstaticprops-static-generation). +To learn more about how `getStaticProps` works, check out the [Data Fetching documentation](/docs/basic-features/data-fetching/get-static-props.md). #### Scenario 2: Your page paths depend on external data @@ -176,7 +176,7 @@ export async function getStaticProps({ params }) { export default Post ``` -To learn more about how `getStaticPaths` works, check out the [Data Fetching documentation](/docs/basic-features/data-fetching.md#getstaticpaths-static-generation). +To learn more about how `getStaticPaths` works, check out the [Data Fetching documentation](/docs/basic-features/data-fetching/get-static-paths.md). ### When should I use Static Generation? @@ -195,7 +195,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.md#fetching-data-on-the-client-side). +- 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 **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 @@ -228,7 +228,7 @@ export default Page As you can see, `getServerSideProps` is similar to `getStaticProps`, but the difference is that `getServerSideProps` is run on every request instead of on build time. -To learn more about how `getServerSideProps` works, check out our [Data Fetching documentation](/docs/basic-features/data-fetching.md#getserversideprops-server-side-rendering) +To learn more about how `getServerSideProps` works, check out our [Data Fetching documentation](/docs/basic-features/data-fetching/get-server-side-props.md) ## Summary