homeaboutvideotry it nowpricingdocs
Guide

Build a video library page

List your videos from your server, show posters in a grid, and play each one on click.

What you are building

A page that shows every ready video as a poster card, such as a lesson library, a help video index or a gallery of clips. The list comes from your server, using your private key. The posters and the playback need no key.

Listing videos needs your private key, so do it on the server only. Never put the private key in browser code.

List the videos on the server

listVideos returns one page at a time, newest first by default. Ask for videos that are ready, so a card never links to something still encoding. Each video carries its name, duration and ready-made URLs, including the poster.

server.ts
import express from "express"
import { Fileboy } from "@cd2/fileboy-node"

const fileboy = Fileboy({
  publicKey: process.env.FILEBOY_PUBLIC_KEY!,
  privateKey: process.env.FILEBOY_PRIVATE_KEY!,
})

const app = express()

app.get("/api/videos", async (req, res) => {
  const page = await fileboy.listVideos({
    status: "ready",
    limit: 24,
    cursor: typeof req.query.cursor === "string" ? req.query.cursor : undefined,
  })

  res.json({
    videos: page.data.map(video => ({
      id: video.id,
      name: video.name,
      duration: video.duration,
      poster: video.urls?.poster,
    })),
    nextCursor: page.nextCursor,
  })
})
const { data: videos } = await fileboy.listVideos({ status: "ready", limit: 20 })

await fileboy.updateVideo(videos[0].id, { name: "Launch day" })
await fileboy.destroyVideo(videos[0].id) // original, renditions, posters and transcripts

Show the posters as a grid

The poster is an ordinary image URL, so it works in an img tag. Each card links to a page for that video.

VideoGrid.tsx
import { useEffect, useState } from "react"

type Card = { id: string; name: string; duration: number | null; poster?: string }

export function VideoGrid() {
  const [videos, setVideos] = useState<Card[]>([])

  useEffect(() => {
    fetch("/api/videos")
      .then(res => res.json())
      .then(body => setVideos(body.videos))
  }, [])

  return (
    <div style={{ display: "grid", gap: 16, gridTemplateColumns: "repeat(auto-fill, minmax(240px, 1fr))" }}>
      {videos.map(video => (
        <a key={video.id} href={`/videos/${video.id}`}>
          <img src={video.poster} alt="" style={{ width: "100%", aspectRatio: "16 / 9", objectFit: "cover" }} />
          <div>{video.name}</div>
          {video.duration != null && <small>{Math.round(video.duration)} seconds</small>}
        </a>
      ))}
    </div>
  )
}

Play a video on its own page

VideoPage.tsx
import "@cd2/fileboy-player"
import { useParams } from "react-router-dom"

export function VideoPage() {
  const { id } = useParams<{ id: string }>()

  return <fileboy-player video-id={id} preload="" />
}

If your pages are not React, the same element works from a script tag, or use an iframe.

Keep the list fresh

  • Page through longer libraries with nextCursor. Paging stays stable while videos are added or deleted.
  • A video.ready or video.deleted webhook tells your server when to refresh a cached list, so you never poll.
  • Rename a video, or give it a description, tags and your own metadata, with updateVideo, and delete it with destroyVideo. Deleting removes the original, every rendition, the posters and the captions.
  • Find videos by tag or by your own ids with listVideos({ tags: [...], metadata: {...} }), so you can show one course's or one customer's videos without keeping a list of ids.

Checked against the current libraries in November 2026. Found something that no longer works? Tell us.

Go deeper

Still choosing a tool?

Fileboy is small on purpose. This comparison says where it fits and where another option is the better call.

Fileboy vs Mux · All comparisons

Try it

The free plan needs no card and includes 1,000 files, so you can run every example above.

More guides: How to add image upload to a React app · Resize images on the fly with a URL · Stream video with HLS without running ffmpeg · Add captions and subtitles to a video · All guides

Add Fileboy to your next project

We built Fileboy to stop rebuilding file handling for every app. Create an app, paste your key and upload a file. The free plan needs no card.