traffical

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Traffical

Traffical

Traffical is a parameter-first experimentation and optimization platform. It unifies feature flags, A/B testing, and contextual bandits into a single system. SDKs resolve parameters locally at the edge — no per-request API calls, sub-millisecond latency, works offline.
Traffical是一款以参数为核心的实验与优化平台。它将功能标志、A/B测试和上下文多臂老虎机整合到单一系统中。SDK在边缘节点本地解析参数——无需每次请求调用API,延迟低于毫秒级,支持离线使用。

Mental Model

核心思路

Traffical is parameter-first. You define parameters with defaults, and Traffical handles the rest.
┌─────────────────────────────────────────────────────────────────────┐
│  Your Code                                                          │
│                                                                     │
│  1. Define parameters with defaults                                 │
│  2. Use the resolved values                                         │
│  3. Track events on conversion                                      │
└─────────────────────────────────────────────────────────────────────┘
                              │  (hidden from you)
┌─────────────────────────────────────────────────────────────────────┐
│  Traffical                                                          │
│                                                                     │
│  • Layers & policies for mutual exclusivity                         │
│  • Bucket assignment & deterministic hashing                        │
│  • Thompson Sampling & contextual bandits                           │
│  • Statistical analysis & optimization                              │
└─────────────────────────────────────────────────────────────────────┘
Key insights:
  1. Parameters, Not Experiments — You define parameters with defaults. Experiments, feature flags, and optimizations are policies that control parameter assignment. Your code doesn't need to know which.
  2. Resolution Is Local — The SDK fetches a config bundle once and caches it. Every resolution call is synchronous from cache — no network latency, no render flicker.
  3. Decisions Are Tracked Automatically — When you call
    useTraffical()
    or
    decide()
    , a decision event is automatically sent to Traffical (enabled by default via
    trackDecisions: true
    ). This connects parameter resolution to conversion events for intent-to-treat analysis. No manual setup needed.
  4. Track Events for Learning — Call
    track()
    when valuable actions happen (purchase, signup, etc.). Traffical uses this data for adaptive optimization.
Traffical的核心是以参数为优先。你只需定义带默认值的参数,剩下的由Traffical处理。
┌─────────────────────────────────────────────────────────────────────┐
│  你的代码                                                          │
│                                                                     │
│  1. 定义带默认值的参数                                             │
│  2. 使用解析后的参数值                                             │
│  3. 在转化节点跟踪事件                                             │
└─────────────────────────────────────────────────────────────────────┘
                              │  (对你透明的底层逻辑)
┌─────────────────────────────────────────────────────────────────────┐
│  Traffical                                                          │
│                                                                     │
│  • 用于互斥性的层级与策略机制                                       │
│  • 用户分组与确定性哈希算法                                         │
│  • 汤普森采样与上下文多臂老虎机算法                                 │
│  • 统计分析与自动优化                                               │
└─────────────────────────────────────────────────────────────────────┘
核心要点:
  1. 参数优先,而非实验优先——你只需定义带默认值的参数。实验、功能标志和优化都是控制参数分配的策略,你的代码无需关心具体是哪种策略。
  2. 本地解析参数——SDK会一次性获取配置包并缓存。所有解析请求直接从缓存同步读取——无网络延迟,无页面闪烁。
  3. 自动跟踪决策事件——当你调用
    useTraffical()
    decide()
    时,决策事件会自动发送到Traffical(默认通过
    trackDecisions: true
    启用)。这会将参数解析与转化事件关联,用于意向治疗分析,无需手动配置。
  4. 跟踪事件以实现优化——当用户完成有价值的操作(如购买、注册)时调用
    track()
    。Traffical会利用这些数据进行自适应优化。

When to Use Traffical

适用场景

ScenarioAction
Adding a new featureWrap in feature flag for gradual rollout
Changing existing UIA/B test against current implementation
Modifying conversion pathsExperiment with success metrics
Updating algorithms/logicTest impact before full rollout
Anything affecting revenueAlways experiment first
场景操作
新增功能用功能标志包裹,逐步推出
修改现有UI与当前实现进行A/B测试
调整转化路径针对成功指标进行实验
更新算法/逻辑全面推出前测试影响
任何影响营收的变更务必先进行实验

Recommended Workflow

推荐工作流

Always use the Traffical CLI to manage parameters. The CLI is the primary tool for setting up and syncing configuration. Do not skip it.
  1. Initialize — Run
    npx @traffical/cli init --api-key <management-key> --framework <name> --yes
    to set up the project non-interactively (or check for an existing
    .traffical/
    directory). The user must provide a Management Key or Full Access key from the dashboard. Always pass
    --framework
    and
    --yes
    to avoid interactive prompts.
  2. Define parameters — Add parameters and events to
    .traffical/config.yaml
  3. Sync — Run
    npx @traffical/cli push
    to sync parameters to the Traffical platform
  4. Install SDK — Add the appropriate SDK package to your project
  5. Use in code — Resolve parameters and track events using the SDK
  6. Verify — Run
    npx @traffical/cli status
    to confirm everything is in sync
请始终使用Traffical CLI管理参数。CLI是设置和同步配置的主要工具,请勿跳过这一步。
  1. 初始化——运行
    npx @traffical/cli init --api-key <management-key> --framework <name> --yes
    以非交互式方式设置项目(或检查是否存在
    .traffical/
    目录)。用户必须提供来自控制台的管理密钥或全权限密钥。请始终传入
    --framework
    --yes
    以避免交互式提示。
  2. 定义参数——在
    .traffical/config.yaml
    中添加参数和事件
  3. 同步——运行
    npx @traffical/cli push
    将参数同步到Traffical平台
  4. 安装SDK——为项目添加对应的SDK包
  5. 代码中使用——使用SDK解析参数并跟踪事件
  6. 验证——运行
    npx @traffical/cli status
    确认所有内容已同步

The Traffical CLI

Traffical CLI

The CLI (
@traffical/cli
) is how you initialize projects, define parameters, and keep local config in sync with the Traffical platform. You can run it via
npx
(no global install required):
bash
npx @traffical/cli <command>
Or install globally for shorter commands:
bash
npm install -g @traffical/cli
traffical <command>
CLI(
@traffical/cli
)用于初始化项目、定义参数,并保持本地配置与Traffical平台同步。你可以通过
npx
运行它(无需全局安装):
bash
npx @traffical/cli <command>
或全局安装以使用更短的命令:
bash
npm install -g @traffical/cli
traffical <command>

Check for existing setup

检查现有配置

Look for a
.traffical/
directory or
traffical.yaml
in the project root. If it exists, the project is already initialized — check the config for existing parameters before creating new ones.
在项目根目录查找
.traffical/
目录或
traffical.yaml
文件。如果存在,说明项目已初始化——在创建新参数前,请检查现有配置。

Initialize a new project

初始化新项目

If no
.traffical/
directory exists, initialize Traffical:
Important: The
--api-key
flag requires a real Management Key or Full Access key. Never fabricate or guess API keys. If no key is available in environment variables (
TRAFFICAL_API_KEY
) or
~/.trafficalrc
, ask the user to provide one from https://app.traffical.io/settings/api-keys.
bash
undefined
如果不存在
.traffical/
目录,请初始化Traffical:
重要提示:
--api-key
标志需要有效的管理密钥或全权限密钥。请勿伪造或猜测API密钥。如果环境变量(
TRAFFICAL_API_KEY
)或
~/.trafficalrc
中没有可用密钥,请让用户从https://app.traffical.io/settings/api-keys获取。
bash
undefined

Basic init (will auto-detect framework and prompt if needed):

基础初始化(会自动检测框架,必要时提示):

npx @traffical/cli init --api-key <management-key>
npx @traffical/cli init --api-key <management-key>

Fully non-interactive init (recommended for AI agents and CI/CD):

完全非交互式初始化(推荐AI Agent和CI/CD使用):

npx @traffical/cli init --api-key <management-key> --framework react --yes

**Available flags for `init`:**

| Flag | Description |
|------|-------------|
| `--api-key <key>` | Management or Full Access key (falls back to `TRAFFICAL_API_KEY` env var or `~/.trafficalrc`) |
| `--framework <name>` | Skip framework detection. Values: `react`, `nextjs`, `svelte`, `sveltekit`, `vue`, `nuxt`, `node` |
| `--project <id>` | Use a specific project (skips project selection prompt, useful with org-scoped keys) |
| `-y, --yes` | Auto-accept all detected defaults — no interactive prompts |
| `--no-sdk-key` | Skip automatic SDK key creation |

> **For AI agents:** Always pass `--framework` and `--yes` to avoid interactive prompts that will hang in non-TTY environments.

