Search code examples
reactjsastrojs

Can't send email in Contact.jsx component in Astro.js using Emailjs but it's not doing anything


I've attempted to setup a contact form using Emailjs in my Astro project using 2 different ways, one using the template from the Emailjs docs, https://www.emailjs.com/docs/examples/reactjs/, and the other from a tutorial. In my Astro project, which does have react added to it and emailjs installed, the form doesn't work using either of the 2 ways.

I created a react app just to see if the same form component would work there and it did. I'm not entirely sure what the issue is with my react form component in Astro.js.

When I hit submit I don't get an error. The form acts as if it's been submitted and the values clear but nothing actually gets sent and the URL changes from http://localhost:4321/ to http://localhost:4321/? when I use Way 1. When I use Way 2 it'll change the URL from http://localhost:4321/ to http://localhost:4321/?user_name=asdfadf&user_email=test%40gmail.com&message=asdfadfasdfadf.

Way 1 (From YouTube Tutorial) -

import emailjs from '@emailjs/browser';

const Contact = () => {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [message, setMessage] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();

    const serviceId = 'service_dighcxs';
    const templateId = 'template_gxyynmw';
    const publicKey = '0KNtQ2nWh28eb1DE-';

    const templateParams = {
      name: name,
      email: email,
      message: message,
    };

    emailjs
      .send(serviceId, templateId, templateParams, publicKey)
      .then((response) => {
        console.log('email sent successfully', response);
        setName('');
        setEmail('');
        setMessage('');
      })
      .catch((error) => {
        console.log('error sending email', error);
      });
  };

  return (
    <form onSubmit={handleSubmit} className='emailForm'>
      <input
        type='text'
        placeholder='Your Name'
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <input
        type='email'
        placeholder='Your Email'
        value={email}
        onChange={(e) => setEmail(e.target.value)}
      />
      <textarea
        placeholder='Your Message'
        value={message}
        onChange={(e) => setMessage(e.target.value)}
      ></textarea>
      <button type='submit'>Send Email</button>
    </form>
  );
};

export default Contact;

Way 2 (From Emailjs Docs) -

import React, { useRef } from 'react';
import emailjs from '@emailjs/browser';

const Contact = () => {
  const form = useRef();

  const sendEmail = (e) => {
    e.preventDefault();

    emailjs
      .sendForm(
        'service_dighcxs',
        'template_gxyynmw',
        form.current,
        '0KNtQ2nWh28eb1DE-'
      )
      .then(
        (result) => {
          console.log(result.text);
          console.log('message sent', result);
        },
        (error) => {
          console.log(error.text);
        }
      );
  };

  return (
    <>
      <h1>cheese</h1>
      <form ref={form} onSubmit={sendEmail}>
        <label>Name</label>
        <input type='text' name='user_name' />
        <label>Email</label>
        <input type='email' name='user_email' />
        <label>Message</label>
        <textarea name='message' />
        <input type='submit' value='Send' />
      </form>
    </>
  );
};

export default Contact;

astro.config (showing react integration) -

import { defineConfig } from 'astro/config';
import tailwind from "@astrojs/tailwind";

import react from "@astrojs/react";

// https://astro.build/config
export default defineConfig({
  integrations: [tailwind(), react()]
});

Solution

  • I have been trying to do the same thing for my project. The code you got from the YouTube video seems correct and worked when I tried it. Did you try adding 'client:load' to your component when you call it in your astro file? Also don't forget to import useState in the component's code.

    import emailjs from '@emailjs/browser';
    import { useState } from 'react';
    
    const Contact = () => {
      const [name, setName] = useState('');
      const [email, setEmail] = useState('');
      const [message, setMessage] = useState('');
    
      const handleSubmit = (e) => {
        e.preventDefault();
    
        const serviceId = 'service_dighcxs';
        const templateId = 'template_gxyynmw';
        const publicKey = '0KNtQ2nWh28eb1DE-';
    
        const templateParams = {
          name: name,
          email: email,
          message: message,
        };
    
        emailjs
          .send(serviceId, templateId, templateParams, publicKey)
          .then((response) => {
            console.log('email sent successfully', response);
            setName('');
            setEmail('');
            setMessage('');
          })
          .catch((error) => {
            console.log('error sending email', error);
          });
      };
    
      return (
        <form onSubmit={handleSubmit} className='emailForm'>
          <input
            type='text'
            placeholder='Your Name'
            value={name}
            onChange={(e) => setName(e.target.value)}
          />
          <input
            type='email'
            placeholder='Your Email'
            value={email}
            onChange={(e) => setEmail(e.target.value)}
          />
          <textarea
            placeholder='Your Message'
            value={message}
            onChange={(e) => setMessage(e.target.value)}
          ></textarea>
          <button type='submit'>Send Email</button>
        </form>
      );
    };
    
    export default Contact;
    ---
    import Contact from "../components/Contact";
    ---
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width" />
        <meta name="generator" content={Astro.generator} />
        <title>Contact me</title>
      </head>
      <body>
        <Contact client:load />
      </body>
    </html>