Giter Site home page Giter Site logo

baroshem / nuxt-newsletter Goto Github PK

View Code? Open in Web Editor NEW
56.0 1.0 7.0 1.58 MB

✉️ Nuxt module for first class integration with popular newsletter providers

Home Page: https://nuxt-newsletter.netlify.app/

License: MIT License

Shell 1.09% Vue 32.53% TypeScript 66.38%
buttondown mailchimp newsletter nuxt nuxt-module nuxtjs revue vue

nuxt-newsletter's Introduction

nuxt-newsletter

nuxt-newsletter

npm version npm downloads Github Actions CI License

Newsletter module for Nuxt 3

Features

  • Nuxt 3 ready
  • Easy integration with Mailchimp, Revue, Buttondown
  • Unstyled NewletterForm.vue component
  • Handy useNewsletterSubscribe composable
  • TypeScript support

📖  Read the documentation

Setup

yarn add nuxt-newsletter # yarn
npm i nuxt-newsletter # npm

Basic usage

Firstly, you need to add nuxt-newsletter to your Nuxt config.

// nuxt.config.js

{
    modules: [
        "nuxt-newsletter",
    ],
    newsletter: {
      // mailchimp | revue | buttondown
      <YOUR_NEWSLETTER_PROVIDER>: {
        // options like apiKey
      }
    }
}

Then you can start using nuxt-newsletter in your app!

<template>
  <div>
    <newsletter-form />
  </div>
</template>

Development

  1. Clone this repository
  2. Install dependencies using yarn install or npm install
  3. Prepare playground environment using yarn dev:prepare or npm run dev:prepare
  4. Start development server using yarn dev or npm run dev

License

MIT License

nuxt-newsletter's People

Contributors

baroshem avatar clemcode avatar intevel avatar smarroufin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

nuxt-newsletter's Issues

Not compatible with Nuxt3.rc12 or Nuxt3.rc13 projects

Please update dependencies to Nuxt3 rc13.
Currently, the module is not compatible when adding it to a rc12 or rc13 Nuxt3 project.

Output Errors / Warnings:
1.

