Skip to main content

Overview

The getFileUrl query returns a temporary signed URL for accessing files stored in Convex. This URL allows authenticated users to retrieve files associated with their cards while maintaining security through ownership validation.

getFileUrl

Retrieves a signed URL for a file belonging to a specific card.

Parameters

fileId
Id<'_storage'>
required
The storage ID of the file to retrieve. This can be:
  • The main file (card.fileId)
  • A thumbnail (card.thumbnailId)
  • A link preview screenshot (card.metadata.linkPreview.screenshotStorageId)
  • A link preview image (card.metadata.linkPreview.imageStorageId)
cardId
Id<'cards'>
required
The ID of the card that owns the file. Used for authorization checks.

Returns

url
string | null
A temporary signed URL that can be used to access the file. Returns null if the file doesn’t exist.

Example

import { useQuery } from "convex/react";
import { api } from "@teak/convex";

function CardImage({ card }) {
  const fileUrl = useQuery(api.card.getFileUrl, {
    fileId: card.fileId,
    cardId: card._id
  });

  if (!fileUrl) {
    return <div>Loading...</div>;
  }

  return <img src={fileUrl} alt={card.content} />;
}

Authorization

The query enforces strict access control:
  1. Authentication - User must be logged in
  2. Ownership - The card must belong to the authenticated user
  3. File Association - The file must be associated with the specified card
If any of these checks fail, the query will throw an error:
  • “Unauthenticated call to getFileUrl” - User is not logged in
  • “Card not found” - Card doesn’t exist
  • “Unauthorized access to file” - Card belongs to a different user
  • “File does not belong to the specified card” - File is not associated with the card

Location

packages/convex/card/getFileUrl.ts:4

URL Expiration

Signed URLs generated by Convex are temporary and will expire after a certain period. Applications should:
  • Cache URLs for short periods
  • Re-fetch URLs when needed rather than storing them permanently
  • Handle cases where URLs have expired by requesting new ones

File Types

The getFileUrl query works with all file types stored in Teak:
  • Images - JPEG, PNG, GIF, WebP, etc.
  • Videos - MP4, WebM, MOV, etc.
  • Audio - MP3, WAV, M4A, etc.
  • Documents - PDF, Word documents, text files
  • Thumbnails - Generated preview images
  • Link Previews - Screenshots and images from link metadata

Use Cases

Displaying Card Media

const mediaUrl = useQuery(api.card.getFileUrl, {
  fileId: card.fileId,
  cardId: card._id
});

return card.type === "video" ? (
  <video src={mediaUrl} controls />
) : (
  <img src={mediaUrl} alt="Card media" />
);

Showing Thumbnails

const thumbnailUrl = useQuery(api.card.getFileUrl, {
  fileId: card.thumbnailId,
  cardId: card._id
});

return <img src={thumbnailUrl} className="thumbnail" />;

Downloading Files

const fileUrl = useQuery(api.card.getFileUrl, {
  fileId: card.fileId,
  cardId: card._id
});

const downloadFile = () => {
  const link = document.createElement('a');
  link.href = fileUrl;
  link.download = card.fileMetadata?.fileName || 'download';
  link.click();
};

Security

Important: Signed URLs provide temporary access to files. Do not:
  • Share URLs with other users (they’re tied to the requesting user)
  • Store URLs permanently (they expire)
  • Use URLs for files from cards you don’t own (authorization will fail)
The authorization checks ensure that:
  • Users can only access their own files
  • Files can only be accessed through cards they belong to
  • All access is audited through the card ownership system

Build docs developers (and LLMs) love