3

I want to use Mailchimp API in my website so users can enter their email in a field and subscribe to a newsletter. I do not want to use any libraries.

I created a simple form for now with an email field and subscribe button for testing purposes and tried to achieve my goal with XMLHttpRequest. However it does not work, and I am not sure whats wrong or if I need another approach? Is my code structure for the API request correct? I created a Codesandbox with the code. If needed I can paste it also here.

2 Answers2

1

It's a back end only API.

You're not supposed to ship this API key with your JavaScript application. It's intended for back end use only, where you can keep the key private.

Probably the issue described in no more detail than "it does not work", is because Mailchimp will block the request if you try to use the key from a browser. Their documentation describes in detail.

Because of the potential security risks associated with exposing account API keys, Mailchimp does not support client-side implementation of our API using CORS requests or including API keys in mobile apps.

If you still want to use the API for this, you'll have to set up your own back end service which receives the data from the front end of your site and forwards it to Mailchimp.

For example, if your website uses PHP, you could preserve your form's JS code, but point it to your own custom endpoint / PHP file instead.

Mailchimp has a PHP client library you could use to make crafting the HTTP request more robust and less verbose. But you could also do it "manually" if you also don't want to install a PHP library.

// form-submission.php
function read_key() {
    // Could also come from other source, like environment variables.
    // As long as it's in a safe place and can't be leaked.
    return file_get_contents(SECRET_KEY_LOCATION);
}
$apiKey = read_key();
require_once('/path/to/MailchimpMarketing/vendor/autoload.php');

$mailchimp = new MailchimpMarketing\ApiClient();

$mailchimp->setConfig([
    'apiKey' => $api_key,
    'server' => 'YOUR_SERVER_PREFIX'
]);

$response = $mailchimp->lists->addListMember( /* ... form data */);
print_r($response);

Depending on your use case you may need to use one of the many other API endpoints.

inwerpsel
  • 2,677
  • 1
  • 14
  • 21
-1

The issue is the onSubmit() callback on your "form" element is never executed. In order for the onSubmit() callback on your form to be called upon clicking the "Subscribe" button, the button needs to have a type="submit" attribute on it.

i.e.,

const handleSubmit = () => { ... }

return (
   ...
    <Box 
      onSubmit={handleSubmit}
    >
      <TextField ... />

      <Button
        type="submit"  <-- Add this in order to call onSubmit() upon click
      >
        Subscribe
      </Button>
    </Box>
   ...

Edit:

OP is using the MailChimp API from the client. The MailChimp API will not work on the client side. You can only use the MailChimp API on the server side.

However, you can utilize MailChimp's embedded form action URL to subscribe to user's emails on the client side (in a React component). You can avoid the user from being forwarded to MailChimp by sending a fetch POST request with the embedded form action URL.

This below example may need some tweaking, but this is the general idea on how this can be accomplished.

function handleSubmit(event) {
    event.preventDefault();

    // fetch URL is from MailChimp embedded form action url.
    fetch('http://mailchimp.us8.list-manage.com/subscribe/post', {
        method: 'POST',
        // Not sure if MailChimp used urlencoded or json. You can modify this request to use either.
        headers:{
          'Content-Type': 'application/x-www-form-urlencoded'
        },    
        body: new URLSearchParams({
            'u': 'a123cd45678ef90g7h1j7k9lm',  <-- found in embedded form code.
            'id': 'ab2c468d10',  <-- found in embedded form code.
            'MERGE0': email,  <-- email to be subscribed.
    })
    });
}
g0rb
  • 2,234
  • 1
  • 9
  • 13
  • I see yes, I somehow overlooked this. But when I try it to make a subscribe, the email never gets subscribed at mailchimp. Is my xml http request correct? –  Sep 09 '22 at 22:43
  • @Figario, you can't call the Mailchimp API from a client. Because of the potential security risks associated with exposing account API keys, Mailchimp does not support client-side implementation of the API. You will need to write a backend service that will call the Mailchimp API. Read more about it here: https://mailchimp.com/help/about-api-keys/ – g0rb Sep 10 '22 at 06:56
  • Ah okay I thought it is possible because there these npm packages to do it in the frontend like this for example https://www.npmjs.com/package/react-mailchimp-subscribe –  Sep 12 '22 at 11:37
  • @Figario, the npm packages are using a different URL than you are using. You are using the MailChimp API URL, which isn't supported client-side. The npm packages use a URL from the action found in the generated embedded form code on MailChimp. In other words, you should use the URL of the form action of the generated embedded form code found on MailChimp. – g0rb Sep 14 '22 at 19:53
  • Ok I understand. The thing is why I do not want to use the embedded form code from Mailchimp is because it forwards to Mailchimp in the process. I want to keep the users on the page with my custom form and I suppose this is only possible with the Mailchimpa API. Or can I make a post request also with the action found in the generated form code on the client side? –  Sep 15 '22 at 09:27
  • @Figario, you should be able to make a `fetch` post request using the embedded form action URL found on MailChimp. By doing a `fetch` or `XHR` request, it shouldn't forward the user to MailChimp. – g0rb Sep 15 '22 at 16:29
  • @Figario, I updated the answer to show how you can use the MailChimp embedded form action with a react form component. – g0rb Sep 15 '22 at 16:53