In SingleBlogPost.jsx i have:
export async function getStaticPaths() {
const res = await fetch("http://localhost:1337/api/posts");
let { data } = await res.json();
const paths = data.map((data) => ({
params: { slug: data.attributes.slug },
}));
return {
paths,
fallback: "blocking",
};
}
where I generate blog pages by their slug. But then in getStaticProps I need to fetch single post by slug but I want to do it by id.
export async function getStaticProps(context) {
console.log("context", context);
const { slug } = context.params;
console.log("slug is:", slug);
const res = await fetch("http://localhost:1337/api/posts");
const { data } = await res.json();
return {
props: {
data,
},
revalidate: 10, // In seconds
};
}
And I want to keep url like /blog/:slug , I dont want to include id. in url .When I already fetch all posts in getStaticPaths how I can access post id in getStaticProps to avoid fetching by slug?
In SingleBlogPost.jsx i have:
export async function getStaticPaths() {
const res = await fetch("http://localhost:1337/api/posts");
let { data } = await res.json();
const paths = data.map((data) => ({
params: { slug: data.attributes.slug },
}));
return {
paths,
fallback: "blocking",
};
}
where I generate blog pages by their slug. But then in getStaticProps I need to fetch single post by slug but I want to do it by id.
export async function getStaticProps(context) {
console.log("context", context);
const { slug } = context.params;
console.log("slug is:", slug);
const res = await fetch("http://localhost:1337/api/posts");
const { data } = await res.json();
return {
props: {
data,
},
revalidate: 10, // In seconds
};
}
And I want to keep url like /blog/:slug , I dont want to include id. in url .When I already fetch all posts in getStaticPaths how I can access post id in getStaticProps to avoid fetching by slug?
Share Improve this question asked Jan 22, 2022 at 17:58 sakicmilansakicmilan 1031 silver badge5 bronze badges 1- 1 Take a look at this thread, some useful answers are posted here – Casper Kuethe Commented Jan 22, 2022 at 18:17
3 Answers
Reset to default 1You can filter your API response by your slug to get the same result
const res = await fetch(`http://localhost:1337/api/posts?filters[slug][$eq]${slug}`);
This will generate your desired result
It looks like recently released a workaround using a file system cache.
The crux of the solution is that they save the body object in memory, using something like this:
this.cache = Object.create(null)
and creating methods to update and fetch data from the cache.
Discussion here: https://github./vercel/next.js/discussions/11272#discussionment-2257876
Example code: https://github./vercel/examples/blob/main/build-output-api/serverless-functions/.vercel/output/functions/index.func/node_modules/y18n/index.js#L139:10
I found a concise work around that uses the object-hash
package. I basically create a hash of the params object and use that to create the tmp filename both on set and get. The tmp file contains a json with the data I want to pass between the two infamous static callbacks.
The gist of it:
function setParamsData({params, data}) {
const hash = objectHash(params)
const tmpFile = `/tmp/${hash}.json`
fs.writeFileSync(tmpFile, JSON.stringify(data))
}
function getParamsData (context) {
const hash = objectHash(context.params)
const tmpFile = `/tmp/${hash}.json`
context.data = JSON.parse(fs.readFileSync(tmpFile))
return context
}
We can then use these helpers in the getStaticPaths
and getStaticProps
callbacks to pass data between them.
export function getStaticPaths(context) {
setParamsData({...context, data: {some: 'extra data'})
return {
paths: [],
fallback: false,
}
}
export function getStaticProps(context) {
context = getParamsData(context)
context.data // => {some: 'extra data'}
}
I'm sure someone can think of a nicer API then re-assigning a argument variable.
The tmp file creation is likely not OS independent enough and could use some improvement.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744782770a4593440.html
评论列表(0条)