Skip to content

Commit

Permalink
update email sending to use resend.
Browse files Browse the repository at this point in the history
  • Loading branch information
antlossway committed Mar 4, 2024
1 parent 4fbe856 commit 46c6d46
Show file tree
Hide file tree
Showing 7 changed files with 8,109 additions and 3,434 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,18 @@ to add a image, simply put a image named "opengraph-image.png" in the root layou
<meta name="twitter:description" content="The place to show what I have learned. Create with next.js, tailwindCSS">
<meta name="twitter:image" content="link to the iamge">
```

## email function

### option 1

use Node mailer to send email, using mailtrap as SMTP server

### option 2 (currently in use)

use resend.com to send email (it's a complete email platform).
optionally use react.email to build email template.

### option 3

use some SaaS platform like mailerlite or loops. They provide embedded form and many other features.
11,369 changes: 7,976 additions & 3,393 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"lint": "next lint"
},
"dependencies": {
"@react-email/components": "^0.0.15",
"@react-email/tailwind": "^0.0.14",
"autoprefixer": "10.4.16",
"eslint": "8.56.0",
"eslint-config-next": "^14.0.4",
Expand All @@ -24,6 +26,7 @@
"rehype-autolink-headings": "^7.1.0",
"rehype-highlight": "^7.0.0",
"rehype-slug": "^6.0.0",
"resend": "^3.2.0",
"tailwindcss": "3.4.1"
},
"devDependencies": {
Expand Down
6 changes: 4 additions & 2 deletions src/app/demo/page.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import HeightTransition from "@/components/(demo)/HeightTransition"
import NewsLetter from "@/components/NewsLetter"
import React from "react"

const page = () => {
return (
<div>
<h1>Demo component</h1>
<HeightTransition>
{/* <HeightTransition>
tailwindcss - transition height auto using max-height
</HeightTransition>
</HeightTransition> */}
<NewsLetter />
</div>
)
}
Expand Down
36 changes: 36 additions & 0 deletions src/app/email-template/newsletter.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react"
import {
Html,
Body,
Head,
Heading,
Hr,
Container,
Preview,
Section,
Text,
} from "@react-email/components"
import { Tailwind } from "@react-email/tailwind"

export default function NewsletterEmail({ subscriberEmail }) {
return (
<Html>
<Head />
<Preview>New message</Preview>
<Tailwind>
<Body className="bg-gray-100 my-10 px-10 py-4 rounded-md text-black">
<Container>
<Section>
<Heading>
Hello, I will gladly share my update with you. Keep in touch!
</Heading>
<Text>Some new subscriber</Text>
<Hr />
<Text>Sender email {subscriberEmail}</Text>
</Section>
</Container>
</Body>
</Tailwind>
</Html>
)
}
88 changes: 49 additions & 39 deletions src/components/NewsLetter.jsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,59 @@
"use client"

import React, { useState } from 'react'
import { newsLetterSignup } from "@/lib/actions/mySendEmail"
import React, { useState } from "react"

export default function NewsLetter() {
// const [email, setEmail] = useState('')
const [newSub, setNewSub] = useState(false)

const handleNewsletter = async(e) => {
e.preventDefault()
const email = e.target[0].value
// console.log(email)

// register the new subscriber's email into mailing list
const res = await fetch("/api/newsletter", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
email
})
})
// console.log(res)
res.status === 201 && setNewSub(true)

}
// const [email, setEmail] = useState('')
const [newSub, setNewSub] = useState(false)

const handleNewsletter = async (e) => {
e.preventDefault()
const email = e.target[0].value
// console.log(email)

// register the new subscriber's email into mailing list
// const res = await fetch("/api/newsletter", {
// method: "POST",
// headers: {
// "Content-Type": "application/json"
// },
// body: JSON.stringify({
// email
// })
// })
// res.status === 201 && setNewSub(true)

const data = await newsLetterSignup(email)
setNewSub(true)
// console.log("debug newsLetterSignup: ", data)
}

return (
<div className="grid place-items-center place-content-center
">

<div className='p-3'>
<h2 className='mb-3'>This is to test newletter function</h2>
<form className='flex flex-col gap-4 sm:flex-row items-stretch justify-stretch'
onSubmit={handleNewsletter}>
<input type="email"
placeholder='email'
required
className='px-4 py-2 bg-transparent outline-none border border-gray-400 focus:border-gray-200 rounded-lg dark:text-white/80' />

<button className='px-4 py-2 bg-black/70 dark:bg-gray-500 rounded-lg text-white font-medium hover:scale-105 hover:transition-transform active:translate-y-1 '>Join newsletter</button>
<div
className="grid place-items-center place-content-center
"
>
<div className="p-3">
<h2 className="mb-3">This is to test newletter function</h2>
<form
className="flex flex-col gap-4 sm:flex-row items-stretch justify-stretch"
onSubmit={handleNewsletter}
>
<input
type="email"
placeholder="email"
required
className="px-4 py-2 bg-transparent outline-none border border-gray-400 focus:border-gray-200 rounded-lg dark:text-white/80"
/>

<button className="px-4 py-2 bg-black/70 dark:bg-gray-500 rounded-lg text-white font-medium hover:scale-105 hover:transition-transform active:translate-y-1 ">
Join newsletter
</button>
</form>
{
newSub && <p className='mt-3'>Thanks for subscribing to the newsletter!</p>
}
{newSub && (
<p className="mt-3">Thanks for subscribing to the newsletter!</p>
)}
</div>
</div>
)
Expand Down
26 changes: 26 additions & 0 deletions src/lib/actions/mySendEmail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"use server"
// use resend to send email
import { Resend } from "resend"
import NewsLetterEmail from "@/app/email-template/newsletter"
import React from "react"

const resend = new Resend(process.env.RESEND_API_KEY)

export async function newsLetterSignup(subscriberEmail) {
try {
const data = await resend.emails.send({
from: "MySite Notif <[email protected]>", // TODO: my own domain
to: process.env.EMAIL_PERSONAL, // send to myself
subject: `new subscriber ${subscriberEmail}`,
reply_to: subscriberEmail,
// text: "new subscriber alert",
react: <NewsLetterEmail subscriberEmail={subscriberEmail} />,
// react: React.createElement(NewsLetterEmail, { subscriberEmail }),
})
return data
} catch (error) {
return {
error: "something wrong with the email sending process",
}
}
}

0 comments on commit 46c6d46

Please sign in to comment.