FRAMEWORKS

Next.js video

Complete video infrastructure for a Next.js app. Install the packages and you get uploads, adaptive playback, live streams, DRM, analytics and AI features, without building your own encoding, storage and delivery.

Free plan: 10 videos, 100K streaming minutes, 300 minutes of subtitles and moderation. No credit card.

Node 18+ · App Routerruntime
@fastpix/fastpix-nodeserver SDK
MITlicense

TRUSTED BY PRODUCT TEAMS SHIPPING VIDEO AT SCALE

Customer logoCustomer logoCustomer logoCustomer logoCustomer logoCustomer logo

What you get

What you get from FastPix for Next.js video

Four things you don't have to build or run yourself.

One video API

Upload, storage, delivery, the player, analytics and AI all come from the same API. No Vite plugin, nothing added to your build.

Built-in encoding

FastPix turns each upload into several quality levels and packages them for streaming. No FFmpeg, no queue workers.

Analytics already on

The player sends view data on its own. Add a title and a viewer ID and you can see who watched what.

Secure video streaming and DRM

Sign a token on your server and pass it to the player. Widevine, PlayReady and FairPlay are all supported.

Functionality

Every Next.js video capability, from upload to AI

Pick a group, then a capability. Each one tells you whether the code goes in a route handler, a server component or a client component.

Video upload API

A route handler creates the signed URL. The browser then uploads the file straight to FastPix in chunks, so nothing crosses your Vercel function and no body-size limit applies. Create the URL in the handler, never during page render, or Next.js prerenders one URL into the HTML for every visitor.

Where it runs · Route handler creates, browser sends
1// app/api/upload-url/route.ts
2export async function POST() {
3 const upload = await fastpix.inputVideo.upload(
4 { corsOrigin: "*" },
5 { headers: { "X-Client-Type": "web-browser" } },
6 );
7 return Response.json({ url: upload.data.url });
8}

Setup

Install and configure the Next.js video packages

Install the Next.js video packages

The uploader and the player run in the browser. The Node SDK runs in your route handlers, where it creates upload URLs, signs playback tokens and asks for AI features.

npm
1# Browser and server, one install
2npm install @fastpix/fastpix-node @fastpix/fp-react-uploader @fastpix/fp-player
3
4// app/layout.tsx: import the uploader stylesheet once, globally
5import "@fastpix/fp-react-uploader/styles.css";
6
7// The uploader ships its own "use client" banner.
8// You only need the directive for your own createUpload function.

Configure the Next.js video packages

There's no API key. You get two values, an Access Token ID and a Secret Key, and they work as a username and password. Both stay in your route handlers.

Get your access token
.env.local + route.ts
1// .env.local: never prefix these with NEXT_PUBLIC_,
2// which inlines them into the browser bundle.
3FASTPIX_USERNAME=your-access-token-id
4FASTPIX_PASSWORD=your-secret-key
5
6// app/api/upload-url/route.ts
7const fastpix = new Fastpix({
8 security: {
9 username: process.env.FASTPIX_USERNAME, // Access Token ID
10 password: process.env.FASTPIX_PASSWORD, // Secret Key
11 },
12});

A Next.js project with all of it wired

The route handler, the upload page, the webhook and the client player component, in one project you can clone and run. Everything in one place instead of four doc pages.

· Next.js 15· App Router· Route handlers
· Resumable upload· HLS playback

Behind the scenes

What happens after your Next.js app uploads a file

Here's what happens between the file leaving the browser and the video reaching a viewer. None of it is code you write, and none of it runs in your app.

480p
1080p
Encoding renditions
4K

Native uploader

Chunked and resumable, from the browser to a signed URL.

Import from a URL

Or pass a public video URL and FastPix pulls it in.

FastPix

Ingest, encode, package

No FFmpeg, no build step, nothing in your output directory.

Chunked, resumable ingest
Transcode to a ladder
Store and version
Package HLS renditions
Thumbnails and captions
Encrypt for DRM

video.media.ready

The webhook that tells your server the video is ready.

Adaptive playback

One playback ID into the player, on-demand or live.

1
2
3

Upload

From your Next.js app

Process

FastPix handles this

Play

Webhook + playback ID

Your Next.js app only touches the two ends. A server call hands over a signed URL and the player takes the playback ID. In between, a video.media.ready webhook tells your server the video is ready.

FAQ

Next.js video questions, answered

  • Where should I store video files in a Next.js app?

    Not in public/. Files there are served by your app and committed to your repo, so a 200 MB video bloats every deploy and every viewer downloads the same single file at the same bitrate. Put video on storage built for it and reference it by ID. Next.js's own video guide says the same thing, and the reason is that public/ has no byte-range handling, no set of quality levels and no CDN behaviour you control.

  • Why does my Next.js video take so long to start playing?

    Usually because the browser is downloading a single large MP4 before it can show anything. An adaptive stream splits the video into segments and lets the player start on the lowest quality level, so playback begins after one small segment rather than after a whole file. The other half is what paints first: set a poster image so the page has something to show while the manifest loads.

  • How do I upload video in a Next.js app?

    Don't post the file through a route handler. Create a signed upload URL there, then let the uploader send the file straight to storage in chunks. It resumes after a dropped connection, and no serverless body limit or function timeout applies, because the bytes never reach your function.

  • How do I add a background video without hurting LCP?

    Give the element a poster so the first paint is an image rather than a decoded video frame, and muted alongside autoplay because browsers block autoplay with sound. Load the player after mount so its JavaScript stays out of the initial bundle.