Next.js
You will add an uploader that sends files from the browser straight to MediaLit, then keep the file when the user saves. The full app is in examples/next-app-router.
Install the packages
npmnpm install medialit @medialit/reactpnpmpnpm add medialit @medialit/reactyarnyarn add medialit @medialit/reactbunbun add medialit @medialit/reactmedialitruns on your server and holds the API key.@medialit/reactis the browser uploader.Add your API key
Add the key from your app's settings in the dashboard to
.env.local:.env.localMEDIALIT_API_KEY=your_api_key # Only if you self-host MediaLit # MEDIALIT_ENDPOINT=https://medialit.example.comCreate the signature route
The uploader asks this route for a short-lived upload signature, so the API key never reaches the browser.
app/api/medialit/signature/route.tsimport { createSignatureHandler } from "medialit"; import { auth } from "@/auth"; // your app's authentication export const POST = createSignatureHandler({ authorize: async () => { const session = await auth(); return !!session; }, });Anyone who passes
authorizecan upload to your MediaLit app. Returnfalsefor visitors who are not signed in.To put each user's files in their own group, return a group instead of
true:authorize: async () => { const session = await auth(); return session ? { group: session.user.id } : false; },Add the uploader
app/profile/avatar-upload.tsx"use client"; import { useState } from "react"; import { MediaLitUploader } from "@medialit/react"; import "@medialit/react/styles.css"; import { saveAvatar } from "./actions"; export function AvatarUpload() { const [mediaId, setMediaId] = useState<string>(); return ( <form action={() => mediaId && saveAvatar(mediaId)}> <MediaLitUploader signatureEndpoint="/api/medialit/signature" access="public" accept="image/*" maxFileSize={5 * 1024 * 1024} onUploadComplete={(media) => setMediaId(media.mediaId)} /> <button type="submit" disabled={!mediaId}> Save </button> </form> ); }The uploader shows a drop zone, upload progress with a cancel button, and the uploaded file. Read React to change its text, style or behaviour.
Seal the file when the user saves
The upload is temporary until you seal it. If the user leaves without saving, MediaLit deletes it after 24 hours.
app/profile/actions.ts"use server"; import { MediaLit } from "medialit"; const medialit = new MediaLit(); export async function saveAvatar(mediaId: string) { const media = await medialit.seal(mediaId); // Save media.mediaId and media.file with the user's profile. }Sealing a public file gives it its permanent URL, so save the
filereturned byseal, not the one from the upload.
Show private files
Private files have signed URLs that expire. Store the mediaId and get a fresh URL when you render the page:
import { MediaLit } from "medialit";
const medialit = new MediaLit();
export default async function DocumentPage({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const document = await getDocument(id); // from your database
const media = await medialit.get(document.mediaId);
return <a href={media.file}>Download {media.originalFileName}</a>;
}Delete files
await medialit.delete(mediaId);Next steps
React covers every prop of
MediaLitUploaderand theuseMediaLitUploadhook for your own UI.Node.js SDK lists everything the server SDK can do.
How MediaLit works explains sealing, access and groups.
