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

如何在React或Next应用中展示应用版本号与最后更新时间?

实现方案分为两种,你可以根据需求选择

方案1:直接使用已生成的 .version 和 .last-updated 文件

第一步:调整文件输出路径

在你的 Github Actions 工作流中,将生成的两个文件输出到项目的 public 目录下,确保构建后这两个文件可以被前端直接访问。

第二步:前端读取文件内容

Next.js 服务端组件场景

直接在服务端通过文件系统读取内容,无需发起网络请求:

import fs from 'fs/promises'
import path from 'path'

// 读取构建信息
async function getBuildMeta() {
  const version = await fs.readFile(path.join(process.cwd(), 'public/.version'), 'utf8')
  const lastUpdated = await fs.readFile(path.join(process.cwd(), 'public/.last-updated'), 'utf8')
  return {
    version: version.trim(),
    lastUpdated: lastUpdated.trim()
  }
}

// 组件内使用
export default async function Footer() {
  const { version, lastUpdated } = await getBuildMeta()
  return (
    <div className="text-xs text-gray-500">
      <p>版本 v{version}</p>
      <p>最后更新:{new Date(lastUpdated).toLocaleString('zh-CN')}</p>
    </div>
  )
}

Next.js 客户端组件/普通React项目场景

通过fetch请求静态文件内容:

'use client'
import { useEffect, useState } from 'react'

export default function BuildInfo() {
  const [buildMeta, setBuildMeta] = useState({ version: '', lastUpdated: '' })

  useEffect(() => {
    Promise.all([
      fetch('/.version').then(res => res.text()),
      fetch('/.last-updated').then(res => res.text())
    ]).then(([version, lastUpdated]) => {
      setBuildMeta({
        version: version.trim(),
        lastUpdated: lastUpdated.trim()
      })
    })
  }, [])

  return (
    <span className="text-xs text-gray-500">
      v{buildMeta.version} · 更新于 {new Date(buildMeta.lastUpdated).toLocaleDateString('zh-CN')}
    </span>
  )
}

方案2:更优实现(构建时注入环境变量,推荐)

该方案不需要额外维护静态文件,性能更好、代码更简洁。

第一步:修改 Github Actions 工作流配置

在执行构建命令前,将版本号和构建时间注入为环境变量:

# 你的工作流构建步骤前添加该步骤
- name: 注入构建环境变量
  run: |
    # 读取生成的版本号写入环境变量
    echo "NEXT_PUBLIC_APP_VERSION=$(cat .version)" >> $GITHUB_ENV
    # 写入当前构建时间
    echo "NEXT_PUBLIC_BUILD_TIME=$(date -Iseconds)" >> $GITHUB_ENV
# 后续正常执行 npm run build 即可

注意:如果是普通React项目,环境变量前缀需要改为 REACT_APP_ 才能被识别;Next.js 客户端可访问的环境变量必须加 NEXT_PUBLIC_ 前缀

第二步:前端直接使用环境变量

不需要任何异步读取逻辑,直接调用即可:

export default function BuildInfo() {
  const version = process.env.NEXT_PUBLIC_APP_VERSION || '开发版'
  const buildTime = process.env.NEXT_PUBLIC_BUILD_TIME 
    ? new Date(process.env.NEXT_PUBLIC_BUILD_TIME) 
    : new Date()
  
  return (
    <div className="text-xs text-gray-500">
      版本 v{version} · 最后更新 {buildTime.toLocaleString('zh-CN')}
    </div>
  )
}

Notion 同款效果实现参考

你可以参考下面的代码实现点击版本号弹出详情的交互:

'use client'
import { useState } from 'react'

export default function NotionStyleVersion() {
  const [showPopover, setShowPopover] = useState(false)
  const version = process.env.NEXT_PUBLIC_APP_VERSION || '开发版'
  const buildTime = process.env.NEXT_PUBLIC_BUILD_TIME 
    ? new Date(process.env.NEXT_PUBLIC_BUILD_TIME) 
    : new Date()

  return (
    <div className="relative inline-block">
      <button 
        onClick={() => setShowPopover(!showPopover)}
        className="text-xs text-gray-500 hover:text-gray-800 transition-colors"
      >
        v{version}
      </button>
      {showPopover && (
        <div className="absolute bottom-8 left-0 w-64 p-3 bg-white rounded-lg shadow-lg border border-gray-100 text-sm z-50">
          <p className="font-medium mb-1">版本 v{version}</p>
          <p className="text-gray-500 text-xs">最后更新于 {buildTime.toLocaleString('zh-CN')}</p>
          <hr className="my-2" />
          <p className="text-xs text-gray-400">当前已是最新版本</p>
        </div>
      )}
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 17:54:05