Rasterex APINPM Package/docs/components/files/upload

File Upload

Load documents into the canvas and manage session states through the documents surface.

Overview

File Upload allows you to load documents into the canvas by providing a valid file URL/path.

Use the documents surface when the file is reachable by Canvas through a URL or server path:

  • `viewer.documents.open(options)`: The file is reachable by Canvas through a URL or server path (sends the viewAny broker command).

Opening Documents

Select the appropriate configuration parameters depending on your storage and integration environment:

Open a URL

Pass the public URL of the document you want Canvas to load:

  • The URL must be accessible by Canvas. If Canvas is hosted on a separate domain, ensure your file server has cross-origin headers (CORS) enabled.
typescript
const result = await viewer.documents.open({
  url: "https://files.example.com/sample.pdf",
  displayName: "sample.pdf"
});

console.log(result.activeId);
Open a URL

Open a Server Path

Use path when your Canvas deployment resolves paths relative to its own server root or environment:

typescript
await viewer.documents.open({
  path: "/documents/sample.pdf",
  displayName: "sample.pdf"
});
Open a Server Path

Open with Metadata

Furnish metadata properties to configure tabs and cache settings:

  • `displayName`: The display label Canvas shows inside file tabs. It must include the file extension (e.g. Plan.pdf, not just Plan).
  • `cacheId`: A stable cache key. Canvas servers check for previously generated viewable assets under this key to bypass reprocessing on subsequent loads.
  • `mime`: Explicitly states the document MIME type, helping Canvas select the proper file handler.
typescript
await viewer.documents.open({
  url: "https://files.example.com/sample.pdf",
  displayName: "Project Plan.pdf",
  cacheId: "project-plan-v12",
  mime: "application/pdf"
});
Open with Metadata

Tracking Opening & File States

Capture the asynchronous loading phase and session metadata using event subscriptions:

Track Opening Progress

Register listeners before starting loading operations, and save the unsubscribe handles:

typescript
const stopOpening = viewer.documents.on("opening", (event) => {
  console.log("Opening:", event.displayName ?? event.url ?? event.path);
});

const stopOpened = viewer.documents.on("opened", (event) => {
  console.log("Opened file ID:", event.activeId);
});

const stopFailed = viewer.documents.on("failed", (event) => {
  console.error("Failed:", event.error.code, event.error.message);
});

// Load the file
await viewer.documents.open({
  url: "https://files.example.com/sample.pdf",
  displayName: "sample.pdf"
});

// Call handles to clear subscriptions during cleanup
stopOpening();
stopOpened();
stopFailed();
Track Opening Progress

Read Active File State

Subscribe to canvas broadcast streams to render custom host side elements:

typescript
// Capture document metadata
const stopFileInfo = viewer.documents.on("fileInfo", (event) => {
  console.log("Name:", event.fileInfo?.name);
});

// Synchronize file tab collections
const stopFileTabs = viewer.documents.on("fileTabs", (event) => {
  console.log("Active file:", event.activeId, "Tabs list:", event.tabs);
});

// Monitor pages list and selection
const stopPageList = viewer.documents.on("pageList", (event) => {
  console.log("Current page:", event.currentPage, "Total pages:", event.pageCount);
});
Read Active File State

Errors & Timeouts

Safely catch document exceptions and adjust default load timeout values:

Error Handling

Import RasterexViewerError to extract detailed canvas codes:

  • `VIEWER_NOT_READY`: Rejects if .open() is invoked before await ready() resolves.
  • `DOCUMENT_LOAD_FAILED`: Rejects if url/path are missing, another document loading task is in progress, or the canvas fails to return metadata before timing out.
typescript
import { RasterexViewerError } from "@rasterex/viewer";

try {
  await viewer.documents.open({
    url: "https://files.example.com/sample.pdf",
    displayName: "sample.pdf"
  });
} catch (error) {
  if (error instanceof RasterexViewerError) {
    console.error("SDK code:", error.code, "Context details:", error.context);
  }
}
Error Handling

Configuration Timeouts

