.
This commit is contained in:
Generated
Vendored
+202
@@ -0,0 +1,202 @@
|
||||
---
|
||||
title: getStaticProps
|
||||
description: Fetch data and generate static pages with `getStaticProps`. Learn more about this API for data fetching in Next.js.
|
||||
---
|
||||
|
||||
If you export a function called `getStaticProps` (Static Site Generation) from a page, Next.js will prerender this page at build time using the props returned by `getStaticProps`.
|
||||
|
||||
```tsx filename="pages/index.tsx" switcher
|
||||
import type { InferGetStaticPropsType, GetStaticProps } from 'next'
|
||||
|
||||
type Repo = {
|
||||
name: string
|
||||
stargazers_count: number
|
||||
}
|
||||
|
||||
export const getStaticProps = (async (context) => {
|
||||
const res = await fetch('https://api.github.com/repos/vercel/next.js')
|
||||
const repo = await res.json()
|
||||
return { props: { repo } }
|
||||
}) satisfies GetStaticProps<{
|
||||
repo: Repo
|
||||
}>
|
||||
|
||||
export default function Page({
|
||||
repo,
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||
return repo.stargazers_count
|
||||
}
|
||||
```
|
||||
|
||||
```jsx filename="pages/index.js" switcher
|
||||
export async function getStaticProps() {
|
||||
const res = await fetch('https://api.github.com/repos/vercel/next.js')
|
||||
const repo = await res.json()
|
||||
return { props: { repo } }
|
||||
}
|
||||
|
||||
export default function Page({ repo }) {
|
||||
return repo.stargazers_count
|
||||
}
|
||||
```
|
||||
|
||||
> Note that irrespective of rendering type, any `props` will be passed to the page component and can be viewed on the client-side in the initial HTML. This is to allow the page to be [hydrated](https://react.dev/reference/react-dom/hydrate) correctly. Make sure that you don't pass any sensitive information that shouldn't be available on the client in `props`.
|
||||
|
||||
The [`getStaticProps` API reference](/docs/pages/api-reference/functions/get-static-props) covers all parameters and props that can be used with `getStaticProps`.
|
||||
|
||||
## 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 page must be prerendered (for SEO) and be very fast — `getStaticProps` generates `HTML` and `JSON` files, both of which can be cached by a CDN for performance
|
||||
- The data can be publicly cached (not user-specific). This condition can be bypassed in certain specific situation by using a Proxy to rewrite the path.
|
||||
|
||||
## When does getStaticProps run
|
||||
|
||||
`getStaticProps` always runs on the server and never on the client. You can validate code written inside `getStaticProps` is removed from the client-side bundle [with this tool](https://next-code-elimination.vercel.app/).
|
||||
|
||||
- `getStaticProps` always runs during `next build`
|
||||
- `getStaticProps` runs in the background when using [`fallback: true`](/docs/pages/api-reference/functions/get-static-paths#fallback-true)
|
||||
- `getStaticProps` is called before initial render when using [`fallback: blocking`](/docs/pages/api-reference/functions/get-static-paths#fallback-blocking)
|
||||
- `getStaticProps` runs in the background when using `revalidate`
|
||||
- `getStaticProps` runs on-demand in the background when using [`revalidate()`](/docs/pages/guides/incremental-static-regeneration#on-demand-revalidation-with-revalidatepath)
|
||||
|
||||
When combined with [Incremental Static Regeneration](/docs/pages/guides/incremental-static-regeneration), `getStaticProps` will run in the background while the stale page is being revalidated, and the fresh page served to the browser.
|
||||
|
||||
`getStaticProps` does not have access to the incoming request (such as query parameters or HTTP headers) as it generates static HTML. If you need access to the request for your page, consider using [Proxy](/docs/pages/api-reference/file-conventions/proxy) in addition to `getStaticProps`.
|
||||
|
||||
## Using getStaticProps to fetch data from a CMS
|
||||
|
||||
The following example shows how you can fetch a list of blog posts from a CMS.
|
||||
|
||||
```tsx filename="pages/blog.tsx" switcher
|
||||
// posts will be populated at build time by getStaticProps()
|
||||
export default 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,
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```jsx filename="pages/blog.js" switcher
|
||||
// posts will be populated at build time by getStaticProps()
|
||||
export default 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,
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The [`getStaticProps` API reference](/docs/pages/api-reference/functions/get-static-props) 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 shared by using a `lib/` directory. Then it can be shared with `getStaticProps`.
|
||||
|
||||
```js filename="lib/load-posts.js"
|
||||
// The following function is shared
|
||||
// with getStaticProps and API routes
|
||||
// from a `lib/` directory
|
||||
export async function loadPosts() {
|
||||
// Call an external API endpoint to get posts
|
||||
const res = await fetch('https://.../posts/')
|
||||
const data = await res.json()
|
||||
|
||||
return data
|
||||
}
|
||||
```
|
||||
|
||||
```jsx filename="pages/blog.js"
|
||||
// pages/blog.js
|
||||
import { loadPosts } from '../lib/load-posts'
|
||||
|
||||
// This function runs only on the server side
|
||||
export async function getStaticProps() {
|
||||
// Instead of fetching your `/api` route you can call the same
|
||||
// function directly in `getStaticProps`
|
||||
const posts = await loadPosts()
|
||||
|
||||
// Props returned will be passed to the page component
|
||||
return { props: { posts } }
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, if you are **not** using API routes to fetch data, then the [`fetch()`](https://developer.mozilla.org/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 prerendered 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/pages/api-reference/components/link) or [`next/router`](/docs/pages/api-reference/functions/use-router). When you navigate to a page that’s prerendered 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 in the background 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, `_app`, `_document`, or `_error`.
|
||||
|
||||
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.
|
||||
|
||||
> **Good to know**: if you have created a [custom app](/docs/pages/building-your-application/routing/custom-app), ensure you are passing the `pageProps` to the page component as shown in the linked document, otherwise the props will be empty.
|
||||
|
||||
## Runs on every request in development
|
||||
|
||||
In development (`next dev`), `getStaticProps` will be called on every request.
|
||||
|
||||
## Preview Mode
|
||||
|
||||
You can temporarily bypass static generation and render the page at **request time** instead of build time using [**Preview Mode**](/docs/pages/guides/preview-mode). For example, you might be using a headless CMS and want to preview drafts before they're published.
|
||||
Generated
Vendored
+141
@@ -0,0 +1,141 @@
|
||||
---
|
||||
title: getStaticPaths
|
||||
description: Fetch data and generate static pages with `getStaticPaths`. Learn more about this API for data fetching in Next.js.
|
||||
---
|
||||
|
||||
If a page has [Dynamic Routes](/docs/pages/building-your-application/routing/dynamic-routes) 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 prerender all the paths specified by `getStaticPaths`.
|
||||
|
||||
```tsx filename="pages/repo/[name].tsx" switcher
|
||||
import type {
|
||||
InferGetStaticPropsType,
|
||||
GetStaticProps,
|
||||
GetStaticPaths,
|
||||
} from 'next'
|
||||
|
||||
type Repo = {
|
||||
name: string
|
||||
stargazers_count: number
|
||||
}
|
||||
|
||||
export const getStaticPaths = (async () => {
|
||||
return {
|
||||
paths: [
|
||||
{
|
||||
params: {
|
||||
name: 'next.js',
|
||||
},
|
||||
}, // See the "paths" section below
|
||||
],
|
||||
fallback: true, // false or "blocking"
|
||||
}
|
||||
}) satisfies GetStaticPaths
|
||||
|
||||
export const getStaticProps = (async (context) => {
|
||||
const res = await fetch('https://api.github.com/repos/vercel/next.js')
|
||||
const repo = await res.json()
|
||||
return { props: { repo } }
|
||||
}) satisfies GetStaticProps<{
|
||||
repo: Repo
|
||||
}>
|
||||
|
||||
export default function Page({
|
||||
repo,
|
||||
}: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||
return repo.stargazers_count
|
||||
}
|
||||
```
|
||||
|
||||
```jsx filename="pages/repo/[name].js" switcher
|
||||
export async function getStaticPaths() {
|
||||
return {
|
||||
paths: [
|
||||
{
|
||||
params: {
|
||||
name: 'next.js',
|
||||
},
|
||||
}, // See the "paths" section below
|
||||
],
|
||||
fallback: true, // false or "blocking"
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStaticProps() {
|
||||
const res = await fetch('https://api.github.com/repos/vercel/next.js')
|
||||
const repo = await res.json()
|
||||
return { props: { repo } }
|
||||
}
|
||||
|
||||
export default function Page({ repo }) {
|
||||
return repo.stargazers_count
|
||||
}
|
||||
```
|
||||
|
||||
The [`getStaticPaths` API reference](/docs/pages/api-reference/functions/get-static-paths) covers all parameters and props that can be used with `getStaticPaths`.
|
||||
|
||||
## When should I use getStaticPaths?
|
||||
|
||||
You should use `getStaticPaths` if you’re statically prerendering 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 prerendered (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` will only run during build in production, it will not be called during runtime. You can validate code written inside `getStaticPaths` is removed from the client-side bundle [with this tool](https://next-code-elimination.vercel.app/).
|
||||
|
||||
### How does getStaticProps run with regards to getStaticPaths
|
||||
|
||||
- `getStaticProps` runs during `next build` for any `paths` returned during build
|
||||
- `getStaticProps` runs in the background when using `fallback: true`
|
||||
- `getStaticProps` is called before initial render when using `fallback: blocking`
|
||||
|
||||
## Where can I use getStaticPaths
|
||||
|
||||
- `getStaticPaths` **must** be used with `getStaticProps`
|
||||
- You **cannot** use `getStaticPaths` with [`getServerSideProps`](/docs/pages/building-your-application/data-fetching/get-server-side-props)
|
||||
- You can export `getStaticPaths` from a [Dynamic Route](/docs/pages/building-your-application/routing/dynamic-routes) that also uses `getStaticProps`
|
||||
- You **cannot** export `getStaticPaths` from non-page file (e.g. your `components` folder)
|
||||
- You must export `getStaticPaths` as a standalone function, and not a property of the page component
|
||||
|
||||
## Runs on every request in development
|
||||
|
||||
In development (`next dev`), `getStaticPaths` will be called on every request.
|
||||
|
||||
## Generating paths on-demand
|
||||
|
||||
`getStaticPaths` allows you to control which pages are generated during the build instead of on-demand with [`fallback`](/docs/pages/api-reference/functions/get-static-paths#fallback-blocking). Generating more pages during a build will cause slower builds.
|
||||
|
||||
You can defer generating all pages on-demand by returning an empty array for `paths`. This can be especially helpful when deploying your Next.js application to multiple environments. For example, you can have faster builds by generating all pages on-demand for previews (but not production builds). This is helpful for sites with hundreds/thousands of static pages.
|
||||
|
||||
```jsx filename="pages/posts/[id].js"
|
||||
export async function getStaticPaths() {
|
||||
// When this is true (in preview environments) don't
|
||||
// prerender any static pages
|
||||
// (faster builds, but slower initial page load)
|
||||
if (process.env.SKIP_BUILD_STATIC_GENERATION) {
|
||||
return {
|
||||
paths: [],
|
||||
fallback: 'blocking',
|
||||
}
|
||||
}
|
||||
|
||||
// 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 prerender based on posts
|
||||
// In production environments, prerender all pages
|
||||
// (slower builds, but faster initial page load)
|
||||
const paths = posts.map((post) => ({
|
||||
params: { id: post.id },
|
||||
}))
|
||||
|
||||
// { fallback: false } means other routes should 404
|
||||
return { paths, fallback: false }
|
||||
}
|
||||
```
|
||||
Generated
Vendored
+107
@@ -0,0 +1,107 @@
|
||||
---
|
||||
title: Forms and Mutations
|
||||
nav_title: Forms and Mutations
|
||||
description: Learn how to handle form submissions and data mutations with Next.js.
|
||||
---
|
||||
|
||||
Forms enable you to create and update data in web applications. Next.js provides a powerful way to handle form submissions and data mutations using **API Routes**.
|
||||
|
||||
> **Good to know:**
|
||||
>
|
||||
> - We will soon recommend [incrementally adopting](/docs/app/guides/migrating/app-router-migration) the App Router and using [Server Actions](/docs/app/getting-started/mutating-data) for handling form submissions and data mutations. Server Actions allow you to define asynchronous server functions that can be called directly from your components, without needing to manually create an API Route.
|
||||
> - API Routes [do not specify CORS headers](https://developer.mozilla.org/docs/Web/HTTP/CORS), meaning they are same-origin only by default.
|
||||
> - Since API Routes run on the server, we're able to use sensitive values (like API keys) through [Environment Variables](/docs/pages/guides/environment-variables) without exposing them to the client. This is critical for the security of your application.
|
||||
|
||||
## Examples
|
||||
|
||||
### Redirecting
|
||||
|
||||
If you would like to redirect the user to a different route after a mutation, you can [`redirect`](/docs/pages/building-your-application/routing/api-routes#response-helpers) to any absolute or relative URL:
|
||||
|
||||
```ts filename="pages/api/submit.ts" switcher
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const id = await addPost()
|
||||
res.redirect(307, `/post/${id}`)
|
||||
}
|
||||
```
|
||||
|
||||
```js filename="pages/api/submit.js" switcher
|
||||
export default async function handler(req, res) {
|
||||
const id = await addPost()
|
||||
res.redirect(307, `/post/${id}`)
|
||||
}
|
||||
```
|
||||
|
||||
### Setting cookies
|
||||
|
||||
You can set cookies inside an API Route using the `setHeader` method on the response:
|
||||
|
||||
```ts filename="pages/api/cookie.ts" switcher
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
res.setHeader('Set-Cookie', 'username=lee; Path=/; HttpOnly')
|
||||
res.status(200).send('Cookie has been set.')
|
||||
}
|
||||
```
|
||||
|
||||
```js filename="pages/api/cookie.js" switcher
|
||||
export default async function handler(req, res) {
|
||||
res.setHeader('Set-Cookie', 'username=lee; Path=/; HttpOnly')
|
||||
res.status(200).send('Cookie has been set.')
|
||||
}
|
||||
```
|
||||
|
||||
### Reading cookies
|
||||
|
||||
You can read cookies inside an API Route using the [`cookies`](/docs/pages/building-your-application/routing/api-routes#request-helpers) request helper:
|
||||
|
||||
```ts filename="pages/api/cookie.ts" switcher
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
const auth = req.cookies.authorization
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
```js filename="pages/api/cookie.js" switcher
|
||||
export default async function handler(req, res) {
|
||||
const auth = req.cookies.authorization
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Deleting cookies
|
||||
|
||||
You can delete cookies inside an API Route using the `setHeader` method on the response:
|
||||
|
||||
```ts filename="pages/api/cookie.ts" switcher
|
||||
import type { NextApiRequest, NextApiResponse } from 'next'
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
) {
|
||||
res.setHeader('Set-Cookie', 'username=; Path=/; HttpOnly; Max-Age=0')
|
||||
res.status(200).send('Cookie has been deleted.')
|
||||
}
|
||||
```
|
||||
|
||||
```js filename="pages/api/cookie.js" switcher
|
||||
export default async function handler(req, res) {
|
||||
res.setHeader('Set-Cookie', 'username=; Path=/; HttpOnly; Max-Age=0')
|
||||
res.status(200).send('Cookie has been deleted.')
|
||||
}
|
||||
```
|
||||
Generated
Vendored
+108
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: getServerSideProps
|
||||
description: Fetch data on each request with `getServerSideProps`.
|
||||
---
|
||||
|
||||
`getServerSideProps` is a Next.js function that can be used to fetch data and render the contents of a page at request time.
|
||||
|
||||
## Example
|
||||
|
||||
You can use `getServerSideProps` by exporting it from a Page Component. The example below shows how you can fetch data from a 3rd party API in `getServerSideProps`, and pass the data to the page as props:
|
||||
|
||||
```tsx filename="pages/index.tsx" switcher
|
||||
import type { InferGetServerSidePropsType, GetServerSideProps } from 'next'
|
||||
|
||||
type Repo = {
|
||||
name: string
|
||||
stargazers_count: number
|
||||
}
|
||||
|
||||
export const getServerSideProps = (async () => {
|
||||
// Fetch data from external API
|
||||
const res = await fetch('https://api.github.com/repos/vercel/next.js')
|
||||
const repo: Repo = await res.json()
|
||||
// Pass data to the page via props
|
||||
return { props: { repo } }
|
||||
}) satisfies GetServerSideProps<{ repo: Repo }>
|
||||
|
||||
export default function Page({
|
||||
repo,
|
||||
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
|
||||
return (
|
||||
<main>
|
||||
<p>{repo.stargazers_count}</p>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
```jsx filename="pages/index.js" switcher
|
||||
export async function getServerSideProps() {
|
||||
// Fetch data from external API
|
||||
const res = await fetch('https://api.github.com/repos/vercel/next.js')
|
||||
const repo = await res.json()
|
||||
// Pass data to the page via props
|
||||
return { props: { repo } }
|
||||
}
|
||||
|
||||
export default function Page({ repo }) {
|
||||
return (
|
||||
<main>
|
||||
<p>{repo.stargazers_count}</p>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## When should I use `getServerSideProps`?
|
||||
|
||||
You should use `getServerSideProps` if you need to render a page that relies on personalized user data, or information that can only be known at request time. For example, `authorization` headers or a geolocation.
|
||||
|
||||
If you do not need to fetch the data at request time, or would prefer to cache the data and prerendered HTML, we recommend using [`getStaticProps`](/docs/pages/building-your-application/data-fetching/get-static-props).
|
||||
|
||||
## Behavior
|
||||
|
||||
- `getServerSideProps` runs on the server.
|
||||
- `getServerSideProps` can only be exported from a **page**.
|
||||
- `getServerSideProps` returns JSON.
|
||||
- When a user visits a page, `getServerSideProps` will be used to fetch data at request time, and the data is used to render the initial HTML of the page.
|
||||
- `props` passed to the page component can be viewed on the client as part of the initial HTML. This is to allow the page to be [hydrated](https://react.dev/reference/react-dom/hydrate) correctly. Make sure that you don't pass any sensitive information that shouldn't be available on the client in `props`.
|
||||
- When a user visits the page through [`next/link`](/docs/pages/api-reference/components/link) or [`next/router`](/docs/pages/api-reference/functions/use-router), Next.js sends an API request to the server, which runs `getServerSideProps`.
|
||||
- You do not have to call a Next.js [API Route](/docs/pages/building-your-application/routing/api-routes) to fetch data when using `getServerSideProps` since the function runs on the server. Instead, you can call a CMS, database, or other third-party APIs directly from inside `getServerSideProps`.
|
||||
|
||||
> **Good to know:**
|
||||
>
|
||||
> - See [`getServerSideProps` API reference](/docs/pages/api-reference/functions/get-server-side-props) for parameters and props that can be used with `getServerSideProps`.
|
||||
> - 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.
|
||||
|
||||
## Error Handling
|
||||
|
||||
If an error is thrown inside `getServerSideProps`, it will show the `pages/500.js` file. Check out the documentation for [500 page](/docs/pages/building-your-application/routing/custom-error#500-page) to learn more on how to create it. During development, this file will not be used and the development error overlay will be shown instead.
|
||||
|
||||
## Edge Cases
|
||||
|
||||
### Caching with Server-Side Rendering (SSR)
|
||||
|
||||
You can use caching headers (`Cache-Control`) inside `getServerSideProps` to cache dynamic responses. For example, using [`stale-while-revalidate`](https://web.dev/stale-while-revalidate/).
|
||||
|
||||
```jsx
|
||||
// This value is considered fresh for ten seconds (s-maxage=10).
|
||||
// If a request is repeated within the next 10 seconds, the previously
|
||||
// cached value will still be fresh. If the request is repeated before 59 seconds,
|
||||
// the cached value will be stale but still render (stale-while-revalidate=59).
|
||||
//
|
||||
// In the background, a revalidation request will be made to populate the cache
|
||||
// with a fresh value. If you refresh the page, you will see the new value.
|
||||
export async function getServerSideProps({ req, res }) {
|
||||
res.setHeader(
|
||||
'Cache-Control',
|
||||
'public, s-maxage=10, stale-while-revalidate=59'
|
||||
)
|
||||
|
||||
return {
|
||||
props: {},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
However, before reaching for `cache-control`, we recommend seeing if [`getStaticProps`](/docs/pages/building-your-application/data-fetching/get-static-props) with [ISR](/docs/pages/guides/incremental-static-regeneration) is a better fit for your use case.
|
||||
node_modules/next/dist/docs/02-pages/03-building-your-application/03-data-fetching/05-client-side.md
Generated
Vendored
+70
@@ -0,0 +1,70 @@
|
||||
---
|
||||
title: Client-side Fetching
|
||||
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 is useful when your page doesn't require SEO indexing, when you don't need to prerender 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
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
function Profile() {
|
||||
const [data, setData] = useState(null)
|
||||
const [isLoading, setLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
fetch('/api/profile-data')
|
||||
.then((res) => res.json())
|
||||
.then((data) => {
|
||||
setData(data)
|
||||
setLoading(false)
|
||||
})
|
||||
}, [])
|
||||
|
||||
if (isLoading) return <p>Loading...</p>
|
||||
if (!data) 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 recommended** 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/getting-started).
|
||||
|
||||
```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>
|
||||
)
|
||||
}
|
||||
```
|
||||
Generated
Vendored
+37
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: Data Fetching
|
||||
description: Next.js allows you to fetch data in multiple ways, with prerendering, server-side rendering or static-site generation, and incremental static regeneration. Learn how to manage your application data in Next.js.
|
||||
---
|
||||
|
||||
Data fetching in Next.js allows you to render your content in different ways, depending on your application's use case. These include prerendering with **Server-side Rendering** or **Static Generation**, and updating or creating content at runtime with **Incremental Static Regeneration**.
|
||||
|
||||
## Examples
|
||||
|
||||
- [Agility CMS Example](https://github.com/vercel/next.js/tree/canary/examples/cms-agilitycms) ([Demo](https://next-blog-agilitycms.vercel.app/))
|
||||
- [Builder.io Example](https://github.com/vercel/next.js/tree/canary/examples/cms-builder-io) ([Demo](https://cms-builder-io.vercel.app/))
|
||||
- [ButterCMS Example](https://github.com/vercel/next.js/tree/canary/examples/cms-buttercms) ([Demo](https://next-blog-buttercms.vercel.app/))
|
||||
- [Contentful Example](https://github.com/vercel/next.js/tree/canary/examples/cms-contentful) ([Demo](https://app-router-contentful.vercel.app/))
|
||||
- [Cosmic Example](https://github.com/vercel/next.js/tree/canary/examples/cms-cosmic) ([Demo](https://next-blog-cosmic.vercel.app/))
|
||||
- [DatoCMS Example](https://github.com/vercel/next.js/tree/canary/examples/cms-datocms) ([Demo](https://next-blog-datocms.vercel.app/))
|
||||
- [DotCMS Example](https://github.com/vercel/next.js/tree/canary/examples/cms-dotcms) ([Demo](https://nextjs-dotcms-blog.vercel.app/))
|
||||
- [Drupal Example](https://github.com/vercel/next.js/tree/canary/examples/cms-drupal) ([Demo](https://cms-drupal.vercel.app/))
|
||||
- [Enterspeed Example](https://github.com/vercel/next.js/tree/canary/examples/cms-enterspeed) ([Demo](https://next-blog-demo.enterspeed.com/))
|
||||
- [GraphCMS Example](https://github.com/vercel/next.js/tree/canary/examples/cms-graphcms) ([Demo](https://next-blog-graphcms.vercel.app/))
|
||||
- [Keystone Example](https://github.com/vercel/next.js/tree/canary/examples/cms-keystonejs-embedded) ([Demo](https://nextjs-keystone-demo.vercel.app/))
|
||||
- [Kontent.ai Example](https://github.com/vercel/next.js/tree/canary/examples/cms-kontent-ai) ([Demo](https://next-blog-kontent-ai.vercel.app/))
|
||||
- [Makeswift Example](https://github.com/vercel/next.js/tree/canary/examples/cms-makeswift) ([Demo](https://nextjs-makeswift-example.vercel.app/))
|
||||
- [Plasmic Example](https://github.com/vercel/next.js/tree/canary/examples/cms-plasmic) ([Demo](https://nextjs-plasmic-example.vercel.app/))
|
||||
- [Prepr Example](https://github.com/vercel/next.js/tree/canary/examples/cms-prepr) ([Demo](https://next-blog-prepr.vercel.app/))
|
||||
- [Prismic Example](https://github.com/vercel/next.js/tree/canary/examples/cms-prismic) ([Demo](https://next-blog-prismic.vercel.app/))
|
||||
- [Sanity Example](https://github.com/vercel/next.js/tree/canary/examples/cms-sanity) ([Demo](https://next-blog.sanity.build/))
|
||||
- [Sitecore XM Cloud Example](https://github.com/vercel/next.js/tree/canary/examples/cms-sitecore-xmcloud) ([Demo](https://vercel-sitecore-xmcloud-demo.vercel.app/))
|
||||
- [Storyblok Example](https://github.com/vercel/next.js/tree/canary/examples/cms-storyblok) ([Demo](https://next-blog-storyblok.vercel.app/))
|
||||
- [Strapi Example](https://github.com/vercel/next.js/tree/canary/examples/cms-strapi) ([Demo](https://next-blog-strapi.vercel.app/))
|
||||
- [TakeShape Example](https://github.com/vercel/next.js/tree/canary/examples/cms-takeshape) ([Demo](https://next-blog-takeshape.vercel.app/))
|
||||
- [Tina Example](https://github.com/vercel/next.js/tree/canary/examples/cms-tina) ([Demo](https://cms-tina-example.vercel.app/))
|
||||
- [Umbraco Example](https://github.com/vercel/next.js/tree/canary/examples/cms-umbraco) ([Demo](https://nextjs-umbraco-sample-blog.vercel.app/))
|
||||
- [Umbraco Heartcore Example](https://github.com/vercel/next.js/tree/canary/examples/cms-umbraco-heartcore) ([Demo](https://next-blog-umbraco-heartcore.vercel.app/))
|
||||
- [Webiny Example](https://github.com/vercel/next.js/tree/canary/examples/cms-webiny) ([Demo](https://webiny-headlesscms-nextjs-example.vercel.app/))
|
||||
- [WordPress Example](https://github.com/vercel/next.js/tree/canary/examples/cms-wordpress) ([Demo](https://next-blog-wordpress.vercel.app/))
|
||||
- [Blog Starter Example](https://github.com/vercel/next.js/tree/canary/examples/blog-starter) ([Demo](https://next-blog-starter.vercel.app/))
|
||||
- [Static Tweet (Demo)](https://react-tweet.vercel.app/)
|
||||
Reference in New Issue
Block a user