本文概括:
- Next.js SEO优化 :用服务端组件、Streaming 渲染、
next/image和next/font提升加载速度和页面稳定性。 - SEO 配置 :
robots.txt控制抓取,sitemap.xml提供网站结构,可以主动推送Google,百度。 - 页面 metadata :设置 
title、description,使用 Open Graph 优化分享。 - 性能指标:关注 LCP ≤2.5秒,提高主要内容加载速度。
 
基本组件与 SEO 优化
在 Next.js 中,合理使用基础组件可以显著提升页面性能和 SEO 表现:
- 
服务端组件(Server Components)
- 尽量使用服务端组件,它们会在服务器直接渲染 HTML 并发送到前端,加快首次可视渲染,对 SEO 非常友好。
 
 - 
Streaming 渲染
- 使用 Streaming 渲染可以边生成边发送页面,不会影响 SEO,同时可以改善首页性能指标(如 LCP、TTFB)。
 
 - 
Image 组件
- 使用 
next/image组件加载图片,必须设置alt属性,既提升可访问性,也对 SEO 有益。 - 默认会处理 布局偏移问题(Cumulative Layout Shift,CLS) ,确保页面稳定渲染。
 
 - 使用 
 - 
Font 组件
- 使用 
next/font加载字体,可以避免 FOUT/FOIT(字体闪烁或延迟显示),同样减少布局偏移,提高用户体验和 SEO。 - 默认也会阻止布局偏移,保持页面稳定。
 
 - 使用 
 
SEO有关的配置文件
robots.txt
robots.txt 是网站根目录下的文本文件,用于告诉搜索引擎爬虫(如 Googlebot、Bingbot)哪些页面可以抓取,哪些页面不可以抓取。它是 网站爬虫控制协议(Robots Exclusion Standard) 的一部分。
在 SEO(搜索引擎优化) 中,合理设置 robots.txt 的核心目标是:
- 
确保重要页面被抓取
首页、栏目页、文章页、产品页等核心内容必须允许爬虫抓取。
 - 
阻止无关或重复内容抓取
管理后台、用户隐私页、测试页、分页参数页、打印版页面等不需要被抓取,避免浪费爬虫抓取预算(Crawl Budget)并减少重复内容问题。
 
⚠️注意:如果爬虫抓了太多低价值页面,重要页面可能抓取不够,从而影响 SEO 效果。
            
            
              makefile
              
              
            
          
          # 允许所有爬虫
User-agent: *
# 禁止抓取管理后台和用户隐私页
Disallow: /admin/
Disallow: /login/
Disallow: /cart/
Disallow: /checkout/
# 禁止抓取参数化重复内容
Disallow: /*?sort=
Disallow: /*?filter=
# Sitemap 位置(告诉爬虫网站结构)
Sitemap: <https://www.example.com/sitemap.xml>
        sitemap.xml
sitemap.xml 是一个 网站地图文件 ,主要作用是告诉搜索引擎你网站上的页面结构和更新频率,从而帮助搜索引擎 更快、更全面地抓取网站内容,对 SEO 非常重要。
robots.txt告诉爬虫哪些页面不能抓,sitemap.xml告诉爬虫 有哪些页面可以抓。
常见的几个字段如下:
| 标签 | 含义 | 
|---|---|
<loc> | 
页面 URL | 
<lastmod> | 
页面最后修改时间,爬虫可以优先抓取更新过的内容 | 
<changefreq> | 
页面更新频率(always, hourly, daily, weekly, monthly, yearly, never) | 
<priority> | 
页面抓取优先级,0~1,1 表示最重要的页面 | 
在Next.js中,可以使用 next-sitemap库,www.npmjs.com/package/nex...
参考配置即可 next-sitemap.config.js:
            
            
              arduino
              
              
            
          
          /**
 * 使用文档地址 <https://github.com/iamvishnusankar/next-sitemap>
 */
/** @type {import('next-sitemap').IConfig} */
const config = {
  siteUrl: process.env.NEXT_PUBLIC_SITE_URL || "<https://next.anqstar.com>",
  generateRobotsTxt: true,
  sitemapSize: 7000,
  generateIndexSitemap: true,
  robotsTxtOptions: {
    policies: [{ userAgent: "*", allow: "/" }],
  },
};
export default config;
        页面metadata
每个页面都需要取设置title,description等元信息:
可以参考Google的文档:developers.google.com/search/docs...
keywords 这种属性,Google 已经废弃不用了
SEO元数据
| 字段 | 作用 | 示例 | 
|---|---|---|
<title> | 
页面标题,搜索结果显示标题 | <title>我的博客 - 首页</title> | 
<meta name="description"> | 
页面描述,搜索结果摘要 | <meta name="description" content="这是我的技术博客,分享前端知识。"> | 
<meta name="keywords"> | 
页面关键词(现代SEO已很少用) | <meta name="keywords" content="前端, React, SEO"> | 
<link rel="canonical"> | 
标准化URL,避免重复内容 | <link rel="canonical" href="<https://example.com/page>"> | 
<meta name="robots"> | 
控制搜索引擎抓取和索引 | <meta name="robots" content="index,follow"> | 
Open Graph
Open Graph(简称 OG )是 Facebook提出的一套网页元数据协议 ,目的是让网页内容在社交平台(如 Facebook、LinkedIn、微信、QQ 等)分享时,能够以 结构化、漂亮的卡片形式展示,而不仅仅是一个普通链接。
主要字段如下:
| 属性 | 作用 | 示例 | 
|---|---|---|
og:title | 
分享标题 | <meta property="og:title" content="我的博客首页"> | 
og:description | 
分享描述 | <meta property="og:description" content="前端开发教程分享"> | 
og:image | 
分享缩略图 | <meta property="og:image" content="<https://example.com/share.png>"> | 
og:url | 
网页链接 | <meta property="og:url" content="<https://example.com/page>"> | 
og:type | 
内容类型(website/article/video等) | <meta property="og:type" content="website"> | 
og:site_name | 
网站名称 | <meta property="og:site_name" content="我的博客"> | 
在Next.js框架中设置metadata:
注意,需要在服务端组件中使用
静态metadata:
            
            
              arduino
              
              
            
          
          export const metadata: Metadata = {
    title: 'xxx',
    description: 'xxx',
}
        动态metadata:
            
            
              typescript
              
              
            
          
          // app/market/[id]/page.js
interface PageProps {
  params: { id: string };
  searchParams: { q?: string };
}
// 注意这里是异步函数
export async function generateMetadata(
  { params, searchParams, parent }: PageProps & { parent?: Promise<Metadata> }
): Promise<Metadata> {
  // 获取父级 metadata(可选)
  const parentMetadata = parent ? await parent : {};
  // 根据 ID 请求接口获取资源信息
  const resource = await getResourceById(params.id);
  // 从 searchParams 获取搜索关键词
  const keyword = searchParams.q;
  return {
    // 可以继承父级 title
    title: resource?.title ? `${resource.title} - ${parentMetadata.title || "资源市场"}` : parentMetadata.title,
    description: resource?.description || parentMetadata.description || "高效开发资源市场",
    openGraph: {
      title: resource?.title || parentMetadata.title,
      description: resource?.description || parentMetadata.description,
      images: [resource?.cover || "/default.png"],
    },
  };
}
// 页面组件
export default async function ResourcePage({ params, searchParams }: PageProps) {
  const resource = await getResourceById(params.id);
  return (
    <div>
      <h1>{resource?.title}</h1>
      {searchParams.q && <p>搜索关键词: {searchParams.q}</p>}
    </div>
  );
}
        Next.js Metadata 规则
在 Next.js App Router 中,可以在 template、layout、page 等页面定义 metadata。其规则如下:
- 
优先级
- 页面级 (
page) 的metadata优先级最高,会覆盖同名的父级layout或templatemetadata。 layout或template中定义的metadata会作为默认值,如果子级没有覆盖,则会继承。
 - 页面级 (
 - 
合并方式
- 
合并使用 浅合并(shallow merge) :
- 对象类型字段(如 
openGraph、twitter)会被子级直接覆盖,不会递归合并。 - 没有在子级定义的字段,会直接继承父级。
 
 - 对象类型字段(如 
 
 - 
 - 
字段丢失注意
- 如果子级 
metadata对象中没有某些字段,这些字段会从父级继承。 - 但如果子级定义了该字段,则父级同名字段会被覆盖,原值不会保留。
 
 - 如果子级 
 
例子:
            
            
              arduino
              
              
            
          
          // layout.tsx
export const metadata = {
  title: "我的网站",
  description: "网站默认描述",
  openGraph: {
    type: "website",
    images: ["/default.png"],
  },
};
// page.tsx
export const metadata = {
  title: "首页",
  openGraph: {
    title: "首页 OG", // 会覆盖 layout 的 openGraph
  },
};
        - 最终合并结果:
 
            
            
              arduino
              
              
            
          
          {
  title: "首页",
  description: "网站默认描述", // 继承自 layout
  openGraph: {
    title: "首页 OG", // 覆盖了整个 openGraph 对象
    // images 字段丢失了,因为浅合并不会保留 layout 的 images
  }
}
        LCP指标
LCP(Largest Contentful Paint) 是 Web Vitals 中衡量页面加载性能的核心指标之一,用来衡量 页面主要内容加载完成的时间,也就是 用户 能看到页面最大可视内容(通常是图片、视频或大块文本) 的时间,Google 推荐的 LCP 理想值:
| 体验等级 | LCP 时间 | 
|---|---|
| 优秀 | ≤ 2.5 秒 | 
| 需要改进 | 2.5 -- 4 秒 | 
| 差 | > 4 秒 | 
在Next.js中,可以多使用Next.js 提供 next/image 组件,自带优化功能:
- 自动压缩图片
 - 支持 WebP/AVIF 等现代格式
 - 懒加载(lazy loading)可选
 priority属性可提升 LCP 图片加载速度
            
            
              javascript
              
              
            
          
          import Image from 'next/image'
export default function Hero() {
  return (
    <div>
      <h1>欢迎访问我的博客</h1>
      <Image
        src="/hero.jpg"
        alt="首页大图"
        width={1200}
        height={600}
        priority
      />
    </div>
  )
}
        其他优化SEO的办法
直接给Google,百度提交Sitemap文件