Next.js 页脚集成 Wakatime 统计 (Cloudflare Worker API)
本教程将指导您完成一个实用的功能:在您的 Next.js 应用的页脚动态显示来自 Wakatime 的编程时长统计。为了安全地管理您的 Wakatime API Key,我们将使用 Cloudflare Workers 作为中间 API 服务。
学习目标
- 创建一个 Cloudflare Worker 来代理 Wakatime API 请求。
- 在 Cloudflare Worker 中安全地存储和使用 Wakatime API Key。
- 在 Next.js 组件中调用 Cloudflare Worker API。
- 在应用页脚展示获取到的 Wakatime 数据。
前提条件
- 拥有一个 Wakatime 账户及对应的 API Key。
- 拥有一个 Cloudflare 账户。
- 熟悉 Next.js 和 React 的基础知识。
- Node.js 和 npm/yarn 已安装。
- 推荐安装 Cloudflare 的
wrangler
CLI 工具 (可选,也可以通过 Cloudflare Dashboard 操作)。
步骤概览
- 创建 Cloudflare Worker 项目
- 编写 Worker 逻辑以获取 Wakatime 数据
- 配置并部署 Cloudflare Worker
- 在 Next.js 中创建或修改 Footer 组件
- 在 Footer 组件中调用 Worker API 并显示数据
步骤 1: 创建 Cloudflare Worker 项目
您可以通过 Cloudflare Dashboard 或使用 wrangler
CLI 来创建 Worker。
使用 Wrangler CLI (推荐):
# 安装 wrangler (如果尚未安装)npm install -g wrangler
# 登录 wranglerwrangler login
# 创建新的 Worker 项目wrangler init my-wakatime-workercd my-wakatime-worker
这会创建一个包含 wrangler.toml
(配置文件) 和 src/index.js
(或 index.ts
,Worker 代码) 的项目。
通过 Cloudflare Dashboard:
- 登录 Cloudflare Dashboard。
- 导航到 “Workers & Pages”。
- 点击 “Create application”,然后选择 “Create Worker”。
- 给您的 Worker 一个唯一的名称 (例如
wakatime-api-proxy
),然后点击 “Deploy”。 - 点击 “Edit code” 进入在线编辑器。
步骤 2: 编写 Worker 逻辑以获取 Wakatime 数据
打开 src/index.js
(或您在 Dashboard 中编辑的文件),并替换为以下内容:
export default { async fetch(request, env, ctx) { // 允许所有来源的 CORS 请求 (在生产环境中您可能希望更严格) const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, HEAD, POST, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type', }; // 处理 OPTIONS 预检请求 if (request.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders }); } // 从环境变量中获取 Wakatime API Key const WAKATIME_API_KEY = env.WAKATIME_API_KEY; if (!WAKATIME_API_KEY) { return new Response( JSON.stringify({ error: 'Wakatime API key not configured in Worker environment' }), { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' }, } ); } // Wakatime API URL // 您可以根据需要调整 range 参数, e.g., last_7_days, last_30_days, last_6_months, last_year const wakatimeUrl = `https://wakatime.com/api/v1/users/current/all_time_since_today?api_key=${WAKATIME_API_KEY}`; try { const response = await fetch(wakatimeUrl); if (!response.ok) { const errorText = await response.text(); console.error(`Wakatime API error: ${response.status} ${errorText}`); return new Response( JSON.stringify({ error: 'Failed to fetch data from Wakatime API', details: errorText }), { status: response.status, headers: { ...corsHeaders, 'Content-Type': 'application/json' }, } ); } const data = await response.json(); // 返回 Wakatime 数据 return new Response(JSON.stringify(data), { headers: { ...corsHeaders, 'Content-Type': 'application/json' }, }); } catch (error) { console.error('Error fetching Wakatime data:', error); return new Response( JSON.stringify({ error: 'Internal server error in Worker', details: error.message }), { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' }, } ); } },};
代码解释:
- CORS Headers:
corsHeaders
用于允许跨域请求,这在从您的 Next.js 应用 (可能在不同域名或本地开发服务器) 调用 Worker 时是必需的。 - Environment Variable:
env.WAKATIME_API_KEY
用于从 Worker 的环境变量中安全地读取您的 Wakatime API Key。切勿将 API Key硬编码到代码中。 - Wakatime API Call: 使用
fetch
调用 Wakatime 的summaries
API 端点。 - Error Handling: 包含对 API Key 未配置、Wakatime API 调用失败以及其他潜在错误的检查。
步骤 3: 配置并部署 Cloudflare Worker
1. 添加 Wakatime API Key 到环境变量:
-
使用 Wrangler CLI: 在
wrangler.toml
文件中,您可以定义 secrets。首先,通过命令行设置 secret:Terminal window # 将 YOUR_WAKATIME_API_KEY 替换为您的真实 API Keywrangler secret put WAKATIME_API_KEYWrangler 会提示您输入 secret 值。
-
通过 Cloudflare Dashboard:
- 导航到您的 Worker。
- 点击 “Settings” -> “Variables”。
- 在 “Environment Variables” 部分,点击 “Add variable”。
- 设置 “Variable name” 为
WAKATIME_API_KEY
。 - 设置 “Value” 为您的 Wakatime API Key。
- 勾选 “Encrypt” (推荐)。
- 点击 “Save”。
2. 配置 wrangler.toml
(如果使用 Wrangler):
确保您的 wrangler.toml
文件类似如下 (根据您的项目名称调整 name
):
name = "my-wakatime-worker" # 替换为您的 Worker 名称main = "src/index.js" # 或 src/index.tscompatibility_date = "YYYY-MM-DD" # 使用您创建项目时的日期或更新到最新
# 如果您想为 Worker 设置自定义域名/路由,可以在这里配置或在 Dashboard 中配置# [triggers]# routes = [ "your-domain.com/api/wakatime-stats/*" ]
3. 部署 Worker:
-
使用 Wrangler CLI:
Terminal window wrangler deploy部署成功后,Wrangler 会输出您的 Worker URL (例如
https://my-wakatime-worker.your-username.workers.dev
)。 -
通过 Cloudflare Dashboard: 如果您是在线编辑器中编写代码,保存更改后 Worker 会自动部署。您可以在 Worker 的概览页面找到其 URL。
4. 测试 Worker:
在浏览器中访问您的 Worker URL。如果一切配置正确,您应该能看到 Wakatime API 返回的 JSON 数据。如果看到错误,请检查 Worker 日志 (通过 Dashboard 或 wrangler tail
) 和之前的配置步骤。
步骤 4: 在 Next.js 中创建或修改 Footer 组件
假设您的 Next.js 项目结构如下:
my-next-app/├── components/│ └── Footer.js # 我们将创建或修改此文件├── pages/ # 或 app/ 目录 (对于 App Router)│ └── _app.js # 或 layout.js (对于 App Router)└── ...
创建/修改 components/Footer.js
:
// src/components/Footer.js"use client"; // 声明为客户端组件,因为使用了 useState 和 useEffect
import React, { useEffect, useState } from "react";
export default function Footer() { const currentYear = new Date().getFullYear(); const [wakatimeText, setWakatimeText] = useState(""); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null);
useEffect(() => { const fetchWakatimeStats = async () => { setIsLoading(true); setError(null); try { // 请将 'YOUR_WORKER_URL' 替换为您实际部署的 Cloudflare Worker URL const workerUrl = "https://waka.yangzh.cn"; const response = await fetch(workerUrl);
if (!response.ok) { const errorData = await response .json() .catch(() => ({ message: "Failed to parse error response" })); throw new Error( errorData.message || `Error fetching Wakatime stats: ${response.status}` ); }
const result = await response.json();
// 根据您提供的 JSON 结构,我们期望数据在 result.data.text if (result && result.data && result.data.text) { setWakatimeText(result.data.text); } else { // 如果数据结构不符合预期,或者 text 字段不存在 console.warn( 'Wakatime data received, but "text" field is missing or in unexpected structure:', result ); setWakatimeText("Data format error"); } } catch (err) { console.error("Failed to fetch or process Wakatime stats:", err); setError(err.message); setWakatimeText("Could not load stats"); } finally { setIsLoading(false); } };
fetchWakatimeStats(); }, []); // 空依赖数组确保只在组件挂载时运行一次
return ( <footer className="bg-slate-800 text-slate-300 py-8 mt-12"> <div className="container mx-auto px-4 text-center"> <p className="text-sm"> © {currentYear} 《Web前端开发》课程练习平台. 保留所有权利. </p> <p className="text-xs mt-2">使用 Next.js 和 Tailwind CSS 构建</p> <p className="text-xs mt-2"> Wakatime :{" "} {isLoading ? "Loading..." : error ? `Error: ${error}` : wakatimeText} </p> {/* 可以在这里添加更多链接或信息 */} </div> </footer> );}
重要: 将 YOUR_WORKER_URL
替换为您在步骤 3 中获得的实际 Cloudflare Worker URL。
总结
恭喜!您已经成功地将 Wakatime 编程时长统计集成到了您的 Next.js 应用页脚。通过使用 Cloudflare Workers 作为 API 代理,您不仅实现了功能,还确保了 Wakatime API Key 的安全。
您可以进一步扩展此功能,例如:
- 显示更详细的统计数据 (例如,按项目或语言分类的时间)。
- 为数据添加更美观的样式 1。
- 实现更复杂的错误处理或重试逻辑。
- 对 Worker API 的响应进行缓存,以减少对 Wakatime API 的请求频率。
希望本教程对您有所帮助!