This creates:
.traffical/ ├── config.yaml # Parameter and event definitions (committed) ├── .env # TRAFFICAL_API_KEY=... (gitignored, auto-generated SDK key) ├── .gitignore # Ensures .env is never committed ├── AGENTS.md # AI agent integration guide (project-specific) └── TEMPLATES.md # Framework-specific code templates

The CLI auto-detects your framework (React, Next.js, Svelte, SvelteKit, Vue, Nuxt, Node.js) and generates appropriate templates. Existing synced parameters and events are imported into `config.yaml` automatically.

**After init**, add `TRAFFICAL_API_KEY` from `.traffical/.env` to your project's `.env` or hosting environment for runtime SDK use. The auto-generated key has `sdk:read` and `sdk:write` scopes — just enough for parameter resolution and event tracking.
npx @traffical/cli init --api-key <management-key> --framework react --yes

**`init`命令可用标志:**

| 标志 | 描述 |
|------|-------------|
| `--api-key <key>` | 管理密钥或全权限密钥(优先从环境变量`TRAFFICAL_API_KEY`或`~/.trafficalrc`读取) |
| `--framework <name>` | 跳过框架检测。可选值:`react`, `nextjs`, `svelte`, `sveltekit`, `vue`, `nuxt`, `node` |
| `--project <id>` | 使用指定项目(跳过项目选择提示,适用于组织级密钥) |
| `-y, --yes` | 自动接受所有检测到的默认值——无交互式提示 |
| `--no-sdk-key` | 跳过自动创建SDK密钥 |

> **针对AI Agent:**请始终传入`--framework`和`--yes`,避免在非TTY环境中出现交互式提示导致进程挂起。

初始化后会创建以下文件:
.traffical/ ├── config.yaml # 参数和事件定义(需提交到版本控制) ├── .env # TRAFFICAL_API_KEY=...(自动生成的SDK密钥,已加入.gitignore) ├── .gitignore # 确保.env不会被提交 ├── AGENTS.md # 项目专属的AI Agent集成指南 └── TEMPLATES.md # 框架专属的代码模板

CLI会自动检测你的框架(React、Next.js、Svelte、SvelteKit、Vue、Nuxt、Node.js)并生成对应的模板。已同步的参数和事件会自动导入到`config.yaml`中。

**初始化完成后**,将`.traffical/.env`中的`TRAFFICAL_API_KEY`添加到项目的`.env`或托管环境变量中,供运行时SDK使用。自动生成的密钥拥有`sdk:read`和`sdk:write`权限——刚好满足参数解析和事件跟踪的需求。

Managing parameters with the CLI

使用CLI管理参数

After initialization, use the CLI to keep local config and the Traffical platform in sync:
bash
undefined
初始化完成后,使用CLI保持本地配置与Traffical平台同步:
bash
undefined

After adding or modifying parameters in config.yaml — push to platform

在config.yaml中添加或修改参数后——推送到平台

npx @traffical/cli push
npx @traffical/cli push

Before writing code — check what parameters exist and their sync status

编写代码前——检查已存在的参数及其同步状态

npx @traffical/cli status
npx @traffical/cli status

Pull latest parameters from the platform into local config

从平台拉取最新参数到本地配置

npx @traffical/cli pull
npx @traffical/cli pull

Bidirectional sync (local wins for conflicts)

双向同步(冲突时本地配置优先)

npx @traffical/cli sync
npx @traffical/cli sync

Import specific parameters from the dashboard (supports wildcards)

从控制台导入指定参数(支持通配符)

npx @traffical/cli import "ui.*"
npx @traffical/cli import "ui.*"

Validate config without pushing (dry run)

验证配置但不推送(试运行)

npx @traffical/cli push --dry-run

**Always run `npx @traffical/cli push` after modifying `.traffical/config.yaml`.** This syncs your changes to the platform and prevents drift.
npx @traffical/cli push --dry-run

**修改`.traffical/config.yaml`后,请务必运行`npx @traffical/cli push`**。这会将你的变更同步到平台,避免配置漂移。

Authentication

认证机制

