Implement snapshots server
Wire chart screenshots to your backend so takeScreenshot() (and the top-bar camera) can upload a PNG and return a public image URL.
How uploads work
- The SDK captures the chart (
takeClientScreenshot/ built-in camera). - For hosted uploads it calls either:
image_storage_adapter.upload(blob)(preferred when set), orPOSTto construct-timesnapshot_urlwith multipart fieldpreparedImage(PNG).
- The response must yield an image URL (plain text body, or JSON with
url/imageUrl/ similar). - The widget emits
onScreenshotReadywith that URL.
const chart = GoChartingSDK.createChart("#chart", {
datafeed: myDatafeed,
symbol: "NASDAQ:AAPL",
interval: "1D",
licenseKey: "YOUR_LICENSE_KEY",
snapshot_url: "https://your.api/snapshots",
onReady: () => {
chart.subscribe("onScreenshotReady", (imageUrl) => {
console.log("Uploaded:", imageUrl);
});
},
});
// Later:
const imageUrl = await chart.takeScreenshot();Option A — snapshot_url (HTTP endpoint)
Client
snapshot_url: "https://api.example.com/snapshots",Request contract
| Item | Value |
|---|---|
| Method | POST |
| Body | multipart/form-data |
| File field | preparedImage (PNG, filename like chart.png / snapshot.png) |
| Credentials | Omitted by the SDK (credentials: "omit" on the fetch path) |
Response contract
Return the public URL of the stored image:
- Plain text — body is the URL string (optional surrounding quotes are stripped).
- JSON — object with a string field such as
url,imageUrl,src, orlocation.
Examples:
https://cdn.example.com/snaps/abc123.png{ "url": "https://cdn.example.com/snaps/abc123.png" }Non-2xx responses cause takeScreenshot() to reject.
Minimal Node server
import express from "express";
import multer from "multer";
import { randomUUID } from "crypto";
import { writeFile } from "fs/promises";
import path from "path";
const app = express();
const upload = multer({ storage: multer.memoryStorage() });
const PUBLIC_BASE = "https://cdn.example.com/snaps";
app.post("/snapshots", upload.single("preparedImage"), async (req, res) => {
if (!req.file) {
return res.status(400).send("missing preparedImage");
}
const id = randomUUID();
const fileName = `${id}.png`;
await writeFile(path.join("/var/www/snaps", fileName), req.file.buffer);
// Plain-text URL (also valid: res.json({ url: ... }))
res.type("text/plain").send(`${PUBLIC_BASE}/${fileName}`);
});
app.listen(3001);Point the chart at that route:
snapshot_url: "https://api.example.com/snapshots",Serve the saved files from your CDN or static host so the returned URL is reachable in the browser.
Option B — image_storage_adapter (preferred)
When both are set, image_storage_adapter.upload wins over snapshot_url. Use this to call S3, GCS, or your own SDK without a fixed multipart URL.
const chart = GoChartingSDK.createChart("#chart", {
datafeed: myDatafeed,
symbol: "NASDAQ:AAPL",
interval: "1D",
licenseKey: "YOUR_LICENSE_KEY",
image_storage_adapter: {
async upload(blob) {
const form = new FormData();
form.append("file", blob, "chart.png");
const res = await fetch("https://api.example.com/upload", {
method: "POST",
body: form,
headers: { Authorization: `Bearer ${token}` },
});
if (!res.ok) throw new Error("upload failed");
const { url } = await res.json();
return url; // must be a non-empty string
},
},
});Local-only capture (no server)
If you only need a canvas or data URL in the page:
const canvas = await chart.takeClientScreenshot();
const dataUrl = canvas.toDataURL("image/png");takeClientScreenshot does not call snapshot_url or the image adapter.
Top-bar camera
The built-in screenshot control uses the same upload path when configured. Hide it with exclude options if you only want programmatic capture — see Configuration and Chart API exclude.screenshot.
Checklist
- Endpoint accepts
POSTmultipart with fieldpreparedImage - Response is a reachable HTTPS image URL (text or JSON)
- CORS allows your chart origin if the upload host differs
- Prefer
image_storage_adapterwhen you need auth headers or custom storage - Subscribe to
onScreenshotReadyand/orawait chart.takeScreenshot()
Related
- Chart API —
takeScreenshot,takeClientScreenshot,onScreenshotReady - Configuration —
snapshot_url,image_storage_adapter