Configuration as Code
Introduction
Abby aims to have the best Developer Experience possible.
This is why Abby is fully configurable via Code. No need to click some buttons in a GUI.
You abby.config.ts
(or abby.config.js
) file is the single source of truth for your Abby project.
Your configuration should be written in a file called abby.config.ts
(or abby.config.js
) which should be located in the root of your project.
Every integration offers a defineConfig
helper function which offers a typesafe way to define your configuration.
import { defineConfig } from "@tryabby/core";
// or import { defineConfig } from "@tryabby/<integration>";
The config needs to be the default export of the file so that the CLI can find it.
import { defineConfig } from "@tryabby/core";
// or import { defineConfig } from "@tryabby/<integration>";
export default defineConfig(
{
// your projectId and other sensitive data here
},
{
// your flags, tests, etc. here
}
);
The first parameter includes all data that might be configured via environment variables. You should not use environment variables in the second parameter, because the type inference might suffer and the CLI could potentially resolve those environment variables!
Philosophy
This configuration has two purposes:
1. Integrations
Abby has many integrations to other tools and frameworks. Those can import the config and use it to configure themselves.
For example the @tryabby/nextjs
integration uses the config to configure the Next.js framework. Reading the config makes the integrations fully typesafe
2. CLI
The Abby CLI uses the config to know what to do. It reads from the config and can then be used to create tests or feature flags on the Abby platform without any further configuration.
Example
// abby.config.ts
import { defineConfig } from "@tryabby/core";
// or import { defineConfig } from "@tryabby/<integration>";
export default defineConfig(
{
projectId: "my-project-id",
currentEnvironment: "development",
},
{
environments: ["development", "production"],
tests: {
SignupButton: {
variants: ["A", "B"],
},
},
flags: ["showFooter"],
remoteConfig: {
customButtonText: "String",
maxUserCount: "Number",
AdvancedTestStats: "JSON",
},
settings: {
flags: {
defaultValue: false,
devOverrides: {
showFooter: true,
},
},
remoteConfig: {
defaultValues: {
JSON: {},
Number: 0,
String: "",
},
devOverrides: {
maxUserCount: 40,
AdvancedTestStats: {},
customButtonText: "My cool button",
},
},
},
}
);
Config Reference
The defineConfig
function takes two objects as a parameter, that will be merged together when read.
The merged object can contain the following properties:
Name | Type | Required | Description | details |
---|---|---|---|---|
projectId | string | ✅ | The ID of your project in Abby | - |
apiUrl | string | The URL of the Abby API. Defaults to the hosted version | - | |
currentEnvironment | string | ✅ | The current environment of your application | link |
tests | object | An object containing your defined A/B Tests | - | |
flags | array | An array containing your defined Feature Flag names | - | |
remoteConfig | object | An object containing your Remote Configuration variables | - | |
settings | object | An object with additional settings for Abby | - | |
debug | boolean | A boolean to show additional debug information | - | |
fetch | fetch | You can pass in a custom fetch function. Defaults to globalThis.fetch | - |
tests
The tests property is an object containing your defined A/B Tests. You probably want to use the Copy Button in your dashboard to copy the tests object. They keys of the object represent the names of your predefined A/B tests. The values are objects containing the following properties:
Name | Type | Required | Description |
---|---|---|---|
variants | Array<string> | ✅ | An array of strings containing the variants of the test |
Example
const abby = createAbby({
// ... your config
tests: {
"test-abtest": {
variants: ["control", "variant-a", "variant-b"],
},
},
});
flags
The flags property is an array containing your defined Feature Flags. You probably want to use the Copy Button in your dashboard to copy the flags array.
Example
const abby = createAbby({
// ... your config
flags: ["test-flag"],
});
remoteConfig
The remoteConfig property is an object containing your Remote Configuration variables and their respective types.
Example
const abby = createAbby({
// ... your config
remoteConfig: {
myStringVariable: "String",
myNumberVariable: "Number",
myJSONVariable: "JSON",
},
});
settings
The settings property is an object containing additional settings for Abby. The following properties are available:
-
flags.defaultValue
: Allows you to set a fallback boolean value for your Feature Flags, in case you forgot to add them in your dashboard or when they could not be fetched correctly.flags: { defaultValue: true, },
-
flags.devOverrides
: An object containing the values of feature flags in development mode. The keys of the object represent the names of the flags.flags: { devOverrides: { showHeader: true, showFooter: false, }, },
-
remoteConfig.defaultValues
: An object containing default values for each Remote Configuration type.remoteConfig: { defaultValues: { String: "Default string value", Number: 100, JSON: { default: true }, }, },
-
remoteConfig.devOverrides
: An object containing the values of Remote Configuration variables in development mode. The keys of the object represent the names of the flags. The values need to be of the type of the variable. The value must be of the same type as the variable.remoteConfig: { devOverrides: { myStringVariable: "dev mode string value", myNumberVariable: 100, JSON: { devMode: true }, }, },
debug
A boolean that you can toggle on to get debug information logged to the console. Mostly useful in development to see where something potentially goes wrong.
fetch
You can pass a custom fetch function in here. This defaults to the global fetch function. This is mostly needed for older versions of Node.js which don't have a global fetch function.