内容丰富 API,但有 next.js 未定义错误
Contentful API with next.js undefined error
我在使用 next.js 框架向 contentful 发出 graphql 请求时遇到未定义的错误。我为“新闻”创建了一个页面,我可以在其中接收所有帖子并且效果很好。但是当我在 nextjs 上制作 动态页面 时,我从 contentful 得到了未定义的响应。看看我下面的意思。
// 新闻/[slug].tsx
import { Box, Text } from "@chakra-ui/react";
import React from "react";
import { fetchContent } from "../../utils/contentful";
const NewsArticlePage = ({ post }) => {
console.log("post", post.slug);
return (
<Box>
<Text>{post.title}</Text>
<Text>{post.slug}</Text>
</Box>
);
};
export default NewsArticlePage;
export async function getStaticProps(context) {
// Fetch necessary data for the blog post using params.id
console.log("context params slug", context.params.slug);
const response = await fetchContent(`
query getBlogPost($slug: String) {
blogPostCollection(where: {slug: ${context.params.slug}}) {
items {
title
slug
}
}
}
`);
console.log("response", response);
const post = response.blogPostCollection.items.pop();
if (!post) {
return { props: {} };
}
// Return the post as props
return {
props: {
post,
},
};
}
export async function getStaticPaths() {
// Return a list of possible value for id
const response = await fetchContent(`
{
blogPostCollection {
items {
contentfulMetadata {
tags {
id
name
}
}
title
slug
description
body
heroImage {
title
description
contentType
fileName
size
url
width
height
}
author {
name
title
company
shortBio
email
phone
facebook
twitter
github
}
publishDate
tags
}
}
}
`);
console.log('response' ,response);
const paths = response.blogPostCollection.items.map((post) => ({
params: {
slug: post.slug,
},
}));
// console.log(paths);
return {
paths,
fallback: false,
};
}
fetchContent 是我正在使用的一个挂钩,它只是通过传入查询来获取内容。这是钩子:
// utils/contentful
const space = process.env.NEXT_PUBLIC_CONTENTFUL_SPACE_ID;
const accessToken = process.env.NEXT_PUBLIC_CONTENTFUL_ACCESS_TOKEN;
export async function fetchContent(query) {
// add a try / catch loop for nicer error handling
try {
const res = await fetch(
`https://graphql.contentful.com/content/v1/spaces/${space}`,
{
method: "POST",
headers: {
"content-type": "application/json",
authorization: `Bearer ${accessToken}`,
},
// throw our query (a string) into the body directly
body: JSON.stringify({ query }),
}
);
const { data } = await res.json();
return data;
} catch (error) {
// add a descriptive error message first,
// so we know which GraphQL query caused the issue
console.error(
`There was a problem retrieving entries with the query ${query}`
);
console.error(error);
}
}
正如我所说,获取相同查询 (blogPostCollection) 的新闻页面获取所有帖子。但是动态创建的帖子会遇到未定义的响应。感谢任何帮助。谢谢
我忘了提到在 graphiql 中,查询运行得很好。单帖查询没有问题
您需要使用 getStaticPaths
静态生成所有基于 slug 的不同静态页面。
在此处查看 Next.js 文档:https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation
这是添加到您的 [slug].js 页面的代码示例:
export async function getStaticPaths() {
const blogPostSlugs = // fetch all blog post slugs via GraphQL
// For example
//
// const query = `{
// blogPostCollection {
// items {
// slug
// }
// }
// }`;
const paths = blogPostSlugs.map((slug) => {
return { params: { slug } };
});
return {
paths,
};
}
export async function getStaticProps({ params }) {
// Do whatever you need to fetch your post
const post = // fetch your post via slug as you do above using params.slug
return {
props: {
post,
},
};
}
有关完整代码示例,请参阅 GitHub 上的此文件:https://github.com/whitep4nth3r/nextjs-contentful-blog-starter/blob/d80dc1e44a827bc3e6e30ca8c699a4b60f626040/pages/blog/%5Bslug%5D.js#L26
我在使用 next.js 框架向 contentful 发出 graphql 请求时遇到未定义的错误。我为“新闻”创建了一个页面,我可以在其中接收所有帖子并且效果很好。但是当我在 nextjs 上制作 动态页面 时,我从 contentful 得到了未定义的响应。看看我下面的意思。
// 新闻/[slug].tsx
import { Box, Text } from "@chakra-ui/react";
import React from "react";
import { fetchContent } from "../../utils/contentful";
const NewsArticlePage = ({ post }) => {
console.log("post", post.slug);
return (
<Box>
<Text>{post.title}</Text>
<Text>{post.slug}</Text>
</Box>
);
};
export default NewsArticlePage;
export async function getStaticProps(context) {
// Fetch necessary data for the blog post using params.id
console.log("context params slug", context.params.slug);
const response = await fetchContent(`
query getBlogPost($slug: String) {
blogPostCollection(where: {slug: ${context.params.slug}}) {
items {
title
slug
}
}
}
`);
console.log("response", response);
const post = response.blogPostCollection.items.pop();
if (!post) {
return { props: {} };
}
// Return the post as props
return {
props: {
post,
},
};
}
export async function getStaticPaths() {
// Return a list of possible value for id
const response = await fetchContent(`
{
blogPostCollection {
items {
contentfulMetadata {
tags {
id
name
}
}
title
slug
description
body
heroImage {
title
description
contentType
fileName
size
url
width
height
}
author {
name
title
company
shortBio
email
phone
facebook
twitter
github
}
publishDate
tags
}
}
}
`);
console.log('response' ,response);
const paths = response.blogPostCollection.items.map((post) => ({
params: {
slug: post.slug,
},
}));
// console.log(paths);
return {
paths,
fallback: false,
};
}
fetchContent 是我正在使用的一个挂钩,它只是通过传入查询来获取内容。这是钩子:
// utils/contentful
const space = process.env.NEXT_PUBLIC_CONTENTFUL_SPACE_ID;
const accessToken = process.env.NEXT_PUBLIC_CONTENTFUL_ACCESS_TOKEN;
export async function fetchContent(query) {
// add a try / catch loop for nicer error handling
try {
const res = await fetch(
`https://graphql.contentful.com/content/v1/spaces/${space}`,
{
method: "POST",
headers: {
"content-type": "application/json",
authorization: `Bearer ${accessToken}`,
},
// throw our query (a string) into the body directly
body: JSON.stringify({ query }),
}
);
const { data } = await res.json();
return data;
} catch (error) {
// add a descriptive error message first,
// so we know which GraphQL query caused the issue
console.error(
`There was a problem retrieving entries with the query ${query}`
);
console.error(error);
}
}
正如我所说,获取相同查询 (blogPostCollection) 的新闻页面获取所有帖子。但是动态创建的帖子会遇到未定义的响应。感谢任何帮助。谢谢
我忘了提到在 graphiql 中,查询运行得很好。单帖查询没有问题
您需要使用 getStaticPaths
静态生成所有基于 slug 的不同静态页面。
在此处查看 Next.js 文档:https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation
这是添加到您的 [slug].js 页面的代码示例:
export async function getStaticPaths() {
const blogPostSlugs = // fetch all blog post slugs via GraphQL
// For example
//
// const query = `{
// blogPostCollection {
// items {
// slug
// }
// }
// }`;
const paths = blogPostSlugs.map((slug) => {
return { params: { slug } };
});
return {
paths,
};
}
export async function getStaticProps({ params }) {
// Do whatever you need to fetch your post
const post = // fetch your post via slug as you do above using params.slug
return {
props: {
post,
},
};
}
有关完整代码示例,请参阅 GitHub 上的此文件:https://github.com/whitep4nth3r/nextjs-contentful-blog-starter/blob/d80dc1e44a827bc3e6e30ca8c699a4b60f626040/pages/blog/%5Bslug%5D.js#L26