Introduction
React overlay for the TradingView Charting Library that adds iC Candle’s pattern scanner, results iframe, pattern tracker, and news/event integration in one package.
Published as ESM and CommonJS; component styles are bundled and injected at runtime (no separate CSS import).
| Surface | Role |
|---|---|
| Scanner popup | Draggable overlay over the chart. Select a bar window via the managed date_range selector, then run a scan or subscribe to pattern alerts. |
| Results iframe | Host-owned side panel pointing at the iC Candle embed app (embed-iccandle-app.iccandle.ai) — search results, similar events, auth, billing. Navigate it via submitCallback; use header=false to hide embed chrome. |
| Chart sync | Bidirectional postMessage bridge: pattern selection, chart replay, news marks, sign-in tokens, loading state, pricing, chart resolution. |
Install
npm install @iccandle/reactjs-widget
# or
pnpm add @iccandle/reactjs-widget
Prerequisites
| Requirement | Details |
|---|---|
| React 18+ | react and react-dom are peer dependencies — install them in your app. |
| TradingView Charting Library | Obtain from TradingView, host static assets (e.g. /charting_library/ in public), and bootstrap the widget yourself. This package does not ship the charting library. |
Quick start
import { useCallback, useEffect, useRef, useState } from "react";
import type {
ChartingLibraryWidgetOptions,
IChartingLibraryWidget,
ResolutionString,
} from "charting_library/charting_library";
import { widget } from "charting_library/charting_library";
import {
WidgetIccandle,
withPlayChart,
getCustomIndicators,
handleResultIframeLoad,
WIDGET_RESULT_URL,
} from "@iccandle/reactjs-widget";
const LIBRARY_PATH = "/charting_library/";
function App() {
const containerRef = useRef<HTMLDivElement>(null);
const resultIframeRef = useRef<HTMLIFrameElement | null>(null);
const [chartWidget, setChartWidget] = useState<IChartingLibraryWidget | null>(
null,
);
const [iframeSrc, setIframeSrc] = useState(
`${WIDGET_RESULT_URL}/en?theme=light&header=false`,
);
const [iframeLoaded, setIframeLoaded] = useState(false);
const submitCallback = useCallback((nextSrc: string) => {
const url = new URL(nextSrc);
url.searchParams.set("header", "false");
setIframeSrc((prev) => (prev === url.toString() ? prev : url.toString()));
}, []);
const handleIframeLoad = useCallback(() => {
setIframeLoaded(true);
handleResultIframeLoad(resultIframeRef.current);
}, []);
return (
<div className="iccandle-selector-widget__container">
<div className="iccandle-selector-widget__chart-pane">
<WidgetIccandle
chartWidget={chartWidget}
submitCallback={submitCallback}
theme="light"
language="en"
iframeLoaded={iframeLoaded}
resultIframeRef={resultIframeRef}
>
<ChartHost
containerRef={containerRef}
onReady={setChartWidget}
/>
</WidgetIccandle>
</div>
<iframe
ref={resultIframeRef}
src={iframeSrc}
className="iccandle-selector-widget__iframe"
title="iC Candle results"
onLoad={handleIframeLoad}
/>
</div>
);
}
function ChartHost({
containerRef,
onReady,
}: {
containerRef: React.RefObject<HTMLDivElement | null>;
onReady: (w: IChartingLibraryWidget | null) => void;
}) {
useEffect(() => {
const el = containerRef.current;
if (!el) return;
const options: ChartingLibraryWidgetOptions = {
container: el,
library_path: LIBRARY_PATH,
symbol: "EURUSD",
interval: "60" as ResolutionString,
datafeed: withPlayChart(yourDatafeed), // enables chart replay injection
locale: "en",
autosize: true,
drawings_access: {
type: "black",
tools: [{ name: "Date Range" }],
},
custom_indicators_getter: () => getCustomIndicators("light"),
};
const tv = new widget(options);
onReady(tv);
return () => {
try {
tv.remove();
} catch {
/* no-op */
}
onReady(null);
};
}, [containerRef, onReady]);
return <div ref={containerRef} style={{ height: "100%", width: "100%" }} />;
}
Pass resultIframeRef and call handleResultIframeLoad on iframe load so the embed receives the host origin (required for sign-in to write iccandle_token) and so Stripe ?payment=success can refresh the subscription.
Typical flow
- User activates the scanner and adjusts the bar window (the widget manages a
date_rangeshape on the chart). - Scanner caches the selected candles and calls
submitCallbackwith an embed URL (host sets the results iframesrc; useheader=falseto hide embed chrome). - The embed app returns matches; selecting a pattern redraws the range on the chart. Replay / news flows inject predicted candles via custom indicators.
Next steps
- Get started — install, host charting library, bootstrap TradingView, wrap with
WidgetIccandle - Configuration — props, exports, auth, postMessage bridge, theming
- Seamless auth example — sign the user in with
get-user-token - Troubleshooting — common issues