npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@supaapps/mayicookies

v0.1.4

Published

Browser consent management SDK for mayicookies.

Readme

@supaapps/mayicookies

Browser SDK for mayicookies consent banners, preferences, consent recording, optional script activation, Global Privacy Control handling, and Google Consent Mode v2.

Customer Setup Flow

  1. Sign in to Mayicookies.
  2. Create a workspace.
  3. Add a site and whitelist the production domain.
  4. Configure policy text, categories, and any managed scripts.
  5. Copy the site-specific script tag, npm config, or GTM setup values from the site install page.
  6. Install Mayicookies before analytics, ads, or vendor tags run.

The site key is public and site-specific. Do not reuse a key across unrelated customer sites.

Script Tag Install

Use the hosted loader when you are not bundling npm code. The loader imports the SDK from the same CDN path, fetches the site runtime config, shows the banner when needed, writes the GTM-readable consent cookie, and exposes window.Mayicookies.

<script
  async
  src="https://app.mayicookies.com/mayicookies/loader.js"
  data-site-key="site_REPLACE_WITH_SITE_KEY"
  data-api-url="https://api.mayicookies.com/api"
  data-mode="auto"
></script>

Place the snippet in <head> before Google Tag Manager, gtag.js, analytics, ads, heatmaps, chat widgets, or other optional vendor scripts.

Supported loader attributes:

| Attribute | Default | Description | | --- | --- | --- | | data-site-key | Required | Public Mayicookies site key from the dashboard. | | data-mayicookies-site-key | None | Namespaced alias for data-site-key. | | data-api-url | https://api.mayicookies.com/api | Mayicookies API base URL. | | data-mayicookies-api-url | None | Namespaced alias for data-api-url. | | data-mode | auto | Jurisdiction mode: auto, gdpr, ccpa, cpra, vcdpa, or pipeda. | | data-auto-block | true | Set to false to disable activation of manually blocked scripts. | | data-google-consent-mode | true | Set to false to stop writing the GTM consent cookie and dataLayer updates. | | data-gtm-consent-cookie-name | mayicookies_gtm_consent | Cookie read by the Mayicookies GTM template. | | data-gtm-consent-cookie-max-age-days | 180 | Consent cookie lifetime in days. | | data-gtm-consent-push-data-layer | true | Set to false to disable mayicookies_consent_update dataLayer events. | | data-gtm-consent-data-layer-event | mayicookies_consent_update | Custom dataLayer event name for consent updates. |

npm Install

npm install @supaapps/mayicookies

Initialize once on every public page before optional tags run.

import { Mayicookies } from '@supaapps/mayicookies';

await Mayicookies.init({
  siteKey: 'site_REPLACE_WITH_SITE_KEY',
  apiUrl: 'https://api.mayicookies.com/api',
  mode: 'auto',
  autoBlock: true,
});

Plain JavaScript:

import { Mayicookies } from '@supaapps/mayicookies';

Mayicookies.init({
  siteKey: 'site_REPLACE_WITH_SITE_KEY',
  apiUrl: 'https://api.mayicookies.com/api',
  mode: 'auto',
  autoBlock: true,
}).catch((error) => {
  console.error('Mayicookies failed to initialize', error);
});

Next.js or React

For Next.js App Router, initialize in a client component mounted from the root layout.

'use client';

import { useEffect } from 'react';
import { Mayicookies } from '@supaapps/mayicookies';

export function MayicookiesProvider() {
  useEffect(() => {
    void Mayicookies.init({
      siteKey: process.env.NEXT_PUBLIC_MAYICOOKIES_SITE_KEY!,
      apiUrl: process.env.NEXT_PUBLIC_MAYICOOKIES_API_URL ?? 'https://api.mayicookies.com/api',
      mode: 'auto',
      autoBlock: true,
    });
  }, []);

  return null;
}
import { MayicookiesProvider } from './MayicookiesProvider';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <MayicookiesProvider />
        {children}
      </body>
    </html>
  );
}

For a regular React SPA, render the same provider at the top of the app before route content that can load optional tags.

Manual Script Blocking

For scripts that must wait for consent, change type to text/plain and add data-mayicookies-category.

<script
  type="text/plain"
  data-mayicookies-category="analytics"
  src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"
></script>
<script type="text/plain" data-mayicookies-category="marketing">
  console.log('Runs only after marketing consent is granted.');
</script>

Common categories:

  • necessary: required site behavior, always enabled.
  • analytics: measurement and performance tooling.
  • marketing: ads, retargeting, conversion pixels.
  • preferences: personalization and preference storage.
  • sale_share: CCPA/CPRA sale or sharing choice.

The dashboard policy controls the categories available for each site.

