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

madgic-ad-widget

v2.8.0

Published

Embeddable ad widget for Madgic ad platform

Downloads

35

Readme

madgic-ad-widget

Embeddable ad widget for the Madgic advertising platform. Display contextual ads on your website with a simple React component.

Installation

npm install madgic-ad-widget
# or
yarn add madgic-ad-widget

Quick Start

import MadgicAd from 'madgic-ad-widget';

function App() {
  return (
    <MadgicAd
      apiKey="pk_your_publisher_api_key"
      context="Your page content or description for ad matching"
    />
  );
}

For Chat Applications: The default import is optimized to prevent re-renders, which is crucial for chat/messaging apps where ads should remain static after initial render.

For Other Use Cases: If you need the component to update when props change, use the named import:

import { MadgicAd } from 'madgic-ad-widget';

Features

  • Easy Integration - Drop-in React component
  • Contextual Ads - Automatically matches ads to your content
  • AI-Generated Text - Server-side AI text generation via banner endpoint
  • Beautiful Design - Professional default styling
  • Fully Typed - Complete TypeScript support
  • Customizable - Override styles with custom CSS classes
  • Click Tracking - Built-in impression and click tracking
  • Error Handling - Graceful loading and error states
  • Mobile Responsive - Works perfectly on all devices
  • Chat Optimized - Memoized version prevents re-renders in chat/messaging apps

Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | apiKey | string | ✅ | - | Your Madgic publisher API key (starts with pk_) | | context | string | ✅ | - | Content context for ad matching | | adCount | number | ❌ | 1 | Number of ads to display (1-3) | | adServerUrl | string | ❌ | https://adserver.madgic.ai | Custom AdServer URL (dev/testing only) | | className | string | ❌ | '' | Additional CSS class for the container | | customText | string \| function | ❌ | - | Override AI-generated ad text | | ctaText | string \| function | ❌ | - | Override AI-generated CTA text | | renderAd | function | ❌ | - | Custom render function for full control | | hideAdBadge | boolean | ❌ | false | Hide "Sponsored by Madgic" badge | | onAdLoad | (ads: Ad[]) => void | ❌ | - | Callback when ads successfully load | | onAdClick | (ad: Ad) => void | ❌ | - | Callback when an ad is clicked | | onError | (error: Error) => void | ❌ | - | Callback when an error occurs |

Usage Examples

Basic Usage

import MadgicAd from 'madgic-ad-widget';

function BlogPost() {
  return (
    <article>
      <h1>My Blog Post</h1>
      <p>Content goes here...</p>

      <MadgicAd
        apiKey="pk_your_api_key"
        context="Blog post about sustainable fashion and eco-friendly clothing brands"
      />
    </article>
  );
}

Note: All ads now use AI-generated text and CTA from the server automatically. You can override this behavior using the customText and ctaText props if needed.

Multiple Ads

<MadgicAd
  apiKey="pk_your_api_key"
  context="Article about AI and machine learning"
  adCount={2}
/>

With Event Callbacks

import MadgicAd from 'madgic-ad-widget';

function MyComponent() {
  const handleAdLoad = (ads) => {
    console.log(`Loaded ${ads.length} ads`);
  };

  const handleAdClick = (ad) => {
    console.log('User clicked ad:', ad.phrase);
    // Track in your analytics
  };

  const handleError = (error) => {
    console.error('Ad loading failed:', error);
  };

  return (
    <MadgicAd
      apiKey="pk_your_api_key"
      context="Tech news and gadget reviews"
      onAdLoad={handleAdLoad}
      onAdClick={handleAdClick}
      onError={handleError}
    />
  );
}

Custom Styling

import MadgicAd from 'madgic-ad-widget';
import './custom-ad-styles.css';

function StyledAd() {
  return (
    <MadgicAd
      apiKey="pk_your_api_key"
      context="Your content context"
      className="my-custom-ad"
    />
  );
}

custom-ad-styles.css:

.my-custom-ad .madgic-ad-container {
  background: #f0f0f0;
  border-radius: 8px;
}

.my-custom-ad .madgic-ad-cta {
  background: #ff6b6b;
}

Development/Testing with Custom Server