If you expect large drawings that require extensive server-side parsing, adjust the commandTimeoutMs on the viewer instance:

typescript
const viewer = createViewer({
  container: "#viewer",
  commandTimeoutMs: 60000 // 60 seconds command timeout limit
});
Configuration Timeouts

TypeScript Typings

Import SDK typing interfaces for full type-safety inside your editor:

  • `DocumentOpenOptions`: Defines URL, server path, display name, cache key, and mime configurations.
  • `DocumentOpenResult`: Defines the resolved promise output containing correlation IDs and file details.
typescript
import type {
  DocumentOpenOptions,
  DocumentOpenResult
} from "@rasterex/viewer";

const options: DocumentOpenOptions = {
  url: "https://files.example.com/sample.pdf",
  displayName: "sample.pdf"
};

const result: DocumentOpenResult = await viewer.documents.open(options);
TypeScript Typings

Canvas Broker Mapping

The SDK converts methods to internal broker frames as shown below:

  • `viewer.documents.open(...)` maps to the Canvas command `viewAny`.
  • `viewer.documents.on("fileInfo", ...)` subscribes to the Canvas event `fileInfo`.
  • `viewer.documents.on("fileTabs", ...)` subscribes to the Canvas event `fileTabs`.
  • `viewer.documents.on("pageList", ...)` subscribes to the Canvas event `pageList`.

Vanilla Integration

Copy these project setup files to configure mounting, event subscriptions, and file loading handles:

import { createViewer } from "@rasterex/viewer";
import "./style.css";

const viewer = createViewer({
  container: "#viewer"
});

const fileUrlInput = document.querySelector("#file-url");
const statusEl = document.querySelector("#status");

function setStatus(message) {
  if (statusEl) statusEl.textContent = message;
}

async function startViewer() {
  await viewer.mount();
  await viewer.ready();

  viewer.documents.on("opening", (event) => {
    setStatus(`Opening ${event.displayName || "document"}...`);
  });

  viewer.documents.on("fileInfo", (event) => {
    setStatus(`Active document: ${event.fileInfo?.name}`);
  });
  
  setStatus("Viewer ready");
}

async function openUrl() {
  const url = fileUrlInput?.value.trim();
  if (!url) return;

  try {
    await viewer.documents.open({
      url,
      displayName: url.split("/").pop() || "document.pdf"
    });
  } catch (error) {
    setStatus("Could not open document");
  }
}

document.querySelector("#open-url")?.addEventListener("click", () => {
  openUrl().catch(console.error);
});

startViewer().catch((error) => {
  console.error(error);
  setStatus("Viewer failed to start");
});
Vanilla Integration

React Integration

Open URLs inside a standard React functional hook:

import { useEffect, useRef, useState } from "react";
import { createViewer, type RasterexViewer } from "@rasterex/viewer";
import "./style.css";

export function FileOpeningExample() {
  const containerRef = useRef<HTMLDivElement | null>(null);
  const viewerRef = useRef<RasterexViewer | null>(null);
  const [fileUrl, setFileUrl] = useState("https://pdfobject.com/pdf/sample.pdf");
  const [status, setStatus] = useState("Starting viewer...");

  useEffect(() => {
    if (!containerRef.current) return undefined;

    const viewer = createViewer({ container: containerRef.current });
    viewerRef.current = viewer;

    const unsubscribe = viewer.documents.on("fileInfo", (event) => {
      setStatus(`Active file: ${event.fileInfo?.name}`);
    });

    async function start(): Promise<void> {
      await viewer.mount();
      await viewer.ready();
      setStatus("Viewer ready");
    }

    void start().catch((error) => {
      console.error(error);
      setStatus("Viewer failed to start");
    });

    return () => {
      unsubscribe();
      viewer.destroy();
      viewerRef.current = null;
    };
  }, []);

  async function openUrl(): Promise<void> {
    const viewer = viewerRef.current;
    const url = fileUrl.trim();
    if (!viewer || !url) return;

    setStatus("Opening document URL...");
    try {
      await viewer.documents.open({
        url,
        displayName: url.split("/").pop() || "document.pdf"
      });
    } catch (error) {
      setStatus("Failed to load URL");
    }
  }

  return (
    <div>
      <div ref={containerRef} style={{ height: 600 }} />
      <input value={fileUrl} onChange={(event) => setFileUrl(event.target.value)} />
      <button type="button" onClick={() => void openUrl()}>Open URL</button>
      <pre>{status}</pre>
    </div>
  );
}
React Integration