Traffical uses different API key types for different purposes:
Key TypePrefixPurposeScopes
SDK Key
traffical_sk_*
Runtime SDKs — fetch config, send events
sdk:read
,
sdk:write
Management Key
traffical_sk_*
CLI, CI/CD — create/modify entities, push/pull/sync
mgmt:read
,
mgmt:write
Full Access Key
traffical_sk_*
Administrative — all operations
sdk:*
,
mgmt:*
,
admin
Traffical为不同场景使用不同类型的API密钥:
密钥类型前缀用途权限范围
SDK密钥
traffical_sk_*
运行时SDK——获取配置、发送事件
sdk:read
,
sdk:write
管理密钥
traffical_sk_*
CLI、CI/CD——创建/修改实体、推送/拉取/同步
mgmt:read
,
mgmt:write
全权限密钥
traffical_sk_*
管理员操作——所有权限
sdk:*
,
mgmt:*
,
admin

How init handles keys

初始化流程中的密钥处理

  1. You provide a Management Key (or Full Access key) via
    --api-key
    or
    ~/.trafficalrc
  2. The CLI authenticates and selects org/project
  3. The CLI auto-creates a project-scoped SDK key via the API and saves it to
    .traffical/.env
  4. The
    .traffical/.gitignore
    is created/updated to ensure
    .env
    is never committed
This means:
  • The Management Key stays in
    ~/.trafficalrc
    (for CLI operations like push/pull/sync)
  • The SDK Key goes into
    .traffical/.env
    (for runtime use in your app)
  • Only the least-privileged key (SDK) is used at runtime — no risk of leaking management access
  1. 你通过
    --api-key
    ~/.trafficalrc
    提供管理密钥(或全权限密钥)
  2. CLI完成认证并选择组织/项目
  3. CLI通过API自动创建项目级SDK密钥,并保存到
    .traffical/.env
  4. 创建/更新
    .traffical/.gitignore
    ,确保
    .env
    不会被提交
这意味着:
  • 管理密钥存储在
    ~/.trafficalrc
    中(用于CLI的推送/拉取/同步操作)
  • SDK密钥存储在
    .traffical/.env
    中(用于应用运行时)
  • 运行时仅使用权限最低的SDK密钥——无泄露管理权限的风险

SDK key location

SDK密钥位置

The SDK key auto-generated by
init
is stored in:
.traffical/.env
init
命令自动生成的SDK密钥存储在:
.traffical/.env

Contains: TRAFFICAL_API_KEY=traffical_sk_...

内容:TRAFFICAL_API_KEY=traffical_sk_...


Copy this value to your project's `.env` or hosting environment variables for your SDK to use at runtime.

请将该值复制到项目的`.env`或托管环境变量中,供SDK运行时使用。

SDK configuration values

SDK配置参数

After
traffical init
, the
.traffical/config.yaml
contains
project.id
and
project.orgId
. Use these values (along with an
env
like
"production"
) when initializing the SDK. The SDK key is in
.traffical/.env
as
TRAFFICAL_API_KEY
.
traffical init
完成后,
.traffical/config.yaml
中包含
project.id
project.orgId
。初始化SDK时,请使用这些值(以及
env
参数,如
"production"
)。SDK密钥可在
.traffical/.env
中找到,对应
TRAFFICAL_API_KEY

Install an SDK

安装SDK

PackageUse case
@traffical/react
React and Next.js apps
@traffical/svelte
Svelte and SvelteKit apps
@traffical/node
Server-side Node.js (Express, Fastify, etc.)
@traffical/js-client
Any browser environment
bash
undefined
包名适用场景
@traffical/react
React和Next.js应用
@traffical/svelte
Svelte和SvelteKit应用
@traffical/node
服务端Node.js(Express、Fastify等)
@traffical/js-client
任何浏览器环境
bash
undefined

Pick the one matching your framework

选择与你的框架匹配的包

npm install @traffical/react
npm install @traffical/react

or

npm install @traffical/svelte
npm install @traffical/svelte

or

npm install @traffical/node
undefined
npm install @traffical/node
undefined

SDK Usage

SDK使用示例

React / Next.js

React / Next.js

Provider setup (wrap your app once):
tsx
import { TrafficalProvider } from "@traffical/react";

function App() {
  return (
    <TrafficalProvider
      config={{
        orgId: "org_xxx",
        projectId: "proj_xxx",
        env: "production",
        apiKey: "pk_live_your_public_key",
      }}
      // Optional: provide unitKeyFn for logged-in users
      // unitKeyFn: () => currentUser.id,
    >
      <MyApp />
    </TrafficalProvider>
  );
}
Use in components:
tsx
import { useTraffical } from "@traffical/react";

