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

Next.js页面meta标签无法被爬虫抓取的问题求助

问题解决:Next.js页面Meta标签无法被爬虫识别

问题背景

使用Next.js + TypeStack开发,通过MongoDB获取数据,浏览器开发者工具中能正常看到页面的title和meta描述,但Bing搜索引擎检测提示标题和Meta描述标签缺失,问题根源在于当前采用的客户端数据获取方式。

核心原因

当前代码用useEffect + axios做客户端渲染,数据获取和Meta标签渲染都依赖客户端JS执行。但绝大多数搜索引擎爬虫(包括Bing的URL检测工具)不会执行页面JS,只会抓取服务器返回的初始HTML内容——初始HTML里没有Meta标签,自然被判定为缺失。

解决方案

改用Next.js提供的**服务端渲染(SSR)或静态站点生成(SSG)**方案,在服务器端提前获取数据并渲染出包含完整Meta标签的HTML,确保爬虫能直接抓取到所需内容。

方案1:使用getServerSideProps(服务端渲染)

适合内容频繁更新的场景,每次请求都会在服务器端获取最新数据并渲染页面。

修改[pid].tsx代码如下:

import React from 'react'
import { useRouter } from 'next/router';
import Head from 'next/head';
import Navbar from '@/sections/Navbar';
import BlogBody from '@/sections/BlogBody';
import Footer from '@/sections/Footer';
import { IBlog } from '@/schema/blogSchema';
import Error from '@/components/Error';
import Loading from '@/components/Loading';
// 直接在服务端调用数据库查询逻辑,无需通过客户端API
import { searchExactBlog } from '@/services/blogService';

interface BlogProps {
  currentDoc: IBlog | null;
  isError: boolean;
}

const Blog = ({ currentDoc, isError }: BlogProps) => {
  const _router = useRouter();
  
  // 路由过渡阶段显示加载
  if (_router.isFallback) {
    return <Loading />;
  }

  return (
    <>
      <Head>
        <title>{currentDoc ? `${currentDoc.title} - Wayne Blogs` : 'Wayne Blogs'}</title>
        <meta name="description" content={currentDoc?.desc || 'Wayne Blogs - 分享技术与思考'} />
        <meta name="author" content={currentDoc?.author || 'Wayne'} />
        <link rel="shortcut icon" href="/favicon.svg" type="image/x-icon" />
      </Head>

      <Navbar />
      <main>
        {isError ? (
          <Error text="获取文章失败,请刷新页面重试" />
        ) : currentDoc ? (
          <BlogBody blogInfo={currentDoc} />
        ) : (
          <Error text="该文章不存在" />
        )}
        <Footer />
      </main>
    </>
  )
}

// 服务端数据获取逻辑
export async function getServerSideProps(context: any) {
  const { pid } = context.params;
  let currentDoc: IBlog | null = null;
  let isError = false;

  try {
    const result = await searchExactBlog(pid);
    currentDoc = result.data[0] || null;
  } catch (err) {
    isError = true;
  }

  return {
    props: { currentDoc, isError }
  }
}

export default Blog

方案2:使用getStaticProps + getStaticPaths(静态站点生成)

适合内容不频繁更新的博客场景,提前生成静态页面,性能更优。

修改[pid].tsx代码如下:

import React from 'react'
import Head from 'next/head';
import Navbar from '@/sections/Navbar';
import BlogBody from '@/sections/BlogBody';
import Footer from '@/sections/Footer';
import { IBlog } from '@/schema/blogSchema';
import Error from '@/components/Error';
import { getAllBlogIds, getBlogById } from '@/services/blogService';

interface BlogProps {
  currentDoc: IBlog;
}

const Blog = ({ currentDoc }: BlogProps) => {
  return (
    <>
      <Head>
        <title>{`${currentDoc.title} - Wayne Blogs`}</title>
        <meta name="description" content={currentDoc.desc} />
        <meta name="author" content={currentDoc.author} />
        <link rel="shortcut icon" href="/favicon.svg" type="image/x-icon" />
      </Head>

      <Navbar />
      <main>
        <BlogBody blogInfo={currentDoc} />
        <Footer />
      </main>
    </>
  )
}

// 获取所有需要静态生成的博客ID
export async function getStaticPaths() {
  const paths = await getAllBlogIds(); // 返回格式:[{ params: { pid: 'blog-1' } }, ...]
  
  return {
    paths,
    fallback: 'blocking' // 未提前生成的页面会在首次请求时自动生成
  }
}

// 根据ID获取数据并生成静态页面
export async function getStaticProps(context: any) {
  const { pid } = context.params;
  const currentDoc = await getBlogById(pid);

  // 文章不存在则返回404
  if (!currentDoc) {
    return { notFound: true }
  }

  return {
    props: { currentDoc },
    revalidate: 86400 // 每天自动重新生成页面,更新内容
  }
}

export default Blog

关键注意事项

  • 禁止在客户端通过useEffect获取数据后渲染Meta标签,爬虫无法识别这类动态添加的内容。
  • 服务端获取数据时,直接调用数据库查询逻辑,无需通过客户端API请求,减少网络开销。
  • 使用服务端/静态生成方案时,组件直接接收服务端传递的props,无需再用useState管理数据状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 22:44:58