news 2026/9/18 17:16:06

使用 Vercel Flags SDK 与 Flags Explorer 构建 Next.js 功能开关:flags-sdk/vercel 示例深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 Vercel Flags SDK 与 Flags Explorer 构建 Next.js 功能开关:flags-sdk/vercel 示例深度解析

使用 Vercel Flags SDK 与 Flags Explorer 构建 Next.js 功能开关:flags-sdk/vercel 示例深度解析

【免费下载链接】examplesEnjoy our curated collection of examples and solutions. Use these patterns to build your own robust and scalable applications.项目地址: https://gitcode.com/GitHub_Trending/examples1/examples

本篇文章围绕开源仓库 flags-sdk/vercel 示例展开,系统讲解如何通过@flags-sdk/vercel适配器将 Flags SDK 与 Vercel 原生 Feature Flags 能力打通,在 Next.js 电商页面中用功能开关控制横幅显隐与结算按钮颜色,并借助 Flags Explorer 在本地实时切换开关。读完本文,你将掌握从 Vercel Dashboard 创建开关、到flags.ts声明、再到proxy.ts预计算与路由重写的完整落地链路,可直接复用到自己的项目中。

示例整体架构:从 Flag 定义到页面渲染的完整链路

本示例是一个典型的 Next.js 电商商品详情页 + 购物车 Demo,核心演示了三类典型用法:

  • 布尔开关:控制页面顶部促销横幅(summer sale、free delivery)的显示与隐藏;
  • 字符串开关:控制"Proceed to Checkout"(去结算)按钮的颜色(blue/green/red);
  • 本地调试能力:通过 Flags Explorer 在本地开发环境实时覆盖开关取值,无需改动代码。

Flag 配置全部托管在 Vercel Dashboard(项目控制台的Flags标签页),应用侧只负责"声明"与"消费"。整个数据流分为四层,可从仓库源码逐一印证:

  1. flags.ts:集中声明所有 Flag 的定义(key、默认值、可选值、描述);
  2. proxy.ts:Next.js 中间件(proxy),对请求做 Flag 预计算(precompute),并把请求重写到携带组合编码的动态路由/[code]
  3. 路由页面:app/[code]/page.tsx 等页面按code读取 Flag 值并渲染对应 UI;
  4. Vercel 平台:Dashboard 中的 Flag 配置与FLAGS/FLAGS_SECRET环境变量负责提供取值来源。

需要说明的是:proxy.ts是 Next.js 16 中由middleware.ts演进而来的新命名约定,仓库中该文件通过export const config = { matcher: [...] }指定拦截范围,功能等价于传统中间件。

第一步:在 flags.ts 中声明功能开关

所有 Flag 都集中定义在 flags.ts,使用 Flags SDK 的flag()工厂函数创建,并通过createVercelAdapter()将取值交给 Vercel Flags 后端:

import { flag } from 'flags/next' import { createVercelAdapter } from '@flags-sdk/vercel' import { identify, type Entities } from './lib/identify' const vercelFlagsAdapter = createVercelAdapter() export const showSummerBannerFlag = flag<boolean, Entities>({ key: 'summer-sale', adapter: vercelFlagsAdapter(), defaultValue: false, identify, description: 'Show the summer sale banner', options: [ { value: true, label: 'Show' }, { value: false, label: 'Hide' }, ], }) export const showFreeDeliveryBannerFlag = flag<boolean, Entities>({ key: 'free-delivery', adapter: vercelFlagsAdapter(), defaultValue: false, identify, description: 'Show the free delivery banner', options: [ { value: true, label: 'Show' }, { value: false, label: 'Hide' }, ], }) export const proceedToCheckoutColorFlag = flag<string, Entities>({ key: 'proceed-to-checkout-color', adapter: vercelFlagsAdapter(), defaultValue: 'blue', identify, description: 'Color of the proceed to checkout button', options: [ { value: 'blue', label: 'Blue' }, { value: 'green', label: 'Green' }, { value: 'red', label: 'Red' }, ], }) export const productFlags = [ showFreeDeliveryBannerFlag, showSummerBannerFlag, proceedToCheckoutColorFlag, ] as const