Vue Integration

Open URLs inside a Vue composition component setup:

<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref, shallowRef } from "vue";
import { createViewer, type RasterexViewer } from "@rasterex/viewer";
import "./style.css";

const containerRef = ref<HTMLElement | null>(null);
const viewerRef = shallowRef<RasterexViewer | null>(null);
const fileUrl = ref("https://pdfobject.com/pdf/sample.pdf");
const status = ref("Starting viewer...");

let unsubscribe: (() => void) | undefined;

onMounted(async () => {
  if (!containerRef.value) return;

  const viewer = createViewer({ container: containerRef.value });
  viewerRef.value = viewer;

  unsubscribe = viewer.documents.on("fileInfo", (event) => {
    status.value = `Active file: ${event.fileInfo?.name}`;
  });

  try {
    await viewer.mount();
    await viewer.ready();
    status.value = "Viewer ready";
  } catch (error) {
    console.error(error);
    status.value = "Viewer failed to start";
  }
});

onBeforeUnmount(() => {
  unsubscribe?.();
  viewerRef.value?.destroy();
  viewerRef.value = null;
});

async function openUrl() {
  const viewer = viewerRef.value;
  const url = fileUrl.value.trim();
  if (!viewer || !url) return;

  status.value = "Opening URL...";
  try {
    await viewer.documents.open({
      url,
      displayName: url.split("/").pop() ?? "document.pdf"
    });
  } catch (error) {
    status.value = "Failed to load URL";
  }
}

</script>

<template>
  <div>
    <div ref="containerRef" style="height: 600px" />
    <input v-model="fileUrl" />
    <button type="button" @click="openUrl">Open URL</button>
    <pre>{{ status }}</pre>
  </div>
</template>
Vue Integration

Angular Integration

Open URLs inside an Angular component:

import {
  AfterViewInit,
  Component,
  ElementRef,
  OnDestroy,
  ViewChild
} from "@angular/core";
import { createViewer, type RasterexViewer } from "@rasterex/viewer";

@Component({
  selector: "app-file-opening",
  templateUrl: "./file-opening.component.html"
})
export class FileOpeningComponent implements AfterViewInit, OnDestroy {
  @ViewChild("viewerContainer", { static: true })
  viewerContainer!: ElementRef<HTMLElement>;

  status = "Starting viewer...";
  private viewer: RasterexViewer | null = null;
  private unsubscribe?: () => void;

  async ngAfterViewInit(): Promise<void> {
    const viewer = createViewer({
      container: this.viewerContainer.nativeElement
    });

    this.viewer = viewer;

    this.unsubscribe = viewer.documents.on("fileInfo", (event) => {
      this.status = `Active file: ${event.fileInfo?.name}`;
    });

    try {
      await viewer.mount();
      await viewer.ready();
      this.status = "Viewer ready";
    } catch (error) {
      console.error(error);
      this.status = "Viewer failed to start";
    }
  }

  async openUrl(url: string): Promise<void> {
    if (!this.viewer || !url.trim()) return;

    this.status = "Opening URL...";
    try {
      await this.viewer.documents.open({
        url: url.trim(),
        displayName: url.split("/").pop() || "document.pdf"
      });
    } catch (error) {
      this.status = "Failed to load URL";
    }
  }

  ngOnDestroy(): void {
    this.unsubscribe?.();
    this.viewer?.destroy();
  }
}
Angular Integration

Live Preview

Test the interactive preview below to see how the session initializes when a new file is requested.

Interactive Workbench

File upload preview

Paste a file URL and send the view message to load a new file in the Canvas.

Additional Resources

Continue with related file workflows and API references.