Skip to main content
The useFiles hook provides methods for uploading and downloading files within your widget. Files are managed by the host and can be referenced across tool calls.

Basic usage

import { useFiles } from "skybridge/web";
import { useState } from "react";

function FileUploader() {
  const { upload } = useFiles();
  const [fileId, setFileId] = useState<string | null>(null);

  const handleUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (file) {
      const { fileId } = await upload(file);
      setFileId(fileId);
    }
  };

  return (
    <div>
      <input type="file" onChange={handleUpload} />
      {fileId && <p>Uploaded file ID: {fileId}</p>}
    </div>
  );
}

Returns

upload

upload: (file: File) => Promise<{ fileId: string }>
Uploads a file to the host. Returns a promise that resolves with the file metadata containing a unique fileId.
  • file: File
    • The file object to upload

getDownloadUrl

getDownloadUrl: (file: { fileId: string }) => Promise<{ downloadUrl: string }>
Get the download URL of a file that was previously uploaded. Returns a promise that resolves with a downloadUrl that can be used to fetch the file content.
  • file: { fileId: string }
    • An object containing the fileId of the file to download
Only files uploaded by the same connector instance can be downloaded.

Examples

Image Upload and Preview

import { useFiles } from "skybridge/web";
import { useState } from "react";

function ImageUploader() {
  const { upload, getDownloadUrl } = useFiles();
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [isUploading, setIsUploading] = useState(false);

  const handleUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) return;

    setIsUploading(true);
    try {
      const { fileId } = await upload(file);
      const { downloadUrl } = await getDownloadUrl({ fileId });
      setPreviewUrl(downloadUrl);
    } catch (error) {
      console.error("Upload failed:", error);
    } finally {
      setIsUploading(false);
    }
  };

  return (
    <div>
      <input
        type="file"
        accept="image/*"
        onChange={handleUpload}
        disabled={isUploading}
      />
      {isUploading && <p>Uploading...</p>}
      {previewUrl && <img src={previewUrl} alt="Preview" />}
    </div>
  );
}

Document Manager

import { useFiles } from "skybridge/web";
import { useState } from "react";

type Document = {
  name: string;
  fileId: string;
};

function DocumentManager() {
  const { upload, getDownloadUrl } = useFiles();
  const [documents, setDocuments] = useState<Document[]>([]);

  const handleUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) return;

    const { fileId } = await upload(file);
    setDocuments((prev) => [...prev, { name: file.name, fileId }]);
  };

  const handleDownload = async (doc: Document) => {
    const { downloadUrl } = await getDownloadUrl({ fileId: doc.fileId });
    window.open(downloadUrl, "_blank");
  };

  return (
    <div>
      <input type="file" onChange={handleUpload} />
      <ul>
        {documents.map((doc) => (
          <li key={doc.fileId}>
            {doc.name}
            <button onClick={() => handleDownload(doc)}>Download</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

Multiple File Upload

import { useFiles } from "skybridge/web";
import { useState } from "react";

function MultiFileUploader() {
  const { upload } = useFiles();
  const [uploadedIds, setUploadedIds] = useState<string[]>([]);
  const [progress, setProgress] = useState<number>(0);

  const handleUpload = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const files = Array.from(event.target.files || []);
    if (files.length === 0) return;

    const ids: string[] = [];
    for (let i = 0; i < files.length; i++) {
      const { fileId } = await upload(files[i]);
      ids.push(fileId);
      setProgress(((i + 1) / files.length) * 100);
    }
    setUploadedIds(ids);
    setProgress(0);
  };

  return (
    <div>
      <input type="file" multiple onChange={handleUpload} />
      {progress > 0 && <progress value={progress} max={100} />}
      {uploadedIds.length > 0 && (
        <p>Uploaded {uploadedIds.length} files</p>
      )}
    </div>
  );
}