- getStaticProps (Static Generation): Fetch data at **build time**.
- getStaticPaths (Static Generation): Specify dynamic routes to pre-render pages based on data.
- getServerSideProps (Server-side Rendering): Fetch data on **each request**.
```
```
export async function getStaticProps(context) {
return {
props: {}, // will be passed to the page component as props
}
}
```
context 是一个包含以下key的对象:
- params - 为使用动态路由的页面存放路径参数(route) 例,`[id].js` 在params中为 `{id:...}`. 一般和`getStaticPaths`搭配使用。
- preview - 为`true`时,page时preview 模式,其他为undefined
- previewData - 存放由`setPreviewData`设置的preview data
- locale - 正在使用的locale
- locales - 所有支持的
- defaultLocale - 配置 的默认locale
返回的对象里包括:
* props - 可由page 里的组件接收的 对象
* ravalidate - 默认为false,此时不会做revalidate, 页面会缓存直到下次build
* notFound - 布尔值,是否允许页面返回404 和页面
* redirect - 配置重定向到的内部和外部资源
```js
return {
redirect: {
destination: '/',
permanent: false,
},
}
```
TypeScript 中用 `GetStaticProps`
```ts
import { GetStaticProps } from 'next'
export const getStaticProps: GetStaticProps = async (context) => {
// ...
}
```
Next.js 默认静态生成的时间为60s
```js
// next.config.js
module.exports = {
// time in seconds of no pages generating during static
// generation before timing out
staticPageGenerationTimeout: 90,
}
```
增量静态再生
Incremental Static Regeneration (ISR) enables you to use static-generation on a per-page basis, **without needing to rebuild the entire site**
```jsx
function Blog({ posts }) {
return (
// 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
```
### 使用process.cwd() 直接读取文件
``__dirname` 在next.js 中不可用
```jsx
import { promises as fs } from 'fs'
import path from 'path'
// posts will be populated at build time by getStaticProps()
function Blog({ posts }) {
return (
{post.content}
// 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
```
`getStaticProps` 只在build 时候运行一次,它并不能接收请求中的数据,比如查询参数,http headers。
只在sever 上运行
### `getStaticPaths`
```jsx
export async function getStaticPaths() {
return {
paths: [
{ params: { ... } } // See the "paths" section below
],
fallback: true, false, or 'blocking' // See the "fallback" section below
};
}
```
* paths - 检测哪一个path需要被预加载
`pages/posts/[id].js`
```js
return {
paths: [
{ params: { id: '1' } },
{ params: { id: '2' } }
],
fallback: ...
}
```
在build 时候会生成posts/1 和posts/2 使用`pages/posts/[id].js`.
#### fallback:false
不会返回任何路径,返回到404 页面。
#### fallback:true
getStaticProps 的行为会改变
* getStaticPaths 返回的路径会由getStaticProps 挂载到html
* build 时候没有自动生成的path 不会产生404 page。Next.js 会提供一个页面的fallback 版本。
在这个Fallback 的页面中:props 是空的;查看这个fallback 是否正被挂载: `router.isFallback` will be `true`.
* 适用于有大量页面需要挂载
#### fallback: blocking
由 getStaticPaths 返回的新路径会等待html的生成