Feature Gates
ChartFeatures is the typed product-capability contract for a chart widget.
Use it to decide which controls and workflows are available without coupling
application code to chart implementation details.

Gate by user surface
| Surface | Decision inputs | Required consistency |
|---|---|---|
| Symbol and data controls | Datafeed capabilities plus symbol-search, interval, and comparison settings | Do not show options the feed cannot resolve/load |
| Indicators and drawings | Product entitlement plus indicator/drawing feature objects | Remove or preserve active objects according to documented lifecycle |
| Storage and templates | Storage adapter plus storage feature gates | Hide actions when no implementation exists |
| Trading and order flow | Broker capabilities plus host permission | Never expose an action the broker will always reject |
| Accessibility and shortcuts | Host policy plus accessibility/shortcut settings | Preserve an alternate path when hiding chrome |
sdk.chart.mount({
mount: '#chart',
symbol: 'AAPL',
interval: '1D',
datafeed,
features: {
symbolSearch: {
showLogos: true,
showExchangeLogos: true,
allowArbitraryInput: false,
},
chartTypes: ['candles', 'line', 'area'],
customIntervals: ['1m', '5m', '15m', '1H', '1D'],
comparisons: {
enabled: true,
showSymbolLabels: true,
extendTimeScale: false,
},
drawings: {
enabled: true,
persistenceMode: 'embedded',
},
builtInIndicators: true,
templates: true,
contextMenu: true,
objectTree: true,
userSettings: true,
shortcuts: true,
},
});
Defaults, owners, and runtime changes
Three rules apply to every gate in the matrix below:
- Default: a gate is enabled unless set to
false, except where the Default column says otherwise. Gates with an external dependency are enabled only while that dependency is met. - Owner: a gate controls availability only. The state it exposes belongs to the owner listed under Feature Ownership; the gate never becomes a second state store.
- Runtime mutability: the runtime counterparts that exist are
chart.customization().setShortcuts(...),setToolbar(...), andsetContextMenu(...), which adjust behavior within an enabled gate.
features is fixed at constructionThere is no setFeatures. Turning a gate on or off requires recreating the
widget, so decide feature policy before you mount. Plan any product tier that
changes a user's available features as a remount, not a live update.
Capability matrix by surface
Symbol and market data
| Gate | Default | Affected UI | Depends on |
|---|---|---|---|
symbolSearch | On | Search input, filtering, logos, arbitrary-input policy, request behavior | — |
comparisons | On | Comparison search, symbol labels, time-scale extension | — |
watchlist | On while supported | Watchlist panel and toolbar entry | Datafeed getWatchlist and updateWatchlist |
news | On while supported | News panel | Datafeed getNews |
details | On | Instrument details panel | — |
dataWindow | On | Data-window panel | Market-data controller attached |
marketEvents | On | Market-event markers | Configured event providers |
sessionBadge | On | OHLC-row market session badge, variant, popover | — |
sessions | On | Session shading, break lines, extended-hours selector | — |
orderFlow | On while supported | Order-flow overlays dropdown (footprint, liquidity heatmap) | Datafeed depth: getDepth or subscribeDepth |
invalidSymbol | On | Visible state for unresolved symbols or failed initial history | — |
Chart canvas, indicators, and drawings
| Gate | Default | Affected UI | Depends on |
|---|---|---|---|
chartTypes | On; array restricts | Chart-type selector and available types | — |
customIntervals | On | Custom-interval entry in the interval selector | — |
intervalFamilies | Policy object | Interval families offered before datafeed/symbol narrowing | — |
drawings | On | Drawing tools, rail visibility, storage mode, sharing | Persistence additionally needs a storage adapter with drawing operations |
drawingTools | All tools | Restricts the available drawing-tool ids | drawings enabled |
builtInIndicators | On; array restricts | Built-in indicator catalog, exclusions, disabled states, defaults | — |
customIndicators | On | Registered custom indicators and time-scale extension | Host-registered indicator definitions |
indicatorInputs | On | Indicator input editing and symbol-valued input search | — |
replay | On | Bar replay controls | Replay controller wired; state persistence needs the storage adapter |
offscreenRenderSuspend | On | Suspends engine layout/paint while the chart is scrolled off-screen | — |
chartControls | On | Floating quick buttons, pane-header controls, settings-dialog presentation | — |
Toolbars, menus, and input
| Gate | Default | Affected UI | Depends on |
|---|---|---|---|
contextMenu | On | Chart, scale, and object context menus | — |
shortcuts | On | Widget-root keyboard actions (runtime: setShortcuts) | — |
actions | On | Custom-action registration surface | — |
mobileToolbar | Off (opt-in) | Mobile toolbar | — |
priceAxisScaleControls | On | Price-axis scale controls and quick actions | — |
objectTree | On | Object-tree panel visibility and interactions | — |
Storage and workspace
| Gate | Default | Affected UI | Depends on |
|---|---|---|---|
layoutStorage | On while supported | Chart-layout persistence, storage toolbar entry, favorites | Storage adapter chart-layout operations |
workspaceTabs | Off (opt-in) | Named chart-layout tabs, restoration, autosave, tab strip | Chart-layout storage adapter |
workspaceLayoutControls | On (multi-chart) | Native multi-chart split/remove/sync controls | Multi-chart widget |
workspaceLegend | Per-chart saved settings | Multi-chart legend display policy | Multi-chart widget |
userSettings | On | User-setting API and optional persistence | Persistence needs storage adapter user-settings operations |
templates | On | Chart, indicator, and drawing template workflows plus the storage-menu entry (chart / indicator / drawing / toolbar / importExport sub-flags) | Template storage via the storage adapter |
Trading
| Gate | Default | Affected UI | Depends on |
|---|---|---|---|
trading | On | On-chart trading affordances, order ticket, depth ladder, account manager, price-axis order UI, notifications | Broker adapter attached for live actions |
alerts | On | Alert creation UI and overlays | — |
Boolean and object forms
Many capability groups accept either a boolean or an object. Use the boolean form when only availability matters and the object form when the feature has its own policy.
features: {
drawings: true,
workspaceTabs: {
enabled: true,
restoreActive: true,
autoSave: { delayMs: 1200 },
maxVisible: 8,
},
userSettings: {
enabled: true,
persistence: false,
},
}
Feature ownership
A feature gate controls availability; it does not become a second state store.
- Chart-layout identity and persistence belong to
ChartWorkspaceLayoutController. - Chart state belongs to
ChartApiandChartState. - Visual values belong to
CustomizationState,ChartTheme, and typed style settings. - Data capability truth belongs to
MarketDataFeedandSymbolInfo. - Broker actions belong to
TradingBrokerAdapter. - Widget and terminal panel arrangement belongs to
WidgetLayoutStateand its separate widget layout storage boundary, outside chart workspace storage.
Host-owned UI
The SDK intentionally leaves application-shell concerns to the host. Compose
navigation, account management, page routing, onboarding, permission prompts,
and terminal panel arrangement around the chart. Register chart actions with
chart.customization().registerAction(...) when host UI needs to invoke chart
behavior.
Why typed features
Typed features provide:
- editor autocomplete and compile-time validation
- clear ownership for nested policies
- stable persistence and inspection
- explicit defaults
- direct mapping from product requirements to SDK configuration
Unknown or invalid fields are reported by customization inspection instead of being silently forwarded into the runtime.
Built-in controls
Every control the SDK renders has a public identity, on the same terms as the
actions you register yourself. Host-registered actions are ordered and hidden by
id through toolbar.groups, toolbar.actionIds, and toolbar.hiddenActionIds;
built-in controls carry the same three facts — a stable id, the surface that
owns them, and the typed option that gates them.
import {
BUILT_IN_CONTROLS,
getBuiltInControl,
listBuiltInControlsForSurface,
} from '@tradescript/pro/sdk';
listBuiltInControlsForSurface('period-bar').map((control) => control.id);
// ['toolbar', 'toolbar.hints', 'toolbar.quick-search', 'toolbar.interval-selector', ...]
getBuiltInControl('toolbar.screenshot');
// { id, label: 'Screenshot', surface: 'period-bar', group: 'export',
// visibility: { option: 'toolbar', field: 'screenshotButtonVisible' } }
Each entry's visibility names the option that shows or hides it today, so the id and
the switch are never out of step:
chart.customization().setToolbar({ screenshotButtonVisible: false });
Surfaces are period-bar, drawing-sidebar, chart-canvas, pane-header and
time-scale; CHART_CONTROL_SURFACES lists them. Resolve ids with
isBuiltInControlId — exact inventory membership, never an id prefix.
The inventory supplies identity and gating: every built-in control has a public id, a surface owner, and the typed option that shows or hides it. Ordering those ids alongside your own controls, replacing what one renders, and adding controls of your own build on the same ids — see Toolbar and Settings Extensions.
Related pages
- Customization Precedence — where feature policy sits relative to themes, overrides, and saved state.
- Chrome Slots — styling the controls a gate leaves visible.
- Toolbar and Settings Extensions — ordering those ids and rendering your own controls among them.
- Toolbars — the visible controls each toolbar gate governs.
- Widget Options — where
featuresis passed at construction.