Next.js Discord

Discord Forum

Nextjs 14 nodemailer works locally, but not in production.

Answered
Yellow croaker posted this in #help-forum
Open in Discord
Yellow croakerOP
Hello i'm using nodeMailer with my nextjs project. I'm facing an issue where the nodemailer works on localhost, but in production it does not send any email.
What could cause this kind issue?
Here is shorthanded code.

contact/page.tsx
export default function ContactPage() {
  const [isSubmitting, setIsSubmitting] = useState(false);
  const {
    register,
    handleSubmit,
    formState: { errors },
    reset,
  } = useForm<ContactFormData>({
    resolver: zodResolver(contactSchema),
  });

  const onSubmit = async (data: ContactFormData) => {
    setIsSubmitting(true);
    try {
      await sendEmail({
        title: data.title || '',
        ...
      });
      reset();
    } catch (error) {
    } finally {
      setIsSubmitting(false);
    }
  };
return(
      <form onSubmit={handleSubmit(onSubmit)}>
            <TextInput
              label="Provide title"
              placeholder="Syötä otsikko"
              error={errors.title?.message}
              {...register('title')}
            />
            <Button
              type="submit"
              loading={isSubmitting}
              fullWidth
              size="lg"
              color={getButtonColor()}
              leftSection={getButtonIcon()}
            >
              {getButtonText()}
            </Button>
        </Grid>
      </form>


actions/submit.ts
'use server';
import nodemailer from 'nodemailer';
const email = process.env.EMAIL;
const password = process.env.EMAIL_PASSWORD;
const transporter = nodemailer.createTransport({
  service: 'gmail',
  secure: true,
  port: 465,
  auth: {
    user: email,
    pass: password,
  },
});

export async function sendEmail(formData: {

try {
    await new Promise((resolve, reject) => {
      transporter.sendMail(mailOptions, (err, info) => {
        if (err) {
          reject(err);
        } else {
          resolve(info);
        }
      });
    });

    return { success: true };

}catch (error) {
...

}
Answered by Yellow croaker
I did two things and one of these made it to work:

I made new app password for my google and used that.

Second:

I made changes to createTransport:

  try {
    const transporter = nodemailer.createTransport({
      host: 'smtp.gmail.com',
      port: 587, // port was 465
      secure: false, // WAS true
      auth: {
        user: email,
        pass: password,
      },
    });


I made these same time, so im testing which one was the that worked.
View full answer

6 Replies

African Slender-snouted Crocodile
Probably not this, but worth checking - are your environment variables for the auth configured on your production deployment?
@African Slender-snouted Crocodile Probably not this, but worth checking - are your environment variables for the auth configured on your production deployment?
Yellow croakerOP
Yeah, just checked them to be sure. They are identical with the .env file.
African Slender-snouted Crocodile
Maybe check that your dependencies are correctly installed via your package.json (or equivalents for pnpm or whichever).
You probably have all dev dependencies installed locally but the production installation probably drops those (so make sure it's in dependencies, not devDependencies, etc)
Yellow croakerOP
Hey it works i explain waht i did!
African Slender-snouted Crocodile
Are any errors printed? Consider adding some more logging to the server action, these should be available in the server logs
Yellow croakerOP
I did two things and one of these made it to work:

I made new app password for my google and used that.

Second:

I made changes to createTransport:

  try {
    const transporter = nodemailer.createTransport({
      host: 'smtp.gmail.com',
      port: 587, // port was 465
      secure: false, // WAS true
      auth: {
        user: email,
        pass: password,
      },
    });


I made these same time, so im testing which one was the that worked.
Answer