简体   繁体   English

如何通过 getStaticProps() 在 Next.js 上动态设置标题

[英]How to dynamically set a title in <Head> on Next.js through getStaticProps()

I am prerendering this page for a specific post on my Next.js application:我正在为我的 Next.js 应用程序上的特定帖子预呈现此页面:

import Head from 'next/head';
import Link from 'next/link';
import client from '../../lib/apollo/client'
import POSTS_WITH_SLUGS from '../../lib/queries/allposts'
import POST from '../../lib/queries/post'
import styles from '../../styles/Home.module.css';
import blogStyles from '../../styles/Blog.module.css';

export default function Post({ postData }) {
    const router = useRouter();

    if (!router.isFallback && !postData?.slug) {
        return <p>hmm... looks like an error</p>
    }

    const formatDate = date => {
        const newDate = new Date(date);

        return `${newDate.getDate()}/${
            newDate.getMonth() + 1
        }/${newDate.getFullYear()}`
    };

    return (
        <div className={styles.container}>
            <Head>
                <title>{postData.title}</title>
                <link rel='icon' href='/favicon.ico' />
            </Head>

            <main className={styles.main}>
                {router.isFallback ? (
                    <h2>Loading...</h2>
                ) : (
                    <article className={blogStyles.article}>
                        <div className={blogStyles.postmeta}>
                            <h1 className={styles.title}>{postData.title}</h1>
                            <p>{formatDate(postData.date)}</p>
                            <img src={postData.featuredImage.node.sourceUrl} />
                        </div>
                        <div
                            className='post-content content'
                            dangerouslySetInnerHTML={{ __html: postData.content }}
                        />
                    </article>
                )}
                <p>
                    <Link href={`/blog`}>
                        <a>Back</a>
                    </Link>
                </p>
            </main>
        </div>
    )
}

export async function getStaticPaths() {
    // const allPosts = await getAllPostsWithSlug();

    const { data } = await client.query({
        query: POSTS_WITH_SLUGS
    });

    if (
        data?.posts &&
        data?.posts.edges !== null &&
        data?.posts.edges.node !== null &&
        data?.posts.edges.length > 0
    ) {
        return {
            paths: data?.posts.edges.map(({ node }) => `/blog/${node.slug}`) || [],
            fallback: true
        }
    }

}


export async function getStaticProps({ params }) {
    const { data } = await client.query({
        query: POST,
            variables: {
                id: params.slug,
                idType: 'SLUG'
            }
        });

    return {
      props: {
        postData: data.post
      }
    };
  }

Everything works fine on npm run dev but when I run npm run build I get this error:npm run dev上一切正常,但是当我运行npm run build时,我收到此错误:

Error occurred prerendering page "/blog/[slug]". Read more: https://err.sh/next.js/prerender-error
TypeError: Cannot read property 'title' of undefined

I believe the error is due to the <Head> component from Next where I'm trying to set the <title> dynamically through {postData.title} .我相信错误是由于 Next 中的<Head>组件引起的,我试图通过{postData.title}动态设置<title> I'm getting the data as a prop from getStaticProps() .我从getStaticProps()获取数据作为道具。

I'm not sure what mistake I'm making but I do wonder if I have to create that <Head> component outside the /pages directory.我不确定自己犯了什么错误,但我确实想知道是否必须在/pages目录之外创建那个<Head>组件。 Any help would be highly appreciated.任何帮助将不胜感激。 Thanks!谢谢!

Let me explain how Next.js will “fallback” when requesting any of the other posts after the initial build.让我解释一下在初始构建后请求任何其他帖子时 Next.js 将如何“回退”。 There are two options to choose from: blocking and true .有两个选项可供选择: blockingtrue

  • fallback: blocking (preferred) – when a request is made to a page that hasn't been generated, Next.js will server-render the page on the first request. fallback: blocking (首选)– 当对尚未生成的页面发出请求时,Next.js 将在第一个请求时服务器呈现该页面。 Future requests will serve the static file from the cache.未来的请求将从缓存中提供 static 文件。
  • fallback: true – when a request is made to a page that hasn't been generated, Next.js will immediately serve a static page with a loading state on the first request. fallback: true – 当对尚未生成的页面发出请求时,Next.js 将立即提供 static 页面,并在第一个请求上加载 state。 When the data is finished loading, the page will re-render with the new data and be cached.数据加载完成后,页面将使用新数据重新渲染并被缓存。 Future requests will serve the static file from the cache.未来的请求将从缓存中提供 static 文件。

Unless you want to serve that static loading shell, followed by loading your post on the client-side, I would change from true to blocking .除非您想为 static 加载 shell 提供服务,然后在客户端加载您的帖子,否则我会从true更改为blocking That will solve your issue!这将解决您的问题!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM