Reference
TypeScript types
One declaration file, saved anywhere your tsconfig already looks, and vpEmbed is typed with no import, no dependency and nothing to bundle.
Getting them
The loader is a script at a URL rather than a package, so there is nothing for npm install to bring types along with. Download the declarations and put them wherever your tsconfig already includes. types/vp-embed.d.ts is the usual place.
curl -o types/vp-embed.d.ts https://view.verticalprop.com/embed.d.tsIt declares the surface and nothing else: no runtime code, no side effects, nothing that reaches a bundle. Deleting it changes only what your editor knows.
window.vpEmbed is typed with no import, and the named types are importable when you want to annotate your own code: import type { VpDatafeed } from '../types/vp-embed'. Writing a datafeed is where that pays for itself: the compiler reports a getBars returning seconds where the chart expects milliseconds.const chart = window.vpEmbed.chart('#mine');
if (!chart) throw new Error('not mounted yet');
await chart.setStyle({ bg: '#0b0f19', up: '#26a69a' });
// ^ the 10 roles, and nothing else, offered here
await chart.setInterval('60');
// ^ the intervals the frame accepts, as a union
chart.on('orderMove', (e) => {
// ^ every event name ^ typed { handle, price } for THIS event
moveOrder(e.handle, e.price);
});What is in it
| Type | What it is |
|---|---|
VpEmbed | The global: scan, datafeed, chart. |
VpChart | Everything you can call on a mounted chart, with on() typed per event. |
VpChartEvents | The event name → payload map. Its keys are the union VpChartEventName. |
VpChartStyle | The 10 colour roles. |
VpOrderLineProps | …and VpPositionLineProps, VpExecutionProps, VpToolbarButtonOptions. What a create* call takes. |
VpLineHandle | …and VpToolbarButton. What one resolves to. Generic in its own props, so handle.set() offers the right keys. |
VpDatafeed | Your side: VpBar, VpSymbolInfo, VpSearchItem, VpPeriodParams. The two required methods are non-optional and the four others are not. |
VpInterval | …and VpChartType, VpTheme, VpNumberFormat, VpLineStyle, VpSinglePointShape, VpMultiPointShape. Unions rather than string, which is where most of the value is. |
The unions are the point. lineStyle: number compiles and lineStyle: 9 is a commandError at runtime, because the engine draws five. VpLineStyle is 0 | 1 | 2 | 3 | 4, so the same mistake is caught in the editor. The same applies to intervals, chart types, shape names and colour roles: every allowlist the frame enforces is a union here.
They cannot drift from what the frame accepts
Every method, event, property and role in the file is paired against the allowlist the embed actually enforces, in BOTH directions. A method added to the loader with no declaration fails the build, and so does a declaration for something that no longer exists.
The second direction is the one that matters more. A missing type is an inconvenience you notice immediately; a STALE one is an editor confidently completing a call the frame will refuse, and the reader has no reason to doubt it. That is the same reasoning behind every other table in this reference, and it is why the declarations are hand-written and machine-checked rather than either alone: a generator can print lineStyle: 0 | 1 | 2 | 3 | 4 and cannot tell you that 2 is dashed.
window.vpEmbed is declared as always present, which is true once embed.js has executed and not before. There is no pre-load stub, so an inline script calling it beside an async loader tag loses the race. See the quickstart for why that snippet omits async.Without the loader
A page that writes its own postMessage bridge holds none of these objects. There is no VpChart, because that is the loader's wrapper. What it does hold is the same argument shapes: VpOrderLineProps is what goes in a command message's args, and VpChartEvents is what arrives in an event message's payload. Import those and leave the rest.
import type { VpChartEvents, VpOrderLineProps } from '../types/vp-embed';
function draw(props: VpOrderLineProps) {
frame.contentWindow!.postMessage({
ns: 'vp-embed', v: 1, type: 'command',
id: 'c1', method: 'createOrderLine', args: [props],
}, '*');
}
window.addEventListener('message', (ev: MessageEvent) => {
if (ev.origin !== 'https://view.verticalprop.com') return;
if (ev.source !== frame.contentWindow) return; // the one people forget
if (ev.data?.type !== 'event') return;
if (ev.data.name === 'orderMove') {
const p = ev.data.payload as VpChartEvents['orderMove'];
moveOrder(p.handle, p.price);
}
});The wire itself is on Wire messages, and the reasoning for writing your own bridge is on Without our script.