Default Values
Default value vs override rules
Section titled “Default value vs override rules”Every GrowthBook Feature has two layers of value resolution:
- Override rules — conditions, percentage rollouts, or experiment assignments you configure per environment. When a rule matches the current user context, it wins.
- Default value — the value returned when no rule matches. This is your safe floor.
When GrowthBook is completely unreachable (network error, CDN outage), the SDK falls back to the fallback argument you pass directly in your code — it never returns null or throws.
The three fallback layers
Section titled “The three fallback layers”flowchart TD
call["SDK call"] --> loaded{"GrowthBook loaded?"}
loaded -- "YES" --> rules["Evaluate rules"]
loaded -- "NO" --> fb["Return the fallback argument from your code"]
rules --> match{"Match found?"}
match -- "Yes" --> rv["Return rule value"]
match -- "No match" --> dv["Return Feature default value"] Always pass a sensible fallback
Section titled “Always pass a sensible fallback”// BAD — if GrowthBook is unreachable, getFeatureValue returns undefinedconst text = gb.getFeatureValue('banner-text');
// GOOD — safe fallback keeps the app workingconst text = gb.getFeatureValue('banner-text', 'Welcome');The fallback argument is the last line of defence. It should represent the experience you want users to have if GrowthBook is down — usually the current, stable behaviour.
Setting the default value in GrowthBook
Section titled “Setting the default value in GrowthBook”- Open a Feature in the GrowthBook UI.
- Click Edit next to the Default Value field.
- Enter the value, e.g.
Welcomefor a string flag. - Click Save.
The default value takes effect immediately for all environments where no override rule produces a match.
Changing the default value
Section titled “Changing the default value”To update a default value without adding a rule:
- Open the Feature.
- Click Edit on the Default Value.
- Change the value and click Save.
The change is applied globally across every environment that does not have an overriding rule. No deploy required.
Worked example — banner text
Section titled “Worked example — banner text”import { GrowthBook } from '@growthbook/growthbook';
const gb = new GrowthBook({ apiHost: 'https://cdn.growthbook.io', clientKey: process.env.GROWTHBOOK_CLIENT_KEY, attributes: { id: 'user-123', country: 'TH', },});
await gb.init({ timeout: 2000 });
// Returns the GrowthBook default value when no rule matches,// or 'Welcome' when GrowthBook cannot be reached.const bannerText = gb.getFeatureValue('banner-text', 'Welcome');
document.getElementById('banner').textContent = bannerText;import { GrowthBook } from '@growthbook/growthbook';
const gb = new GrowthBook({
apiHost: 'https://cdn.growthbook.io',
clientKey: process.env.GROWTHBOOK_CLIENT_KEY,
attributes: {
id: 'user-123',
country: 'TH',
},
});
await gb.init({ timeout: 2000 });
// Safe fallback: 'Welcome' is used only if GrowthBook
// cannot be reached at all.
const bannerText = gb.getFeatureValue('banner-text', 'Welcome');
document.getElementById('banner').textContent = bannerText;Trade-offs
Section titled “Trade-offs”| Option | Benefit | Cost |
|---|---|---|
| Safe fallback default value | The app doesn’t break even if the SDK fails | The feature may look less complete during fallback |
| Default matching the new experience | Closer to what you intended | Risky if the SDK fails and you have to rely on this default |
Common mistakes
Section titled “Common mistakes”- Setting the default value to “on” for a risky feature (it should always be a safe fallback)
- Not testing that the app behaves correctly when the SDK cannot connect and falls back to the default
- Forgetting that the default value is different from “the value set in the UI”
💡 Real-world example
Feature-flagging systems at large scale are commonly designed so the default is always “safe” when the config service is down, so the whole app doesn’t crash.