Skip to content

Commit 179a9c9

Browse files
authored
Added satori and improved react email (#1877)
* Improved the react email docs and added a video * Copy * Added a link to the cursor rules * Added satori example * Copy updates * Added react pdf link
1 parent 18ad897 commit 179a9c9

File tree

7 files changed

+326
-7
lines changed

7 files changed

+326
-7
lines changed

docs/docs.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -332,14 +332,15 @@
332332
"guides/examples/open-ai-with-retrying",
333333
"guides/examples/pdf-to-image",
334334
"guides/examples/puppeteer",
335+
"guides/examples/react-pdf",
336+
"guides/examples/react-email",
337+
"guides/examples/resend-email-sequence",
338+
"guides/examples/satori",
335339
"guides/examples/scrape-hacker-news",
336340
"guides/examples/sentry-error-tracking",
337341
"guides/examples/sharp-image-processing",
338342
"guides/examples/supabase-database-operations",
339343
"guides/examples/supabase-storage-upload",
340-
"guides/examples/react-pdf",
341-
"guides/examples/react-email",
342-
"guides/examples/resend-email-sequence",
343344
"guides/examples/vercel-ai-sdk",
344345
"guides/examples/vercel-sync-env-vars"
345346
]

docs/guides/examples/react-email.mdx

+184-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ description: "Learn how to send beautiful emails using React Email and Trigger.d
66

77
## Overview
88

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

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

