如何为每个 FaunaDB 文档生成单独的 NextJS 页面?
How can I generate a separate NextJS page for each FaunaDB Document?
如何在 sub-directory 中的每个页面上生成不同的标题?
我的代码没有抛出任何错误,但不幸的是 Title
组件在它应该呈现的每个页面上呈现 every title-item
,例如每个 app.com/title/<title>
呈现 相同的 视图(标题列表)。我认为 getStaticPaths
参数化正确,但我认为 getStaticProps
不是。
export default function Title({ paper }) {
// paper is just the entire dataset, and isn't split by id or author etc.
return (
<div>
{paper.map(paper => (
<h1>{paper.data.title}</h1>
))}
</div>
)
}
export async function getStaticProps({ params }) {
// ideally, results should be split down to e.g. `/api/getPapers/title`, but this didn't work
const results = await fetch(`http://localhost:3000/api/getPapers/`).then(res => res.json());
return {
props: {
paper: results
}
}
}
export async function getStaticPaths() {
const papers = await fetch('http://localhost:3000/api/getPapers').then(res => res.json());
const paths = papers.map(paper => {
return {
params: {
authors: paper.data.title.toLowerCase().replace(/ /g, '-')
}
}
})
return {
paths,
fallback: false
}
}
这是 getPapers
API 函数。
const faunadb = require("faunadb");
// your secret hash
const secret = process.env.FAUNADB_SECRET_KEY;
const q = faunadb.query;
const client = new faunadb.Client({ secret });
module.exports = async (req, res) => {
try {
const dbs = await client.query(
q.Map(
// iterate each item in result
q.Paginate(
// make paginatable
q.Match(
// query index
q.Index("all_research_papers") // specify source
)
),
(ref) => q.Get(ref) // lookup each result by its reference
)
);
// ok
res.status(200).json(dbs.data);
} catch (e) {
// something went wrong
res.status(500).json({ error: e.message });
}
};
您正在 Path 对象中返回 authors
。您将需要确保您的页面文件以 authors
命名。例如:
app_directory
|- pages
|- home.js
|- title
|- [authors].js
也许你在 params
对象中说 authors
的地方,你的意思是 title
。在这种情况下,重命名 params
对象和页面文件名。
const paths = papers.map(paper => {
return {
params: {
title: paper.data.title.toLowerCase().replace(/ /g, '-')
}
}
})
app_directory
|- pages
|- home.js
|- title
|- [title].js
这是 getStaticPaths()
的文档。 https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation
编辑:
由于您的 API 函数 returns 来自您查询的页面,结果的形状可能是
{
before: [/* before cursor */],
after: [/* after cursor */],
data: [
{ /* paper Document */ },
{ /* paper Document */ },
{ /* paper Document */ },
]
}
在这种情况下,您的代码将需要映射到 papers.data
而不是 papers
本身。
const paths = papers.data // select the data
.map(paper => {
return {
params: {
title: paper.data.title.toLowerCase().replace(/ /g, '-')
}
}
})
我尝试为每个文档呈现单独的页面时缺少 dynamic API 调用。我只是希望通过 single (batched-document) API 调用呈现动态页面。
这是一条典型的动态 API 路由,名为 [index.js]
:
const faunadb = require('faunadb')
// your secret hash
const secret = process.env.FAUNADB_SECRET_KEY
const q = faunadb.query
const client = new faunadb.Client({ secret })
export default async (req, res) => {
const {
query: { index },
} = req;
try {
const papers = await client.query(
q.Get(q.Ref(q.Collection('<name of the collection>'), index))
);
res.status(200).json(papers.data);
} catch (e) {
res.status(500).json({ error: e.message });
}
};
动态检索数据后,您可以设置动态 page 路由,例如[id].js
,使用 useSWR.
获取数据
const { data, error } = useSWR(`/api/getPapers/${id}`, fetcher);
这是一个示例获取函数:
const fetcher = (url) => fetch(url).then((r) => r.json());
在我的例子中,我可以使用调用 {data.<field>}
.
检索任何给定的字段
如何在 sub-directory 中的每个页面上生成不同的标题?
我的代码没有抛出任何错误,但不幸的是 Title
组件在它应该呈现的每个页面上呈现 every title-item
,例如每个 app.com/title/<title>
呈现 相同的 视图(标题列表)。我认为 getStaticPaths
参数化正确,但我认为 getStaticProps
不是。
export default function Title({ paper }) {
// paper is just the entire dataset, and isn't split by id or author etc.
return (
<div>
{paper.map(paper => (
<h1>{paper.data.title}</h1>
))}
</div>
)
}
export async function getStaticProps({ params }) {
// ideally, results should be split down to e.g. `/api/getPapers/title`, but this didn't work
const results = await fetch(`http://localhost:3000/api/getPapers/`).then(res => res.json());
return {
props: {
paper: results
}
}
}
export async function getStaticPaths() {
const papers = await fetch('http://localhost:3000/api/getPapers').then(res => res.json());
const paths = papers.map(paper => {
return {
params: {
authors: paper.data.title.toLowerCase().replace(/ /g, '-')
}
}
})
return {
paths,
fallback: false
}
}
这是 getPapers
API 函数。
const faunadb = require("faunadb");
// your secret hash
const secret = process.env.FAUNADB_SECRET_KEY;
const q = faunadb.query;
const client = new faunadb.Client({ secret });
module.exports = async (req, res) => {
try {
const dbs = await client.query(
q.Map(
// iterate each item in result
q.Paginate(
// make paginatable
q.Match(
// query index
q.Index("all_research_papers") // specify source
)
),
(ref) => q.Get(ref) // lookup each result by its reference
)
);
// ok
res.status(200).json(dbs.data);
} catch (e) {
// something went wrong
res.status(500).json({ error: e.message });
}
};
您正在 Path 对象中返回 authors
。您将需要确保您的页面文件以 authors
命名。例如:
app_directory
|- pages
|- home.js
|- title
|- [authors].js
也许你在 params
对象中说 authors
的地方,你的意思是 title
。在这种情况下,重命名 params
对象和页面文件名。
const paths = papers.map(paper => {
return {
params: {
title: paper.data.title.toLowerCase().replace(/ /g, '-')
}
}
})
app_directory
|- pages
|- home.js
|- title
|- [title].js
这是 getStaticPaths()
的文档。 https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation
编辑:
由于您的 API 函数 returns 来自您查询的页面,结果的形状可能是
{
before: [/* before cursor */],
after: [/* after cursor */],
data: [
{ /* paper Document */ },
{ /* paper Document */ },
{ /* paper Document */ },
]
}
在这种情况下,您的代码将需要映射到 papers.data
而不是 papers
本身。
const paths = papers.data // select the data
.map(paper => {
return {
params: {
title: paper.data.title.toLowerCase().replace(/ /g, '-')
}
}
})
我尝试为每个文档呈现单独的页面时缺少 dynamic API 调用。我只是希望通过 single (batched-document) API 调用呈现动态页面。
这是一条典型的动态 API 路由,名为 [index.js]
:
const faunadb = require('faunadb')
// your secret hash
const secret = process.env.FAUNADB_SECRET_KEY
const q = faunadb.query
const client = new faunadb.Client({ secret })
export default async (req, res) => {
const {
query: { index },
} = req;
try {
const papers = await client.query(
q.Get(q.Ref(q.Collection('<name of the collection>'), index))
);
res.status(200).json(papers.data);
} catch (e) {
res.status(500).json({ error: e.message });
}
};
动态检索数据后,您可以设置动态 page 路由,例如[id].js
,使用 useSWR.
const { data, error } = useSWR(`/api/getPapers/${id}`, fetcher);
这是一个示例获取函数:
const fetcher = (url) => fetch(url).then((r) => r.json());
在我的例子中,我可以使用调用 {data.<field>}
.