function CheckoutButton() {
  const { params, track } = useTraffical({
    defaults: {
      "checkout.button.color": "#1E6EFB",
      "checkout.button.label": "Buy now",
    },
  });

  return (
    <button
      style={{ backgroundColor: params["checkout.button.color"] }}
      onClick={() => track("checkout_click")}
    >
      {params["checkout.button.label"]}
    </button>
  );
}
Provider配置(仅需在应用根组件包裹一次):
tsx
import { TrafficalProvider } from "@traffical/react";

function App() {
  return (
    <TrafficalProvider
      config={{
        orgId: "org_xxx",
        projectId: "proj_xxx",
        env: "production",
        apiKey: "pk_live_your_public_key",
      }}
      // 可选:为已登录用户提供unitKeyFn
      // unitKeyFn: () => currentUser.id,
    >
      <MyApp />
    </TrafficalProvider>
  );
}
组件中使用:
tsx
import { useTraffical } from "@traffical/react";

function CheckoutButton() {
  const { params, track } = useTraffical({
    defaults: {
      "checkout.button.color": "#1E6EFB",
      "checkout.button.label": "立即购买",
    },
  });

  return (
    <button
      style={{ backgroundColor: params["checkout.button.color"] }}
      onClick={() => track("checkout_click")}
    >
      {params["checkout.button.label"]}
    </button>
  );
}

Svelte / SvelteKit

Svelte / SvelteKit

Layout setup:
svelte
<!-- src/routes/+layout.svelte -->
<script>
  import { setTrafficalContext } from "@traffical/svelte";

  setTrafficalContext({
    orgId: "org_xxx",
    projectId: "proj_xxx",
    env: "production",
    apiKey: "pk_live_your_public_key",
    context: { userId: data.user?.id ?? "anonymous" },
  });
</script>

<slot />
Use in components (
params
and
track
are Svelte stores — use
$
prefix):
svelte
<script>
  import { getTraffical } from "@traffical/svelte";

  const { params, track } = getTraffical({
    defaults: {
      "checkout.button.color": "#1E6EFB",
      "checkout.button.label": "Buy now",
    },
  });
</script>

<button
  style="background-color: {$params['checkout.button.color']}"
  on:click={() => $track("checkout_click")}
>
  {$params["checkout.button.label"]}
</button>
布局配置:
svelte
<!-- src/routes/+layout.svelte -->
<script>
  import { setTrafficalContext } from "@traffical/svelte";

  setTrafficalContext({
    orgId: "org_xxx",
    projectId: "proj_xxx",
    env: "production",
    apiKey: "pk_live_your_public_key",
    context: { userId: data.user?.id ?? "anonymous" },
  });
</script>

<slot />
组件中使用
params
track
是Svelte存储对象——需加
$
前缀):
svelte
<script>
  import { getTraffical } from "@traffical/svelte";

  const { params, track } = getTraffical({
    defaults: {
      "checkout.button.color": "#1E6EFB",
      "checkout.button.label": "立即购买",
    },
  });
</script>

<button
  style="background-color: {$params['checkout.button.color']}"
  on:click={() => $track("checkout_click")}
>
  {$params["checkout.button.label"]}
</button>

Node.js (Server-side)

Node.js(服务端)

typescript
import { createTrafficalClient } from "@traffical/node";

const traffical = await createTrafficalClient({
  orgId: "org_xxx",        // from .traffical/config.yaml
  projectId: "proj_xxx",   // from .traffical/config.yaml
  env: "production",
  apiKey: process.env.TRAFFICAL_API_KEY!,  // from .traffical/.env
});

// Resolve parameters (synchronous, from cached bundle)
const params = traffical.getParams({
  context: { userId: "user_789", locale: "en-US" },
  defaults: {
    "checkout.button.color": "#1E6EFB",
    "pricing.discount_pct": 0,
  },
});

// Track events (value goes in properties, unitKey in options)
traffical.track("purchase", { value: 49.99 }, { unitKey: "user_789" });
typescript
import { createTrafficalClient } from "@traffical/node";

const traffical = await createTrafficalClient({
  orgId: "org_xxx",        // 来自.traffical/config.yaml
  projectId: "proj_xxx",   // 来自.traffical/config.yaml
  env: "production",
  apiKey: process.env.TRAFFICAL_API_KEY!,  // 来自.traffical/.env
});

