NextJS V12.3.0中next/image组件alt属性重复显示问题
问题描述
使用Next.js的next/image组件渲染CDN图片,已正确设置alt属性,图片可正常显示,但在谷歌缓存的纯文本版本中,alt文本重复出现(例如原alt为"Some Image ALT",显示为"Some Image ALTSome Image ALT")。
代码示例
<div className="videoCard__image"> <Image src={bannerUrl} alt={titleLabel} layout="responsive" width={123.6} height={120} className="videoCard__image--banner" priority={loadPriority} sizes="33vw" quality={80} /> <PlayCircleOutline className="videoCard__image--play-icon" /> </div>
问题根源
next/image组件会渲染两个<img>标签:
- 一个用于正常加载场景的优化版
<img> - 一个放在
<noscript>标签内的降级<img>,用于禁用JS的环境
这两个<img>都会继承你设置的alt属性值,而谷歌缓存的纯文本模式会解析页面中所有内容(包括<noscript>内的元素),导致两个alt文本被叠加显示,造成重复。
解决方案
方案1:自定义Image组件,清空noscript内img的alt
创建一个封装组件,通过useEffect修改<noscript>内img的alt为空字符串,避免重复显示:
import { useEffect, useRef } from 'react'; import NextImage from 'next/image'; const CustomImage = (props) => { const containerRef = useRef(null); useEffect(() => { if (!containerRef.current) return; const noscriptImg = containerRef.current.querySelector('noscript img'); if (noscriptImg) noscriptImg.alt = ''; }, []); return ( <div ref={containerRef}> <NextImage {...props} /> </div> ); }; export default CustomImage;
之后在项目中用CustomImage替代原next/image组件即可。
方案2:升级到Next.js v13+(App Router)
Next.js v13+的next/image组件(App Router版本)重构了渲染逻辑,不再在<noscript>内重复渲染带相同alt的img标签,从根源解决问题。升级后使用新版组件:
import Image from 'next/image'; <div className="videoCard__image"> <Image src={bannerUrl} alt={titleLabel} width={123.6} height={120} className="videoCard__image--banner" priority={loadPriority} sizes="33vw" quality={80} /> <PlayCircleOutline className="videoCard__image--play-icon" /> </div>
注意:新版组件移除了layout属性,响应式通过sizes和容器样式控制。
验证方式
修改后查看页面渲染后的HTML,确认:
- 方案1中
<noscript>内的imgalt为空 - 方案2中无重复的img标签
随后提交页面到谷歌搜索控制台,等待缓存更新后查看纯文本版本,确认alt文本仅显示一次。
内容的提问来源于stack exchange,提问作者Yatin
相关产品推荐
相关产品推荐

