I want to use nextjs application to send email by send grid,because of its serverless feature. I send my first email via send grid demo, just now I want to send a date from my form.
form.js
import React, {useState} from 'react';
import { useForm } from 'react-hook-form';
import {
Row,
Col,
Container,
Form,
FormGroup,
Input,
Button,
} from "reactstrap";
function Form() {
const [hasSuccessfullySentMail, setHasSuccessfullySentMail] = useState(false);
const [hasErrored, setHasErrored] = useState(false);
const { register, handleSubmit, formState } = useForm();
const { isSubmitSuccessful, isSubmitting, isSubmitted, errors } = formState;
async function onSubmit(payload) {
try {
const res = await fetch('/api/sendEmail', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ subject: 'Email from contact form', ...payload }),
});
if (res.status !== 204) {
setHasErrored(true);
}
} catch {
setHasErrored(true);
return;
}
setHasSuccessfullySentMail(true);
}
const isSent = isSubmitSuccessful && isSubmitted;
const isDisabled = isSubmitting || isSent;
const isSubmitDisabled = Object.keys(errors).length > 0 || isDisabled;
return (
<>
<Form onSubmit={handleSubmit(onSubmit)}>
<Row>
<Col lg="6">
<FormGroup className="m-t-15">
<Input type="text" placeholder="Wpisz swoje imię" id="name" disabled={isDisabled} {...register('name', { required: true })} />
</FormGroup>
</Col>
<Col lg="6">
<FormGroup className="m-t-15">
<Input type="text" placeholder="Twój Email" id="email" disabled={isDisabled} {...register('email', { required: true })} />
</FormGroup>
</Col>
<Col lg="12">
<FormGroup className="m-t-15">
<Input
as="textarea"
placeholder="Wpisz swoją wiadomość..."
id="description"
disabled={isDisabled}
{...register('description', { required: true })}
/>
</FormGroup>
</Col>
<Col lg="12">
<Button
type="submit" disabled={isSubmitDisabled}
className="btn btn-danger-gradiant m-t-20 btn-arrow"
>
<span>
{" "}
Wyślij <i className="ti-arrow-right"></i>
</span>
</Button>
</Col>
</Row>
</Form>
</> )
}
export default Form
Problem is that in my console I do not see any headers's tag. I look inside Safari > developers tool > network. When I use mailchimp I can notice that something is sending as post-json in 1sec. Looking into console I get message that something is sending but after 40s as web pack-hmr. I think this is something differ.
in sendMail.js
require('dotenv').config(sendgrid.env)
require('dotenv').config(sendgrid)
import sendgrid from '@sendgrid/mail';
sendgrid.setApiKey(process.env.SENDGRID_API_KEY);
export default async (req, res) => {
const body = JSON.parse(req.body);
const message = `
Name: ${body.name}\r\n
Email: ${body.email}\r\n
Message: ${body.message}
`;
const data = {
to: '[email protected]',
from: '[email protected]',
subject: 'wiadomosc od klienta',
text: message,
html: message.replace(/\r\n/g, '<br>')
};
console.log(data)
sendgrid.send(data);
return res.status(200).json({ status: 'Ok' });
};
technically, there must be here some mistakes, but send grid is good installed and configured. So I need to change only this piece of code.
CodePudding user response:
I have answer for my first of problem. My SendGrid post date to api/contact but there something not work as it should.
import { useState } from 'react'
import {
Row,
Col,
Container,
Form,
FormGroup,
Input,
Button,
} from "reactstrap";
function Form() {
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [message, setMessage] = useState('')
const [submitted, setSubmitted] = useState(false)
const [status, setStatus] = useState('')
async function handleOnSubmit(e) {
e.preventDefault();
const formData = {
name,
email,
message
}
console.log("przesylam dane");
setSubmitted(true)
fetch('/api/contact', {
method: 'POST',
body: JSON.stringify(formData)
}).then((res) => {
if (res.status === 200) {
console.log("czyszcze pola")
setSubmitted(false)
setName('')
setEmail('')
setMessage('')
setStatus('success')
}
else {
console.log("pokazuej blad")
setStatus('error')
}
})
}
return (<>
<Form action='submit' method='POST' onSubmit={handleOnSubmit}>
<Row>
<Col lg="6">
<div id="name" isRequired className="m-t-15">
<Input style={{width: "100%"}}
placeholder="Wpisz swoje imię" type="text" value={name} onChange={(e) => { setName(e.target.value) }} />
</div>
</Col>
<Col lg="6">
<div id="email" isRequired className="m-t-15">
<Input style={{width: "100%"}}
placeholder="Wpisz swój adres email" type="email" value={email} onChange={(e) => { setEmail(e.target.value) }} />
</div>
</Col>
<Col lg="12">
<div id="text" isRequired className="m-t-15">
<Input
as="textarea" style={{width: "100%"}}
placeholder="Wpisz swoją wiadomość.."
value={message}
onChange={(e) => { setMessage(e.target.value) }}
/>
</div>
</Col>
<Col lg="12">
<Button type="submit"
isLoading={submitted}
loadingText="Submitting"
className="btn btn-danger-gradiant m-t-20 btn-arrow"
style={{width: "200px"}}
>
{" "}
Wyślij <i className="ti-arrow-right"></i> </Button>
</Col>
</Row>
{status === "success" ? <span style={{color: "green"}}>wiadomość przesłana</span> : ""}
{status === "error" ? <span style={{color: "red"}}>wiadomość nie została wysłana</span> : "" }
</Form>
</> )
}
export default Form
CodePudding user response:
I have recently used SendGrid as it is an external resolver API I did this in my API portion of next.js and works correctly.
// api/mail
import { news_letter_template } from "../../../util/email_templates";
const sendGrid = require("@sendgrid/mail");
sendGrid.setApiKey(process.env.NEXT_PUBLIC_SENDGRID_KEY);
// add this before handler!
export const config = {
api: {
externalResolver: true,
},
};
export default function handler(req, res) {
const body = JSON.parse(req.body);
console.log('request came => ',body);
const msg = news_letter_template(body.email);
sendGrid
.send(msg)
.then(() => {
return res.status(200).json({ send: true });
})
.catch((err) => {
return res.status(400).json({ send: false });
});
}
setting externalResolver
to true
made my code works correctly.
//utils/email_templates
const SENDER_EMAIL =
process.env.NEXT_PUBLIC_SENDER_EMAIL || "[email protected]";
const weblog_social = {
insta: "https://www.instagram.com/weblog",
fb: "https://www.facebook.com/weblog",
linkedIn: "https://www.linkedin.com/company/weblog",
};
const news_letter_template = (reciverEmail) => {
const msg = {
to: reciverEmail,
from: SENDER_EMAIL,
subject: "newsletter",
html: `<p>Dear subscriber,</p><p>Thanks for signing up for
newsletter!</p>
<p> looking forward to hearing from you. </p>
<p><a href="${weblog_social.insta}">Instagram</a></p>
<p><a href="${weblog_social.fb}">Facebook</a></p>
<p><a href="${weblog_social.linkedIn}">LinkedIn</a></p>
`,
};
return msg;
};
export { news_letter_template };