Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -332,14 +332,15 @@
"guides/examples/open-ai-with-retrying",
"guides/examples/pdf-to-image",
"guides/examples/puppeteer",
"guides/examples/react-pdf",
"guides/examples/react-email",
"guides/examples/resend-email-sequence",
"guides/examples/satori",
"guides/examples/scrape-hacker-news",
"guides/examples/sentry-error-tracking",
"guides/examples/sharp-image-processing",
"guides/examples/supabase-database-operations",
"guides/examples/supabase-storage-upload",
"guides/examples/react-pdf",
"guides/examples/react-email",
"guides/examples/resend-email-sequence",
"guides/examples/vercel-ai-sdk",
"guides/examples/vercel-sync-env-vars"
]
Expand Down
187 changes: 184 additions & 3 deletions docs/guides/examples/react-email.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ description: "Learn how to send beautiful emails using React Email and Trigger.d

## Overview

This example demonstrates how to use Trigger.dev to send emails using React Email.
This example demonstrates how to use Trigger.dev to send emails using [React Email](https://react.email/).

<Note>
This example uses [Resend](https://resend.com) as the email provider. You can use other email
providers like [SendGrid](https://sendgrid.com) or [Loops](https://loops.so) as well. Full list of
providers like [Loops](https://loops.so) or [SendGrid](https://sendgrid.com) etc. Full list of
their integrations can be found [here](https://react.email/docs/introduction#integrations).
</Note>

Expand Down Expand Up @@ -98,7 +98,7 @@ export const sendEmail = task({
});
```

## How the email should look
## The email

This example email should look like this:
![React Email](/images/react-email.png)
Expand All @@ -121,3 +121,184 @@ To test this task in the [dashboard](https://cloud.trigger.dev), you can use the
## Deploying your task

Deploy the task to production using the Trigger.dev CLI `deploy` command.

## Using Cursor / AI to build your emails

In this video you can see how we use Cursor to build a welcome email.

We recommend using our [Cursor rules](https://trigger.dev/changelog/cursor-rules-writing-tasks/) to help you build your tasks and emails.

#### Video: creating a new email template using Cursor

<video
src="https://content.trigger.dev/trigger-welcome-email-cursor.mp4"
controls
muted
autoPlay
loop
/>

#### The generated email template

![Cursor](/images/react-email-welcome.png)

#### The generated code

```tsx trigger/welcome.tsx
import {
Body,
Button,reac
Container,
Head,
Hr,
Html,
Img,
Link,
Preview,
Section,
Text,
} from "@react-email/components";

const baseUrl = process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: "";

export const TriggerDevWelcomeEmail = () => (
<Html>
<Head />
<Preview>Welcome to Trigger.dev - Your background jobs platform!</Preview>
<Body style={main}>
<Container style={container}>
<Section style={box}>
<Img
src="https://trigger.dev/assets/triggerdev-lockup--light.svg"
width="150"
height="40"
alt="Trigger.dev"
/>
<Hr style={hr} />
<Text style={paragraph}>
Thanks for signing up for Trigger.dev! You're now ready to start
creating powerful background jobs and workflows.
</Text>
<Text style={paragraph}>
You can monitor your jobs, view runs, and manage your projects right
from your dashboard.
</Text>
<Button style={button} href="https://cloud.trigger.dev/dashboard">
View your Trigger.dev Dashboard
</Button>
<Hr style={hr} />
<Text style={paragraph}>
To help you get started, check out our{" "}
<Link style={anchor} href="https://trigger.dev/docs">
documentation
</Link>{" "}
and{" "}
<Link style={anchor} href="https://trigger.dev/docs/quickstart">
quickstart guide
</Link>
.
</Text>
<Text style={paragraph}>
You can create your first job using our SDK, set up integrations,
and configure triggers to automate your workflows. Take a look at
our{" "}
<Link style={anchor} href="https://trigger.dev/docs/examples">
examples
</Link>{" "}
for inspiration.
</Text>
<Text style={paragraph}>
Join our{" "}
<Link style={anchor} href="https://discord.gg/kA47vcd8Qr">
Discord community
</Link>{" "}
to connect with other developers and get help when you need it.
</Text>
<Text style={paragraph}>
We're here to help you build amazing things. If you have any
questions, check out our{" "}
<Link style={anchor} href="https://trigger.dev/docs">
documentation
</Link>{" "}
or reach out to us on Discord.
</Text>
<Text style={paragraph}>— The Trigger.dev team</Text>
<Hr style={hr} />
<Text style={footer}>Trigger.dev Inc.</Text>
</Section>
</Container>
</Body>
</Html>
);

export default TriggerDevWelcomeEmail;

const main = {
backgroundColor: "#0E0C15",
fontFamily:
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
};

const container = {
backgroundColor: "#1D1B27",
margin: "0 auto",
padding: "20px 0 48px",
marginBottom: "64px",
};

const box = {
padding: "0 48px",
};

const hr = {
borderColor: "#2D2B3B",
margin: "20px 0",
};

const paragraph = {
color: "#E1E1E3",
fontSize: "16px",
lineHeight: "24px",
textAlign: "left" as const,
};

const anchor = {
color: "#A78BFA",
};

const button = {
backgroundColor: "#7C3AED",
borderRadius: "6px",
color: "#fff",
fontSize: "16px",
fontWeight: "bold",
textDecoration: "none",
textAlign: "center" as const,
display: "block",
width: "100%",
padding: "12px",
};

const footer = {
color: "#9CA3AF",
fontSize: "12px",
lineHeight: "16px",
};
```

## 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.

<CardGroup cols={2}>
<Card title="Components" icon="puzzle-piece" href="https://react.email/components">
Pre-built components you can copy and paste into your emails.
</Card>
<Card title="Templates" icon="rectangle-list" href="https://react.email/templates">
Extensive pre-built templates ready to use.
</Card>
</CardGroup>
133 changes: 133 additions & 0 deletions docs/guides/examples/satori.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
title: "Generate OG Images using Satori"
sidebarTitle: "Satori OG Images"
description: "Learn how to generate dynamic Open Graph images using Satori and Trigger.dev."
---

## Overview

This example demonstrates how to use Trigger.dev to generate dynamic Open Graph (OG) images using Vercel's [Satori](https://github.com/vercel/satori). The task takes a title and image URL as input and generates a beautiful OG image with text overlay.

This can be customized and extended however you like, full list of options can be found [here](https://github.com/vercel/satori).

## Task code

```tsx trigger/generateOgImage.ts
import { schemaTask } from "@trigger.dev/sdk/v3";
import { z } from "zod";
import satori from "satori";
import sharp from "sharp";
import { join } from "path";
import fs from "fs/promises";

export const generateOgImage = schemaTask({
id: "generate-og-image",
schema: z.object({
width: z.number().optional(),
height: z.number().optional(),
title: z.string(),
imageUrl: z.string().url(),
}),
run: async (payload) => {
// Load font
const fontResponse = await fetch(
"https://github.com/googlefonts/roboto/raw/main/src/hinted/Roboto-Regular.ttf"
).then((res) => res.arrayBuffer());

// Fetch and convert image to base64
const imageResponse = await fetch(payload.imageUrl);
const imageBuffer = await imageResponse.arrayBuffer();
const imageBase64 = `data:${
imageResponse.headers.get("content-type") || "image/jpeg"
};base64,${Buffer.from(imageBuffer).toString("base64")}`;

const markup = (
<div
style={{
width: payload.width ?? 1200,
height: payload.height ?? 630,
display: "flex",
backgroundColor: "#121317",
position: "relative",
fontFamily: "Roboto",
}}
>
<img
src={imageBase64}
width={payload.width ?? 1200}
height={payload.height ?? 630}
style={{
objectFit: "cover",
}}
/>
<h1
style={{
fontSize: "60px",
fontWeight: "bold",
color: "#fff",
margin: 0,
position: "absolute",
top: "50%",
transform: "translateY(-50%)",
left: "48px",
maxWidth: "60%",
textShadow: "0 2px 4px rgba(0,0,0,0.5)",
}}
>
{payload.title}
</h1>
</div>
);

const svg = await satori(markup, {
width: payload.width ?? 1200,
height: payload.height ?? 630,
fonts: [
{
name: "Roboto",
data: fontResponse,
weight: 400,
style: "normal",
},
],
});

const fileName = `og-${Date.now()}.jpg`;
const tempDir = join(process.cwd(), "tmp");
await fs.mkdir(tempDir, { recursive: true });
const outputPath = join(tempDir, fileName);

await sharp(Buffer.from(svg))
.jpeg({
quality: 90,
mozjpeg: true,
})
.toFile(outputPath);

return {
filePath: outputPath,
width: payload.width,
height: payload.height,
};
},
});
```

## Image example

This image was generated using the above task.

![OG Image](/images/react-satori-og.jpg)

## Testing your task

To test this task in the [dashboard](https://cloud.trigger.dev), you can use the following payload:

```json
{
"title": "My Awesome OG image",
"imageUrl": "<your-image-url>",
"width": 1200, // optional, defaults to 1200
"height": 630 // optional, defaults to 630
}
```
4 changes: 4 additions & 0 deletions docs/guides/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ Task code you can copy and paste to use in your project. They can all be extende
| [Vercel AI SDK](/guides/examples/vercel-ai-sdk) | Use Vercel AI SDK to generate text using OpenAI. |
| [Vercel sync environment variables](/guides/examples/vercel-sync-env-vars) | Automatically sync environment variables from your Vercel projects to Trigger.dev. |

## Cursor rules

If you use Cursor, we have a set of Cursor rules which will help you build your tasks. You can find our installation guide [here](https://trigger.dev/changelog/cursor-rules-writing-tasks/).

<Note>
If you would like to see a guide for your framework, or an example task for your use case, please
request it in our [Discord server](https://trigger.dev/discord) and we'll add it to the list.
Expand Down
Binary file added docs/images/react-email-welcome.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/react-satori-og.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.