[h3] Implicit event handler conversion is deprecated. Use `eventHandler()` or `fromNodeMiddleware()` to define event handlers. 
     Route: /api/newsletter/subscribe 
     Handler: async (req, res) => {
  const { email } = await _file_home_projects_nuxt_starter_ad6gbk_node_modules_h3_dist_index_mjs.useBody(req);
  if (!email) {
    console.error("`[@nuxtjs/newsletter]` Missing `email` in the subscribe body");
    return;
  }
  const newsletterConfig = useRuntimeConfig().newsletter;
  const providerName = Object.keys(newsletterConfig)[0];
  try {
    const mailchimp = await 𝐢𝐦𝐩𝐨𝐫𝐭('file:///home/projects/nuxt-starter-ad6gbk/node_modules/@mailchimp/mailchimp_marketing/src/index.js').then((r) => r.default || r);
    mailchimp.setConfig({
      apiKey: newsletterConfig[providerName].apiKey,
      server: newsletterConfig[providerName].serverPrefix
    });
    let result;
    try {
      const response = await mailchimp.lists.addListMember(newsletterConfig[providerName].audienceId, {
        email_address: email,
        status: "subscribed"
      });
      result = { message: `Email ${response.email_address} subscribed to Mailchimp`, status: 200 };
    } catch (err) {
      result = { message: err.response.body.title, status: err.status };
    }
    res.statusCode = result.status;
    res.end(JSON.stringify(result.message));
  } catch (error) {
    res.statusCode = 500;
    res.end("Unexpected error occured", error);
  }
[POST] /api/newsletter/subscribe
2022-11-10T19:53:50.300Z	f5f840f8-0919-43bd-b554-2612317e490c	ERROR	[nuxt] [request error] [unhandled] [500] Cannot set properties of undefined (setting 'statusCode')
  at _BxWD19 (./chunks/nitro/vercel.mjs:442:20)  
  at processTicksAndRejections (node:internal/process/task_queues:96:5)  
  at async Object.handler (./node_modules/h3/dist/index.mjs:634:19)  
  at async Server.toNodeHandle (./node_modules/h3/dist/index.mjs:698:7)

ReferenceError: useNewsletterSubscribe is not defined

Hi,
I am struggling to get this to work. I have the below setup, but I get ReferenceError: useNewsletterSubscribe is not defined.
Any idea what I'm doing wrong?

component:

<script setup lang="ts">

  const submitEmail = ref(null);
  const successful = ref(false);
  const error = ref(false);


  const props = defineProps({
    subscribe:{required:false,type:Object},
  })


  const submitSubscribe = async (e) => {
    const result = await useNewsletterSubscribe(submitEmail.value);
    console.log(result);
  }


</script>

Nuxt.config

modules: [
    "@nuxtjs/sanity",
    "nuxt-jsonld",
    "@pinia/nuxt",
    "@nuxt/image-edge",
    "@nuxtjs/robots",
    "@pinia-plugin-persistedstate/nuxt",
    'nuxt-simple-sitemap',
    'nuxt-schema-org',
    "@vueuse/nuxt",
    "nuxt-newsletter",
  ],
newsletter:{
    mailchimp: {
      apiKey: process.env.MAILCHIMP_API_KEY,
      serverPrefix: process.env.MAILCHIMP_SERVER_PREFIX,
      audienceId: process.env.MAILCHIMP_AUDIENCE_ID
    }
  },

error:

Subscribe.vue:39 Uncaught (in promise) ReferenceError: useNewsletterSubscribe is not defined
    at submitSubscribe (Subscribe.vue:39:20)
    at chunk-VT7SFOAW.js:1706:16
    at callWithErrorHandling (chunk-JROTR2UA.js:186:18)
    at callWithAsyncErrorHandling (chunk-JROTR2UA.js:194:17)
    at HTMLFormElement.invoker (chunk-VT7SFOAW.js:516:5)

Nuxt info

Operating System: Darwin
Node Version: v16.20.0
Nuxt Version: 3.6.1
Nitro Version: 2.5.2
Package Manager: [email protected]
Builder: vite
User Config: -
Runtime Modules: -
Build Modules: -

Wrong MailChimp url

Hello Guys, I'd like to suggest a change in your plugin. I had a 500 error with MailChimp which was solved changing the line 2 in useNewsletterSubscribe.mjs.

export async function useNewsletterSubscribe(email) {
  return await $fetch("/api/newsletter/subscribe", {
    body: { email },
    method: "POST"
  }).catch((e) => e.data);
}

to:

export async function useNewsletterSubscribe(email) {
  return await $fetch("/api/newsletter/subscribe/members", {
    body: { email },
    method: "POST"
  }).catch((e) => e.data);
}

added /members

Thank you

Support client only composable

The current result for newsletter can be also achieved on the client side without invoking any server handlers. User should have an option to choose whether he wants to add emails to the newsletter from the server or client side.

useNewsletterSubscribe error

UPDATE: I saw now that I only need to call it in fetch('/api/newsletter/subscribe')
but I only have the email field, so how can I add the other fields like firstName and lastName so that they will be included in the post data to MailChimp?

const result = await $fetch("/api/newsletter/subscribe", {
    method: "post",
    body: formData.value,
  });
  console.log("result****", result);

Hello, I can't find where the useNewsLetterSubscibe composable is or where to implement it in your docs.

I have completed the setup with MailChimp without the component option. I just have no idea how to actually use it.

Where is the composable coming from or how/where do I add it as it doesn't seem to be auto-imported?

I get an error when trying to submit the form because useNewsletterSubscribe is not defined.

Screenshot 2023-01-22 at 11 41 32

Screenshot 2023-01-22 at 11 34 13

//nuxt.config.ts
...
modules: [
    "@nuxtjs/tailwindcss",
    "@tailwindcss/typography",
    "nuxt-newsletter",
  ],
  newsletter: {
    mailchimp: {
      apiKey: process.env.MAILCHIMP_API_KEY,
      audienceId: process.env.MAILCHIMP_AUDIENCE_ID,
      serverPrefix: process.env.MAILCHIMP_SERVER_PREFIX,
    },
  },
...
<script lang="ts" setup>
definePageMeta({
  layout: "construction",
});

// form data
const formData = ref({});
const firstName = ref({ val: "", isValid: true });
const surname = ref({ val: "", isValid: true });
const email = ref({ val: "", isValid: true });

const formIsValid = ref(true);

// methods
const validateForm = () => {
  formIsValid.value = true;

  // form details
  if (firstName.value.val === "") {
    firstName.value.isValid = false;
    formIsValid.value = false;
  }
  if (surname.value.val === "") {
    surname.value.isValid = false;
    formIsValid.value = false;
  }
  if (email.value.val === "" || !email.value.val.includes("@")) {
    email.value.isValid = false;
    formIsValid.value = false;
  }
};

async function handleSubmit() {
  validateForm();
  if (!formIsValid.value) {
    return;
  }

  formData.value = {
    firstName: firstName.value.val,
    surname: surname.value.val,
    email: email.value.val,
  };
  
  const result = await useNewsletterSubscribe(formData.value);
  console.log(result);
}
</script>

TIA!

Provide a custom url for subscribing

This feature is a recommendation based on the conversation on Twitter. (https://twitter.com/GwynHockridge/status/1546580353292402689?s=20&t=HCbpzfd3xAMxQr71EOkBhg)

Gwyn recommended to implement a feature when a user can define an url where the request will be sent from the frontend instead of localhost to handle the subscription.

The use case is a static application that does not have a server middleware but the users would still want to be able to add to newsletter.

The implementation could look like this:

import { defineNuxtConfig } from 'nuxt'

export default defineNuxtConfig({
  ssr: false,
  modules: ['nuxt-newsletter'],
  newsletter: {
    url: 'https://my-custom-server.com'
  }
})

After setting the url property, useNewsletterSubscribe composable will instead send a request to that url and await for the response:

import { useRuntimeConfig } from '#imports'

export async function useNewsletterSubscribe(email: string) {
  const newsletterConfig = useRuntimeConfig().newsletter

  return await $fetch(newsletterConfig.url || '/api/newsletter/subscribe', {
    body: { email },
    method: 'POST'
  }).catch(e => e.data);

Move component option to top-level

It should be a top-level option:

newsletter: {
  component: true,
  // mailchimp | revue | buttondown
  <YOUR_NEWSLETTER_PROVIDER>: {
    // options like apiKey
  }
}

Also, you could support the provider prop in the component to use one of the providers defined (default to the first one defined).

Incompatible Node version

When installing, I'm getting the following error:

error @nuxt/[email protected]: The engine "node" is incompatible with this module. Expected version "^14.16.0 || ^16.10.0 || ^17.0.0 || ^18.0.0 || ^19.0.0". Got "20.11.1"

Getting an console error on non 200 request

In general - thank you for that little module. Works very well!

When submitting an email to Mailchimp, that already is registered, I get an error 400 on the console. I guess this is based on throwing this exception.

While you catch the error first you then throw this exception - not sure if I want to expose such an error on the console. I just ran this locally with development as NODE_ENV. Maybe this is not exposed on production?

Is there anything I can do without showing this error on console?

Double Opt-In missing for Mailchimp

Double Opt-In (DOI) is currently not available with this module, as the status is hardcoded to subscribed.

As DOI is necessary for countries like Austria, Germany, Greece, Switzerland, Luxembourg and Norway this should be configurable for MC. To be more flexible, I would suggest setting the status to either one of these supported types (see MC API docs):

  • pending This is the necessary status for DOI
  • subscribed
  • unsubscribed
  • cleaned
  • transactional

To leave this decision to the user, a new config option, f. ex. memberStatus could be introduced with a default value being subscribed.

I tested this: when setting pending as the status, the email is not directly added to the audience but instead you receive a DOI email, if you really want to subscribe.

I would create a PR, if that helps :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.