RORK LABJP
FUNDING — Rork raises a $15M seed led by Left Lane CapitalRORK MAX — Rork Max generates native Swift apps instead of React NativePLATFORM — It targets iPhone, iPad, Watch, and Vision Pro, reaching Live Activities and Core MLGROWTH — Traffic keeps climbing at 743K monthly visits and 85% growthTEST — The Companion app lets you test on a real device without a paid Apple Developer accountSTACK — Built on React Native and Expo for true native experiences, not web wrappersFUNDING — Rork raises a $15M seed led by Left Lane CapitalRORK MAX — Rork Max generates native Swift apps instead of React NativePLATFORM — It targets iPhone, iPad, Watch, and Vision Pro, reaching Live Activities and Core MLGROWTH — Traffic keeps climbing at 743K monthly visits and 85% growthTEST — The Companion app lets you test on a real device without a paid Apple Developer accountSTACK — Built on React Native and Expo for true native experiences, not web wrappers
Articles/App Dev
App Dev/2026-06-30Intermediate

Previewing Files In-App in Rork — calling Quick Look safely from Expo

How to preview PDFs, images, and Office documents in place without sending users out of your app, using Quick Look (QLPreviewController) from Rork (Expo). Covers pre-downloading remote files, the local-URL requirement, the Android FileProvider alternative, and handling the share button.

Rork480Expo127Quick Lookfile previewindie developer35

Premium Article

A user taps an invoice PDF they received inside the app, gets bounced out to Safari, and can't find their way back — building apps as an indie developer, I've felt the pain of this "left and never returned" experience. Sending someone away just to view a file breaks the context they were in.

iOS has a mechanism built for exactly this: Quick Look (QLPreviewController). It opens PDFs, images, text, CSV, and Office documents like Word and Excel as a full-screen preview inside your app. A standard Rork app is generated as React Native (Expo), so you call this native Quick Look through a thin bridge module. The crux of the design was knowing precisely what you can and can't hand it.

What Quick Look can and can't open

First, the premise. Quick Look is a local file preview mechanism. Getting this wrong is how the first implementation stumbles.

  • It opens local file URLs (paths starting with file://)
  • Passing an https:// remote URL directly won't work. You have to download it locally first
  • Supported formats are broad: PDF, images (JPEG/PNG/HEIC), text, CSV, RTF, iWork, Microsoft Office, USDZ (3D), and more
  • A correct extension is the hint for type detection. With an extensionless name like document.tmp, even genuine PDF content sometimes won't open

What I tripped on first was handing it a signed URL fetched from the server as-is. Quick Look just shows a blank, with no error. Locking in the rule "always cache remote files before opening" from the start is the shortcut.

Cache the remote file first

In Expo, download with expo-file-system and hand the saved local URI to Quick Look. If it's already downloaded, reusing it instead of re-fetching keeps the wait short even for a large PDF.

// downloadForPreview.ts
import * as FileSystem from 'expo-file-system';
 
// Cache a remote URL and return the file:// local path
export async function ensureLocalCopy(remoteUrl: string, filename: string) {
  const target = FileSystem.cacheDirectory + filename;
 
  const info = await FileSystem.getInfoAsync(target);
  if (info.exists) return target; // don't re-download if present
 
  const { uri, status } = await FileSystem.downloadAsync(remoteUrl, target);
  if (status !== 200) {
    throw new Error(`download failed: ${status}`);
  }
  return uri;
}

Always include the correct extension in the filename. If the server doesn't return one, deriving .pdf or .xlsx from the Content-Type yourself keeps Quick Look's type detection stable.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
You'll be able to let users view PDFs, images, and Office docs inside the app instead of handing them to an external app
You'll see, with working code, why passing a remote URL directly fails and the correct flow of caching first, then opening the local URL
You'll learn the design that folds iOS Quick Look and Android FileProvider+ACTION_VIEW into one call site, plus when to suppress the share button
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

App Dev2026-06-29
Clipboard UX in Expo apps — copy and paste without flooding users with iOS's paste banner
When you wire up copy and paste with expo-clipboard, iOS's paste permission banner can fire constantly and quietly erode trust. Here's exactly when the banner appears, and how hasStringAsync lets you gate a Paste button without ever reading the contents.
App Dev2026-06-29
Respecting Metered Connections and Low Data Mode in an Image-Heavy Rork App
In an image-heavy Rork (Expo) app, hold back prefetching on metered connections and Low Data Mode. Read the connection's character from NetInfo details, drop image quality, and defer prefetch with an adaptive policy layer, all with working code.
App Dev2026-06-27
Before You Ask 'Are You Sure?' — Consider an Undoable Delete
Showing a confirmation dialog every time someone removes a list item trains them to tap OK without reading. Here is how to build an undoable delete in a Rork (Expo) app, and where confirmation dialogs still belong.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →