Nuxt 框架在 SEO 方面的优势主要体现在以下几个方面:
<head>
标签,包括 title, meta 描述等关键 SEO 元素。Nuxt 框架内置了多个强大的 SEO 工具,让开发者可以轻松地优化他们的应用程序。让我们详细了解这些功能:
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 的占位标志文本。
Nuxt 可以自动为你的页面生成规范链接,这有助于防止重复内容问题。你可以在nuxt.config.js
中配置这个功能:
export default defineNuxtConfig({ app: { head: { link: [{ rel: 'canonical', href: 'https://example.com' }] } } })
这些语法糖能为 Nuxt 应用提供了坚实的 SEO 基础。在下一节中,我们将探讨如何使用 @nuxtjs/seo 模块来进一步增强你的 SEO 策略。
@nuxtjs/seo 是一个功能强大的 Nuxt.js 模块,专门用于优化网站的搜索引擎表现。它提供了一套全面的 SEO 工具,使开发者能够轻松实现各种 SEO 最佳实践。
@nuxtjs/seo 模块主要提供以下功能:
要使用 @nuxtjs/seo 模块,首先需要安装:
npm install @nuxtjs/seo
然后在 nuxt.config.ts
文件中添加模块:
export default defineNuxtConfig({ modules: ['@nuxtjs/seo'] })
@nuxtjs/seo 模块允许你在 nuxt.config.ts
中直接配置 SEO 设置。
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
: 网站的规范 URLname
: 网站名称description
: 网站描述defaultLocale
: 默认语言enabled
: 是否启用 site 配置(默认为 true )debug
: 是否启用调试模式(默认为 false )indexable
: 控制网站是否可以被搜索引擎索引(默认在生产环境为 true )trailingSlash
: 控制 URL 是否应该包含尾部斜杠(默认为 false ),尾斜杠应该是网站统一的,不然会出现索引页面分流的问题。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 )@nuxtjs/seo 模块允许你配置 robots.txt 文件:
export default defineNuxtConfig({ robots: { UserAgent: '*', Disallow: '/private', Allow: '/', Sitemap: 'https://example.com/sitemap.xml' } })
这将生成一个 robots.txt 文件,允许所有搜索引擎爬虫访问除 /private
目录外的所有页面,并指向你的站点地图。
站点地图配置会自动帮你生成文件路由的页面,如果你需要额外的内容,就使用 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 )
include
和 exclude
: 用于过滤要包含或排除的路由
discoverImages
和 discoverVideos
: 是否在预渲染时发现路由中的图片和视频(默认为 true )
cacheMaxAgeSeconds
: 站点地图的缓存时间(默认为 600 秒)
debug
: 是否启用调试模式(默认为 false )
内容是 SEO 的核心,Nuxt 社区当然有库来帮助你创建和管理 SEO 友好的内容。
Nuxt Content 模块是一个强大的文档驱动模块,它可以帮助你轻松管理和呈现 Markdown 、JSON 、YAML 、XML 和 CSV 文件。
npm install @nuxt/content
nuxt.config.ts
中配置:export default defineNuxtConfig({ modules: ['@nuxt/content'] })
--- 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 中。
<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>
使用规范链接( canonical URLs ):
useHead({ link: [{ rel: 'canonical', href: 'https://example.com/original-page' }] })
创建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>
在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() } } ] } })
使用服务器端渲染( SSR ): Nuxt 默认支持 SSR ,确保搜索引擎可以看到完整的页面内容。
对于动态内容,使用useFetch
或useAsyncData
,不加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 请求中非常关键的配置项!
<ClientOnly>
组件包裹仅客户端渲染的内容:<ClientOnly> <ComplexChart :data="chartData" /> </ClientOnly>
Nuxt 的 Seo 其实非常的方便,相对于 Next 都是配置形的,开发体验非常的好,且页面性能和一些用户体验上都会大于 Next ,比较中肯的说,不考虑社区问题,它几乎就是 SSR 前端框架的最佳实践。