// 解析参数(同步操作,从缓存读取)
const params = traffical.getParams({
  context: { userId: "user_789", locale: "en-US" },
  defaults: {
    "checkout.button.color": "#1E6EFB",
    "pricing.discount_pct": 0,
  },
});

// 跟踪事件(值放在properties中,unitKey放在options中)
traffical.track("purchase", { value: 49.99 }, { unitKey: "user_789" });

Node.js (CLI / Scripts)

Node.js(CLI / 脚本)

For non-web contexts like CLI tools, batch jobs, or scripts, you can use
@traffical/node
without a web server. Use a machine or job identifier instead of a user ID:
typescript
import { createTrafficalClient } from "@traffical/node";

const traffical = await createTrafficalClient({
  orgId: "org_xxx",        // from .traffical/config.yaml
  projectId: "proj_xxx",   // from .traffical/config.yaml
  env: "production",
  apiKey: process.env.TRAFFICAL_API_KEY!,
});

const params = traffical.getParams({
  context: { unitKey: "batch-job" },
  defaults: {
    "feature.new_algorithm": false,
    "processing.batch_size": 100,
  },
});

if (params["feature.new_algorithm"]) {
  // Use new algorithm
}
对于CLI工具、批处理任务或脚本等非Web场景,你可以在不启动Web服务器的情况下使用
@traffical/node
。请使用机器或任务标识符替代用户ID:
typescript
import { createTrafficalClient } from "@traffical/node";

const traffical = await createTrafficalClient({
  orgId: "org_xxx",        // 来自.traffical/config.yaml
  projectId: "proj_xxx",   // 来自.traffical/config.yaml
  env: "production",
  apiKey: process.env.TRAFFICAL_API_KEY!,
});

const params = traffical.getParams({
  context: { unitKey: "batch-job" },
  defaults: {
    "feature.new_algorithm": false,
    "processing.batch_size": 100,
  },
});

if (params["feature.new_algorithm"]) {
  // 使用新算法
}

track() API

track() API

The
track()
signature differs between client-side and server-side SDKs:
  • React/Svelte (client-side):
    track(event, properties?)
    — The
    decisionId
    and
    unitKey
    are automatically bound from the provider context. Just call
    track("purchase", { value: 49.99 })
    .
  • Node.js (server-side):
    track(event, properties?, options?)
    — You must provide
    unitKey
    in the third argument:
    traffical.track("purchase", { value: 49.99 }, { unitKey: userId })
    . Optionally pass
    decisionId
    for explicit attribution.
客户端与服务端SDK的
track()
签名有所不同:
  • React/Svelte(客户端):
    track(event, properties?)
    ——
    decisionId
    unitKey
    会自动从Provider上下文中获取。只需调用
    track("purchase", { value: 49.99 })
    即可。
  • Node.js(服务端):
    track(event, properties?, options?)
    ——你必须在第三个参数中提供
    unitKey
    traffical.track("purchase", { value: 49.99 }, { unitKey: userId })
    。也可以传入
    decisionId
    进行显式归因。

Config-as-Code

即码配置(Config-as-Code)

Parameters and events are defined in
.traffical/config.yaml
(or
traffical.yaml
). This file is the source of truth — version-control it alongside your code.
yaml
version: "1.0"
project:
  id: proj_xxx
  orgId: org_xxx

parameters:
  checkout.button.color:
    type: string
    default: "#1E6EFB"
    description: Primary CTA button color

  checkout.show_trust_badges:
    type: boolean
    default: false

  pricing.discount_pct:
    type: number
    default: 0

events:
  purchase:
    valueType: currency
    unit: USD
    description: User completes a purchase

  add_to_cart:
    valueType: count
    description: User adds item to cart
参数和事件定义在
.traffical/config.yaml
(或
traffical.yaml
)中。该文件是唯一可信源——请与代码一起提交到版本控制。
yaml
version: "1.0"
project:
  id: proj_xxx
  orgId: org_xxx

parameters:
  checkout.button.color:
    type: string
    default: "#1E6EFB"
    description: 主CTA按钮颜色

  checkout.show_trust_badges:
    type: boolean
    default: false

  pricing.discount_pct:
    type: number
    default: 0

events:
  purchase:
    valueType: currency
    unit: USD
    description: 用户完成购买

  add_to_cart:
    valueType: count
    description: 用户将商品加入购物车

