Horizon Framework

Configuration Variables

Configuration variables allow you to read runtime configuration values stored in the platform. They are fetched from the platform API at /configuration/extension/<key>.

Results are cached using the SWR (Stale-While-Revalidate) strategy. The first call fetches from the API and populates the cache. Subsequent calls within the TTL (1 hour) return the cached value immediately while a background refresh is triggered to keep the cache warm. Use the bypassCache option to skip the cache and always fetch fresh data.

React Hook: useConfigurationVariable

Use useConfigurationVariable inside a React component to reactively fetch a configuration variable. The hook re-fetches automatically when the key changes. Errors are suppressed internally — if the API call fails, value is null and loading returns to false. Use fetchConfigurationVariable directly if you need explicit error handling.

import { useConfigurationVariable } from '@skedulo/horizon-core'

const MyComponent = () => {
  const { value, loading } = useConfigurationVariable('MY_CONFIG_KEY')

  if (loading) return <div>Loading...</div>

  return <div>Config Value: {value ?? 'Not configured'}</div>
}
// Bypass the SWR cache to always fetch fresh data
const MyComponent = () => {
  const { value, loading } = useConfigurationVariable('MY_CONFIG_KEY', {
    bypassCache: true,
  })

  if (loading) return <div>Loading...</div>

  return <div>Config Value: {value ?? 'Not configured'}</div>
}

Parameters

ParameterTypeDescription
keystringThe configuration key to fetch
optionsobjectOptional settings
options.bypassCacheboolean (default: false)When true, skips the SWR cache and always fetches fresh data

Return Value

PropertyTypeDescription
valuestring | nullThe configuration variable value, or null if not yet loaded or if the request failed
loadingbooleantrue while the request is in flight

Standalone Function: fetchConfigurationVariable

Use fetchConfigurationVariable outside of React components (e.g. in services or utility functions) when you need to fetch a configuration variable imperatively.

import { fetchConfigurationVariable } from '@skedulo/horizon-core'
import { ApiClientV1 } from '@skedulo/horizon-core'

// Throws on error (default behaviour) — result is served from the SWR cache
const variable = await fetchConfigurationVariable(apiClient, 'MY_CONFIG_KEY')
console.log(variable?.value)

// Suppress errors — returns null instead of throwing
const variable = await fetchConfigurationVariable(apiClient, 'MY_CONFIG_KEY', {
  suppressErrors: true,
})

// Bypass the cache — always fetch fresh data from the API
const variable = await fetchConfigurationVariable(apiClient, 'MY_CONFIG_KEY', {
  bypassCache: true,
})

Parameters

ParameterTypeDescription
apiClientApiClientV1An API client instance
keystringThe configuration key to fetch
optionsIFetchConfigurationVariableOptionsOptional settings
options.suppressErrorsboolean (default: false)When true, errors are caught and null is returned instead of rethrowing
options.bypassCacheboolean (default: false)When true, skips the SWR cache and always fetches fresh data from the API

Return Value

Returns Promise<IConfigurationVariable | null>.

  • Resolves to an IConfigurationVariable object ({ key: string; value: string }) on success.
  • Resolves to null when suppressErrors is true and an error occurs.
  • Throws the caught error when suppressErrors is false (default).

Caching

Both fetchConfigurationVariable and useConfigurationVariable use a shared SWR cache backed by CacheFactory from horizon-framework.

  • Strategy: Stale-While-Revalidate (SWR). When a cached entry exists and has not expired, its value is returned immediately and a background refresh is triggered to keep the cache warm.
  • TTL: 1 hour (default from CacheFactory).
  • Persistence: Cached entries are persisted to IndexedDB so they survive page refreshes.
  • Background refresh throttle: Background refreshes are throttled to at most once per minute per key to avoid hammering the API.

Bypass Cache

Pass bypassCache: true to skip the cache entirely and always fetch fresh data from the API. This is useful in scenarios where you need the latest value unconditionally, such as after performing a mutation.

// Fetch fresh data without reading from or writing to the cache
const variable = await fetchConfigurationVariable(apiClient, 'MY_CONFIG_KEY', {
  bypassCache: true,
})

Cache Control (localStorage)

The cache behaviour can be controlled globally via localStorage. This is primarily useful for debugging or in automated tests.

HORIZON_CORE_ENABLED_CACHES valueEffect
all (default)Persisted cache enabled for all keys
localIn-memory cache only (no IndexedDB)
noneAll caching disabled (NoOp)
<comma-separated names>Enable only named caches

Error Handling

useConfigurationVariable suppresses errors internally — when the API call fails, value is null and loading returns to false. The hook does not expose an error property. This keeps component code simple for the common case where a missing config variable is treated as "not configured".

If you need to distinguish between a successful null response and an API failure, use fetchConfigurationVariable directly:

// Let the error propagate — caller handles it
try {
  const variable = await fetchConfigurationVariable(apiClient, 'MY_CONFIG_KEY')
} catch (error) {
  console.error('Failed to load config:', error)
}

// Suppress the error — returns null on failure
const variable = await fetchConfigurationVariable(apiClient, 'MY_CONFIG_KEY', {
  suppressErrors: true,
})
if (!variable) {
  // Handle missing config gracefully
}