Knockbox

Install

One script tag, then mark your buttons.

You need a public key, which Knockbox creates for each app in your dashboard. Below, YOUR_PUBLIC_KEY is a placeholder. The key is public by design: it only lets your own site send clicks and emails to your own doors.

1. The snippet

Paste it once, in the <head> (or just before </body>) of every page that has buttons to test.

html
<script src="https://knockbox-flame.vercel.app/w.js" data-app="YOUR_PUBLIC_KEY" defer></script>

Then mark any button or link. The value must match the slug of a door you created in the dashboard:

html
<button data-knockbox="ai-insights">Your feature</button>

Clicking a marked element no longer runs its original action. It opens a popup that says the feature isn't available yet and asks for an email. Elements that appear later (React, route changes) are picked up automatically.

Plain HTML

index.html
<!doctype html>
<html>
  <head>
    <!-- 1. Once per site -->
    <script src="https://knockbox-flame.vercel.app/w.js" data-app="YOUR_PUBLIC_KEY" defer></script>
  </head>
  <body>
    <!-- 2. On every button you want to test -->
    <button data-knockbox="ai-insights">AI insights</button>
  </body>
</html>

React (Vite or Create React App)

Simplest: put the script in index.html and only add the attribute in your components.

index.html + a component
<!-- index.html (Vite) or public/index.html (CRA) -->
<head>
  <script src="https://knockbox-flame.vercel.app/w.js" data-app="YOUR_PUBLIC_KEY" defer></script>
</head>

// Any component. The widget picks the button up even if it renders late.
<button data-knockbox="ai-insights">AI insights</button>

If you can't edit index.html, load it once from a component instead:

useKnockbox.ts
// Alternative: load the script from a component, once.
import { useEffect } from "react";

export function useKnockbox() {
  useEffect(() => {
    if (document.querySelector("script[data-app]")) return;
    const s = document.createElement("script");
    s.src = "https://knockbox-flame.vercel.app/w.js";
    s.defer = true;
    s.dataset.app = "YOUR_PUBLIC_KEY";
    document.head.appendChild(s);
  }, []);
}

// Call useKnockbox() once in your root component (App.tsx).

Next.js (App Router)

app/layout.tsx
// app/layout.tsx (Next.js App Router)
import Script from "next/script";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script
          src="https://knockbox-flame.vercel.app/w.js"
          data-app="YOUR_PUBLIC_KEY"
          strategy="afterInteractive"
        />
      </body>
    </html>
  );
}

// Anywhere in a page or component:
// <button data-knockbox="ai-insights">AI insights</button>

Let your AI do it

Paste this into Lovable, Bolt, v0 or Claude Code. It asks for the smallest possible change: one script tag and some attributes, no new keys and no touching your logic. Replace the two placeholder lines at the end with your own features.

prompt
Add the Knockbox widget to this app. It shows a "not available yet" popup that collects emails when someone clicks a feature that does not exist yet. Do exactly the following and nothing else.

1. Add this script tag ONCE, in the <head> of index.html (or in the root layout; if this is Next.js use next/script with strategy="afterInteractive"). Keep the src and the data-app value exactly as written:
<script src="https://knockbox-flame.vercel.app/w.js" data-app="YOUR_PUBLIC_KEY" defer></script>

2. For each feature listed at the end, find the existing button or link that would open it and add a data-knockbox attribute with the slug, for example:
<button data-knockbox="ai-insights">AI insights</button>
If the element is one of my own components, forward the attribute to the underlying DOM element. Slugs use lowercase letters, numbers and hyphens only.

3. Do NOT change any existing logic: keep onClick handlers, routes, styles, state and API calls as they are. If a feature has no button yet, tell me instead of inventing a page.

4. Do NOT add any API keys, environment variables, packages or backend code. The widget is a single script and needs none. YOUR_PUBLIC_KEY is a placeholder: leave it as is, I will replace it with my public key from the Knockbox dashboard.

5. When you finish, list the files you changed and the slugs you added.

Features to mark (button label -> slug):
- <label> -> <slug>
- <label> -> <slug>

Good to know

  • The widget sets no cookies. It keeps a random visitor id in localStorage.
  • It only reports from the domains you list for the app, and it never breaks your page if our server is unreachable.
  • The popup always says plainly that the feature isn't available yet.