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

featurely-feature-reporter

v1.0.10

Published

Embeddable widget for collecting user feature requests and bug reports with Featurely

Readme

featurely-feature-reporter

Embeddable widget for collecting user feature requests and bug reports with Featurely.

📦 Installation

npm install featurely-feature-reporter

🚀 Quick Start

import { FeatureReporter } from "featurely-feature-reporter";

const reporter = new FeatureReporter({
  apiKey: "your-featurely-api-key",
  projectId: "your-project-id",
  position: "bottom-right",
  color: "blue",
  icon: "comment",
});

reporter.init();

✨ Features

  • 💡 Feature Requests - Let users submit feature ideas
  • 🐛 Bug Reports - Collect bug reports with screenshots
  • 📸 Screenshot Capture - Automatic or manual screenshot capture
  • 🎨 Customizable - Colors, icons, and positioning
  • 🎯 Draggable Widget - Optional drag-to-reposition functionality
  • 📱 Mobile Responsive - Works great on all devices
  • 🔒 User Context - Track submissions by user
  • 🔗 Dashboard Link - Optional link to your public roadmap
  • 🎭 TypeScript - Fully typed with comprehensive definitions

📖 Usage

Basic Setup

import { FeatureReporter } from "featurely-feature-reporter";

// Initialize the widget
const reporter = new FeatureReporter({
  apiKey: "ft_live_your_api_key",
  projectId: "proj_123",
});

// Render the widget
reporter.init();

With User Context

const reporter = new FeatureReporter({
  apiKey: "ft_live_your_api_key",
  projectId: "proj_123",
  user: {
    id: "user_123",
    email: "[email protected]",
    name: "John Doe",
  },
});

reporter.init();

// Update user context later (e.g., after login)
reporter.setUser("user_456", "[email protected]", "Jane Smith");

Full Customization

const reporter = new FeatureReporter({
  apiKey: "ft_live_your_api_key",
  projectId: "proj_123",

  // Position
  position: "bottom-right", // 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'right-center' | 'left-center'

  // Appearance
  color: "purple", // 'blue' | 'green' | 'purple' | 'red' | 'orange' | 'pink'
  icon: "lightbulb", // 'comment' | 'lightbulb' | 'bug' | 'message' | 'plus' | 'star'

  // Features
  enableFeatureRequests: true,
  enableBugReports: true,
  draggable: true,
  showDashboardLink: true,

  // Custom labels
  labels: {
    widgetTooltip: "Send feedback",
    featureRequestTitle: "💡 Request a Feature",
    bugReportTitle: "🐛 Report a Bug",
    submitButton: "Send",
    cancelButton: "Close",
  },

  // Callbacks
  onSubmit: (type, data) => {
    console.log(`${type} submitted:`, data);
  },
  onError: (error) => {
    console.error("Submission error:", error);
  },
});

reporter.init();

React Integration

import { useEffect, useRef } from "react";
import { FeatureReporter } from "featurely-feature-reporter";

function App() {
  const reporterRef = useRef<FeatureReporter | null>(null);

  useEffect(() => {
    reporterRef.current = new FeatureReporter({
      apiKey: process.env.REACT_APP_FEATURELY_API_KEY!,
      projectId: process.env.REACT_APP_FEATURELY_PROJECT_ID!,
      position: "bottom-right",
      color: "blue",
    });

    reporterRef.current.init();

    return () => {
      reporterRef.current?.destroy();
    };
  }, []);

  return <div>Your app content</div>;
}

Next.js Integration

// app/layout.tsx or pages/_app.tsx
"use client";

import { useEffect } from "react";
import { FeatureReporter } from "featurely-feature-reporter";

export default function RootLayout({ children }) {
  useEffect(() => {
    if (typeof window !== "undefined") {
      const reporter = new FeatureReporter({
        apiKey: process.env.NEXT_PUBLIC_FEATURELY_API_KEY!,
        projectId: process.env.NEXT_PUBLIC_FEATURELY_PROJECT_ID!,
      });

      reporter.init();

      return () => reporter.destroy();
    }
  }, []);

  return (
    <html>
      <body>{children}</body>
    </html>
  );
}

Vue Integration

<script setup>
import { onMounted, onUnmounted } from "vue";
import { FeatureReporter } from "featurely-feature-reporter";

let reporter = null;

onMounted(() => {
  reporter = new FeatureReporter({
    apiKey: import.meta.env.VITE_FEATURELY_API_KEY,
    projectId: import.meta.env.VITE_FEATURELY_PROJECT_ID,
  });

  reporter.init();
});

onUnmounted(() => {
  reporter?.destroy();
});
</script>

🔧 Configuration

FeatureReporterConfig

| Option | Type | Required | Default | Description | | ----------------------- | ---------------- | -------- | ------------------------- | ------------------------- | | apiKey | string | ✅ | - | Your Featurely API key | | projectId | string | ✅ | - | Your Featurely project ID | | apiUrl | string | ❌ | 'https://featurely.no' | Custom API endpoint | | position | WidgetPosition | ❌ | 'bottom-right' | Widget position | | color | WidgetColor | ❌ | 'blue' | Widget color theme | | icon | WidgetIcon | ❌ | 'comment' | Widget icon | | draggable | boolean | ❌ | false | Allow widget dragging | | enableFeatureRequests | boolean | ❌ | true | Enable feature requests | | enableBugReports | boolean | ❌ | true | Enable bug reports | | showDashboardLink | boolean | ❌ | false | Show dashboard link | | user | UserInfo | ❌ | - | User context | | labels | Labels | ❌ | - | Custom text labels | | onSubmit | function | ❌ | - | Submission callback | | onError | function | ❌ | - | Error callback |

Position Options

  • 'bottom-right' - Bottom right corner (default)
  • 'bottom-left' - Bottom left corner
  • 'top-right' - Top right corner
  • 'top-left' - Top left corner
  • 'right-center' - Right side, vertically centered
  • 'left-center' - Left side, vertically centered

Color Options

  • 'blue' (default)
  • 'green'
  • 'purple'
  • 'red'
  • 'orange'
  • 'pink'

Icon Options

  • 'comment' (default) - Chat bubble
  • 'lightbulb' - Light bulb
  • 'bug' - Bug icon
  • 'message' - Message icon
  • 'plus' - Plus sign
  • 'star' - Star icon

📸 Screenshot Capture

The widget includes built-in screenshot capability for bug reports:

Automatic Capture (Recommended)

Install html2canvas for automatic full-page screenshots:

npm install html2canvas
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/html2canvas.min.js"></script>

When html2canvas is available, the widget will automatically capture full-page screenshots when users click "Capture Screenshot".

Manual Upload Fallback

If html2canvas is not available, the widget will fall back to a file upload input, allowing users to manually select screenshot files.

🎯 API Methods

init()

Initialize and render the widget on the page.

reporter.init();

setUser(userId, email?, name?)

Update user context for submissions.

reporter.setUser("user_123", "[email protected]", "John Doe");

show()

Show the widget if it was hidden.

reporter.show();

hide()

Hide the widget.

reporter.hide();

destroy()

Remove the widget from the page and clean up.

reporter.destroy();

🌐 Environment Variables

Store your API credentials securely:

React/Vite:

VITE_FEATURELY_API_KEY=ft_live_your_key
VITE_FEATURELY_PROJECT_ID=proj_123

Next.js:

NEXT_PUBLIC_FEATURELY_API_KEY=ft_live_your_key
NEXT_PUBLIC_FEATURELY_PROJECT_ID=proj_123

Vanilla JS:

const reporter = new FeatureReporter({
  apiKey: window.FEATURELY_API_KEY,
  projectId: window.FEATURELY_PROJECT_ID,
});

🎨 Custom Styling

The widget injects minimal styles with high specificity. You can override them:

/* Customize widget button */
.featurely-widget-button {
  width: 64px !important;
  height: 64px !important;
}

/* Customize modal */
.featurely-modal-content {
  border-radius: 16px !important;
}

All styles are prefixed with featurely- to avoid conflicts.

🔒 Privacy & Security

  • Screenshots are captured client-side and sent directly to your Featurely project
  • No third-party services are used for screenshots
  • User data is only sent to your Featurely project
  • API keys should be stored in environment variables
  • All submissions are sent over HTTPS

📱 Browser Support

  • Chrome/Edge (latest)
  • Firefox (latest)
  • Safari (latest)
  • Mobile browsers (iOS Safari, Chrome Mobile)

Screenshot capture requires:

  • html2canvas for automatic capture
  • FileReader API for manual upload (universally supported)

🤝 Contributing

Contributions are welcome! Please open an issue or PR.

📄 License

MIT License - see LICENSE file for details.

🔗 Links

💬 Support

For issues or questions: