Skip to main content

Resume bar replay

Use this optional integration only when users need to stop a bar-replay session and continue it later. Replay persistence is a bookmark: it restores the replay position and playback speed after a reload or device switch.

It saves status, startBarIndex, currentBarIndex, totalBars, speed, persistedAt, and optional metadata. It does not save historical bars, market data, datafeed state, layouts, drawings, indicators, trades, or replay results. The datafeed must load the required history again before the bookmark can be restored.

The built-in replay bar has no Save or Resume action, and the widget does not automatically save or load replay state. Call saveState() and loadState() from your own UI, or build an autosave policy from replay events. A restored playing session always opens as paused, so loading never starts playback without user action.

The full playback lifecycle is covered in Replay. This page defines only its storage boundary.

Adapter support

AdapterSave and load replay state
Default browser-local adapterSupported
createLocalChartStorageAdapterSupported
createRestChartStorageAdapterSupported through the fixed /replay route
Custom ChartStorageAdapterSupported when it implements both replay methods

Use the REST adapter when replay progress must follow an authenticated user across devices and your backend can expose the standard route. Use a custom adapter only when your route or transport must differ.

Configure replay persistence

The same createRestChartStorageAdapter used for layouts, drawings, templates, and settings now implements saveReplayState and loadReplayState. Configure it once and pass it as the chart's storage option.

replayStorage.ts
import { createRestChartStorageAdapter } from '@tradescript/pro/sdk';

declare function getAccessToken(): Promise<string>;

export const storage = createRestChartStorageAdapter({
baseUrl: 'https://api.example.com/chart-storage',
apiVersion: 'v1',
clientId: 'pro-terminal',
userId: 'user-123',
workspaceId: 'primary',
headers: async () => ({
Authorization: `Bearer ${await getAccessToken()}`,
}),
});

The factory makes no request during construction. Keep authenticated identity on the server; user, workspace, and chart context in the query are routing keys, not proof of authorization.

Implement the REST route

With the configuration above, replay uses these operations:

OperationRequest and body
SavePOST /v1/replay?layout={layoutId} with { "state": ReplayState }
LoadGET /v1/replay?layout={layoutId}

The adapter also sends configured client, user, and workspace context, plus request-level chartId, symbol, and interval when available. A request can override the configured user and workspace. The layout query is omitted when no layoutId is supplied.

Load may return ReplayState directly or under state, with or without the standard { "status": "ok", "data": ... } envelope. Return 404 when no bookmark exists; the adapter maps it to null. Other HTTP failures reject.

See REST chart storage adapter for the complete response and production rules.

Save and restore

const replay = widget.replay();

await replay.saveState({
layoutId: 'opening-drive',
chartId: 'chart-1',
});

const restored = await replay.loadState({
layoutId: 'opening-drive',
chartId: 'chart-1',
});

saveState() stamps persistedAt. loadState() resolves null when no state exists.

Verify the boundary

  • Save after moving the replay cursor, reload the page, and restore with the same chart and layout context.
  • Confirm the restored cursor and speed match, while status is paused if the saved session was playing.
  • Load with a different user, workspace, chart, and layout in turn; each must miss unless sharing is intentional.
  • Confirm no replay state is written until your integration calls saveState(); the built-in controls do not persist it automatically.

Next steps