关键字段说明

字段含义本示例取值
keyFlag 的唯一标识,必须与 Vercel Dashboard 中创建的 Flag key 完全一致summer-salefree-deliveryproceed-to-checkout-color
adapter取值适配器,vercelFlagsAdapter()负责与 Vercel Flags 后端通信三个 Flag 均使用
defaultValue未配置或取不到值时使用的兜底默认值false/false/'blue'
identify标识当前访问者(实体),用于按用户维度解析 Flag统一使用lib/identify.ts的 stable id
options可选项列表,会同步展示在 Flags Explorer 与 Vercel Dashboard 中,便于可视化切换见上表
description人类可读描述,帮助团队理解该开关用途各 Flag 均有

泛型与实体识别(identify)

flag<boolean, Entities>中的第二个泛型参数Entities来自 lib/identify.ts,声明了访问者实体的结构:

export type Entities = { user?: { id: string } }

identify函数通过dedupe包裹(同一请求内只执行一次),从stable-idCookie 中读取用户标识并作为user.id上报:

export const identify = dedupe(async (): Promise<Entities> => { const stableId = await getStableId() return { user: { id: stableId.value }, } }) satisfies Identify<Entities>

stable-id的生成逻辑在 lib/get-stable-id.ts:优先读取请求头x-generated-stable-id(首次请求由 proxy 生成并注入),其次读stable-idCookie,都没有则用nanoid()现场生成并标记为"新生成"。购物车场景下还有一个并行的cart-id(见 lib/get-cart-id.ts),两者逻辑一致,共同支撑"无登录用户也能按稳定身份解析 Flag"的能力。

第二步:在 Vercel Dashboard 创建功能开关

Flag 配置不需要写代码,直接在 Vercel 项目控制台的Flags标签页创建即可。README 要求创建以下三个开关:

