From ddcd17178afddd9eefbfc87b6d2c6da7b63aaf00 Mon Sep 17 00:00:00 2001 From: D-K-P <8297864+D-K-P@users.noreply.github.com> Date: Mon, 15 Sep 2025 18:14:49 +0100 Subject: [PATCH 1/5] Added nano banana task --- .../replicate-nano-banana-image-to-image.mdx | 124 ++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 docs/guides/examples/replicate-nano-banana-image-to-image.mdx diff --git a/docs/guides/examples/replicate-nano-banana-image-to-image.mdx b/docs/guides/examples/replicate-nano-banana-image-to-image.mdx new file mode 100644 index 0000000000..2fa6fb8791 --- /dev/null +++ b/docs/guides/examples/replicate-nano-banana-image-to-image.mdx @@ -0,0 +1,124 @@ +--- +title: "Image-to-image generation using Replicate and nano-banana" +sidebarTitle: "Nano banana image-to-image" +description: "Learn how to generate images from source image URLs using Replicate and Trigger.dev." +--- + +## Overview + +This example demonstrates how to use Trigger.dev to generate images from source image URLs using [Replicate](https://replicate.com/), the [nano-banana-image-to-image](https://replicate.com/meta/nano-banana-image-to-image) model. + +## Task code + +```tsx trigger/generateImage.tsx +import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; +import { task, wait } from "@trigger.dev/sdk"; +import Replicate, { Prediction } from "replicate"; + +// Initialize clients +const replicate = new Replicate({ + auth: process.env.REPLICATE_API_TOKEN, +}); + +const s3Client = new S3Client({ + region: "auto", + endpoint: process.env.R2_ENDPOINT, + credentials: { + accessKeyId: process.env.R2_ACCESS_KEY_ID ?? "", + secretAccessKey: process.env.R2_SECRET_ACCESS_KEY ?? "", + }, +}); + +const model = "google/nano-banana"; + +export const generateImageAndUploadToR2 = task({ + id: "generate-image-and-upload-to-r2", + run: async (payload: { prompt: string; imageUrl: string }) => { + const { prompt, imageUrl } = payload; + + const token = await wait.createToken({ + timeout: "10m", + }); + + // Use Flux with structured prompt + const output = await replicate.predictions.create({ + model: model, + input: { prompt, image_input: [imageUrl] }, + // pass the provided URL to Replicate's webhook, so they can "callback" + webhook: token.url, + webhook_events_filter: ["completed"], + }); + + const result = await wait.forToken(token); + // unwrap() throws a timeout error or returns the result 👆 + + if (!result.ok) { + throw new Error("Failed to create prediction"); + } + + const generatedImageUrl = result.output.output; + + const image = await fetch(generatedImageUrl); + const imageBuffer = Buffer.from(await image.arrayBuffer()); + + const base64Image = Buffer.from(imageBuffer).toString("base64"); + + const timestamp = Date.now(); + const filename = `generated-${timestamp}.png`; + + // Generate unique key for R2 + const sanitizedFileName = filename.replace(/[^a-zA-Z0-9.-]/g, "_"); + const r2Key = `uploaded-images/${timestamp}-${sanitizedFileName}`; + + const uploadParams = { + Bucket: process.env.R2_BUCKET, + Key: r2Key, + Body: imageBuffer, + ContentType: "image/png", + // Add cache control for better performance + CacheControl: "public, max-age=31536000", // 1 year + }; + + const uploadResult = await s3Client.send(new PutObjectCommand(uploadParams)); + + // Construct the public URL using the R2_PUBLIC_URL env var + const publicUrl = `${process.env.R2_PUBLIC_URL}/${r2Key}`; + + return { + success: true, + publicUrl, + originalPrompt: prompt, + sourceImageUrl: imageUrl, + }; + }, +}); +``` + +## Environment variables + +You will need to set the following environment variables: + +``` +TRIGGER_SECRET_KEY= +REPLICATE_API_TOKEN= +R2_ENDPOINT= +R2_ACCESS_KEY_ID= +R2_SECRET_ACCESS_KEY= +R2_BUCKET= +R2_PUBLIC_URL= +``` + +## Learn more + +### React Email docs + +Check out the [React Email docs](https://react.email/docs) and learn how to set up and use React Email, including how to preview your emails locally. + + + + Pre-built components you can copy and paste into your emails. + + + Extensive pre-built templates ready to use. + + From 88edd78a509d17a85439dddfd7257eb3257e6058 Mon Sep 17 00:00:00 2001 From: D-K-P <8297864+D-K-P@users.noreply.github.com> Date: Mon, 15 Sep 2025 18:17:24 +0100 Subject: [PATCH 2/5] Renamed the file and updated docs.json --- docs/docs.json | 2 + .../replicate-nano-banana-image-to-image.mdx | 124 ------------------ docs/guides/introduction.mdx | 2 + 3 files changed, 4 insertions(+), 124 deletions(-) delete mode 100644 docs/guides/examples/replicate-nano-banana-image-to-image.mdx diff --git a/docs/docs.json b/docs/docs.json index 06b2bc3353..b4529e80da 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -343,6 +343,7 @@ "guides/example-projects/mastra-agents-with-memory", "guides/example-projects/meme-generator-human-in-the-loop", "guides/example-projects/openai-agents-sdk-typescript-playground", + "guides/example-projects/product-image-generator", "guides/example-projects/realtime-csv-importer", "guides/example-projects/realtime-fal-ai", "guides/example-projects/turborepo-monorepo-prisma", @@ -376,6 +377,7 @@ "guides/examples/puppeteer", "guides/examples/react-pdf", "guides/examples/react-email", + "guides/examples/replicate-image-generation", "guides/examples/resend-email-sequence", "guides/examples/satori", "guides/examples/scrape-hacker-news", diff --git a/docs/guides/examples/replicate-nano-banana-image-to-image.mdx b/docs/guides/examples/replicate-nano-banana-image-to-image.mdx deleted file mode 100644 index 2fa6fb8791..0000000000 --- a/docs/guides/examples/replicate-nano-banana-image-to-image.mdx +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: "Image-to-image generation using Replicate and nano-banana" -sidebarTitle: "Nano banana image-to-image" -description: "Learn how to generate images from source image URLs using Replicate and Trigger.dev." ---- - -## Overview - -This example demonstrates how to use Trigger.dev to generate images from source image URLs using [Replicate](https://replicate.com/), the [nano-banana-image-to-image](https://replicate.com/meta/nano-banana-image-to-image) model. - -## Task code - -```tsx trigger/generateImage.tsx -import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; -import { task, wait } from "@trigger.dev/sdk"; -import Replicate, { Prediction } from "replicate"; - -// Initialize clients -const replicate = new Replicate({ - auth: process.env.REPLICATE_API_TOKEN, -}); - -const s3Client = new S3Client({ - region: "auto", - endpoint: process.env.R2_ENDPOINT, - credentials: { - accessKeyId: process.env.R2_ACCESS_KEY_ID ?? "", - secretAccessKey: process.env.R2_SECRET_ACCESS_KEY ?? "", - }, -}); - -const model = "google/nano-banana"; - -export const generateImageAndUploadToR2 = task({ - id: "generate-image-and-upload-to-r2", - run: async (payload: { prompt: string; imageUrl: string }) => { - const { prompt, imageUrl } = payload; - - const token = await wait.createToken({ - timeout: "10m", - }); - - // Use Flux with structured prompt - const output = await replicate.predictions.create({ - model: model, - input: { prompt, image_input: [imageUrl] }, - // pass the provided URL to Replicate's webhook, so they can "callback" - webhook: token.url, - webhook_events_filter: ["completed"], - }); - - const result = await wait.forToken(token); - // unwrap() throws a timeout error or returns the result 👆 - - if (!result.ok) { - throw new Error("Failed to create prediction"); - } - - const generatedImageUrl = result.output.output; - - const image = await fetch(generatedImageUrl); - const imageBuffer = Buffer.from(await image.arrayBuffer()); - - const base64Image = Buffer.from(imageBuffer).toString("base64"); - - const timestamp = Date.now(); - const filename = `generated-${timestamp}.png`; - - // Generate unique key for R2 - const sanitizedFileName = filename.replace(/[^a-zA-Z0-9.-]/g, "_"); - const r2Key = `uploaded-images/${timestamp}-${sanitizedFileName}`; - - const uploadParams = { - Bucket: process.env.R2_BUCKET, - Key: r2Key, - Body: imageBuffer, - ContentType: "image/png", - // Add cache control for better performance - CacheControl: "public, max-age=31536000", // 1 year - }; - - const uploadResult = await s3Client.send(new PutObjectCommand(uploadParams)); - - // Construct the public URL using the R2_PUBLIC_URL env var - const publicUrl = `${process.env.R2_PUBLIC_URL}/${r2Key}`; - - return { - success: true, - publicUrl, - originalPrompt: prompt, - sourceImageUrl: imageUrl, - }; - }, -}); -``` - -## Environment variables - -You will need to set the following environment variables: - -``` -TRIGGER_SECRET_KEY= -REPLICATE_API_TOKEN= -R2_ENDPOINT= -R2_ACCESS_KEY_ID= -R2_SECRET_ACCESS_KEY= -R2_BUCKET= -R2_PUBLIC_URL= -``` - -## Learn more - -### React Email docs - -Check out the [React Email docs](https://react.email/docs) and learn how to set up and use React Email, including how to preview your emails locally. - - - - Pre-built components you can copy and paste into your emails. - - - Extensive pre-built templates ready to use. - - diff --git a/docs/guides/introduction.mdx b/docs/guides/introduction.mdx index 9bf4695651..420494ea66 100644 --- a/docs/guides/introduction.mdx +++ b/docs/guides/introduction.mdx @@ -52,6 +52,7 @@ Example projects are full projects with example repos you can fork and use. Thes | [Mastra agents with memory](/guides/example-projects/mastra-agents-with-memory) | Use Mastra to create a weather agent that can collect live weather data and generate clothing recommendations. | — | [View the repo](https://github.com/triggerdotdev/examples/tree/main/mastra-agents) | | [OpenAI Agents SDK for Python guardrails](/guides/example-projects/openai-agent-sdk-guardrails) | Use the OpenAI Agents SDK for Python to create a guardrails system for your AI agents. | — | [View the repo](https://github.com/triggerdotdev/examples/tree/main/openai-agent-sdk-guardrails-examples) | | [OpenAI Agents SDK for TypeScript playground](/guides/example-projects/openai-agents-sdk-typescript-playground) | A playground containing 7 AI agents using the OpenAI Agents SDK for TypeScript with Trigger.dev. | — | [View the repo](https://github.com/triggerdotdev/examples/tree/main/openai-agents-sdk-with-trigger-playground) | +| [Product image generator](/guides/example-projects/product-image-generator) | Transform basic product photos into professional marketing shots using Replicate's image generation models. | Next.js | [View the repo](https://github.com/triggerdotdev/examples/tree/main/product-image-generator) | | [Python web crawler](/guides/python/python-crawl4ai) | Use Python, Crawl4AI and Playwright to create a headless web crawler with Trigger.dev. | — | [View the repo](https://github.com/triggerdotdev/examples/tree/main/python-crawl4ai) | | [Realtime CSV Importer](/guides/example-projects/realtime-csv-importer) | Upload a CSV file and see the progress of the task streamed to the frontend. | Next.js | [View the repo](https://github.com/triggerdotdev/examples/tree/main/realtime-csv-importer) | | [Realtime Fal.ai image generation](/guides/example-projects/realtime-fal-ai) | Generate an image from a prompt using Fal.ai and show the progress of the task on the frontend using Realtime. | Next.js | [View the repo](https://github.com/triggerdotdev/examples/tree/main/realtime-fal-ai-image-generation) | @@ -79,6 +80,7 @@ Task code you can copy and paste to use in your project. They can all be extende | [React email](/guides/examples/react-email) | Send an email using React Email. | | [React to PDF](/guides/examples/react-pdf) | Use `react-pdf` to generate a PDF and save it to Cloudflare R2. | | [Resend email sequence](/guides/examples/resend-email-sequence) | Send a sequence of emails over several days using Resend with Trigger.dev. | +| [Replicate image generation](/guides/examples/replicate-image-generation) | Learn how to generate images from source image URLs using Replicate and Trigger.dev. | | [Satori](/guides/examples/satori) | Generate OG images using React Satori. | | [Scrape Hacker News](/guides/examples/scrape-hacker-news) | Scrape Hacker News using BrowserBase and Puppeteer, summarize the articles with ChatGPT and send an email of the summary every weekday using Resend. | | [Sentry error tracking](/guides/examples/sentry-error-tracking) | Automatically send errors to Sentry from your tasks. | From b6bf1a777503cf0d5fec5fa008dc6d335af01aa2 Mon Sep 17 00:00:00 2001 From: D-K-P <8297864+D-K-P@users.noreply.github.com> Date: Mon, 15 Sep 2025 18:20:14 +0100 Subject: [PATCH 3/5] Added product imgae generator demo project --- .../product-image-generator.mdx | 61 +++++++++ .../examples/replicate-image-generation.mdx | 124 ++++++++++++++++++ 2 files changed, 185 insertions(+) create mode 100644 docs/guides/example-projects/product-image-generator.mdx create mode 100644 docs/guides/examples/replicate-image-generation.mdx diff --git a/docs/guides/example-projects/product-image-generator.mdx b/docs/guides/example-projects/product-image-generator.mdx new file mode 100644 index 0000000000..c34c116035 --- /dev/null +++ b/docs/guides/example-projects/product-image-generator.mdx @@ -0,0 +1,61 @@ +--- +title: "Product image generator using Replicate and Trigger.dev" +sidebarTitle: "Product image generator" +description: "AI-powered product image generator that transforms basic product photos into professional marketing shots using Replicate's image generation models" +--- + +## Overview + +This project demonstrates how to build an AI-powered product image generator that transforms basic product photos into professional marketing shots. Users upload a product image and receive three professionally styled variations: clean product shots, lifestyle scenes, and hero shots with dramatic lighting. + +## Video + +