useFiles
The useFiles hook provides methods for uploading, selecting, and downloading files within your view. Files are managed by the host and can be referenced across tool calls.
Basic usage
Section titled “Basic usage”import { useFiles } from "@usefractal/frac/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
Section titled “Returns”upload
Section titled “upload”upload: (file: File, options?: { library?: boolean }) => 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
options?: { library?: boolean }- Pass
{ library: true }to also save the upload into the user’s ChatGPT file library (when available)
- Pass
selectFiles
Section titled “selectFiles”selectFiles: () => Promise<Array<{ fileId: string; fileName?: string; mimeType?: string }>>Opens ChatGPT’s file library picker and returns app-authorized files selected by the user. Feature-detect before using — this method may not be available on all host versions.
getDownloadUrl
Section titled “getDownloadUrl”getDownloadUrl: (file: { fileId: string }) => Promise<{ downloadUrl: string }>Get the download URL of a file. Returns a promise that resolves with a downloadUrl that can be used to fetch the file content.
file: { fileId: string }- An object containing the
fileIdof the file to download
- An object containing the
Examples
Section titled “Examples”Image Upload and Preview
Section titled “Image Upload and Preview”import { useFiles } from "@usefractal/frac/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> );}Upload to File Library
Section titled “Upload to File Library”import { useFiles } from "@usefractal/frac/web";import { useState } from "react";
function LibraryUploader() { 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) return;
// Save to the user's ChatGPT file library const { fileId } = await upload(file, { library: true }); setFileId(fileId); };
return ( <div> <input type="file" onChange={handleUpload} /> {fileId && <p>Saved to library: {fileId}</p>} </div> );}Select Files from Library
Section titled “Select Files from Library”import { useFiles } from "@usefractal/frac/web";import type { FileMetadata } from "@usefractal/frac/web";import { useState } from "react";
function FileSelector() { const { selectFiles, getDownloadUrl } = useFiles(); const [files, setFiles] = useState<FileMetadata[]>([]);
const handleSelect = async () => { const selected = await selectFiles(); setFiles(selected); };
const handleDownload = async (fileId: string) => { const { downloadUrl } = await getDownloadUrl({ fileId }); window.open(downloadUrl, "_blank"); };
return ( <div> <button onClick={handleSelect}>Select from Library</button> <ul> {files.map((file) => ( <li key={file.fileId}> {file.fileName ?? file.fileId} {file.mimeType && <span> ({file.mimeType})</span>} <button onClick={() => handleDownload(file.fileId)}> Download </button> </li> ))} </ul> </div> );}Document Manager
Section titled “Document Manager”import { useFiles } from "@usefractal/frac/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
Section titled “Multiple File Upload”import { useFiles } from "@usefractal/frac/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> );}See also
Section titled “See also”FileRef: Helper schema and types for ChatGPT file references in tool inputs and output.