Scripts configured in the Mayicookies dashboard are also activated by the SDK after consent. Dashboard-managed scripts support:

  • External script URLs.
  • Inline script code.
  • Optional URL match patterns such as /checkout/* or https://shop.example.com/products/*.
  • Script attributes such as data-*, id, async, or crossorigin.

The SDK only injects a dashboard-managed script when the visitor granted that script's consent category and the current URL matches its pattern.

Preferences Button

Expose a footer, privacy page, or account settings button so visitors can reopen choices.

import { Mayicookies } from '@supaapps/mayicookies';

export function CookieSettingsButton() {
  return (
    <button type="button" onClick={() => Mayicookies.openPreferences()}>
      Cookie settings
    </button>
  );
}

With the script loader, use:

<button type="button" onclick="window.Mayicookies?.openPreferences()">Cookie settings</button>

Google Tag Manager CMP Template

Use the bundled Mayicookies CMP template for GTM containers. It calls GTM consent APIs directly, sets denied optional defaults on Consent Initialization - All Pages, reads the Mayicookies consent cookie, and listens for SDK updates through window.mayicookiesAddConsentModeListener.

Recommended setup:

  1. In GTM, open Templates.
  2. Import or create the mayicookies CMP template from packages/gtm-template/template.tpl.
  3. Create one tag from that template.
  4. Trigger it on Consent Initialization - All Pages.
  5. Keep cookieName as mayicookies_gtm_consent unless you changed the SDK cookie name.
  6. Keep wait_for_update at 500.
  7. Keep ads_data_redaction enabled.
  8. Leave url_passthrough disabled unless your legal and analytics setup requires it.
  9. Publish only after GTM Preview and Tag Assistant confirm consent order and states.

Consent Mode v2 mapping:

| Mayicookies choice | Google consent type | | --- | --- | | analytics=true | analytics_storage=granted | | marketing=true | ad_storage=granted | | marketing=true and sale_share !== false and GPC disabled | ad_user_data=granted, ad_personalization=granted | | preferences=true | functionality_storage=granted, personalization_storage=granted | | Always | security_storage=granted |

Before consent, optional Google storage types default to denied.

Direct gtag.js Bridge

Use this only when you do not use the GTM template.

import { Mayicookies, installGoogleConsentModeBridge } from '@supaapps/mayicookies';

await Mayicookies.init({
  siteKey: 'site_REPLACE_WITH_SITE_KEY',
  apiUrl: 'https://api.mayicookies.com/api',
  mode: 'auto',
  autoBlock: true,
});

installGoogleConsentModeBridge();

installGoogleConsentModeBridge() sends a default denied optional state with wait_for_update: 500, then sends gtag('consent', 'update', ...) when preferences change.

Verify Installation

Check these on a real allowed domain:

  • Network request to /api/public/sites/{siteKey}/config returns 200.
  • First visit with no stored consent shows the banner.
  • Accept all records a POST to /api/public/sites/{siteKey}/consents.
  • Reject optional keeps optional scripts blocked.
  • Category-specific scripts activate only after that category is granted.
  • A mayicookies:consent:{siteKey} localStorage entry exists after saving.
  • A mayicookies_gtm_consent cookie exists when Google Consent Mode is enabled.
  • GTM Preview shows the Mayicookies CMP tag firing before Google or vendor tags.
  • Tag Assistant shows denied optional defaults before consent and updated values after preference changes.
  • window.Mayicookies.openPreferences() opens the preferences modal.

Common Failures

| Symptom | Likely cause | Fix | | --- | --- | --- | | Banner never appears | Missing or wrong siteKey, API request failed, or snippet loads after a blocking error. | Check DevTools console and the config request URL/status. | | Config request returns 403 | Domain is not whitelisted for the site. | Add the exact production domain in the Mayicookies site settings. | | Consent is not recorded | API URL is wrong, network/CORS issue, or public consent endpoint is blocked. | Verify the POST to /consents and API logs. | | Optional script runs before consent | Script was left as normal JavaScript. | Use type="text/plain" and data-mayicookies-category. | | Optional script never runs after consent | Category key does not match the dashboard category or data-auto-block="false" is set. | Align the category key and keep auto-block enabled. | | GTM sees no updates | CMP tag did not run on Consent Initialization or cookie names differ. | Check GTM trigger order and cookieName. | | Google Ads personalization remains denied | Visitor opted out of sale/share or Global Privacy Control is enabled. | This is expected privacy behavior. |

Runtime API

  • Mayicookies.init(config)
  • Mayicookies.getConsent()
  • Mayicookies.setConsent(choices)
  • Mayicookies.onConsentChange(listener)
  • Mayicookies.getGoogleConsentModeState()
  • Mayicookies.onGoogleConsentModeChange(listener)
  • Mayicookies.openPreferences()
  • Mayicookies.resetConsent()
  • mapConsentToGoogleConsentMode(snapshot)
  • installGoogleConsentModeBridge(options)