How it fits together
Traffic for document data goes through your backend: the widget only callsproxyUrl - your server holds the Bigdata credentials, reaches Bigdata’s Documents and Content APIs, and returns JSON (and file URLs) the viewer can use.
Where each part runs - the document viewer and your proxy live on your side; file storage, annotation, and catalog APIs run in Bigdata’s infrastructure.
What happens at each step - the browser issues GET requests to your proxyUrl; your server adds the API key, calls Bigdata, and returns RPJSON and signed URLs. Time-limited URLs are often re-fetched through /proxy-document on your side so the browser does not need direct cross-origin access to signed storage or your key.
Why you need a backend endpoint
End users can open developer tools and read any secret shipped to the page. The widget therefore sends only toproxyUrl. Your server (or serverless function, or BFF) should:
- Authenticate the end user if needed (cookie, session, or signed token).
- Add the Bigdata API key to the outbound request when you call Bigdata.
- Forward the external paths the widget uses
GET /proxy-document?url=…when dealing with a signed URL (without adding authentication).
Browser compatibility
The script bundle targets modern evergreen browsers. It is not supported in Internet Explorer or other legacy engines without current Web APIs. Supported browsers| Browser | Guidance |
|---|---|
| Chrome | Recent stable (desktop and Android). |
| Edge | Recent stable (Chromium-based). |
| Firefox | Recent stable. |
| Safari | 16.4 or newer on macOS and iOS. Earlier versions lack reliable support for constructible stylesheets and adoptedStyleSheets on the widget’s Shadow DOM, which the bundle uses to inject CSS. |
- JavaScript enabled - the widget mounts via script and does not render without JS.
- CORS to your
proxyUrl- if the embed and the API are on different origins, allowGET(and preflight whengetHeadersadds non-simple request headers). Misconfigured CORS is a common “nothing loads” symptom, see Troubleshooting. - Third-party cookies - not required for the default embed pattern - auth is between the visitor’s browser and your
proxyUrl(or headers fromgetHeaders, or cookies you set on that origin).
Quickstart
Add a sized container
Add a wrapper element and give it the size you want (fixed pixels, percentage, flex, grid, or
min-height-whatever fits your page). The widget mounts inside it and stretches to fill the container’s box.Load the script
Use the widget script URL from Bigdata. Example shape (version path may differ). Load it before the inline script that constructs the widget so
BigdataDocumentViewer is defined:Initialize the widget
Create the widget with
BigdataDocumentViewer.init({ ... }) (or new BigdataDocumentViewer.BigdataDocumentWidget({ ... })). At minimum set container and proxyUrl. Set openDocument when you know which file to show first, and add theme and getHeaders as needed-see the configuration reference below.The Bigdata web app’s Widget Playground (under Playground →
Widgets) loads the same UMD and wires
getHeaders to the signed-in
user-use it as a live example when you integrate auth.Global API: BigdataDocumentViewer
After the bundle loads, the UMD global BigdataDocumentViewer exposes init, BigdataDocumentWidget, and (for multiple widgets) BigdataWidgetManager. init(config) is equivalent to new BigdataDocumentWidget(config); both return the mounted instance.
UMD BigdataDocumentViewer members
| Property / method | Type | Description |
|---|---|---|
BigdataDocumentViewer.init | function | init(config): pass the config object in Configuration reference. |
BigdataDocumentViewer.BigdataDocumentWidget | class | Constructor: pass the same config as above. |
BigdataDocumentViewer.BigdataWidgetManager | class | Optional. Shared manager and base theme across
widgets. |
BigdataDocumentViewer.init(...) (or new ...BigdataDocumentWidget(...)) if you need to call destroy() or use addListener / emit.
Proxy contract (summary)
What your BFF should serve (per path)| Aspect | Expected behavior |
|---|---|
| Public doc | GET {proxyUrl}/v1/documents/{documentId}. The response is either a limited view or includes a signed url for the full annotated content - the widget may follow with /proxy-document to load RPJSON. Align with Fetch document. |
| Private doc | GET {proxyUrl}/contents/v1/documents/{documentId}/annotated. The JSON includes a signed url; the viewer loads RPJSON via /proxy-document. See Get annotated document. |
| Proxy pass-through | GET {proxyUrl}/proxy-document?url={encodeURIComponent(signedUrl)} - your server fetches signedUrl, returns the body to the client (RPJSON or bytes). Required when the browser must not call the signed host directly. |
| Original file | GET {proxyUrl}/contents/v1/documents/{documentId}/original for PDF / download flows, as used by the file URL helper. Match Get original document style responses. |
getHeaders, the widget merges the returned map onto requests the HTTP client makes to your proxyUrl (for example Authorization: Bearer ...).
Buffering and JSON - if the viewer stays on “loading” while your proxy already finished, check that your framework is not transforming or stripping the JSON body, and that CORS and proxy-document are implemented for GET.
Configuration reference
Top-level options
config options (top level)
| Option | Type | Description |
|---|---|---|
container | string or HTMLElement | Required. Where the widget mounts: a CSS selector that document.querySelector resolves, or a DOM element. |
proxyUrl | string | Required (for loading documents). The base of your BFF. Without it, the inner queries for RPJSON will not run. |
instanceId | string | Optional. Stable id for this instance when several widgets share a page;
if omitted, the implementation uses “document”. |
manager | BigdataWidgetManager | Optional. Shared manager across widgets for coordinated events and a common base theme. |
getHeaders | function | Optional. () => Promise<Record<string, string>> -
merged onto requests to your origin (e.g. bearer for your BFF). |
openDocument | object | Optional. Initial documentId, isPrivate, and
optional matchesInformation; see
openDocument (shape)
. |
theme | object | Optional. Visual settings; see
theme
. |
openDocument (shape)
openDocument fields
| Field | Type | Description |
|---|---|---|
documentId | string | Required when you open a document. The public document id or private content id your backend uses. |
isPrivate | boolean | true = private Content flow (
/contents/v1/…/annotated); false = public GET /v1/documents/{id} path. |
matchesInformation | object | Optional highlighting: { cqsChunks: […] } or { cnums: number[] } from your search or app, when you
need chunk alignment. |
instance.emit("opendocument", { documentId, isPrivate, matchesInformation? }) to load another document (same instance).
theme
The widget runs inside an open Shadow DOM, so host-page CSS does not change its internal layout or colors. Size the mount container in your page - the widget fills that container. You can also set theme.width and theme.height if you need explicit dimensions on the widget instead of relying on the container alone.
Theme values are merged with defaults. preset chooses a base palette before overrides:
theme.preset values
preset | Behavior |
|---|---|
light | Light background and text colors. |
dark | Dark background and text colors. |
auto | Follows the user’s system preference (
prefers-color-scheme). |
theme field reference
| Field | Type | Description |
|---|---|---|
primaryColor | string | Accents (controls, highlights). |
backgroundColor | string | Widget background. |
surfaceColor | string | Surfaces and panels. |
textColor | string | Primary text. |
textSecondaryColor | string | Muted text. |
borderColor | string | Borders and dividers. |
fontFamily | string | Font stack; can default like the chat widget to inherit the host. |
fontSize | string | Base size; defaults in the same family as the chat widget (e.g. 16px). |
borderRadius | string | Corner radius (e.g. 8px). |
width | string | Optional fixed width when not using a fully sized container. |
height | string | Optional fixed height when not using a fully sized container. |
preset | ”light” | “dark” | “auto” | Base palette; see the table above. |
Multiple widgets and shared theming
Create oneBigdataWidgetManager with an optional shared theme, pass it as manager in each BigdataDocumentViewer.init / BigdataDocumentWidget config, and give each widget a distinct instanceId. That way instances stay isolated but can share base styling-including when you add the chat widget and document viewer widget on the same page.
Instance lifecycle and events
destroy()- Unmounts React, clears the shadow root, and unregisters the instance. Call this when removing the widget from the page.addListener(event, handler)/removeListener(event, handler)- Subscribe to widget events.
instanceName, timestamp, and data:
data payload (summary) per event
| Event | data shape (summary) |
|---|---|
ready | { widgetName: “BIGDATA_DOCUMENT_WIDGET” } (fires after mount). |
opendocument | Same as openDocument: documentId, isPrivate, optional matchesInformation. |
opendocument to change what is on screen, see openDocument (shape) in Top-level options.)
Troubleshooting
Blank area or widget does not appear
Blank area or widget does not appear
Confirm the script URL loads (network tab, no 404). Ensure
container
matches an existing element. Check the browser console for validation errors
(for example invalid proxyUrl). The inner fetch also needs a valid
openDocument / emit("opendocument", ...) with a documentId,
and a configured proxyUrl, or nothing will request RPJSON.CORS errors
CORS errors
Your
proxyUrl origin must allow the site origin that embeds the widget
(Access-Control-Allow-Origin and related headers for GET and, if you use
getHeaders, the necessary preflight).401 or 403 from proxy
401 or 403 from proxy
The proxy is rejecting the request before Bigdata. Verify server-side auth
and that forwarded credentials and
getHeaders match what your BFF
expects.Document id works in the app but not the embed
Document id works in the app but not the embed
For Content-originated files, set
isPrivate: true and the
content_id your proxy expects. For public catalog content, set
isPrivate: false and the id you would pass to Fetch
document. Mixing public vs private
flags is a frequent cause of 404s at the proxy.RPJSON never appears; loading never finishes
RPJSON never appears; loading never finishes
A missing or incorrect
/proxy-document is common: the first response
returns a signed url that the browser must not call cross-origin.
Ensure GET .../proxy-document?url= downloads the server-side and
returns the JSON. If your BFF is slow but correct, also confirm you are not
stripping or buffering the response body. Check upstream API key
pass-through for /v1/documents/... and /contents/.../annotated.