Skip to content

Join the Seedly owners community →

File Storage

R2 in Your App

Uploading files from code and common file storage patterns

Written by 4 min read1 activity
Pixl, your presenter

Pixl presents

Upload a file, save its URL, show it. Three steps, and somehow people still stuff images into the database. Don't be them.Upload a file, save its URL, show it. Three steps, and somehow people still stuff images into the database. Don't be them.

Pixl lifts a framed photo up a pulley into a loft, the rope end tied to a hook on his desk
Upload the file, keep its URL, show it later

Using R2 in Your Code#

Here's a simple example of uploading a file to R2. You'll usually lean on a library to make this easier.

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
 
// Create a client (R2 uses the S3 protocol)
// Keys come from environment variables, never pasted into your code
const client = new S3Client({
  region: 'auto',
  endpoint: `https://${process.env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com`,
  credentials: {
    accessKeyId: process.env.R2_ACCESS_KEY_ID,
    secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
  },
})
 
// Upload a file
async function uploadFile(file, filename) {
  await client.send(new PutObjectCommand({
    Bucket: 'my-bucket',
    Key: filename,
    Body: file,
  }))
 
  // R2 doesn't hand you a URL back, you build it from the key
  return `https://files.your-domain.com/${filename}`
}

Install the SDK first with npm install @aws-sdk/client-s3. The upload itself doesn't return a link, so the function builds one from the file's key. That files.your-domain.com address only works for public files after you connect a custom domain to the bucket in the R2 settings (private files get a signed URL instead, like you saw last lesson). You save that URL or the key to your database, then use it anywhere in your app to show the file. That's really it.

Common File Storage Patterns#

Pixl holds a clipboard of three photos, each linked by thread to a bucket on a shelf
A post points to its media files stored in R2

Profile Pictures#

Step 1. Upload#

The user uploads their photo. You save it to R2.

Step 2. Store URL#

Save the R2 URL to the user's profile in your database.

Step 3. Display#

When you show the profile, drop the URL into an image tag.

Document Uploads#

Some apps let users upload documents like PDFs and spreadsheets. Same idea.

  • Store the file in R2
  • Save the URL and some metadata (filename, size, type) to your database
  • Show a download link in your app

User-Generated Content#

Apps like Instagram or Twitter let people upload images and videos with their posts. Here's how that usually shakes out.

  • Each post has one or more media files sitting in R2
  • The post in your database points to those file URLs
  • When the feed loads, the images come straight from R2

TL;DR#

  • Never store user uploads on your application server, use object storage instead
  • Cloudflare R2 is affordable, fast, and has ZERO egress fees
  • R2 is S3-compatible, so you get to use standard tools and libraries
  • Keep the file URLs in your database and the files themselves in R2
  • Use signed URLs for private files that shouldn't be out in public

This lesson ends with a short activity.