Skip to content

Instantly share code, notes, and snippets.

@zanderswai
Created November 12, 2025 13:25
Show Gist options
  • Select an option

  • Save zanderswai/c770f5e5b72f0b80894d0adf542d2cc5 to your computer and use it in GitHub Desktop.

Select an option

Save zanderswai/c770f5e5b72f0b80894d0adf542d2cc5 to your computer and use it in GitHub Desktop.
Customized Payload Media Endpoints: path: api/media
import { NextRequest, NextResponse } from "next/server";
import { getPayload } from "payload";
import config from "../../payload.config";
import {
handleS3Read,
handleS3Upload,
handleS3Delete,
} from "../../storage/s3-adapter";
/**
* POST /api/media
* Create a new media document with S3 upload
*/
export async function POST(request: NextRequest) {
try {
const payload = await getPayload({ config });
const formData = await request.formData();
const id = formData.get("where[and][0][id][in][0]") as string;
const depth = formData.get("depth") as string;
const file = formData.get("file") as File;
const alt = formData.get("alt") as string;
let finalDoc: any;
if (id || depth) {
finalDoc = await FindMediaById(payload, id, depth);
} else if (file || alt) {
finalDoc = await UploadFileToS3(payload, file, alt);
}
return NextResponse.json({ doc: finalDoc }, { status: 201 });
} catch (error) {
console.error("[Media API] POST error:", error);
return NextResponse.json(
{
error:
error instanceof Error ? error.message : "Failed to upload media",
},
{ status: 500 }
);
}
}
async function FindMediaById(payload: any, id: string, depth: string) {
const result = await payload.findByID({
collection: "media",
id: id,
limit: 1,
depth,
});
if (!result) {
throw new Error("Media not found");
}
// Apply S3 read to generate signed URLs
const finalDoc = await handleS3Read(result);
// Also process sizes if they exist
if (finalDoc.sizes) {
for (const sizeKey in finalDoc.sizes) {
let size = finalDoc.sizes[sizeKey];
if (size) {
size = await handleS3Read(size);
finalDoc.sizes[sizeKey] = size;
}
}
}
return finalDoc;
}
async function UploadFileToS3(payload: any, file: File, alt: string) {
if (!file) {
return NextResponse.json({ error: "No file provided" }, { status: 400 });
}
// Upload file to S3
const url = await handleS3Upload(file);
// Create media document in database
const mediaDoc = await payload.create({
collection: "media",
data: {
filename: file.name,
url: url,
alt: alt,
},
overrideAccess: true,
});
// Generate signed URL
return await handleS3Read(mediaDoc);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment