10

How can I do to send an email with Vuejs2. I manage to get the input data and turned them into json but I can not send them to a mailbox.

I look for the side of PHPMailer but facing PHP and Vue do not mix.

How can I send the form content?

Template :

 <div class="JC-contact__form">
  <b-form @submit="onSubmit" v-if="show">

    <b-form-group class="JC-contact__form--lastName">
      <b-form-input type="text" v-model="form.lastName"> </b-form-input>
    </b-form-group>

    <b-form-group class="JC-contact__form--firstName">
      <b-form-input type="text" v-model="form.firstName"> </b-form-input>
    </b-form-group>

    <b-form-group>
      <b-form-input type="text" v-model="form.topic"> </b-form-input>
    </b-form-group>
    <b-form-group>
      <b-form-input type="email" v-model="form.email"></b-form-input>
    </b-form-group>

    <b-form-textarea v-model="form.text"></b-form-textarea>

    <b-button type="submit">Envoyer</b-button>
  </b-form>

</div>

Script :

  export default {
    name: 'Contact',
    data () {
      return {
        form: {
          lastName: '',
          firstName: '',
          topic: '',
          email: '',
          text: ''
        },
        file: null,
        show: true
      }
    },
    methods: {
      onSubmit (evt) {
        evt.preventDefault();
        alert(JSON.stringify(this.form));
      },
      onReset (evt) {
        evt.preventDefault();
        /* Reset our form values */
        this.form.lastName = '';
        this.form.firstName = '';
        this.form.topic = '';
        this.form.email = '';
        this.form.text = '';
        /* Trick to reset/clear native browser form validation state */
        this.show = false;
        this.$nextTick(() => {
          this.show = true
        });
      }
    }
  }
DenisMasot
  • 697
  • 5
  • 11
  • 21
  • Browser doesn't send mails. Servers do. You need to call some api to send mail. – Erndob Mar 07 '18 at 11:01
  • 1
    You may want to take a look at [EmailJS](https://www.emailjs.com/?src=so), which allows sending email using pre-built templates directly from Javascript [disclosure - I'm one of the creators] – Sasha Mar 07 '18 at 13:11

5 Answers5

8

Sending mail from Vue directly is not possible as you need some sort of server to handle the mail protocol. This can never be done directly from the browser. I am not familiar with PHP, so I can't help you with that. In node you need the nodemailer package and some smtp server to handle the email like Amazon Simple Email Server (or you could use your gmail account). What you could also do is use axios to send a post request to SendGrid or Mandrill or some service like that. They will convert your request to an email and send it to an address specified in you request body.

More info here:

https://sendgrid.com/docs/API_Reference/Web_API/mail.html

https://mandrillapp.com/api/docs/

Imre_G
  • 2,468
  • 1
  • 17
  • 33
6

This is how I did:

Mailing from the server side

The PHP mail() function will just work fine. Nothing fancy here.

mail.php - This one must be located somewhere accessible on your server.

<?php

$name = "Undefined name";

if(isset($_POST['name'])){
    $name = $_POST['name'];
}

$message = "<p>Hi!</p>";
$message .= "<p>Wazaaaaa $name</p>";

$to_email = 'dest@mail.com';
$subject = 'Mail subject';
$headers[] = 'MIME-Version: 1.0';
$headers[] = 'Content-type: text/html; charset=UTF-8';
$headers[] = 'From: Biloo <noreply@ydomain.com>';

mail($to_email, $subject, $message, implode("\r\n", $headers));

?>

Be aware that headers values must be trustworthy (no unverified user-submited values).


Sending data to the mailing script

Then VueJS is suppposed to send the appropriate data to the mailing script:

components/Mail.vue

<template>
   <div>
      <transition name="fade" mode="out-in">
          <div v-if="sent">
              <p>Thanks</p>
          </div>
      </transition>
      </div>
      <div v-if="!sent" class="formGroup">
          <b-form @submit="onSubmit">
              <b-form-input
                  id="input-name"
                  v-model="form.name"
                  type="text"
                  required
                  placeholder="Name"
              />
              <b-button type="submit">
                  Contact
              </b-button>
          </b-form>
      </div>
   </div>
</template>

<script>
const querystring = require("querystring");

export default {
    data() {
        return {
          sent: false,
          form: {
              name: ""
          }
        };
    },
    methods: {
      onSubmit(e) {
          e.preventDefault();
          this.$axios
             .post(
                 "https://theServer.com/mail.php",
                  querystring.stringify(this.form)
             )
             .then(res => {
                 this.sent = true;
             });
      }
    }
};
</script>

Here, it is important to note that the default behavior of Axios is to post a JSON object. However, doing so, PHP will receive an empty $_POST value. Data must therefore be formatted using the querystringdependency before being posted.

Querystring can be installed with npm:

npm i querystring

Community
  • 1
  • 1
Yako
  • 3,405
  • 9
  • 41
  • 71
  • 1
    The part i dont understand here is url you sent in this.$axios.post and how does it trigger that php file? Can you please explain that? Do i have to create api with php or? – Edin Osmic Sep 30 '22 at 20:34
0
<template>    
<div class="request-a-callback-form">
 <transition name="fade" mode="out-in">
  <div v-if="sent">
   <p>Thanks for contacting us, we will get back to you shortly...</p>
  </div>
 </transition>
 <form v-on:submit="sendForm">
  <input type="text" v-model="ContactForm.name" placeholder="Your Name">
  <input type="text" v-model="ContactForm.email" placeholder="Email Address">
  <input type="text" v-model="ContactForm.phone" placeholder="Phone Number">
  <input type="text" v-model="ContactForm.subject" placeholder="Subject">
  <textarea v-model="ContactForm.message" rows="8" cols="80" class="form-control"> 
  </textarea>
  <br>
  <button data-text="submit" type="submit" class="btn btn-primary">Submit</button>
 </form>
</div>
</template>
        <script>
        export default {
          data() {
            return {
              sent: false,
              ContactForm: {
                name : '',
                email: '',
                phone: '',
                subject: '',
                message: ''
              }
            }
          },
          methods: {
            sendForm(e) {
              e.preventDefault()
              console.log(this.ContactForm)
              this.$axios.post('api/mailserver.php',
              querystring.stringify(this.ContactForm)).then(res => {
                this.sent = true
              })
            }
          }
        }
        </script>

    Your php Server

    <?php
    // Allow from any origin
     if(isset($_SERVER["HTTP_ORIGIN"]))
     {
        // You can decide if the origin in $_SERVER['HTTP_ORIGIN'] is something you want to 
      allow, or as we do here, just allow all
        header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
     }
     else
     {
        //No HTTP_ORIGIN set, so we allow any. You can disallow if needed here
        header("Access-Control-Allow-Origin: *");
     }

     header("Access-Control-Allow-Credentials: true");
     header("Access-Control-Max-Age: 600");    // cache for 10 minutes

     if($_SERVER["REQUEST_METHOD"] == "OPTIONS")
     {
        if (isset($_SERVER["HTTP_ACCESS_CONTROL_REQUEST_METHOD"]))
            header("Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT"); 
  //Make 
        sure you remove those you do not want to support

        if (isset($_SERVER["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"]))
            header("Access-Control-Allow-Headers: 
           {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

           //Just exit with 200 OK with the above headers for OPTIONS method
        exit(0);
      }
    //From here, handle the request as it is ok


     if(!empty($_POST['name'])){
        $name = $_POST['name'];
        $email = $_POST['email'];
        $phone = $_POST['phone'];
        $subject = $_POST['subject'];
        $message = $_POST['message'];
     }

     $message = "$message";

     $to_email = '<email to be sent to>';
     $subject = "$subject";
     $headers[] = 'MIME-Version: 1.0';
     $headers[] = 'Content-type: text/html; charset=UTF-8';
     $headers[] = "From: <$email>";

     mail($to_email, $subject, $message, implode("\r\n", $headers));

    ?>
  • How do you create that url(api) to actually handle mailserver.php file, do you have to create that api on server? – Edin Osmic Sep 30 '22 at 20:55
0

You can also send client-side Emails using EmailJS. It helps you to send emails using vuejs or any other client side technology, connect EmailJS to one of the supported email services once you create an account, create an email template, and use VueJS to trigger an email. Here is a link to their documentation https://www.emailjs.com/docs/examples/vuejs/

Aaron Katema
  • 1
  • 1
  • 1
0

You may try mailjs package. mailjs

Zia
  • 506
  • 3
  • 20