V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
leia
V2EX  ›  搜索引擎优化

Nuxt 的 SEO 实践

  •  
  •   leia · 16 天前 · 622 次点击

    第 9 章:Nuxt 的 SEO 实践

    1. 引言

    Nuxt 框架在 SEO 方面的优势主要体现在以下几个方面:

    1. 服务器端渲染(SSR): Nuxt 默认支持 SSR,这意味着搜索引擎爬虫可以直接看到完整的页面内容,而不需要执行 JavaScript 。
    2. 内置的元标签管理: Nuxt 提供了比 Next 更简单的 API 来管理<head>标签,包括 title, meta 描述等关键 SEO 元素。
    3. 静态站点生成(SSG): 通过 nuxt generate 命令,可以生成完全静态的网站,进一步提高了性能和 SEO 友好度。

    2. Nuxt 内置的 SEO 功能

    Nuxt 框架内置了多个强大的 SEO 工具,让开发者可以轻松地优化他们的应用程序。让我们详细了解这些功能:

    useHead 和 useSeoMeta 组合式函数

    Nuxt 有 2 个组合式函数,使得管理头部元标签变得更加简单和灵活:

    useHead: 这个函数允许你动态设置<head>标签的内容。

    useHead({
      title: 'My Amazing Site',
      meta: [{ name: 'description', content: 'This is my amazing site built with Nuxt 3' }],
      link: [{ rel: 'canonical', href: 'https://example.com' }]
    })
    

    useSeoMeta: 这个函数专门用于设置 SEO 相关的元标签。

    useSeoMeta({
      title: 'My Amazing Site',
      ogTitle: 'My Amazing Site - The Best Site Ever',
      description: 'This is my amazing site built with Nuxt 3',
      ogDescription: 'Experience the best site ever built with Nuxt 3',
      ogImage: 'https://example.com/image.jpg'
    })
    

    这两者最终达成的效果是一致的,都是在 head 里面去设置源数据标签,并没有很特殊的区别使用场景,只是有 ts 类型和进行结构简化了当使用 useSeoMeta 的时候。

    动态元标签管理

    Nuxt 允许你根据页面内容或路由动态地更新元标签。这对于创建独特的、针对每个页面优化的元描述和标题非常有用。

    const route = useRoute()
    
    useHead(() => ({
      title: `${route.params.productName} - Our Store`,
      meta: [
        { name: 'description', content: `Learn more about ${route.params.productName} and purchase it from our store.` }
      ]
    }))
    

    这个场景的考虑是这样的,因为有 lazy 标识,会直接进入页面进行客户端渲染,但因为是新进入页面此时请求还没有拿到数据,title 在浏览器上方显示的就是undefined-product, 而当请求结束后,因为data是一个响应式对象,会直接更新页面的title

    const { data } = await useFetch('/api/products/[id]', {
      lazy: true
    })
    useHead(() => ({
      title: `${data.title}-product`
    }))
    

    这只是个小 demo ,更好的做法是,当没数据的时候,有一个 title 的占位标志文本。

    自动生成规范链接( canonical URLs )

    Nuxt 可以自动为你的页面生成规范链接,这有助于防止重复内容问题。你可以在nuxt.config.js中配置这个功能:

    export default defineNuxtConfig({
      app: {
        head: {
          link: [{ rel: 'canonical', href: 'https://example.com' }]
        }
      }
    })
    

    这些语法糖能为 Nuxt 应用提供了坚实的 SEO 基础。在下一节中,我们将探讨如何使用 @nuxtjs/seo 模块来进一步增强你的 SEO 策略。

    3. @nuxtjs/seo 模块

    @nuxtjs/seo 是一个功能强大的 Nuxt.js 模块,专门用于优化网站的搜索引擎表现。它提供了一套全面的 SEO 工具,使开发者能够轻松实现各种 SEO 最佳实践。

    功能介绍和使用方法

    @nuxtjs/seo 模块主要提供以下功能:

    1. 自动生成和管理元标签
    2. 创建结构化数据( Schema.org
    3. 生成站点地图( Sitemap )
    4. 配置 robots.txt
    5. 提供动态 SEO 规则生成

    要使用 @nuxtjs/seo 模块,首先需要安装:

    npm install @nuxtjs/seo
    

    然后在 nuxt.config.ts 文件中添加模块:

    export default defineNuxtConfig({
      modules: ['@nuxtjs/seo']
    })
    

    在 nuxt.config 中配置 SEO

    @nuxtjs/seo 模块允许你在 nuxt.config.ts 中直接配置 SEO 设置。

    site 配置

    site 配置定义了网站的基本信息,这是在使用 nuxtjs/seo 必须的:

    export default defineNuxtConfig({
      site: {
        url: 'https://example.com',
        name: 'My Awesome Site',
        description: 'This is my awesome website',
        defaultLocale: 'en',
        enabled: true,
        debug: false,
        indexable: true,
        trailingSlash: false
      }
    })
    

    主要参数说明:

    • url: 网站的规范 URL
    • name: 网站名称
    • description: 网站描述
    • defaultLocale: 默认语言
    • enabled: 是否启用 site 配置(默认为 true )
    • debug: 是否启用调试模式(默认为 false )
    • indexable: 控制网站是否可以被搜索引擎索引(默认在生产环境为 true )
    • trailingSlash: 控制 URL 是否应该包含尾部斜杠(默认为 false ),尾斜杠应该是网站统一的,不然会出现索引页面分流的问题。

    schemaOrg 配置

    schemaOrg 配置用于生成结构化数据也就是ld-json

    export default defineNuxtConfig({
      schemaOrg: {
        identity: {
          type: 'Organization',
          name: 'Example Company',
          url: 'https://example.com',
          logo: 'https://example.com/logo.png'
        },
        defaults: true,
        minify: true,
        reactive: false,
        enabled: true,
        debug: false
      }
    })
    

    主要参数说明:

    • identity: 定义网站或组织的身份信息
    • defaults: 是否启用默认的 Schema.org 设置(默认为 true )
    • minify: 是否压缩 Schema.org 输出(默认在生产环境为 true )
    • reactive: 是否启用客户端反应性(默认在开发环境或非 SSR 模式下为 true )
    • enabled: 是否启用 Schema.org (默认为 true )
    • debug: 是否启用调试模式(默认为 false )

    robots.txt 配置

    @nuxtjs/seo 模块允许你配置 robots.txt 文件:

    export default defineNuxtConfig({
      robots: {
        UserAgent: '*',
        Disallow: '/private',
        Allow: '/',
        Sitemap: 'https://example.com/sitemap.xml'
      }
    })
    

    这将生成一个 robots.txt 文件,允许所有搜索引擎爬虫访问除 /private 目录外的所有页面,并指向你的站点地图。

    sitemap 配置

    站点地图配置会自动帮你生成文件路由的页面,如果你需要额外的内容,就使用 sources 配置, 添加一个 Nuxt 的 SeverApi 返回额外的结果。

    export default defineNuxtConfig({
      sitemap: {
        enabled: true,
        sortEntries: true,
        sources: ['/api/sitemap-urls'],
        excludeAppSources: false,
        autoLastmod: true,
        sitemaps: false,
        defaultSitemapsChunkSize: 1000,
        include: ['/**'],
        exclude: ['/admin/**'],
        xsl: '/__sitemap__/style.xsl',
        discoverImages: true,
        discoverVideos: true,
        sitemapName: 'sitemap.xml',
        cacheMaxAgeSeconds: 600,
        sitemapsPathPrefix: '/__sitemap__/',
        debug: false
      }
    })
    

    主要参数说明:

    • enabled: 是否生成站点地图(默认为 true )

    • sortEntries: 是否对站点地图条目进行排序(默认为 true )

    • sources: 用于站点地图的数据源

      // server/api/__sitemap__/urls.ts 通常在这个位置定义
      import { defineSitemapEventHandler } from '#imports'
      import { characterUrls } from '~/characterUrls'
      
      export default defineSitemapEventHandler(async () => {
        const internalLinks = await $fetch('/api/internal-links')
        if (internalLinks) {
          const internalLinksNodes = internalLinks.map((link) =>
            asSitemapUrl({ loc: link, lastmod: new Date().toISOString(), priority: 0.8 })
          )
          return [...internalLinksNodes, ...characterUrls]
        }
        return []
      })
      
    • autoLastmod: 是否自动检测每个 URL 的最后修改日期(默认为 false )

    • sitemaps: 是否生成多个站点地图(默认为 false )

    • includeexclude: 用于过滤要包含或排除的路由

    • discoverImagesdiscoverVideos: 是否在预渲染时发现路由中的图片和视频(默认为 true )

    • cacheMaxAgeSeconds: 站点地图的缓存时间(默认为 600 秒)

    • debug: 是否启用调试模式(默认为 false )

    4. Nuxt Content

    内容是 SEO 的核心,Nuxt 社区当然有库来帮助你创建和管理 SEO 友好的内容。

    使用 Nuxt Content 模块管理 SEO 友好的内容

    Nuxt Content 模块是一个强大的文档驱动模块,它可以帮助你轻松管理和呈现 Markdown 、JSON 、YAML 、XML 和 CSV 文件。

    1. 安装 Nuxt Content:
    npm install @nuxt/content
    
    1. nuxt.config.ts中配置:
    export default defineNuxtConfig({
      modules: ['@nuxt/content']
    })
    
    1. 创建 SEO 友好的内容:
    ---
    sitemap:
      loc: /agreement/community-guidelines
    title: 'My Amazing Blog Post'
    description: 'This is a blog post about amazing things'
    date: '2023-05-20'
    ---
    
    // 内容
    

    这个 sitemap 的配置项,会自动把这个链接添加到 Sitemap 中。

    1. 在组件中使用内容:
    <script setup>
    const { data } = await useAsyncData('home', () => queryContent('/').find())
    </script>
    
    <template>
      <ContentList v-slot="{ list }">
        <div v-for="article in list" :key="article._path">
          <h2>{{ article.title }}</h2>
          <p>{{ article.description }}</p>
        </div>
      </ContentList>
    </template>
    

    5. 常见 SEO 问题及解决方案

    处理重复内容

    使用规范链接( canonical URLs ):

    useHead({
      link: [{ rel: 'canonical', href: 'https://example.com/original-page' }]
    })
    

    管理 404 和 301 重定向

    1. 创建自定义 404 页面:

    创建pages/404.vue文件:

    <template>
      <div>
        <h1>404 - Page Not Found</h1>
        <p>Sorry, the page you are looking for does not exist.</p>
        <NuxtLink to="/">Go back to homepage</NuxtLink>
      </div>
    </template>
    
    <script setup>
    useHead({
      title: '404 - Page Not Found',
      meta: [{ name: 'robots', content: 'noindex' }]
    })
    </script>
    
    1. 实现 301 重定向:

    nuxt.config.ts中配置重定向:

    export default defineNuxtConfig({
      nitro: {
        handlers: [
          {
            route: '/old-page',
            handler: (event) => {
              event.node.res.writeHead(301, { Location: '/new-page' })
              event.node.res.end()
            }
          }
        ]
      }
    })
    

    解决 JavaScript 渲染内容的 SEO 挑战

    1. 使用服务器端渲染( SSR ): Nuxt 默认支持 SSR ,确保搜索引擎可以看到完整的页面内容。

    2. 对于动态内容,使用useFetchuseAsyncData,不加lazy的配置项就是在任何情况下都 ssr 渲染。加了之后意味着如果是通过 Nuxt 本身的 路由方式跳转过来的时候,会直接先进入页面,然后变成客户端渲染。而这对于爬虫是没有影响的:

    <script setup>
    const { data } = await useFetch('/api/products')
    </script>
    
    <template>
      <div v-for="product in data" :key="product.id">
        <h2>{{ product.name }}</h2>
        <p>{{ product.description }}</p>
      </div>
    </template>
    

    这一段内容本来应该是 Nuxt 里面最重要的一部分,但我们这个章节是讲 SEO~,就稍微了解一下 lazy 这个对于在 Nuxt 请求中非常关键的配置项!

    1. 使用<ClientOnly>组件包裹仅客户端渲染的内容:
    <ClientOnly>
      <ComplexChart :data="chartData" />
    </ClientOnly>
    

    6. 结论

    Nuxt 的 Seo 其实非常的方便,相对于 Next 都是配置形的,开发体验非常的好,且页面性能和一些用户体验上都会大于 Next ,比较中肯的说,不考虑社区问题,它几乎就是 SSR 前端框架的最佳实践。

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2824 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 07:02 · PVG 15:02 · LAX 00:02 · JFK 03:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.