Flag Key类型可选值 / 默认值用途
summer-saleBooleantrue/false(默认false控制夏季促销横幅显隐
free-deliveryBooleantrue/false(默认false控制免运费横幅显隐
proceed-to-checkout-colorStringbluegreenred(默认blue控制结算按钮颜色

所有 Flag 的 key 都声明在 flags.ts 中,创建时务必与之一一对应。仓库还内置了一个 setup 页面,它会以清单(checklist)形式列出全部必需 Flag 的 key、类型、默认值与一键创建链接,并实时显示FLAGS_SECRET环境变量是否已配置(Configured / Missing 状态徽标),方便部署后自查。

第三步:部署与本地开发全流程

一键部署

README 提供了 Vercel 部署入口,点击后会依次完成三件事:

  1. 将该仓库克隆到你的 GitHub 账户;
  2. 创建一个新的 Vercel 项目;
  3. 立即触发部署——即使你还没有配置任何 Flag,应用也能先跑起来(未配置时会自动进入 setup 引导页,详见下文)。

Step 1:链接本地项目

要使用 Flags Explorer,需要先把本地项目与云端项目关联:

vercel link

按提示从列表中选中刚部署的项目即可。

Step 2:在 Vercel Dashboard 创建功能开关

打开项目控制台的Flags标签页,按上文表格创建summer-salefree-deliveryproceed-to-checkout-color三个开关。

Step 3:拉取环境变量

执行以下命令拉取包含 SDK 密钥的FLAGS环境变量:

vercel env pull

Step 4:安装依赖并启动开发服务器

pnpm install pnpm dev

依赖清单见 package.json,核心依赖包括@flags-sdk/vercel@1.4.5@vercel/flags-core@1.7.0flags@4.1.0以及 Next.js 16 与 React 19。

本地开发要点

本地调试时需确保满足三点:

  1. 已用vercel link关联项目;
  2. 已用vercel env pull拉取环境变量;
  3. .env.local中设置FLAGS_SECRET——它用于 Flags 预计算(precompute),并保障 Flags Explorer 本地覆盖(override)的安全性。

第四步:未配置时的降级行为(/setup 引导页)

README 明确说明:如果FLAGSFLAGS_SECRET缺失,请求会被重写到/setup,直到配置完成。这一逻辑在 proxy.ts 中实现:

export async function proxy(request: NextRequest) { const hasFlagsSecret = Boolean(process.env.FLAGS_SECRET) if (!hasFlagsSecret) { return NextResponse.rewrite(new URL('/setup', request.url)) } // ... }

setup 页面 承担"配置向导"职责:展示必需 Flag 清单表格(Key / Type / Default / Description)并提供"Create"跳转链接,同时提示执行vercel env pull获取FLAGS。这一设计让模板"开箱即用、逐步配置",即使先部署后配置也不会白屏报错。

源码深潜:proxy 预计算与按组合编码重写

proxy.ts是本示例的技术核心,它把"Flag 组合"编码进 URL,从而让服务端渲染天然感知开关状态:

import { type NextRequest, NextResponse } from 'next/server' import { precompute } from 'flags/next' import { getStableId } from './lib/get-stable-id' import { getCartId } from './lib/get-cart-id' export const config = { matcher: ['/', '/cart'], } export async function proxy(request: NextRequest) { const hasFlagsSecret = Boolean(process.env.FLAGS_SECRET) if (!hasFlagsSecret) { return NextResponse.rewrite(new URL('/setup', request.url)) } // Demo-only: lazily import flags after env validation to avoid loading // the provider setup before users complete /setup. const { productFlags } = await import('@/flags') const stableId = await getStableId() const cartId = await getCartId() const code = await precompute(productFlags) // rewrites the request to the variant for this flag combination const nextUrl = new URL( `/${code}${request.nextUrl.pathname}${request.nextUrl.search}`, request.url ) if (cartId.isFresh) { request.headers.set('x-generated-cart-id', cartId.value) } if (stableId.isFresh) { request.headers.set('x-generated-stable-id', stableId.value) } const headers = new Headers() headers.append('set-cookie', `stable-id=${stableId.value}`) headers.append('set-cookie', `cart-id=${cartId.value}`) return NextResponse.rewrite(nextUrl, { request, headers }) }

关键点拆解:

  • 拦截范围matcher: ['/', '/cart'],只对首页与购物车页做预计算,其他路由直通;
  • 环境校验前置FLAGS_SECRET缺失时直接重写到/setup,避免在用户未完成配置前加载 Provider(源码注释明确说明这是 Demo 专用策略);
  • 编码化路由precompute(productFlags)把三个 Flag 的当前取值编码为一段 code,请求被重写到/{code}{原路径}。例如首页/可能被重写为/<code>/
  • 首访身份注入:首次请求没有 Cookie,proxy 生成的stable-id/cart-id通过x-generated-stable-id/x-generated-cart-id请求头注入,同时在响应中写回同名 Cookie,保证后续请求与identify逻辑能读到一致身份;
  • 预计算的意义:把 Flag 取值"固化"在请求发生前,服务端渲染时无需再发起网络请求,天然适配缓存,这也是为什么要在next.config.mjs中开启cacheComponents: true

路由侧如何消费 Flag

以首页为例(app/[code]/page.tsx),页面组件通过params.code与 flag 定义一起解析取值:

const params = await props.params const showSummerBanner = await showSummerBannerFlag(params.code, productFlags)

showSummerBannerFlag(params.code, productFlags)的调用方式表明:传入编码与全部 Flag 列表,SDK 即可从编码中还原出当前 Flag 的值,无需在渲染阶段访问外部服务。得到布尔值后,组件 app/summer-sale.tsx 与 app/free-delivery.tsx 决定是否渲染对应横幅(show ? <Banner/> : null)。结算按钮颜色同理,由 proceed-to-checkout.tsx 接收color字符串并传给按钮组件。

配合 Flags Explorer 做本地可视化调试

Flags Explorer 是 Vercel Flags 的本地调试工具,其入口来自 next.config.mjs 中的 Vercel Toolbar 插件:

import withVercelToolbar from '@vercel/toolbar/plugins/next' const nextConfig = { cacheComponents: true, turbopack: { root: path.join(__dirname, ".."), }, } export default withVercelToolbar()(nextConfig)

withVercelToolbar()为开发环境注入 Toolbar,使得运行pnpm dev后,页面上会出现调试入口,你可以在 Flags Explorer 面板中即时启用/禁用summer-salefree-delivery或切换proceed-to-checkout-color的颜色值,改动即时生效,无需改动代码或重新部署。为了让它正常工作,必须满足前面提到的三个前提:项目已vercel link、已vercel env pull、且.env.local中设置了FLAGS_SECRET(预计算与安全的本地覆盖都依赖它)。

小结:完整落地清单

要在你自己的项目中复刻这套方案,按以下顺序操作即可:

  1. 部署:通过 Vercel 一键部署模板(或git clone本仓库后自行部署),无需预先配置 Flag;
  2. 建 Flag:在项目控制台 Flags 标签页创建summer-sale(Boolean)、free-delivery(Boolean)、proceed-to-checkout-color(String,blue/green/red);
  3. 本地联调vercel linkvercel env pull→ 在.env.local写入FLAGS_SECRETpnpm install && pnpm dev
  4. 可视化调试:打开 Flags Explorer,实时切换三个开关观察横幅与按钮颜色的变化;
  5. 上线发布:在 Vercel Dashboard 中把开关调到目标取值并部署发布。

本示例的完整源码与配置均可在本仓库 flags-sdk/vercel 目录下查看,其中 flags.ts 是 Flag 声明的唯一事实来源,proxy.ts 是预计算与重写的中枢,setup 页面 则保证了"先部署、后配置"的平滑体验。建议在此基础上扩展你自己的 Flag key 与业务组件,即可快速搭建一套生产可用的 Vercel Flags 功能开关体系。

【免费下载链接】examplesEnjoy our curated collection of examples and solutions. Use these patterns to build your own robust and scalable applications.项目地址: https://gitcode.com/GitHub_Trending/examples1/examples

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 17:16:05

PeopleSoft AWE工作流配置核心原理与实战指南

简介&#xff1a;本资源是一份面向PeopleSoft开发工程师与HCM系统实施人员的实战型工作流配置指南&#xff0c;聚焦Approval Workflow Engine&#xff08;AWE&#xff09;在费用报销场景中的端到端落地实践。文档以PT8.50FSCM9.1Oracle技术栈为基础&#xff0c;完整覆盖用户权限…

作者头像 李华
网站建设 2026/9/18 17:09:21

知识梳理转思维导图:用Python和Markmap自动生成教案PPTX

简介&#xff1a;面向小学四年级数学教学的学习课件&#xff0c;聚焦人教版四年级下册第五单元“三角形”的知识梳理与思维导图复习。课件包含系统的概念讲解与例题演练&#xff0c;覆盖三角形定义与稳定性、三边关系、按角/按边分类、内角和180以及多边形内角和公式等必考点&a…

作者头像 李华
网站建设 2026/9/18 17:08:44

从FGSM到CW:对抗样本生成与模型鲁棒性评估实践

简介&#xff1a;《基于深度学习的对抗样本生成技术研究综述》是一篇聚焦深度学习安全领域的学术综述&#xff0c;内容详实、结构清晰&#xff0c;适合人工智能、数据研究及网络安全方向的研究生和工程师阅读。文中从对抗样本的起源与基本原理入手&#xff0c;将生成方法划分为…

作者头像 李华
网站建设 2026/9/18 17:08:37

CANN社区组织管理全指南:SIG创建、成员变更与PMC/TSC治理实操

CANN社区组织管理全指南&#xff1a;SIG创建、成员变更与PMC/TSC治理实操 【免费下载链接】community 本项目是CANN开源社区的核心管理仓库&#xff0c;包含社区的治理章程、治理组织、通用操作指引及流程规范等基础信息 项目地址: https://gitcode.com/cann/community …

作者头像 李华
网站建设 2026/9/18 17:05:41

作物需水量预测的神经网络集成:从模型选型到部署实践

简介&#xff1a;面向农业工程、智慧灌溉与机器学习建模研究者&#xff0c;这份《基于神经网络集成的作物需水量预测》PDF是一篇理论与实验结合的期刊论文资料。文章以空气湿度、温度、太阳辐射、风速等气象因子为输入&#xff0c;利用Bagging集成策略构建神经网络预测模型&…

作者头像 李华