Parameter types

参数类型

TypeUse case
string
Colors, labels, URLs, template names
number
Prices, percentages, thresholds, timeouts
boolean
Feature flags, simple toggles
json
Structured config (multiple related settings)
类型适用场景
string
颜色、标签、URL、模板名称
number
价格、百分比、阈值、超时时间
boolean
功能标志、简单开关
json
结构化配置(多个相关设置)

Event value types

事件值类型

Value TypeUse case
currency
Monetary values (revenue, order value)
count
Numeric counts (clicks, items, views)
rate
Percentages or ratios
boolean
Binary events (happened or not)
值类型适用场景
currency
货币价值(收入、订单金额)
count
数值计数(点击、商品数量、浏览量)
rate
百分比或比率
boolean
二元事件(发生或未发生)

Adding events to config.yaml

在config.yaml中添加事件

Define events in the
events:
block of
.traffical/config.yaml
:
yaml
events:
  purchase:
    valueType: currency
    unit: USD
    description: User completes a purchase

  signup:
    valueType: boolean
    description: User creates an account

  page_view:
    valueType: count
    description: User views a page
Each event has:
  • valueType
    (required):
    currency
    ,
    count
    ,
    rate
    , or
    boolean
  • unit
    (optional): unit label for currency events (e.g.,
    USD
    ,
    EUR
    )
  • description
    (optional but recommended): human-readable explanation
After adding events, run
npx @traffical/cli push
to sync them to the platform.
Events discovered at runtime (via
track()
calls) will appear in the dashboard even without config definitions, but defining them in config gives you descriptions, value types, and keeps the config file as the source of truth.
.traffical/config.yaml
events:
区块中定义事件:
yaml
events:
  purchase:
    valueType: currency
    unit: USD
    description: 用户完成购买

  signup:
    valueType: boolean
    description: 用户创建账户

  page_view:
    valueType: count
    description: 用户浏览页面
