Overview

This example demonstrates how to use Trigger.dev to generate a PDF using react-pdf and save it to Cloudflare R2.

Task code

This example must be a .tsx file to use React components.
trigger/generateResumePDF.tsx
import { logger, task } from "@trigger.dev/sdk/v3";
import { renderToBuffer, Document, Page, Text, View } from "@react-pdf/renderer";
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";

// Initialize R2 client
const r2Client = new S3Client({
  // How to authenticate to R2: https://developers.cloudflare.com/r2/api/s3/tokens/
  region: "auto",
  endpoint: process.env.R2_ENDPOINT,
  credentials: {
    accessKeyId: process.env.R2_ACCESS_KEY_ID ?? "",
    secretAccessKey: process.env.R2_SECRET_ACCESS_KEY ?? "",
  },
});

export const generateResumePDF = task({
  id: "generate-resume-pdf",
  run: async (payload: { text: string }) => {
    // Log the payload
    logger.log("Generating PDF resume", payload);

    // Render the ResumeDocument component to a PDF buffer
    const pdfBuffer = await renderToBuffer(
      <Document>
        <Page size="A4">
          <View>
            <Text>{payload.text}</Text>
          </View>
        </Page>
      </Document>
    );

    // Generate a unique filename based on the text and current timestamp
    const filename = `${payload.text.replace(/\s+/g, "-").toLowerCase()}-${Date.now()}.pdf`;

    // Set the R2 key for the PDF file
    const r2Key = `resumes/${filename}`;

    // Set the upload parameters for R2
    const uploadParams = {
      Bucket: process.env.R2_BUCKET,
      Key: r2Key,
      Body: pdfBuffer,
      ContentType: "application/pdf",
    };

    // Log the upload parameters
    logger.log("Uploading to R2 with params", uploadParams);

    // Upload the PDF to R2
    await r2Client.send(new PutObjectCommand(uploadParams));

    // Return the Bucket and R2 key for the uploaded PDF
    return {
      Bucket: process.env.R2_BUCKET,
      Key: r2Key,
    };
  },
});

Testing your task

To test this task in the dashboard, you can use the following payload:

{
  "text": "Hello, world!"
}