Skip to content

Commit 1ca1c1d

Browse files
committed
feat(preview-server): error feedback for rate limiting (#1735)
1 parent 1fc99f9 commit 1ca1c1d

File tree

3 files changed

+55
-43
lines changed

3 files changed

+55
-43
lines changed

.changeset/major-hats-behave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@react-email/preview-server": patch
3+
---
4+
5+
add better feedback for when test sending is rate limited
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'use server';
2+
3+
export async function sendTestEmail(
4+
to: string,
5+
subject: string,
6+
html: string,
7+
): Promise<{ ok: boolean; status: number }> {
8+
const response = await fetch('https://react.email/api/send/test', {
9+
method: 'POST',
10+
headers: { 'Content-Type': 'application/json' },
11+
body: JSON.stringify({
12+
to,
13+
subject,
14+
html,
15+
}),
16+
});
17+
18+
return { ok: response.ok, status: response.status };
19+
}

packages/preview-server/src/components/send.tsx

Lines changed: 31 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,35 @@
11
import * as Popover from '@radix-ui/react-popover';
2-
import * as React from 'react';
2+
import { useId, useState } from 'react';
33
import { toast } from 'sonner';
4+
import { sendTestEmail } from '../actions/send-test-email';
45
import { Button } from './button';
56
import { Text } from './text';
67

78
export const Send = ({ markup }: { markup: string }) => {
8-
const [to, setTo] = React.useState('');
9-
const [subject, setSubject] = React.useState('Testing React Email');
10-
const [isSending, setIsSending] = React.useState(false);
11-
const [isPopOverOpen, setIsPopOverOpen] = React.useState(false);
9+
const [to, setTo] = useState('');
10+
const [subject, setSubject] = useState('Testing React Email');
11+
const [isSending, setIsSending] = useState(false);
12+
const [isPopOverOpen, setIsPopOverOpen] = useState(false);
1213

1314
const onFormSubmit = async (e: React.FormEvent) => {
14-
try {
15-
e.preventDefault();
16-
setIsSending(true);
15+
e.preventDefault();
16+
setIsSending(true);
1717

18-
const response = await fetch('https://react.email/api/send/test', {
19-
method: 'POST',
20-
headers: { 'Content-Type': 'application/json' },
21-
body: JSON.stringify({
22-
to,
23-
subject,
24-
html: markup,
25-
}),
26-
});
18+
const response = await sendTestEmail(to, subject, markup);
2719

28-
if (response.ok) {
29-
toast.success('Email sent! Check your inbox.');
30-
} else {
31-
if (response.status === 429) {
32-
const { error } = (await response.json()) as { error: string };
33-
toast.error(error);
34-
} else {
35-
toast.error('Something went wrong. Please try again.');
36-
}
37-
}
38-
} catch (_exception) {
20+
if (response.ok) {
21+
toast.success('Email sent! Check your inbox.');
22+
} else if (response.status === 429) {
23+
toast.error('Too many requests. Try again in around 1 minute');
24+
} else {
3925
toast.error('Something went wrong. Please try again.');
40-
} finally {
41-
setIsSending(false);
4226
}
27+
28+
setIsSending(false);
4329
};
4430

45-
const toId = React.useId();
46-
const subjectId = React.useId();
31+
const toId = useId();
32+
const subjectId = useId();
4733

4834
return (
4935
<Popover.Root
@@ -114,17 +100,19 @@ export const Send = ({ markup }: { markup: string }) => {
114100
type="checkbox"
115101
/>
116102
<div className="mt-3 flex items-center justify-between">
117-
<Text className="inline-block" size="1">
118-
Powered by{' '}
119-
<a
120-
className="text-white/85 transition duration-300 ease-in-out hover:text-slate-12"
121-
href="https://go.resend.com/react-email"
122-
rel="noreferrer"
123-
target="_blank"
124-
>
125-
Resend
126-
</a>
127-
</Text>
103+
<div className="flex flex-col inline-block">
104+
<Text size="1">
105+
Powered by{' '}
106+
<a
107+
className="text-white/85 transition duration-300 ease-in-out hover:text-slate-12"
108+
href="https://go.resend.com/react-email"
109+
rel="noreferrer"
110+
target="_blank"
111+
>
112+
Resend
113+
</a>
114+
</Text>
115+
</div>
128116
<Button
129117
className="disabled:border-transparent disabled:bg-slate-11"
130118
disabled={subject.length === 0 || to.length === 0 || isSending}

0 commit comments

Comments
 (0)