AJAX Mailchimp signup form integration

138,255

Solution 1

You don't need an API key, all you have to do is plop the standard mailchimp generated form into your code ( customize the look as needed ) and in the forms "action" attribute change post?u= to post-json?u= and then at the end of the forms action append &c=? to get around any cross domain issue. Also it's important to note that when you submit the form you must use GET rather than POST.

Your form tag will look something like this by default:

<form action="http://xxxxx.us#.list-manage1.com/subscribe/post?u=xxxxx&id=xxxx" method="post" ... >

change it to look something like this

<form action="http://xxxxx.us#.list-manage1.com/subscribe/post-json?u=xxxxx&id=xxxx&c=?" method="get" ... >

Mail Chimp will return a json object containing 2 values: 'result' - this will indicate if the request was successful or not ( I've only ever seen 2 values, "error" and "success" ) and 'msg' - a message describing the result.

I submit my forms with this bit of jQuery:

$(document).ready( function () {
    // I only have one form on the page but you can be more specific if need be.
    var $form = $('form');

    if ( $form.length > 0 ) {
        $('form input[type="submit"]').bind('click', function ( event ) {
            if ( event ) event.preventDefault();
            // validate_input() is a validation function I wrote, you'll have to substitute this with your own.
            if ( validate_input($form) ) { register($form); }
        });
    }
});

function register($form) {
    $.ajax({
        type: $form.attr('method'),
        url: $form.attr('action'),
        data: $form.serialize(),
        cache       : false,
        dataType    : 'json',
        contentType: "application/json; charset=utf-8",
        error       : function(err) { alert("Could not connect to the registration server. Please try again later."); },
        success     : function(data) {
            if (data.result != "success") {
                // Something went wrong, do something to notify the user. maybe alert(data.msg);
            } else {
                // It worked, carry on...
            }
        }
    });
}

Solution 2

Based on gbinflames' answer, I kept the POST and URL, so that the form would continue to work for those with JS off.

<form class="myform" action="http://XXXXXXXXXlist-manage2.com/subscribe/post" method="POST">
  <input type="hidden" name="u" value="XXXXXXXXXXXXXXXX">
  <input type="hidden" name="id" value="XXXXXXXXX">
  <input class="input" type="text" value="" name="MERGE1" placeholder="First Name" required>
  <input type="submit" value="Send" name="submit" id="mc-embedded-subscribe">
</form>

Then, using jQuery's .submit() changed the type, and URL to handle JSON repsonses.

$('.myform').submit(function(e) {
  var $this = $(this);
  $.ajax({
      type: "GET", // GET & url for json slightly different
      url: "http://XXXXXXXX.list-manage2.com/subscribe/post-json?c=?",
      data: $this.serialize(),
      dataType    : 'json',
      contentType: "application/json; charset=utf-8",
      error       : function(err) { alert("Could not connect to the registration server."); },
      success     : function(data) {
          if (data.result != "success") {
              // Something went wrong, parse data.msg string and display message
          } else {
              // It worked, so hide form and display thank-you message.
          }
      }
  });
  return false;
});

Solution 3

You should use the server-side code in order to secure your MailChimp account.

The following is an updated version of this answer which uses PHP:

The PHP files are "secured" on the server where the user never sees them yet the jQuery can still access & use.

1) Download the PHP 5 jQuery example here...

http://apidocs.mailchimp.com/downloads/mcapi-simple-subscribe-jquery.zip

If you only have PHP 4, simply download version 1.2 of the MCAPI and replace the corresponding MCAPI.class.php file above.

http://apidocs.mailchimp.com/downloads/mailchimp-api-class-1-2.zip

2) Follow the directions in the Readme file by adding your API key and List ID to the store-address.php file at the proper locations.

3) You may also want to gather your users' name and/or other information. You have to add an array to the store-address.php file using the corresponding Merge Variables.

Here is what my store-address.php file looks like where I also gather the first name, last name, and email type:

<?php

function storeAddress(){

    require_once('MCAPI.class.php');  // same directory as store-address.php

    // grab an API Key from http://admin.mailchimp.com/account/api/
    $api = new MCAPI('123456789-us2');

    $merge_vars = Array( 
        'EMAIL' => $_GET['email'],
        'FNAME' => $_GET['fname'], 
        'LNAME' => $_GET['lname']
    );

    // grab your List's Unique Id by going to http://admin.mailchimp.com/lists/
    // Click the "settings" link for the list - the Unique Id is at the bottom of that page. 
    $list_id = "123456a";

    if($api->listSubscribe($list_id, $_GET['email'], $merge_vars , $_GET['emailtype']) === true) {
        // It worked!   
        return 'Success!&nbsp; Check your inbox or spam folder for a message containing a confirmation link.';
    }else{
        // An error ocurred, return error message   
        return '<b>Error:</b>&nbsp; ' . $api->errorMessage;
    }

}

// If being called via ajax, autorun the function
if($_GET['ajax']){ echo storeAddress(); }
?>

