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
| Option | Default | Description |
|---|---|---|
| slug | required | Your ReleaseNoteKit project slug. |
| position | "bottom-right" | One of bottom-right, bottom-left, top-right, top-left. |
| subscribe | true | Show the email subscribe form in the panel. Set false if you collect subscribers somewhere else. |
| baseUrl | auto | Override 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.