introduction
从v9.3.0开始才支持这个函数 …
暴露一个函数叫做getStaticProps
将在构建时预渲染一个页面(使用从这个函数返回的属性) …
export async function getStaticProps(context) {
return {
props: {}, // will be passed to the page component as props
}
}
你能够在页面顶级范围内导入模块getStaticProps
,使用的导入将不会打包到客户端 .. 这意味着你能够直接在getStaticProps
中写服务端代码,包括从数据库中抓取数据 ..
上下文参数
上下文参数包含以下key:
params
包含了页面的路由参数(如果使用了动态路由) .. 例如页面名称是[id].js
,那么params
将会看起来像{id: ....}
,你应该使用getStaticPaths
进行结合 …preview
= true,那么这个页面位于预览模式,否则undefined
previewData
包含了由setPreviewData
设置的预览数据 ..locale
包含了激活的locale( 如果启用) ..locales
包含了所有支持的locales ..(如果启用) ..defaultLocale
包含了配置的默认locale (如果启用) ..
返回值
返回值应该包含要么props
,redirect
,notFound
(并跟随一个可选的revalidate
属性) ..
props
这个对象是一个key-value 对,每一个值都会被页面组件接收 .. 它应该是一个可序列化对象(因此对于任何传递的props,都能够被JSON.stringify
序列化 ..
revalidate
这个属性考虑到多少秒之后那个页面进行重新生成 ..(默认的false
或者 没有重新验证) …
// 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
}
}
详情了解增量静态重新生成 ..
利用了ISR的这个页面的缓存状态 能够通过阅读x-nextjs-cache
响应头进行决定, 可能的值如下:
MISS
路径不存在于缓存中(最开始出现一次,第一次参观)STALE
存在于缓存中(但是溢出了最大验证时间,因此将在后台进行更新) ..HIT
路径存在于缓存中,相当于命中了 ..
notFound
这个值允许页面返回404
状态码和404
页面,使用true
,这个页面将会返回一个404
(即时之前成功生成了页面),这意味着打算支持之前由用户创建的数据(但是现在被移除了),notFound
允许相同的revalidate
行为 ….
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
}
}
注意到notFound
对于fallback:false
模式是不需要的(因为仅仅从getStaticPaths
中返回的路径才能够被预渲染) …
重定向
redirect
对象允许重定向到内部或者外部资源 ,它应该匹配{destination: string,permanent: boolean}
…
在某些极少情况下,你需要自定义状态码(对于旧的HTTP
客户端为了正确的重定向),在这些情况下,你能够使用statusCode
替代permanent
属性,但是不需要同时使用,你能够next.config.js 设置basePath: false
… 它类似于重定向 …
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
}
}
如果在构建时已知的重定向,它们应该增加到next.config.js
链接中进行替代 ..
使用process.cwd()
读取文件
从文件系统中可以直接读取文件信息
为了这样做需要拿到文件的完整路径 ..
因为Next.js 编译了代码到单独的目录(不能够直接使用__dirname
作为路径,它将返回不同于page 目录的路径)
所以我们通过process.cwd()
去获取Next.js 当前执行的目录路径
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
使用TypeScript
你能够使用来自next
的GetStaticProps
的类型
import { GetStaticProps } from 'next'
export const getStaticProps: GetStaticProps = async (context) => {
// ...
}
如果你想要推断类型,使用InferGetStaticPropsType
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