Skip to content

andyjamesn/nuxt-memberstack

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 

Repository files navigation

Memberstack Module for Nuxt 3

This module is a wrapper around the @memberstack/dom package.

The aim is to make the Memberstack object available across your Nuxt application and implements the Composition API.

Under the hood the Memberstack API get and update calls update a Pinia store through composables to easily make all data available across your application and also makes everything reactive.

Example of using the useMemberStackMember() to get and update user data. Since all values are using Pinia with storeToRefs all values are reactive and the data in the pages update as changes are made.

Here is an example of using the member composable

const { getMember, updateMember } = useMemberStackMember()

Using the above composable will update the DOM when a user logs in so the user data is updated and displayed on the page. Also when updating the members data the page updates without the need to reload.

Setup - Get Started

Requirements

This module (@nuxt/memberstack) and Pinia (@nuxt/pinia) are required.

Pinia is already installed as a dependancy of the module, but it does need to be set in your nuxt.config.js as a module.

Nuxt Config

You can add your Memberstack public key directly into the config but we suggest adding it as an environment variable in a .env file

  modules: ['@nuxt/memberstack', '@pinia/nuxt'],
  memberstack: {
    publicKey: process.env.MEMBERSTACK_PUBLIC_KEY
  },

Using the module

Global instance available

A global instance of the Memberstack object is available as part of the Nuxt context.

This means anything you can do in the Memberstack documentation you can do in Nuxt anywhere

const { $memberstack } = useNuxtApp()

Then you can use it how you normally would as per the Memberstack Docs, eg:

const member = await $memberstack.getCurrentMember()

Please note: You will need to build in the reactivity yourself as this interacts directly with Memberstack. If you want built in reactivity we suggest you use the composables provided.

Composables

Auth Composable

const auth = useMemberStackAuth()

Then call any methods in the composable directly

await auth.login()

Or destructure out all options

const { login, logout, register } = useMemberStackAuth()
Login

When a user is logged in the user data is added to the global Reactive member object.

You can set a redirect to redirect the user to a specific page after login.

await login({
  email: 'john@doe.com',
  password: '123123123',
  redirect: 'dashboard'
})
Reset password

There is no composable for this as there it no need to update the state

Get memberstack context from Nuxt and use to trigger reset email

const { $memberstack: memberstack } = useNuxtApp()
Request token email
await memberstack.sendMemberResetPasswordEmail({
  email: "john@doe.com",
})
Use token to reset password

After token is received, use this call to reset the password. You can also set a redirect back to the login page after password has been successfully reset.

The member object is returned if you want to use it to display a message to the user. But the user does need to login again.

const member = await resetPassword({
  token: '123456',
  newPassword: '54321qwerty',
  redirect: '/login'
})

Member Composable

const { getMember: member, updateMember } = useMemberStackMember()
<template>
  Welcome, {{member.auth.email}}
</template>

Plans

Use the useMemberStackPlans() composable to set and get plans.

const { setPlan, setPlans, plan, plans } = useMemberStackPlans()

Setting a plan or plans makes it available as reactive state in the store. Once set you can then access the them and display them on your page

Setting a plan (Saving it to store/state)

Set a single plan

await setPlan('pln_cl1....')

Set all active or inactive plans

await setPlans('ACTIVE')

Displaying plans

Now you can use them in your page

<template>
  <div v-for="(plan, index) in plans" :key="index">{{ plan.name }}</div>
</template>

Middleware for route protection and redirects

Global Middleware - On All routes

Create a global middleware file: eg ./middleware/auth.global.ts

This will run on all routes and redirect a NOT logged in user to the login page.

export default defineNuxtRouteMiddleware((to) => {
  const { getMember: member } = useMemberStackMember()

  // We need to specify the login page to prevent a circular route error
  if (to.path !== '/login' && !member.value) {
    return navigateTo('/login')
  }
})

Named middleware - On specific routes

Create a global middleware file: eg ./middleware/auth.ts

export default defineNuxtRouteMiddleware((to, _from) => {
  const { getMember: member } = useMemberStackMember()

  if (!member.value) {
    return navigateTo('/login')
  }
})

For named routes you need to specify in the page which middleware to use

<script setup lang="ts">
definePageMeta({
  middleware: ['auth']
})
</script>

Memberstack Role based Middleware

You can check if a user has a certain role.

For example check if a user is an admin and if not redirect them

Create a global middleware file: eg ./middleware/auth-admin.ts

export default defineNuxtRouteMiddleware(() => {
  const { getMember: member } = useMemberStackMember()

  if (typeof window !== 'undefined') {
    if (member !== null) {
      const { permissions } = member.value

      const hasAdminPermissions = permissions.includes('admin')
      if (!hasAdminPermissions) {
        return navigateTo('/pricing')
      }
    }
  }
})

Now on any pages where only admin users are allowed you just need to define the middleware

<script setup lang="ts">
definePageMeta({
  middleware: ['auth-admin']
})
</script>

Development

  • Run npm run dev:prepare to generate type stubs.
  • Use npm run dev to start playground in development mode.

About

Nuxt module for Memberstack

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published