Skip to main content
Drupal is a registered trademark of Dries Buytaert
Release: HeCAPTe 1.0.2 — Minor update available for module hecapte_captcha (1.0.2). Release: Attribution & Licensing 1.2.1 — Minor update available for module attribution (1.2.1). Release: MCP Sentinel 2.29.0 — Minor update available for module mcp_sentinel (2.29.0). Release: Audit Chain 1.10.9 — Minor update available for module audit_chain (1.10.9). Release: Menu Autopilot 1.4.7 — Minor update available for module menu_autopilot (1.4.7). Release: FileGate 1.11.3 — Minor update available for module file_gate (1.11.3). Release: Download Tracker 1.0.7 — Minor update available for module download_tracker (1.0.7). Release: Directory2Block Slideshow 1.0.8 — Minor update available for module directory2block_slideshow (1.0.8). Module Revived: Swagger-PHP OpenAPI 3 documentation generator 1.0.0 — Module swagger_php updated after 10 months of inactivity (1.0.0). Security Coverage: Microsoft Azure AI — Module ai_provider_azure now has official Drupal security advisory coverage.

Simplenews Decoupled

No security coverage

Part of the Simplenews ecosystem · 7 projects

View on drupal.org

By default, the Simplenews module does not enable the user to use the
subscribe / unsubscribe functionality in a decoupled environment, for example, a
React frontend. There are multiple issues with that:

  • The Core Rest API Endpoint does not trigger a confirmation mail if needed
  • You need the permission 'administer simplenews subscriptions' to use the rest endpoint
  • Subscribe / unsubscribe url which is sent in the Mails are always pointing to the D8 installation

This module tries to solve these issues.

Here is the open issue in the Simplenews issue queue regarding this
https://www.drupal.org/project/simplenews/issues/3158939

Configuration

You need to set the base bath to your decoupled environment (this will be used to replace the D8 base URL in the subscribe / unsubscribe URLs)

Add this to your settings.php:

$settings['decoupled_url'] = 'http://localhost:3011';

Here are example React Components to show a basic example using the functionality

The newsletter subscribe form component with Formik and axios:

<Formik
  initialValues={{email: ''}}
  onSubmit={values => {
    axios.post(`${yourBackendUrl}/simplenews-decoupled/subscribe`, {
      "email": values.email,
      "newsletterId": "your_newsletter_id"
    }, {
      withCredentials: true
    })
      .then(result => console.log(result))
      .catch(error => console.log(error.response.data.message));
  }}
>
  <Form>
    <Field
      id="email"
      name="email"
      placeholder="E-Mail"
      type="email"
    />
    <button type="submit">Submit</button>
   </Form>
</Formik>

Route component of the subscribe / unsubscribe confirmation page:

<Route exact path="/newsletter/confirm/:action/:sid/:newsletter_id/:timestamp/:hash" component={NewsletterConfirm} />

Route component of the combined subscribe / unsubscribe confirmation page
<Route exact path="/newsletter/confirm/combined/:sid/:timestamp/:hash" component={NewsletterCombinedConfirm} />

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import axios from 'axios';

class NewsletterConfirm extends Component {
  state = {
    error: false,
    loading: true,
    message: null,
    success: false
  };

  componentDidMount() {
    const { action, sid, newsletter_id, timestamp, hash } = this.props.match.params;

    axios.get(`${yourBackendUrl}/simplenews-decoupled/confirm/${action}/${sid}/${newsletter_id}/${timestamp}/${hash}`)
      .then(response => {
        this.setState({
          message: response.data.message,
          success: true
        });
      })
      .catch(error => {
        // Handle error
        this.setState({
          message: error.response.data.message,
          error: true
        });
      })
      .then(() => {
        this.setState({ loading: false });
      });
  }

  render() {
    return (
      <div>
        {this.state.loading &&
          <Loading />
        }

        <div className="container">
          <div className="row">
            <div className="col-12">
              {this.props.match.params.action === 'remove' ? (
                <h1>Confirm unsubscription</h1>
              ) : (
                <h1>Confirm subscription</h1>
              )}

              {this.state.error &&
              <div className="alert alert-danger" role="alert">
                {this.state.message}
              </div>
              }

              {this.state.success &&
              <div className="alert alert-success" role="alert">
                {this.state.message}
              </div>
              }

            </div>
          </div>
        </div>
      </div>
    );
  }
}

NewsletterConfirm.propTypes = {
  match: PropTypes.object.isRequired
};

export default NewsletterConfirm;

For the combined confirmation, the axios get call should be

axios.get(`${yourBackendUrl}/simplenews-decoupled/confirm/combined/${sid}/${timestamp}/${hash}`)

Depends on

Dependencies of the latest stable release

No dependencies recorded for this project.

Required by

Tracked projects that depend on this one

No tracked projects depend on this one yet.

Activity

Tracked releases
1
Tracked since
May 2023
Latest release
3 years ago
Releases (12 mo)
0
Maintenance
Dormant

Releases

Version Type Core Release date
1.1.0-beta1 Pre-release May 20, 2023