RReleaseNoteKit
In-app widget

One script tag. A “What's new” bubble on every page.

Your customers see the same hosted ReleaseNoteKit page, but as a floating bubble inside your app — with an unread badge that disappears once they've seen the latest release. No subscription. Included with every ReleaseNoteKit project.

Install

Paste this just before </body> on any page where you want the bubble. Replace your-project-slug with your published ReleaseNoteKit slug.

HTML snippet
<script src="https://releasenotekit.toolu.dev/widget.js" async></script>
<script>
  window.addEventListener("load", function () {
    releasenotekit.init({ slug: "your-project-slug" });
  });
</script>

Options

OptionDefaultDescription
slugrequiredYour ReleaseNoteKit project slug.
position"bottom-right"One of bottom-right, bottom-left, top-right, top-left.
subscribetrueShow the email subscribe form in the panel. Set false if you collect subscribers somewhere else.
baseUrlautoOverride only if you self-host the widget script. Detected from the script tag src by default.

How it works

  • The script fetches /p/<slug>/feed.json — the 10 most recent published releases.
  • Renders inside a Shadow DOM, so your site's CSS can't leak in.
  • Tracks the last release the visitor opened in localStorage — the unread badge clears once they open the panel.
  • Visitors can subscribe by email — double opt-in confirm, RFC 8058 one-click unsubscribe in the email headers. Subscribers feed into your dashboard for release blasts.
  • ~15 KB. Zero dependencies. Same brand color and watermark settings as your hosted page.

Framework snippets

The script tag works inside any framework — these snippets show the idiomatic mount point.

React (Vite, CRA)
import { useEffect } from "react";

export function ReleaseNoteKitWidget() {
  useEffect(() => {
    const s = document.createElement("script");
    s.src = "https://releasenotekit.toolu.dev/widget.js";
    s.async = true;
    s.onload = () => (window).releasenotekit?.init({ slug: "your-project-slug" });
    document.body.appendChild(s);
    return () => { s.remove(); };
  }, []);
  return null;
}
Next.js (App Router)
// app/layout.tsx
import Script from "next/script";

export default function Layout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script src="https://releasenotekit.toolu.dev/widget.js" strategy="afterInteractive" />
        <Script id="cl-init" strategy="afterInteractive">{`
          window.addEventListener("load", () => {
            window.releasenotekit?.init({ slug: "your-project-slug" });
          });
        `}</Script>
      </body>
    </html>
  );
}
Vue 3 (Composition API)
<script setup lang="ts">
import { onMounted } from "vue";

onMounted(() => {
  const s = document.createElement("script");
  s.src = "https://releasenotekit.toolu.dev/widget.js";
  s.async = true;
  s.onload = () => (window as any).releasenotekit?.init({ slug: "your-project-slug" });
  document.body.appendChild(s);
});
</script>

<template></template>
Plain HTML
<!-- Just before </body> on any page -->
<script src="https://releasenotekit.toolu.dev/widget.js" async></script>
<script>
  window.addEventListener("load", function () {
    releasenotekit.init({ slug: "your-project-slug" });
  });
</script>

API surface

Want to build your own UI? Hit /p/<slug>/feed.json — CORS-enabled JSON of the 10 latest published releases. The same endpoint powers the bubble.

For email signups without the bubble, POST /api/p/<slug>/subscribe with { email: "..." } — also CORS-enabled.