@@ -98,7 +98,7 @@ export const sendEmail = task({
9898
});
9999
```
100100

101-
## How the email should look
101+
## The email
102102

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

123123
Deploy the task to production using the Trigger.dev CLI `deploy` command.
124+
125+
## Using Cursor / AI to build your emails
126+
127+
In this video you can see how we use Cursor to build a welcome email.
128+
129+
We recommend using our [Cursor rules](https://trigger.dev/changelog/cursor-rules-writing-tasks/) to help you build your tasks and emails.
130+
131+
#### Video: creating a new email template using Cursor
132+
133+
<video
134+
src="https://content.trigger.dev/trigger-welcome-email-cursor.mp4"
135+
controls
136+
muted
137+
autoPlay
138+
loop
139+
/>
140+
141+
#### The generated email template
142+
143+
![Cursor](/images/react-email-welcome.png)
144+
145+
#### The generated code
146+
147+
```tsx trigger/welcome.tsx
148+
import {
149+
Body,
150+
Button,reac
151+
Container,
152+
Head,
153+
Hr,
154+
Html,
155+
Img,
156+
Link,
157+
Preview,
158+
Section,
159+
Text,
160+
} from "@react-email/components";
161+
162+
const baseUrl = process.env.VERCEL_URL
163+
? `https://${process.env.VERCEL_URL}`
164+
: "";
165+
166+
export const TriggerDevWelcomeEmail = () => (
167+
<Html>
168+
<Head />
169+
<Preview>Welcome to Trigger.dev - Your background jobs platform!</Preview>
170+
<Body style={main}>
171+
<Container style={container}>
172+
<Section style={box}>
173+
<Img
174+
src="https://trigger.dev/assets/triggerdev-lockup--light.svg"
175+
width="150"
176+
height="40"
177+
alt="Trigger.dev"
178+
/>
179+
<Hr style={hr} />
180+
<Text style={paragraph}>
181+
Thanks for signing up for Trigger.dev! You're now ready to start
182+
creating powerful background jobs and workflows.
183+
</Text>
184+
<Text style={paragraph}>
185+
You can monitor your jobs, view runs, and manage your projects right
186+
from your dashboard.
187+
</Text>
188+
<Button style={button} href="https://cloud.trigger.dev/dashboard">
189+
View your Trigger.dev Dashboard
190+
</Button>
191+
<Hr style={hr} />
192+
<Text style={paragraph}>
193+
To help you get started, check out our{" "}
194+
<Link style={anchor} href="https://trigger.dev/docs">
195+
documentation
196+
</Link>{" "}
197+
and{" "}
198+
<Link style={anchor} href="https://trigger.dev/docs/quickstart">
199+
quickstart guide
200+
</Link>
201+
.
202+
</Text>
203+
<Text style={paragraph}>
204+
You can create your first job using our SDK, set up integrations,
205+
and configure triggers to automate your workflows. Take a look at
206+
our{" "}
207+
<Link style={anchor} href="https://trigger.dev/docs/examples">
208+
examples
209+
</Link>{" "}
210+
for inspiration.
211+
</Text>
212+
<Text style={paragraph}>
213+
Join our{" "}
214+
<Link style={anchor} href="https://discord.gg/kA47vcd8Qr">
215+
Discord community
216+
</Link>{" "}
217+
to connect with other developers and get help when you need it.
218+
</Text>
219+
<Text style={paragraph}>
220+
We're here to help you build amazing things. If you have any
221+
questions, check out our{" "}
222+
<Link style={anchor} href="https://trigger.dev/docs">
223+
documentation
224+
</Link>{" "}
225+
or reach out to us on Discord.
226+
</Text>
227+
<Text style={paragraph}>— The Trigger.dev team</Text>
228+
<Hr style={hr} />
229+
<Text style={footer}>Trigger.dev Inc.</Text>
230+
</Section>
231+
</Container>
232+
</Body>
233+
</Html>
234+
);
235+
236+
export default TriggerDevWelcomeEmail;
237+
238+
const main = {
239+
backgroundColor: "#0E0C15",
240+
fontFamily:
241+
'-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Ubuntu,sans-serif',
242+
};
243+
244+
const container = {
245+
backgroundColor: "#1D1B27",
246+
margin: "0 auto",
247+
padding: "20px 0 48px",
248+
marginBottom: "64px",
249+
};
250+
251+
const box = {
252+
padding: "0 48px",
253+
};
254+
255+
const hr = {
256+
borderColor: "#2D2B3B",
257+
margin: "20px 0",
258+
};
259+
260+
const paragraph = {
261+
color: "#E1E1E3",
262+
fontSize: "16px",
263+
lineHeight: "24px",
264+
textAlign: "left" as const,
265+
};
266+
267+
const anchor = {
268+
color: "#A78BFA",
269+
};
270+
271+
const button = {
272+
backgroundColor: "#7C3AED",
273+
borderRadius: "6px",
274+
color: "#fff",
275+
fontSize: "16px",
276+
fontWeight: "bold",
277+
textDecoration: "none",
278+
textAlign: "center" as const,
279+
display: "block",
280+
width: "100%",
281+
padding: "12px",
282+
};
283+
284+
const footer = {
285+
color: "#9CA3AF",
286+
fontSize: "12px",
287+
lineHeight: "16px",
288+
};
289+
```
290+
291+
## Learn more
292+
293+
### React Email docs
294+
295+
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.
296+
297+
<CardGroup cols={2}>
298+
<Card title="Components" icon="puzzle-piece" href="https://react.email/components">
299+
Pre-built components you can copy and paste into your emails.
300+
</Card>
301+
<Card title="Templates" icon="rectangle-list" href="https://react.email/templates">
302+
Extensive pre-built templates ready to use.
303+
</Card>
304+
</CardGroup>

docs/guides/examples/react-pdf.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: "This example will show you how to generate a PDF using Trigger.dev
66

77
## Overview
88

9-
This example demonstrates how to use Trigger.dev to generate a PDF using `react-pdf` and save it to Cloudflare R2.
9+
This example demonstrates how to use Trigger.dev to generate a PDF using [react-pdf](https://react-pdf.org/) and save it to Cloudflare R2.
1010

1111
## Task code
1212

docs/guides/examples/satori.mdx

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---
2+
title: "Generate OG Images using Satori"
3+
sidebarTitle: "Satori OG Images"
4+
description: "Learn how to generate dynamic Open Graph images using Satori and Trigger.dev."
5+
---
6+
7+
## Overview
8+
9+
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.
10+
11+
This can be customized and extended however you like, full list of options can be found [here](https://github.com/vercel/satori).
12+
13+
## Task code
14+
15+
```tsx trigger/generateOgImage.ts
16+
import { schemaTask } from "@trigger.dev/sdk/v3";
17+
import { z } from "zod";
18+
import satori from "satori";
19+
import sharp from "sharp";
20+
import { join } from "path";
21+
import fs from "fs/promises";
22+
23+
export const generateOgImage = schemaTask({
24+
id: "generate-og-image",
25+
schema: z.object({
26+
width: z.number().optional(),
27+
height: z.number().optional(),
28+
title: z.string(),
29+
imageUrl: z.string().url(),
30+
}),
31+
run: async (payload) => {
32+
// Load font
33+
const fontResponse = await fetch(
34+
"https://github.com/googlefonts/roboto/raw/main/src/hinted/Roboto-Regular.ttf"
35+
).then((res) => res.arrayBuffer());
36+
37+
// Fetch and convert image to base64
38+
const imageResponse = await fetch(payload.imageUrl);
39+
const imageBuffer = await imageResponse.arrayBuffer();
40+
const imageBase64 = `data:${
41+
imageResponse.headers.get("content-type") || "image/jpeg"
42+
};base64,${Buffer.from(imageBuffer).toString("base64")}`;
43+
44+
const markup = (
45+
<div
46+
style={{
47+
width: payload.width ?? 1200,
48+
height: payload.height ?? 630,
49+
display: "flex",
50+
backgroundColor: "#121317",
51+
position: "relative",
52+
fontFamily: "Roboto",
53+
}}
54+
>
55+
<img
56+
src={imageBase64}
57+
width={payload.width ?? 1200}
58+
height={payload.height ?? 630}
59+
style={{
60+
objectFit: "cover",
61+
}}
62+
/>
63+
<h1
64+
style={{
65+
fontSize: "60px",
66+
fontWeight: "bold",
67+
color: "#fff",
68+
margin: 0,
69+
position: "absolute",
70+
top: "50%",
71+
transform: "translateY(-50%)",
72+
left: "48px",
73+
maxWidth: "60%",
74+
textShadow: "0 2px 4px rgba(0,0,0,0.5)",
75+
}}
76+
>
77+
{payload.title}
78+
</h1>
79+
</div>
80+
);
81+
82+
const svg = await satori(markup, {
83+
width: payload.width ?? 1200,
84+
height: payload.height ?? 630,
85+
fonts: [
86+
{
87+
name: "Roboto",
88+
data: fontResponse,
89+
weight: 400,
90+
style: "normal",
91+
},
92+
],
93+
});
94+
95+
const fileName = `og-${Date.now()}.jpg`;
96+
const tempDir = join(process.cwd(), "tmp");
97+
await fs.mkdir(tempDir, { recursive: true });
98+
const outputPath = join(tempDir, fileName);
99+
100+
await sharp(Buffer.from(svg))
101+
.jpeg({
102+
quality: 90,
103+
mozjpeg: true,
104+
})
105+
.toFile(outputPath);
106+
107+
return {
108+
filePath: outputPath,
109+
width: payload.width,
110+
height: payload.height,
111+
};
112+
},
113+
});
114+
```
115+
116+
## Image example
117+
118+
This image was generated using the above task.
119+
120+
![OG Image](/images/react-satori-og.jpg)
121+
122+
## Testing your task
123+
124+
To test this task in the [dashboard](https://cloud.trigger.dev), you can use the following payload:
125+
126+
```json
127+
{
128+
"title": "My Awesome OG image",
129+
"imageUrl": "<your-image-url>",
130+
"width": 1200, // optional, defaults to 1200
131+
"height": 630 // optional, defaults to 630
132+
}
133+
```

docs/guides/introduction.mdx

+4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ Task code you can copy and paste to use in your project. They can all be extende
7777
| [Vercel AI SDK](/guides/examples/vercel-ai-sdk) | Use Vercel AI SDK to generate text using OpenAI. |
7878
| [Vercel sync environment variables](/guides/examples/vercel-sync-env-vars) | Automatically sync environment variables from your Vercel projects to Trigger.dev. |
7979

80+
## Cursor rules
81+
82+
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/).
83+
8084
<Note>
8185
If you would like to see a guide for your framework, or an example task for your use case, please
8286
request it in our [Discord server](https://trigger.dev/discord) and we'll add it to the list.

docs/images/react-email-welcome.png

52.3 KB
Loading

docs/images/react-satori-og.jpg

59.9 KB
Loading

0 commit comments

Comments
 (0)