<MadgicAd
  apiKey="pk_test_key"
  context="Your content"
  adServerUrl="http://localhost:3002"  // Point to local dev server
/>

Next.js Example

'use client';

import MadgicAd from 'madgic-ad-widget';

export default function ProductPage() {
  return (
    <div>
      <h1>Product Details</h1>

      <MadgicAd
        apiKey={process.env.NEXT_PUBLIC_MADGIC_API_KEY}
        context="E-commerce product page for outdoor gear and camping equipment"
      />
    </div>
  );
}

Chat/Messaging Application Example

For chat and messaging apps, use the default import (memoized version) to prevent performance issues:

import MadgicAd from 'madgic-ad-widget';

function ChatMessage({ message, showAd }) {
  return (
    <div>
      <div className="message">{message.text}</div>

      {showAd && (
        <MadgicAd
          apiKey="pk_your_api_key"
          context={message.text}
        />
      )}
    </div>
  );
}

Why this matters: In chat applications, when new messages arrive, the parent component re-renders. The default (memoized) export prevents old ads from re-rendering, which:

  • ✅ Prevents unwanted scrolling
  • ✅ Avoids redundant API calls
  • ✅ Dramatically improves performance with multiple ads
  • ✅ Keeps ads stable in chat history

The component will render once with the initial context and remain static, even as new messages are added to the chat.

Using the Hook Directly

For more control, use the useAdFetch hook:

import { useAdFetch } from '@madgic/ad-widget';

function CustomAdComponent() {
  const { ads, loading, error, refetch } = useAdFetch({
    apiKey: 'pk_your_api_key',
    context: 'Your content context',
    adCount: 2,
  });

  if (loading) return <div>Loading ads...</div>;
  if (error) return <div>Error: {error.message}</div>;
  if (ads.length === 0) return null;

  return (
    <div>
      {ads.map((ad, index) => (
        <div key={index}>
          <h3>{ad.phrase}</h3>
          <p>{ad.description}</p>
          <a href={ad.link} target="_blank" rel="noopener noreferrer">
            Learn More
          </a>
        </div>
      ))}
      <button onClick={refetch}>Refresh Ads</button>
    </div>
  );
}

TypeScript Support

Full TypeScript definitions are included:

import type { Ad, MadgicAdProps, UseAdFetchReturn } from '@madgic/ad-widget';

const myAd: Ad = {
  campaignId: 'campaign_123',
  phrase: 'Great Product',
  link: 'https://example.com',
  description: 'Best product ever',
};

Customization

The widget comes with default styles that are automatically injected. You can customize any part by adding your own CSS.

Quick Example

/* Customize the badge */
.madgic-ad-badge {
  background-color: rgba(0, 0, 0, 0.8) !important;
  font-size: 10px !important;
}

/* Customize the CTA button */
.madgic-ad-cta {
  background: #ff6600 !important;
}

Note: Use !important to override the injected styles, or increase CSS specificity.

CSS Classes

  • .madgic-ad-wrapper - Outer container
  • .madgic-ad-container - Individual ad container
  • .madgic-ad-badge - Badge with logo
  • .madgic-ad-content - Ad content wrapper
  • .madgic-ad-headline - Ad headline/phrase
  • .madgic-ad-description - Ad description text
  • .madgic-ad-cta - Call-to-action button

📖 See CUSTOMIZATION.md for detailed examples

API Key Security

Your publisher API key (pk_*) is safe to use client-side because:

  1. It's read-only for ad fetching
  2. It's scoped to your publisher account
  3. It cannot access other publishers' data
  4. It cannot create or delete campaigns

This is similar to how Google Maps API keys or analytics tracking IDs work.

Environment Variables

For Next.js or other frameworks, use environment variables:

# .env.local
NEXT_PUBLIC_MADGIC_API_KEY=pk_your_api_key
NEXT_PUBLIC_ADSERVER_URL=https://your-adserver-url.com

Getting Your API Key

  1. Sign up for a Madgic publisher account
  2. Navigate to your dashboard
  3. Generate a new API key from the API Keys section
  4. Copy the key (starts with pk_)

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

License

MIT

Support

For issues and questions: