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

@floo-one/nuxt-feedback

v0.2.4

Published

Drop-in in-app feedback dialog for Nuxt 4 — bugs and ideas to GitHub Issues, with a server-side submit hook.

Downloads

888

Readme

@floo-one/nuxt-feedback

A drop-in in-app feedback dialog for Nuxt 4. Your users press a shortcut, pick Bug or Feedback, and hit send:

  • 🐞 Bug → a GitHub issue (labelled bug) with the full context — reporter, page URL, app build, recent console errors — plus a type (crash / visual / data / performance) and a severity (critical → cosmetic).
  • 💬 Feedback → a GitHub issue on the repo you choose (ideas, praise, or anything else).

It's auth-agnostic (you give it a tiny function to identify the user — it never imports your auth), and when the user is already logged in it doesn't bother asking for their email.


Requirements

  • Nuxt ≥ 4
  • @nuxt/ui ≥ 4 (peer dependency — the dialog is built from Nuxt UI components your app already has)

Setup (3 steps)

1. Install

pnpm add @floo-one/nuxt-feedback

2. Register and configure it

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxt/ui', '@floo-one/nuxt-feedback'],

  feedback: {
    github: { repo: 'your-org/your-repo' }, // where issues are filed
    shortcut: 'g-f',                         // press g then f
    resolveUserPath: './server/feedback-user.ts',
  },
})

3. Tell it who the user is

Create the file you referenced in resolveUserPath. It runs on the server, gets the request event, and returns the logged-in user (or null). Use whatever auth your app already has — the module never touches it.

// server/feedback-user.ts
import type { H3Event } from 'h3'

export default async function resolveUser(event: H3Event) {
  const session = await getServerSession(event) // ← however your app reads the session
  return session?.user
    ? { id: session.user.id, email: session.user.email, name: session.user.name }
    : null
}

Must never throw — return null when logged out. When it returns a user, the dialog hides the email field and attaches their identity to the report automatically. (Omit resolveUserPath entirely to always-anonymous + ask for an email.)

That's it. The dialog auto-mounts everywhere — press g then f, or open it from code:

const { open } = useFeedback()
open()          // last-used type
open('bug')     // or 'feature' (the Feedback tab)

Environment variables

Only one secret is needed — the GitHub token:

| Variable | Required | What it's for | | --- | --- | --- | | NUXT_GITHUB_TOKEN | Yes | A GitHub token the server uses to create issues (bugs and ideas). Read from runtimeConfignever exposed to the browser. |

Getting the GitHub token — create a fine-grained PAT scoped to only your target repo with Issues: Read and write, then:

# .env (local — git-ignored, never commit a real token)
NUXT_GITHUB_TOKEN=github_pat_xxxxxxxx

In production, set NUXT_GITHUB_TOKEN in your host's secret store (Coolify / Vercel / etc.) and redeploy. (No org-restricted PATs? A classic token with the repo scope works too.)


Options

| Option | Type | Default | Description | | --- | --- | --- | --- | | github.repo | string | — | Required. Target repo for issues, "owner/name". | | shortcut | string | 'g-f' | Keybind in Nuxt UI defineShortcuts syntax. Pick one that doesn't clash with your app's chords. | | github.labels.feature | string | 'enhancement' | Label for feedback issues. (Bugs use bug.) | | resolveUserPath | string | — | Path to your identity hook (see step 3). Omit for always-anonymous. | | resolveAppPath | string | — | Path to a hook mapping a submission to an "app bucket" (used for the app: label). Omit to fall back to context.app. | | onSubmitPath | string | — | Path to a hook run server-side after a report is filed — notifications, logging, tracking. Receives (report, result); a throw is caught and ignored. See below. | | enabled | boolean | true | Turn the whole thing off (e.g. per-environment). |

The GitHub token is never an option — it lives only in runtimeConfig (NUXT_GITHUB_TOKEN) and never reaches the client bundle, responses, or logs.


How it routes

bug      → GitHub issue (label: bug)
           carries type     (crash | visual | data | performance)
           and     severity (critical | blocking | annoying | cosmetic)
feedback → GitHub issue (label: enhancement)

Prefixed label scheme (opt in by setting any github.labels.*Prefix or base): issues get <base> + type:<bug|idea> + app:<bucket>, and bugs also get severity:<level> + category:<kind>.

A report is never silently dropped, and submit failures return a clean error toast (no provider internals leak to the client).

React to submissions (onSubmitPath)

Point onSubmitPath at a server file to run your own code after each report is filed — ping Slack, write to a DB, track it for a "my reports" view. It runs after the GitHub issue is created and never blocks the user's submission (a throw is caught and logged).

// server/feedback-submit.ts
export default async function onSubmit(report, result) {
  // report: { type, message, severity?, category?, user, email?, app, labels, context? }
  // result: { channel: 'github', issue: { number, url } }
  await fetch(process.env.SLACK_WEBHOOK!, {
    method: 'POST',
    body: JSON.stringify({ text: `New ${report.type}: ${result.issue.url}` }),
  })
}

Drop it into a repo with one prompt

Paste this into an AI coding agent (Claude Code, Cursor, …) inside the target Nuxt 4 repo:

Integrate the npm package @floo-one/nuxt-feedback into this Nuxt 4 app.

1. Install it: `pnpm add @floo-one/nuxt-feedback`. It needs @nuxt/ui v4 as a peer —
   confirm this app already uses @nuxt/ui (it should).
2. In nuxt.config.ts: add '@floo-one/nuxt-feedback' to `modules`, and add a `feedback`
   block with:
     - github.repo: the "owner/name" of THIS app's GitHub repo (find it from the git remote)
     - shortcut: 'g-f' — but first grep the codebase for existing `defineShortcuts` chords
       and pick a non-colliding one if g-f is taken
     - resolveUserPath: './server/feedback-user.ts'
3. Create server/feedback-user.ts that default-exports
   `async (event: H3Event) => ({ id, email, name }) | null`. Wire it to THIS app's existing
   auth — find how the app reads its session/user on the server and use that. Return null
   when logged out; it must never throw.
4. Add `NUXT_GITHUB_TOKEN` to .env.example with a comment: server-only, a GitHub token with
   "Issues: write" on the repo. Do NOT put a real token anywhere in the code or config —
   I'll set the real value in the host's secret store.
5. Verify: `nuxt typecheck` (or build) passes, and the dialog opens with the shortcut.
   Report what you changed and what I still need to do (set NUXT_GITHUB_TOKEN).

Hard rule: the GitHub token is a secret. Read it only via runtimeConfig (NUXT_GITHUB_TOKEN);
never a public option, never committed, never in the client bundle.

Host the dashboard (live demo)

The repo ships a Dockerfile that builds the dashboard app — today a self-contained demo site with the module installed on a real page (dialog and API routes fully working), and long-term the dashboard for triaging the issues the module files.

On Coolify: create an application from this repo, pick the Dockerfile build pack (port 3000), and set one env var:

| Variable | Value | | --- | --- | | NUXT_GITHUB_TOKEN | A GitHub token with Issues: write on the repo demo submissions should land in (the dashboard targets floo-one/nuxt-feedback). |

Without the token the site still runs and the dialog opens — submits just fail with an error toast.

Or locally:

docker build -t nuxt-feedback-demo .
docker run -p 3000:3000 -e NUXT_GITHUB_TOKEN=github_pat_xxx nuxt-feedback-demo

Develop this module

pnpm install
pnpm dev          # run the dashboard app locally
pnpm lint && pnpm test && pnpm test:types
pnpm prepack      # build the distributable

License

MIT