You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在无头WordPress+WPGraphQL+Next.js中用Yoast获取页面元数据

解决无头WordPress中Next.js获取静态页面Yoast SEO元数据的问题

问题梳理

已实现博客文章的Yoast SEO元数据动态获取,但首页、关于页、联系页这类静态页面仍在手动配置标题、描述,尝试编写的WPGraphQL查询和Next.js代码未生效。

错误点分析

从你提供的代码来看,主要问题有:

  • getStaticProps中把查询返回的page数据赋值给了post变量,但组件接收的props是page,导致组件内无法获取到数据
  • WPGraphQL查询未请求seo.fullHead字段,但组件中尝试解析page.seo.fullHead,会引发报错
  • 静态页面的查询变量硬编码为contact,无法适配不同页面的动态需求
  • NextSeo配置仍为硬编码,未使用从WordPress获取的元数据

解决方案

方案1:单个页面单独处理(如首页、关于页)

以首页(pages/index.js)为例,直接查询首页的SEO数据:

import { NextSeo } from "next-seo";
import Head from "next/head";
import parse from "html-react-parser";
import { client } from "../lib/apollo";
import { gql } from "@apollo/client";
import Layout from "../components/Layout";

export default function Home({ page }) {
  const fullHead = parse(page.seo.fullHead);

  return (
    <>
      <Head>
        <link rel="icon" href="/favicon.svg" />
        {fullHead}
      </Head>
      <NextSeo
        title={page.seo.title}
        description={page.seo.metaDesc}
        openGraph={{
          url: page.seo.canonical,
          title: page.seo.title,
          description: page.seo.metaDesc,
          images: [
            {
              url: "https://url.com/images/logo.svg",
              width: 800,
              height: 600,
              alt: "x x Logo",
            },
          ],
          site_name: "x x",
        }}
      />
      <Layout>
        {/* 页面内容 */}
      </Layout>
    </>
  );
}

export async function getStaticProps() {
  const GET_HOME_PAGE = gql`
    query GetHomePage {
      page(id: "/", idType: URI) {
        seo {
          metaDesc
          title
          canonical
          fullHead
        }
      }
    }
  `;

  const response = await client.query({ query: GET_HOME_PAGE });
  const page = response?.data?.page;

  return {
    props: { page },
    // 可选:设置重验证时间,自动更新数据
    revalidate: 60,
  };
}

关于页(pages/about.js)只需要修改查询中的id为"/about"即可。

方案2:动态路由处理所有静态页面

创建pages/[pageSlug].jsx,通过动态路由匹配所有静态页面,自动获取对应SEO数据:

import { NextSeo } from "next-seo";
import Head from "next/head";
import parse from "html-react-parser";
import { client } from "../lib/apollo";
import { gql } from "@apollo/client";
import Layout from "../components/Layout";
import { useRouter } from "next/router";

export default function StaticPage({ page }) {
  const router = useRouter();
  if (router.isFallback) return <div>加载中...</div>;

  const fullHead = parse(page.seo.fullHead);

  return (
    <>
      <Head>
        <link rel="icon" href="/favicon.svg" />
        {fullHead}
      </Head>
      <NextSeo
        title={page.seo.title}
        description={page.seo.metaDesc}
        openGraph={{
          url: page.seo.canonical,
          title: page.seo.title,
          description: page.seo.metaDesc,
          images: [
            {
              url: "https://url.com/images/logo.svg",
              width: 800,
              height: 600,
              alt: "x x Logo",
            },
          ],
          site_name: "x x",
        }}
      />
      <Layout>
        {/* 渲染页面内容,比如page.content */}
        {parse(page.content)}
      </Layout>
    </>
  );
}

export async function getStaticProps({ params }) {
  const GET_STATIC_PAGE = gql`
    query GetStaticPage($slug: ID!) {
      page(id: $slug, idType: URI) {
        title
        content
        seo {
          metaDesc
          title
          canonical
          fullHead
        }
      }
    }
  `;

  // 处理首页:当slug为空时,URI为"/"
  const pageUri = params.pageSlug ? `/${params.pageSlug}` : "/";
  const response = await client.query({
    query: GET_STATIC_PAGE,
    variables: { slug: pageUri },
  });
  const page = response?.data?.page;

  return {
    props: { page },
    revalidate: 60,
  };
}

export async function getStaticPaths() {
  // 先查询所有静态页面的slug,生成预渲染路径
  const GET_ALL_PAGES = gql`
    query GetAllPages {
      pages {
        nodes {
          uri
        }
      }
    }
  `;

  const response = await client.query({ query: GET_ALL_PAGES });
  const pages = response?.data?.pages?.nodes || [];

  const paths = pages.map((page) => ({
    params: { pageSlug: page.uri.replace("/", "") || "" },
  }));

  return {
    paths,
    fallback: "blocking",
  };
}

关键注意事项

  • 确保WPGraphQL Yoast SEO插件已正确安装并激活,否则无法获取seo字段
  • 查询时必须包含需要用到的所有字段(如fullHead、metaDesc等),避免因字段缺失报错
  • 使用revalidate可以实现静态页面的增量更新,无需重新构建整个项目

内容的提问来源于stack exchange,提问作者Laicus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 15:05:30