每个事件包含:
  • valueType
    (必填):
    currency
    ,
    count
    ,
    rate
    boolean
  • unit
    (可选):货币事件的单位(如
    USD
    ,
    EUR
  • description
    (可选但推荐):人类可读的说明
添加事件后,请运行
npx @traffical/cli push
同步到平台。
即使未在配置中定义,运行时通过
track()
调用的事件也会显示在控制台中,但在配置中定义事件可以添加说明、值类型,确保配置文件作为唯一可信源,避免与控制台出现配置漂移。

Namespaces

命名空间

Namespaces are optional organizational groupings for parameters. They help organize parameters in the dashboard but do not affect how you use them in code.
yaml
parameters:
  bookmarks.max_stored:
    type: number
    default: 100
    namespace: bookmarks   # optional organizational grouping
    description: Maximum bookmarks per user
  • The
    "main"
    namespace is the default and is omitted from config
  • When parameters are imported from the dashboard (via
    npx @traffical/cli pull
    or during
    init
    ), they may include
    namespace: <name>
    — this is normal
  • Namespace is independent of dot-notation naming (e.g.,
    bookmarks.max_stored
    can be in namespace
    bookmarks
    , but this is a convention, not enforced)
  • You do not need to specify a namespace when creating new parameters — they will use the default namespace
命名空间是可选的参数组织方式,可帮助在控制台中整理参数,但不影响代码中的使用方式。
yaml
parameters:
  bookmarks.max_stored:
    type: number
    default: 100
    namespace: bookmarks   # 可选的组织分组
    description: 用户可存储的最大书签数量
  • 默认命名空间为
    main
    ,在配置中可省略
  • 从控制台导入参数时(通过
    npx @traffical/cli pull
    或初始化),参数可能包含
    namespace: <name>
    ——这是正常现象
  • 命名空间与点符号命名无关(例如
    bookmarks.max_stored
    可属于
    bookmarks
    命名空间,但这只是约定,并非强制要求)
  • 创建新参数时无需指定命名空间——将使用默认命名空间

Parameter Naming Conventions

参数命名规范

Use dot notation:
category.subcategory.name
CategoryExamplesUse case
feature.*
feature.new_checkout
,
feature.dark_mode
Feature flags (boolean)
ui.*
ui.cta.text
,
ui.hero.variant
Visual variations
pricing.*
pricing.discount
,
pricing.tier_multiplier
Pricing experiments
copy.*
copy.headline
,
copy.cta_text
Copywriting tests
experiment.*
experiment.checkout.variant
Explicit variant names
请使用点符号:
category.subcategory.name
分类示例适用场景
feature.*
feature.new_checkout
,
feature.dark_mode
功能标志(布尔类型)
ui.*
ui.cta.text
,
ui.hero.variant
视觉变体
pricing.*
pricing.discount
,
pricing.tier_multiplier
定价实验
copy.*
copy.headline
,
copy.cta_text
文案测试
experiment.*
experiment.checkout.variant
显式变体名称

Best Practices

最佳实践

  1. Always use the CLI — Run
    npx @traffical/cli push
    after editing config. Run
    npx @traffical/cli status
    to check sync state. Never skip the CLI — it is the bridge between your config files and the Traffical platform.
  2. Check existing parameters first — Look in
    .traffical/config.yaml
    (or
    traffical.yaml
    ) before creating new ones. Run
    npx @traffical/cli status
    to see what's already defined. Reuse existing parameters where possible.
  3. Define parameters in config, then push — Add new parameters to
    .traffical/config.yaml
    and run
    npx @traffical/cli push
    to sync them. This keeps the config file as the source of truth and prevents drift with the dashboard.
  4. Always provide in-code defaults — Defaults appear in two places: in
    config.yaml
    (the source of truth for the dashboard and experiment setup) and in your
    getParams()
    /
    useTraffical()
    calls (the offline fallback). In-code defaults are what the SDK returns when the config bundle hasn't loaded yet or is unreachable. The bundle's resolved value always takes precedence when available.
  5. Track events at conversion points — Call
    track()
    on purchases, signups, and other valuable actions. This enables adaptive optimization.
  6. Group related parameters — Keep correlated params in one
    useTraffical()
    /
    getTraffical()
    /
    getParams()
    call for proper attribution.
  7. Use meaningful param names — Follow dot notation:
    category.subcategory.name
    . Be descriptive.
  1. 始终使用CLI——编辑配置后运行
    npx @traffical/cli push
    。运行
    npx @traffical/cli status
    检查同步状态。请勿跳过CLI——它是连接配置文件与Traffical平台的桥梁。
  2. 先检查现有参数——在创建新参数前,请查看
    .traffical/config.yaml
    (或
    traffical.yaml
    )。运行
    npx @traffical/cli status
    查看已定义的参数。请尽可能复用现有参数。
  3. 先在配置中定义参数,再推送——在
    .traffical/config.yaml
    中添加新参数,然后运行
    npx @traffical/cli push
    同步到平台。这确保配置文件作为唯一可信源,避免与控制台出现配置漂移。
  4. 始终在代码中提供默认值——默认值出现在两个地方:
    config.yaml
    中(控制台和实验设置的可信源),以及
    getParams()
    /
    useTraffical()
    调用中(离线回退值)。代码中的默认值是SDK在配置包未加载或不可用时返回的值。当配置包可用时,解析后的值将优先使用。
  5. 在转化节点跟踪事件——在用户完成购买、注册等有价值的操作时调用
    track()
    。这是实现自适应优化的前提。
  6. 分组相关参数——将相关参数放在同一个
    useTraffical()
    /
    getTraffical()
    /
    getParams()
    调用中,以确保正确归因。
  7. 使用有意义的参数名称——遵循点符号规范:
    category.subcategory.name
    。名称应具有描述性。

What You Don't Need to Know

无需关注的内部细节

These are internal concepts handled by Traffical automatically:
  • Layers, policies, allocations — Experiment infrastructure is managed in the dashboard
  • Bucket assignment and hashing — Deterministic user assignment happens automatically
  • Whether an A/B test vs. optimization is running — Your code is the same either way
  • Statistical significance calculations — Traffical handles analysis in the background
  • Decision deduplication — Multiple resolution calls are handled efficiently
Just parametrize your app, track conversions, and let Traffical handle the rest.
以下是Traffical自动处理的内部概念,你无需关心:
  • 层级、策略、分配机制——实验基础设施由控制台管理
  • 用户分组与哈希算法——确定性用户分组自动完成
  • 当前运行的是A/B测试还是优化——你的代码无需区分
  • 统计显著性计算——Traffical在后台自动处理分析
  • 决策去重——多次解析请求会被高效处理
只需将你的应用参数化,跟踪转化事件,剩下的交给Traffical即可。

Documentation

文档