You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js如何为favicon及启动屏图片在构建时自动添加哈希后缀

Next.js PWA静态资源自动追加哈希的实现方案

方案1:使用Next.js原生资源导入(最推荐,无需额外配置)

Next.js原生支持导入图片、图标类静态资源,生产构建时会自动为导入的资源生成带内容哈希的路径,同时自动处理资源的输出位置,兼容next build和next export两种场景。

操作步骤:

  1. 把存放favicon和启动屏的assets文件夹从public目录移出,放到项目根目录或者src目录下(public目录下的资源默认会透传不做哈希处理)
  2. 在_app.tsx头部导入所有需要用到的静态资源:
// 导入favicon资源
import faviconIco from '@/assets/icons/favicon.ico'
import favicon192Png from '@/assets/icons/favicon-192.png'
import favicon160Png from '@/assets/icons/favicon-160.png'
import favicon96Png from '@/assets/icons/favicon-96.png'
import favicon64Png from '@/assets/icons/favicon-64.png'
import favicon32Png from '@/assets/icons/favicon-32.png'
import favicon16Png from '@/assets/icons/favicon-16.png'
import favicon57Png from '@/assets/icons/favicon-57.png'
import favicon114Png from '@/assets/icons/favicon-114.png'
import favicon72Png from '@/assets/icons/favicon-72.png'
import favicon144Png from '@/assets/icons/favicon-144.png'
import favicon60Png from '@/assets/icons/favicon-60.png'
import favicon120Png from '@/assets/icons/favicon-120.png'
import favicon76Png from '@/assets/icons/favicon-76.png'
import favicon152Png from '@/assets/icons/favicon-152.png'
import favicon180Png from '@/assets/icons/favicon-180.png'
import browserconfigXml from '@/assets/icons/browserconfig.xml'

// 导入启动屏资源
import iphone5Splash from '@/assets/splashscreens/iphone5_splash.png'
import iphone6Splash from '@/assets/splashscreens/iphone6_splash.png'
import iphoneplusSplash from '@/assets/splashscreens/iphoneplus_splash.png'
import iphonexSplash from '@/assets/splashscreens/iphonex_splash.png'
import iphonexrSplash from '@/assets/splashscreens/iphonexr_splash.png'
import iphonexsmaxSplash from '@/assets/splashscreens/iphonexsmax_splash.png'
import ipadSplash from '@/assets/splashscreens/ipad_splash.png'
import ipadpro1Splash from '@/assets/splashscreens/ipadpro1_splash.png'
import ipadpro3Splash from '@/assets/splashscreens/ipadpro3_splash.png'
import ipadpro2Splash from '@/assets/splashscreens/ipadpro2_splash.png'
  1. 替换Head组件内的硬编码路径为导入的变量即可:
<Head>
  {/* favicon配置 */}
  <link rel="shortcut icon" href={faviconIco} />
  <link rel="icon" sizes="16x16 32x32 64x64" href={faviconIco} />
  <link rel="icon" type="image/png" sizes="196x196" href={favicon192Png} />
  <link rel="icon" type="image/png" sizes="160x160" href={favicon160Png} />
  <link rel="icon" type="image/png" sizes="96x96" href={favicon96Png} />
  <link rel="icon" type="image/png" sizes="64x64" href={favicon64Png} />
  <link rel="icon" type="image/png" sizes="32x32" href={favicon32Png} />
  <link rel="icon" type="image/png" sizes="16x16" href={favicon16Png} />
  <link rel="apple-touch-icon" href={favicon57Png} />
  <link rel="apple-touch-icon" sizes="114x114" href={favicon114Png} />
  <link rel="apple-touch-icon" sizes="72x72" href={favicon72Png} />
  <link rel="apple-touch-icon" sizes="144x144" href={favicon144Png} />
  <link rel="apple-touch-icon" sizes="60x60" href={favicon60Png} />
  <link rel="apple-touch-icon" sizes="120x120" href={favicon120Png} />
  <link rel="apple-touch-icon" sizes="76x76" href={favicon76Png} />
  <link rel="apple-touch-icon" sizes="152x152" href={favicon152Png} />
  <link rel="apple-touch-icon" sizes="180x180" href={favicon180Png} />
  <meta name="msapplication-TileImage" content={favicon144Png} />
  <meta name="msapplication-config" content={browserconfigXml} />

  {/* 启动屏配置 */}
  <link href={iphone5Splash} media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" />
  <link href={iphone6Splash} media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" />
  <link href={iphoneplusSplash} media="(device-width: 621px) and (device-height: 1104px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image" />
  <link href={iphonexSplash} media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image" />
  <link href={iphonexrSplash} media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" />
  <link href={iphonexsmaxSplash} media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3)" rel="apple-touch-startup-image" />
  <link href={ipadSplash} media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" />
  <link href={ipadpro1Splash} media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" />
  <link href={ipadpro3Splash} media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" />
  <link href={ipadpro2Splash} media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2)" rel="apple-touch-startup-image" />
</Head>

方案2:自定义webpack配置(适合不想调整资源存放位置的场景)

如果你不想把assets文件夹移出public目录,可以通过修改next.config.js的webpack配置,为指定路径的资源添加哈希处理:

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config) => {
    config.module.rules.push({
      test: /\.(png|ico|xml)$/i,
      include: [
        /public\/assets\/icons/,
        /public\/assets\/splashscreens/
      ],
      type: 'asset/resource',
      generator: {
        filename: 'static/assets/[name].[contenthash][ext]'
      }
    })
    return config
  }
}

module.exports = nextConfig

配置完成后同样需要把资源作为模块导入到_app.tsx中使用,和方案1的第二步、第三步操作一致。

方案3:后置脚本替换(适合完全不想修改现有业务代码的场景)

如果不想调整现有代码的硬编码路径,可以写一个Node.js脚本,在next export执行完成后触发:

  • 遍历out目录下所有HTML文件,匹配你配置的静态资源路径
  • 计算对应资源文件的哈希值,重命名资源文件为带哈希的格式
  • 替换HTML中的对应资源路径为带哈希的版本
  • 可以把脚本挂在package.json的postexport钩子上自动执行

注意事项

如果项目使用了next-pwa插件,需要把这些带哈希的静态资源添加到PWA的缓存规则中,避免资源更新后缓存不生效的问题。

内容的提问来源于stack exchange,提问作者Ramesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 13:36:02