4) Create your HTML/CSS/jQuery form. It is not required to be on a PHP page.

Here is something like what my index.html file looks like:

<form id="signup" action="index.html" method="get">
    <input type="hidden" name="ajax" value="true" />
    First Name: <input type="text" name="fname" id="fname" />
    Last Name: <input type="text" name="lname" id="lname" />
    email Address (required): <input type="email" name="email" id="email" />
    HTML: <input type="radio" name="emailtype" value="html" checked="checked" />
    Text: <input type="radio" name="emailtype" value="text" />
    <input type="submit" id="SendButton" name="submit" value="Submit" />
</form>
<div id="message"></div>

<script src="jquery.min.js" type="text/javascript"></script>
<script type="text/javascript"> 
$(document).ready(function() {
    $('#signup').submit(function() {
        $("#message").html("<span class='error'>Adding your email address...</span>");
        $.ajax({
            url: 'inc/store-address.php', // proper url to your "store-address.php" file
            data: $('#signup').serialize(),
            success: function(msg) {
                $('#message').html(msg);
            }
        });
        return false;
    });
});
</script>

Required pieces...

  • index.html constructed as above or similar. With jQuery, the appearance and options are endless.

  • store-address.php file downloaded as part of PHP examples on Mailchimp site and modified with your API KEY and LIST ID. You need to add your other optional fields to the array.

  • MCAPI.class.php file downloaded from Mailchimp site (version 1.3 for PHP 5 or version 1.2 for PHP 4). Place it in the same directory as your store-address.php or you must update the url path within store-address.php so it can find it.

Solution 4

For anyone looking for a solution on a modern stack:

import jsonp from 'jsonp';
import queryString from 'query-string';

// formData being an object with your form data like:
// { EMAIL: '[email protected]' }

jsonp(`//YOURMAILCHIMP.us10.list-manage.com/subscribe/post-json?u=YOURMAILCHIMPU&${queryString.stringify(formData)}`, { param: 'c' }, (err, data) => {
  console.log(err);
  console.log(data);
});

Solution 5

Based on gbinflames' answer, this is what worked for me:

Generate a simple mailchimp list sign up form , copy the action URL and method (post) to your custom form. Also rename your form field names to all capital ( name='EMAIL' as in original mailchimp code, EMAIL,FNAME,LNAME,... ), then use this:

      $form=$('#your-subscribe-form'); // use any lookup method at your convenience

      $.ajax({
      type: $form.attr('method'),
      url: $form.attr('action').replace('/post?', '/post-json?').concat('&c=?'),
      data: $form.serialize(),
      timeout: 5000, // Set timeout value, 5 seconds
      cache       : false,
      dataType    : 'jsonp',
      contentType: "application/json; charset=utf-8",
      error       : function(err) { // put user friendly connection error message  },
      success     : function(data) {
          if (data.result != "success") {
              // mailchimp returned error, check data.msg
          } else {
              // It worked, carry on...
          }
      }
Share:
138,255
alexndm
Author by

alexndm

Web Developer, working with JavaScript (React, Node.js), Java

Updated on February 06, 2022

Comments

  • alexndm
    alexndm over 2 years

    Is there any way to integrate mailchimp simple (one email input) with AJAX, so there is no page refresh and no redirection to default mailchimp page.

    This solution doesn't work jQuery Ajax POST not working with MailChimp

    Thanks

  • sid
    sid almost 11 years
    I made a jquery-plugin that uses this method: github.com/scdoshi/jquery-ajaxchimp
  • czerasz
    czerasz over 10 years
    You can also use JSONP. Use the post-json as described. Remove the &c= if You have it in the form action url. Use dataType: 'jsonp' and jsonp: 'c' for Your jQuery ajax call.
  • Ian Warner
    Ian Warner over 10 years
    Note that the email form fields must have name="EMAIL" for mailchimp to process
  • Patrick Canfield
    Patrick Canfield about 10 years
    If you just want to add a signup form to your site and submit it via AJAX, @gbinflames's answer works. Just tried it myself.
  • inorganik
    inorganik about 10 years
    Note that it is a GET request not a post. This answer still works great.
  • Nowaker
    Nowaker almost 10 years
    No, there is no must.
  • v3nt
    v3nt over 9 years
    is validate_input a function somewhere?
  • gbinflames
    gbinflames over 9 years
    Yes, validate_input is a function defined elsewhere, it's used to validate the users input before submitting the form but it's not really relevant to the answer so it was omitted to keep things as simple as possible.
  • kevnk
    kevnk over 9 years
    The method from @sid was the only one I could get working: github.com/scdoshi/jquery-ajaxchimp — Thanks!
  • kevnk
    kevnk over 9 years
    Can you unsubscribe someone using this same method?
  • Nick Tiberi
    Nick Tiberi about 9 years
    Just FYI in case anyone is having issues, the name of the email parameter should be EMAIL (all caps). Otherwise you will get an error stating that the email address is blank.
  • Warpling
    Warpling about 9 years
    If using jQuery it'd be better to .bind() to the form's submit event rather than the click event: $form.submit(function (event) {...});
  • Greg Bell
    Greg Bell almost 9 years
    Has MailChimp disabled this method of accessing the API since this answer was written? I seen no indication in the documentation that a GET/POST without the API key can subscribe a user to a list.
  • Ross
    Ross almost 9 years
    When I use this method, server returns success message but the user is not subscribed (does not appear in list of subscribers)?
  • evolross
    evolross over 8 years
    I just tried this and can confirm it still works. By default, MailChimp doesn't add a new signup to your "list" until they confirm via their email address - FYI. And you can access the message returned by MailChimp in your success block using data.msg (so you can JQuery the response message to your form).
  • Pratik Deshmukh
    Pratik Deshmukh almost 8 years
    Thanks for the code, but i am getting Could not connect to server error. Do you have any idea about this error?
  • squarecandy
    squarecandy over 7 years
    Crap, I gotta say - I implemented @skube's answer a while ago on a site and then later added site-wide https. Just discovered now that it's not working with the mailchimp http AJAX call. Highly recommend going with this method right off the bat if you site might ever need or consider using SSL.
  • phip
    phip over 7 years
    Thanks for this snippet! Still works well and i'm using a POST method. Not sure why it would be a GET request. Can someone elaborate on this? Any links to MailChimp documentation?
  • gonephishing
    gonephishing about 7 years
    It will really help if you can add some article link/ blog posts for doing the same
  • Petra
    Petra over 6 years
    I have added Mailchimp embed code into my html page but Ajax doesn't automatically work as suggested above. I get redirected to another page. How can I make this work without a redirect?
  • D.Dimitrioglo
    D.Dimitrioglo over 6 years
    something similar on top of jQuery github.com/ddimitrioglo/jquery-mailchimp
  • MarcGuay
    MarcGuay over 6 years
    In the MailChimp admin go to your list -> Signup Forms -> Embedded forms -> Classic. You'll see that there is some JS included in the code snippet. This will enable form validation and AJAX submission.
  • Ben Hull
    Ben Hull almost 6 years
    Confirmed working by default today. In the 'Classic' embed form, there are some options under 'Enhance your form', one of which is "Disable all javascript This disables field validation, and inline form submission. The form will submit to your hosted subscribe form." This suggests that 'inline submission' (ie. AJAX) is the default.
  • Adeerlike
    Adeerlike almost 6 years
    using the mailchimp code - how do i plug a custom action to the ajax success ? [like hiding the form]
  • Adeerlike
    Adeerlike over 5 years
    @Masiorama I opted for removing the mc-validate script, as it also contained an old jquery and was too big and vulnerable. so just having html validation and submitting with ajax like in stackoverflow.com/a/15120409/744690
  • ricricucit
    ricricucit about 5 years
    @grsmto posted a better alternative.
  • Beaniie
    Beaniie almost 4 years
    Anyone else getting a 403 Forbidden response while using this answer, these days? Might just be my code but I'm not sure.
  • Jay
    Jay over 3 years
    @Beaniie I used this method on a project last month and it works perfectly.
  • Mike Vosseller
    Mike Vosseller over 3 years
    Just a note of caution that this technique may not work for users with certain content blockers installed. The disconnect.me browser plugin for example blocks network calls to mailchimp by default and simulates a 307 redirect for such calls. If you use this approach you may consider warning the user about content blockers if your error handler is called.
  • Knogobert
    Knogobert over 3 years
    This worked, even though Firefox might try to block the request from leaving by its Enhanced Protection. You can also skip importing 'query-string' package by supplying your own encoder like this: function queryString(data) { return Object.keys(data).map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}‌​`).join('&'); } (skip the .stringify method then)
  • grantmx
    grantmx over 3 years
    Although implied, taking this answer to the next level by including: import serialize from form-serialize'; let formData = serialize(e.target); to get that data out of a form and into an object and only passing in the object as a string to the URL https://...&${formData} queryString.stringify() - is not needed as of 2021
  • Adeerlike
    Adeerlike about 3 years
    used 5 yeasr ago. used today. still gold.
  • Drew Baker
    Drew Baker almost 3 years
    Trying to do this with a fetch() doesn't work because of cors error.
  • Klimenko Kirill
    Klimenko Kirill over 2 years
    @DrewBaker Just pass mode: "no-cors" - that helped me out with cors issue
  • Samuel Gregory
    Samuel Gregory over 2 years
    To follow up on more experimenting, Using Fetch, we don't get access to the returned JSON object so if a user signs up twice, we can't tell them to update their profile (like mailchimp would) nor can we warn them of any messages such as the one I received during testing "too many signups". These errors succeed in the eyes of fetch so frankly I would avoid using it. I just didn't want to download another library to my site but managed to find a standalone AJAX to keep it as lean as possible.