Next.js>13.3启用appDir后,如何添加<link>标签到<head>
在Next.js 13.4 App Router中添加标签到的方案
1. 利用Metadata的links属性(官方推荐)
Next.js App Router的Metadata机制完全支持添加标签,你可能之前没注意到links这个配置项。它可以在根布局或页面组件中定义:
- 全局生效的标签:在
app/layout.tsx里定义根Metadata,所有页面都会继承这些标签:
import type { Metadata } from 'next' export const metadata: Metadata = { links: [ { rel: 'preconnect', href: 'https://fonts.googleapis.com' }, { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap' } ] } export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="zh-CN"> <body>{children}</body> </html> ) }
- 仅首页生效的标签:直接在
app/page.tsx中定义页面级Metadata,它会和根Metadata合并,且SSG模式下会静态生成首页对应的标签:
import type { Metadata } from 'next' export const metadata: Metadata = { links: [ { rel: 'canonical', href: 'https://your-domain.com/' }, { rel: 'alternate', href: 'https://your-domain.com/zh', hreflang: 'zh' } ] } export default function Home() { return <h1>首页</h1> }
2. 动态生成标签(适配复杂场景)
如果需要根据路由或其他条件动态生成标签,且要适配SSG,可以使用generateMetadata函数。比如仅在特定路由下添加标签:
import type { Metadata, ResolvingMetadata } from 'next' export async function generateMetadata( { params, searchParams }: { params: { id: string }, searchParams: { [key: string]: string | string[] | undefined } }, parent: ResolvingMetadata ): Promise<Metadata> { // 获取父级Metadata并合并 const previousLinks = (await parent).links || [] // 仅在当前页面执行时添加特定标签 return { links: [ ...previousLinks, { rel: 'preload', href: '/hero-image.jpg', as: 'image' } ] } } export default function Home() { return <h1>首页</h1> }
3. 客户端动态添加(不推荐用于SSG首屏场景)
如果上述方法不满足需求,也可以在客户端组件中动态创建标签,但注意这会在客户端渲染时才添加,SSG页面首次加载时不会包含这些标签,适合非首屏依赖的场景:
'use client' import { useEffect } from 'react' export default function Home() { useEffect(() => { const link = document.createElement('link') link.rel = 'preconnect' link.href = 'https://cdn.example.com' document.head.appendChild(link) return () => document.head.removeChild(link) }, []) return <h1>首页</h1> }
内容的提问来源于stack exchange,提问作者villasv
相关产品推荐
相关产品推荐

