Next.js 应用程序中的 SEO 元标记未显示在页面源中

问题描述 投票:0回答:2

我在为 Next.js 博客应用程序生成元标记时遇到问题。我目前正在使用 Typescript 和 apollo-codegen 生成查询挂钩以从我的 Strapi 后端获取信息。因为我在许多其他帖子中读到,如果信息是客户端呈现的,动态元标记信息将不会显示在视图页面源中,所以我进行了更改以使用 graphql-codegen-next-ssr (https:/ /github.com/correttojs/graphql-codegen-apollo-next-ssr)。我的所有查询现在都已预渲染。

[slug].tsx

const BlogDetails: PageGetBlogDetailComp = (props) => {
  return props?.data ? (
    <div className=" container mx-auto mb-8 bg-light-neutral px-10 dark:bg-dark-neutral">
      <Head>
        <title>
          Apex Blogs | {props?.data?.blogs?.data[0]?.attributes?.title}
        </title>
        <meta
          property="og:title"
          content={props?.data?.blogs?.data[0].attributes?.title}
        />
        <meta property="og:description" content="Open Graph Description" />
        <meta property="og:type" content="video.movie" />
        <meta
          property="og:image"
          content={
            props?.data?.blogs?.data[0]?.attributes?.featureImage?.data
              ?.attributes?.url
          }
        />
        <meta
          property="og:url"
          content={`https://apex-blogs.vercel.app/blog/${props?.data?.blogs?.data[0]?.attributes?.slug}`}
        />
      </Head>
  //......



export const getStaticProps: GetServerSideProps = async ({ params, req }) => {
  const res = await ssrGetBlogDetail.getServerPage(
    {
      variables: { slug: params?.slug?.toString() || "" },
    },
    { req }
  );

  if (res.props.error) {
    return {
      notFound: true,
    };
  }

  return res;
};

尽管如此,我仍然没有运气看到我的元标签。我什至无法查看在页面源代码的 __app.ts 中添加的标签。元标记仅显示在检查元素中。我可以在页面源中查看元标记的唯一方法是将它们添加到 _document.ts 文件中,但我的标记需要是动态的。

我的目标是拥有可共享的博客文章。如果我需要添加其他信息,请告诉我。

typescript next.js graphql seo apollo
2个回答
3
投票

我将分享我的解决方案。首先,您不需要在每个页面组件中添加

Head
组件。
因为它无论如何都不会显示在源代码中。(但就我而言。)
但是如果您将
Head
组件放入
_app.js
组件中,它将出现在源代码中。
让我们利用这一点。

  1. <Head>
    组件放置在
    _app.js
    文件上,如下所示。
    并删除其他页面组件中所有
    <Head>
    组件。
function MyApp({ Component, pageProps }: AppProps) {
  const router = useRouter()
  return (
    <Suspense>
      <Head>
           <title>{pageProps?.title}</title>
           <meta name="description"  content={pageProps?.description}/>
           <meta property="og:title" content={pageProps?.title} />
      </Head>
      <Component {...pageProps} />
    </Suspense>
  )
}

  1. 并在每个页面组件中添加
    getInitialProps
    功能,如下所示。
    这是发送 _app.js 的
    Head
    组件的内容。因此,当您更改页面时,
    _app.js
    组件将从页面组件的
    pageProps
    函数接收
    getInitialProps
//in Main page component..

import { NextPageContext } from 'next'

export default function Main(){
   return <div>…</div>
}

Main.getInitialProps = async (ctx: NextPageContext) => {
  return {
    title: ’Title you wanna show’,
    description: ’Desc you wanna show’
  }
}

  1. 现在如果你

    console.log(pageProps)
    _app.js
    中,你会看到 您在当前页面组件中传递的所有道具,如下所示。
    { title: ’Title you wanna show’, description: ’Desc you wanna show’ }

  2. option + command + u
    键保存所有代码和开源页面。然后您将看到您添加的所有元标记。


0
投票

确保您从正确的位置导入 Head

import Head from 'next/head';

这是一个正在运行的示例

// on your ./pages/index(or any path here).tsx

import { GetServerSideProps } from "next";
import Head from "next/head";

const getSiteTitle = async () => {
  return Promise.resolve({
    siteTitle: "this is my website title",
  });
};
export default function Index({ siteTitle = null }: HomeProps) {
  return <Home siteTitle={siteTitle} />;
}
export const getServerSideProps: GetServerSideProps<HomeProps> = async () => {
  let siteTitle = null;

  const response = await getSiteTitle(); // any async promise here.

  siteTitle = response.siteTitle;

  if (!siteTitle) {
    return {
      notFound: true,
    };
  }

  return {
    props: { siteTitle }, // will be passed to the page component as props
  };
};

// Home must be a component, you can save this file on src/templates or src/scenes to keep the react pattern.

export type HomeProps = {
  siteTitle: string,
};
export const Home = ({ siteTitle }: HomeProps) => {
  return (
    <>
      <Head>
        <title>{siteTitle}</title>
      </Head>
      <div>
        <h1>Hello World </h1>
      </div>
    </>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.