feat: add a Keep it free sponsor button to the top nav (#427)

Adds a prominent Keep it free sponsor button to the top nav, linking to https://github.com/sponsors/snapotter-hq. Solid orange pill on desktop (left of the avatar), orange heart icon on mobile. Opens in a new tab with rel=noopener noreferrer, so no referrer or user data leaks, and it adds no passive network activity (offline-mode compatible). Fires an opt-in, property-less sponsor_clicked analytics event. Adds sidebar.sponsor and a11y.sponsorLink across all 21 locales.

Claude-Session: https://claude.ai/code/session_01DnYLLA5z4Uf1GDeEPENVgr
This commit is contained in:
SnapOtter
2026-07-04 08:48:16 +00:00
committed by GitHub
parent 3ae48cc76a
commit 7b04317ed2
25 changed files with 115 additions and 2 deletions
@@ -1,8 +1,10 @@
import { ANALYTICS_EVENTS } from "@snapotter/shared";
import { import {
ChevronLeft, ChevronLeft,
ChevronRight, ChevronRight,
FolderOpen, FolderOpen,
Globe, Globe,
Heart,
HelpCircle, HelpCircle,
LayoutGrid, LayoutGrid,
MessageSquare, MessageSquare,
@@ -128,6 +130,8 @@ export function TopNav({
</button> </button>
)} )}
<SponsorButton isDark={isDark} compact />
<button <button
type="button" type="button"
onClick={onHelpClick} onClick={onHelpClick}
@@ -280,12 +284,58 @@ export function TopNav({
<HelpCircle className="h-4 w-4" /> <HelpCircle className="h-4 w-4" />
</button> </button>
<SponsorButton isDark={isDark} />
{!isMobile && <AvatarDropdown onSettingsClick={onSettingsClick} variant={variant} />} {!isMobile && <AvatarDropdown onSettingsClick={onSettingsClick} variant={variant} />}
</div> </div>
</header> </header>
); );
} }
const SPONSOR_URL = "https://github.com/sponsors/snapotter-hq";
function SponsorButton({ isDark, compact = false }: { isDark: boolean; compact?: boolean }) {
const { t } = useTranslation();
const handleClick = () => {
import("@/lib/analytics").then(({ track }) => {
track(ANALYTICS_EVENTS.SPONSOR_CLICKED);
});
};
if (compact) {
return (
<a
href={SPONSOR_URL}
target="_blank"
rel="noopener noreferrer"
onClick={handleClick}
aria-label={t.a11y.sponsorLink}
title={t.a11y.sponsorLink}
className={cn(
"p-1.5 rounded-md transition-colors text-primary",
isDark ? "hover:bg-[#333]" : "hover:bg-muted",
)}
>
<Heart className="h-4 w-4 fill-current" />
</a>
);
}
return (
<a
href={SPONSOR_URL}
target="_blank"
rel="noopener noreferrer"
onClick={handleClick}
className="ms-1 inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-[#1a1814] transition-opacity hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-1"
>
<Heart className="h-3.5 w-3.5 fill-current" aria-hidden="true" />
{t.sidebar.sponsor}
</a>
);
}
function ThemeToggle({ isDark }: { isDark: boolean }) { function ThemeToggle({ isDark }: { isDark: boolean }) {
const { resolvedTheme, toggleTheme } = useTheme(); const { resolvedTheme, toggleTheme } = useTheme();
return ( return (
+1
View File
@@ -12,6 +12,7 @@ export const ANALYTICS_EVENTS = {
AI_BUNDLE_PROMPTED: "ai_bundle_prompted", AI_BUNDLE_PROMPTED: "ai_bundle_prompted",
BATCH_PROCESSED: "batch_processed", BATCH_PROCESSED: "batch_processed",
FEEDBACK_SUBMITTED: "feedback_submitted", FEEDBACK_SUBMITTED: "feedback_submitted",
SPONSOR_CLICKED: "sponsor_clicked",
} as const; } as const;
export type AnalyticsEvent = (typeof ANALYTICS_EVENTS)[keyof typeof ANALYTICS_EVENTS]; export type AnalyticsEvent = (typeof ANALYTICS_EVENTS)[keyof typeof ANALYTICS_EVENTS];
+2
View File
@@ -3819,6 +3819,7 @@ export const ar: TranslationKeys = {
connectionError: "خطأ في الاتصال", connectionError: "خطأ في الاتصال",
}, },
sidebar: { sidebar: {
sponsor: "أبقِه مجانيًا",
tools: "الأدوات", tools: "الأدوات",
grid: "شبكة", grid: "شبكة",
automate: "أتمتة", automate: "أتمتة",
@@ -3838,6 +3839,7 @@ export const ar: TranslationKeys = {
mobileNavSettings: "الإعدادات", mobileNavSettings: "الإعدادات",
}, },
a11y: { a11y: {
sponsorLink: "ادعم SnapOtter على GitHub Sponsors",
skipToContent: "تخطي إلى المحتوى الرئيسي", skipToContent: "تخطي إلى المحتوى الرئيسي",
openSidebar: "فتح الشريط الجانبي", openSidebar: "فتح الشريط الجانبي",
closeSidebar: "إغلاق الشريط الجانبي", closeSidebar: "إغلاق الشريط الجانبي",
+2
View File
@@ -3866,6 +3866,7 @@ export const de: TranslationKeys = {
connectionError: "Verbindungsfehler", connectionError: "Verbindungsfehler",
}, },
sidebar: { sidebar: {
sponsor: "Kostenlos halten",
tools: "Werkzeuge", tools: "Werkzeuge",
grid: "Raster", grid: "Raster",
automate: "Automatisieren", automate: "Automatisieren",
@@ -3885,6 +3886,7 @@ export const de: TranslationKeys = {
mobileNavSettings: "Einstellungen", mobileNavSettings: "Einstellungen",
}, },
a11y: { a11y: {
sponsorLink: "SnapOtter auf GitHub Sponsors unterstützen",
skipToContent: "Zum Hauptinhalt springen", skipToContent: "Zum Hauptinhalt springen",
openSidebar: "Seitenleiste öffnen", openSidebar: "Seitenleiste öffnen",
closeSidebar: "Seitenleiste schließen", closeSidebar: "Seitenleiste schließen",
+2
View File
@@ -3795,6 +3795,7 @@ export const en = {
automate: "Automate", automate: "Automate",
editor: "Editor", editor: "Editor",
files: "Files", files: "Files",
sponsor: "Keep it free",
help: "Help", help: "Help",
settings: "Settings", settings: "Settings",
}, },
@@ -3870,6 +3871,7 @@ export const en = {
helpDialog: "Help", helpDialog: "Help",
navigationMenu: "Navigation", navigationMenu: "Navigation",
homeLink: "SnapOtter home", homeLink: "SnapOtter home",
sponsorLink: "Support SnapOtter on GitHub Sponsors",
}, },
pipelineTemplates: { pipelineTemplates: {
"web-optimize": { "web-optimize": {
+2
View File
@@ -3844,6 +3844,7 @@ export const es: TranslationKeys = {
connectionError: "Error de conexión", connectionError: "Error de conexión",
}, },
sidebar: { sidebar: {
sponsor: "Mantenlo gratis",
tools: "Herramientas", tools: "Herramientas",
grid: "Cuadrícula", grid: "Cuadrícula",
automate: "Automatizar", automate: "Automatizar",
@@ -3863,6 +3864,7 @@ export const es: TranslationKeys = {
mobileNavSettings: "Configuración", mobileNavSettings: "Configuración",
}, },
a11y: { a11y: {
sponsorLink: "Apoya a SnapOtter en GitHub Sponsors",
skipToContent: "Ir al contenido principal", skipToContent: "Ir al contenido principal",
openSidebar: "Abrir barra lateral", openSidebar: "Abrir barra lateral",
closeSidebar: "Cerrar barra lateral", closeSidebar: "Cerrar barra lateral",
+2
View File
@@ -3868,6 +3868,7 @@ export const fr: TranslationKeys = {
connectionError: "Erreur de connexion", connectionError: "Erreur de connexion",
}, },
sidebar: { sidebar: {
sponsor: "Gardons-le gratuit",
tools: "Outils", tools: "Outils",
grid: "Grille", grid: "Grille",
automate: "Automatiser", automate: "Automatiser",
@@ -3887,6 +3888,7 @@ export const fr: TranslationKeys = {
mobileNavSettings: "Paramètres", mobileNavSettings: "Paramètres",
}, },
a11y: { a11y: {
sponsorLink: "Soutenir SnapOtter sur GitHub Sponsors",
skipToContent: "Aller au contenu principal", skipToContent: "Aller au contenu principal",
openSidebar: "Ouvrir le panneau latéral", openSidebar: "Ouvrir le panneau latéral",
closeSidebar: "Fermer le panneau latéral", closeSidebar: "Fermer le panneau latéral",
+2
View File
@@ -3649,6 +3649,7 @@ export const hi: TranslationKeys = {
connectionError: "कनेक्शन त्रुटि", connectionError: "कनेक्शन त्रुटि",
}, },
sidebar: { sidebar: {
sponsor: "इसे मुफ़्त रखें",
tools: "टूल्स", tools: "टूल्स",
grid: "ग्रिड", grid: "ग्रिड",
automate: "ऑटोमेट", automate: "ऑटोमेट",
@@ -3668,6 +3669,7 @@ export const hi: TranslationKeys = {
mobileNavSettings: "सेटिंग्स", mobileNavSettings: "सेटिंग्स",
}, },
a11y: { a11y: {
sponsorLink: "GitHub Sponsors पर SnapOtter का समर्थन करें",
skipToContent: "मुख्य सामग्री पर जाएं", skipToContent: "मुख्य सामग्री पर जाएं",
openSidebar: "साइडबार खोलें", openSidebar: "साइडबार खोलें",
closeSidebar: "साइडबार बंद करें", closeSidebar: "साइडबार बंद करें",
+2
View File
@@ -3844,6 +3844,7 @@ export const id: TranslationKeys = {
connectionError: "Kesalahan koneksi", connectionError: "Kesalahan koneksi",
}, },
sidebar: { sidebar: {
sponsor: "Jaga tetap gratis",
tools: "Alat", tools: "Alat",
grid: "Kisi", grid: "Kisi",
automate: "Otomasi", automate: "Otomasi",
@@ -3863,6 +3864,7 @@ export const id: TranslationKeys = {
mobileNavSettings: "Pengaturan", mobileNavSettings: "Pengaturan",
}, },
a11y: { a11y: {
sponsorLink: "Dukung SnapOtter di GitHub Sponsors",
skipToContent: "Lewati ke konten utama", skipToContent: "Lewati ke konten utama",
openSidebar: "Buka bilah sisi", openSidebar: "Buka bilah sisi",
closeSidebar: "Tutup bilah sisi", closeSidebar: "Tutup bilah sisi",
+2
View File
@@ -3859,6 +3859,7 @@ export const it: TranslationKeys = {
connectionError: "Errore di connessione", connectionError: "Errore di connessione",
}, },
sidebar: { sidebar: {
sponsor: "Mantienilo gratis",
tools: "Strumenti", tools: "Strumenti",
grid: "Griglia", grid: "Griglia",
automate: "Automatizza", automate: "Automatizza",
@@ -3878,6 +3879,7 @@ export const it: TranslationKeys = {
mobileNavSettings: "Impostazioni", mobileNavSettings: "Impostazioni",
}, },
a11y: { a11y: {
sponsorLink: "Sostieni SnapOtter su GitHub Sponsors",
skipToContent: "Vai al contenuto principale", skipToContent: "Vai al contenuto principale",
openSidebar: "Apri barra laterale", openSidebar: "Apri barra laterale",
closeSidebar: "Chiudi barra laterale", closeSidebar: "Chiudi barra laterale",
+2
View File
@@ -3795,6 +3795,7 @@ export const ja: TranslationKeys = {
connectionError: "接続エラー", connectionError: "接続エラー",
}, },
sidebar: { sidebar: {
sponsor: "無料を守る",
tools: "ツール", tools: "ツール",
grid: "グリッド", grid: "グリッド",
automate: "自動化", automate: "自動化",
@@ -3814,6 +3815,7 @@ export const ja: TranslationKeys = {
mobileNavSettings: "設定", mobileNavSettings: "設定",
}, },
a11y: { a11y: {
sponsorLink: "GitHub Sponsors で SnapOtter を支援する",
skipToContent: "メインコンテンツへスキップ", skipToContent: "メインコンテンツへスキップ",
openSidebar: "サイドバーを開く", openSidebar: "サイドバーを開く",
closeSidebar: "サイドバーを閉じる", closeSidebar: "サイドバーを閉じる",
+2
View File
@@ -3776,6 +3776,7 @@ export const ko: TranslationKeys = {
connectionError: "연결 오류", connectionError: "연결 오류",
}, },
sidebar: { sidebar: {
sponsor: "무료로 유지하기",
tools: "도구", tools: "도구",
grid: "그리드", grid: "그리드",
automate: "자동화", automate: "자동화",
@@ -3795,6 +3796,7 @@ export const ko: TranslationKeys = {
mobileNavSettings: "설정", mobileNavSettings: "설정",
}, },
a11y: { a11y: {
sponsorLink: "GitHub Sponsors에서 SnapOtter 후원하기",
skipToContent: "본문으로 건너뛰기", skipToContent: "본문으로 건너뛰기",
openSidebar: "사이드바 열기", openSidebar: "사이드바 열기",
closeSidebar: "사이드바 닫기", closeSidebar: "사이드바 닫기",
+2
View File
@@ -3853,6 +3853,7 @@ export const nl: TranslationKeys = {
connectionError: "Verbindingsfout", connectionError: "Verbindingsfout",
}, },
sidebar: { sidebar: {
sponsor: "Houd het gratis",
tools: "Tools", tools: "Tools",
grid: "Raster", grid: "Raster",
automate: "Automatiseren", automate: "Automatiseren",
@@ -3872,6 +3873,7 @@ export const nl: TranslationKeys = {
mobileNavSettings: "Instellingen", mobileNavSettings: "Instellingen",
}, },
a11y: { a11y: {
sponsorLink: "Steun SnapOtter op GitHub Sponsors",
skipToContent: "Ga naar hoofdinhoud", skipToContent: "Ga naar hoofdinhoud",
openSidebar: "Zijbalk openen", openSidebar: "Zijbalk openen",
closeSidebar: "Zijbalk sluiten", closeSidebar: "Zijbalk sluiten",
+2
View File
@@ -3859,6 +3859,7 @@ export const pl: TranslationKeys = {
connectionError: "Błąd połączenia", connectionError: "Błąd połączenia",
}, },
sidebar: { sidebar: {
sponsor: "Zachowaj darmowość",
tools: "Narzędzia", tools: "Narzędzia",
grid: "Siatka", grid: "Siatka",
automate: "Automatyzacja", automate: "Automatyzacja",
@@ -3878,6 +3879,7 @@ export const pl: TranslationKeys = {
mobileNavSettings: "Ustawienia", mobileNavSettings: "Ustawienia",
}, },
a11y: { a11y: {
sponsorLink: "Wesprzyj SnapOtter na GitHub Sponsors",
skipToContent: "Przejdź do treści", skipToContent: "Przejdź do treści",
openSidebar: "Otwórz panel boczny", openSidebar: "Otwórz panel boczny",
closeSidebar: "Zamknij panel boczny", closeSidebar: "Zamknij panel boczny",
+2
View File
@@ -3851,6 +3851,7 @@ export const ptBR: TranslationKeys = {
connectionError: "Erro de conexão", connectionError: "Erro de conexão",
}, },
sidebar: { sidebar: {
sponsor: "Mantenha gratuito",
tools: "Ferramentas", tools: "Ferramentas",
grid: "Grade", grid: "Grade",
automate: "Automatizar", automate: "Automatizar",
@@ -3870,6 +3871,7 @@ export const ptBR: TranslationKeys = {
mobileNavSettings: "Configurações", mobileNavSettings: "Configurações",
}, },
a11y: { a11y: {
sponsorLink: "Apoie o SnapOtter no GitHub Sponsors",
skipToContent: "Pular para o conteúdo principal", skipToContent: "Pular para o conteúdo principal",
openSidebar: "Abrir barra lateral", openSidebar: "Abrir barra lateral",
closeSidebar: "Fechar barra lateral", closeSidebar: "Fechar barra lateral",
+2
View File
@@ -3847,6 +3847,7 @@ export const ru: TranslationKeys = {
connectionError: "Ошибка подключения", connectionError: "Ошибка подключения",
}, },
sidebar: { sidebar: {
sponsor: "Пусть будет бесплатным",
tools: "Инструменты", tools: "Инструменты",
grid: "Сетка", grid: "Сетка",
automate: "Автоматизация", automate: "Автоматизация",
@@ -3866,6 +3867,7 @@ export const ru: TranslationKeys = {
mobileNavSettings: "Настройки", mobileNavSettings: "Настройки",
}, },
a11y: { a11y: {
sponsorLink: "Поддержать SnapOtter на GitHub Sponsors",
skipToContent: "Перейти к основному содержимому", skipToContent: "Перейти к основному содержимому",
openSidebar: "Открыть боковую панель", openSidebar: "Открыть боковую панель",
closeSidebar: "Закрыть боковую панель", closeSidebar: "Закрыть боковую панель",
+2
View File
@@ -3840,6 +3840,7 @@ export const sv: TranslationKeys = {
connectionError: "Anslutningsfel", connectionError: "Anslutningsfel",
}, },
sidebar: { sidebar: {
sponsor: "Håll det gratis",
tools: "Verktyg", tools: "Verktyg",
grid: "Rutnät", grid: "Rutnät",
automate: "Automatisera", automate: "Automatisera",
@@ -3859,6 +3860,7 @@ export const sv: TranslationKeys = {
mobileNavSettings: "Inställningar", mobileNavSettings: "Inställningar",
}, },
a11y: { a11y: {
sponsorLink: "Stöd SnapOtter på GitHub Sponsors",
skipToContent: "Hoppa till huvudinnehåll", skipToContent: "Hoppa till huvudinnehåll",
openSidebar: "Öppna sidopanel", openSidebar: "Öppna sidopanel",
closeSidebar: "Stäng sidopanel", closeSidebar: "Stäng sidopanel",
+2
View File
@@ -3799,6 +3799,7 @@ export const th: TranslationKeys = {
connectionError: "ข้อผิดพลาดในการเชื่อมต่อ", connectionError: "ข้อผิดพลาดในการเชื่อมต่อ",
}, },
sidebar: { sidebar: {
sponsor: "ให้ใช้ฟรีต่อไป",
tools: "เครื่องมือ", tools: "เครื่องมือ",
grid: "กริด", grid: "กริด",
automate: "อัตโนมัติ", automate: "อัตโนมัติ",
@@ -3818,6 +3819,7 @@ export const th: TranslationKeys = {
mobileNavSettings: "ตั้งค่า", mobileNavSettings: "ตั้งค่า",
}, },
a11y: { a11y: {
sponsorLink: "สนับสนุน SnapOtter บน GitHub Sponsors",
skipToContent: "ข้ามไปยังเนื้อหาหลัก", skipToContent: "ข้ามไปยังเนื้อหาหลัก",
openSidebar: "เปิดแถบด้านข้าง", openSidebar: "เปิดแถบด้านข้าง",
closeSidebar: "ปิดแถบด้านข้าง", closeSidebar: "ปิดแถบด้านข้าง",
+2
View File
@@ -3851,6 +3851,7 @@ export const tr: TranslationKeys = {
connectionError: "Bağlantı hatası", connectionError: "Bağlantı hatası",
}, },
sidebar: { sidebar: {
sponsor: "Ücretsiz kalsın",
tools: "Araçlar", tools: "Araçlar",
grid: "Izgara", grid: "Izgara",
automate: "Otomatikleştir", automate: "Otomatikleştir",
@@ -3870,6 +3871,7 @@ export const tr: TranslationKeys = {
mobileNavSettings: "Ayarlar", mobileNavSettings: "Ayarlar",
}, },
a11y: { a11y: {
sponsorLink: "SnapOtter'ı GitHub Sponsors'ta destekleyin",
skipToContent: "Ana içeriğe geç", skipToContent: "Ana içeriğe geç",
openSidebar: "Kenar çubuğunu aç", openSidebar: "Kenar çubuğunu aç",
closeSidebar: "Kenar çubuğunu kapat", closeSidebar: "Kenar çubuğunu kapat",
+2
View File
@@ -3848,6 +3848,7 @@ export const uk: TranslationKeys = {
connectionError: "Помилка з'єднання", connectionError: "Помилка з'єднання",
}, },
sidebar: { sidebar: {
sponsor: "Нехай буде безкоштовним",
tools: "Інструменти", tools: "Інструменти",
grid: "Сітка", grid: "Сітка",
automate: "Автоматизація", automate: "Автоматизація",
@@ -3867,6 +3868,7 @@ export const uk: TranslationKeys = {
mobileNavSettings: "Налаштування", mobileNavSettings: "Налаштування",
}, },
a11y: { a11y: {
sponsorLink: "Підтримати SnapOtter на GitHub Sponsors",
skipToContent: "Перейти до основного вмісту", skipToContent: "Перейти до основного вмісту",
openSidebar: "Відкрити бічну панель", openSidebar: "Відкрити бічну панель",
closeSidebar: "Закрити бічну панель", closeSidebar: "Закрити бічну панель",
+2
View File
@@ -3840,6 +3840,7 @@ export const vi: TranslationKeys = {
connectionError: "Lỗi kết nối", connectionError: "Lỗi kết nối",
}, },
sidebar: { sidebar: {
sponsor: "Giữ nó miễn phí",
tools: "Công cụ", tools: "Công cụ",
grid: "Lưới", grid: "Lưới",
automate: "Tự động hóa", automate: "Tự động hóa",
@@ -3859,6 +3860,7 @@ export const vi: TranslationKeys = {
mobileNavSettings: "Cài đặt", mobileNavSettings: "Cài đặt",
}, },
a11y: { a11y: {
sponsorLink: "Ủng hộ SnapOtter trên GitHub Sponsors",
skipToContent: "Chuyển đến nội dung chính", skipToContent: "Chuyển đến nội dung chính",
openSidebar: "Mở thanh bên", openSidebar: "Mở thanh bên",
closeSidebar: "Đóng thanh bên", closeSidebar: "Đóng thanh bên",
+2
View File
@@ -3583,6 +3583,7 @@ export const zhCN: TranslationKeys = {
connectionError: "连接错误", connectionError: "连接错误",
}, },
sidebar: { sidebar: {
sponsor: "保持免费",
tools: "工具", tools: "工具",
grid: "网格", grid: "网格",
automate: "自动化", automate: "自动化",
@@ -3602,6 +3603,7 @@ export const zhCN: TranslationKeys = {
mobileNavSettings: "设置", mobileNavSettings: "设置",
}, },
a11y: { a11y: {
sponsorLink: "在 GitHub Sponsors 上支持 SnapOtter",
skipToContent: "跳到主要内容", skipToContent: "跳到主要内容",
openSidebar: "打开侧边栏", openSidebar: "打开侧边栏",
closeSidebar: "关闭侧边栏", closeSidebar: "关闭侧边栏",
+2
View File
@@ -3583,6 +3583,7 @@ export const zhTW: TranslationKeys = {
connectionError: "連線錯誤", connectionError: "連線錯誤",
}, },
sidebar: { sidebar: {
sponsor: "保持免費",
tools: "工具", tools: "工具",
grid: "格線", grid: "格線",
automate: "自動化", automate: "自動化",
@@ -3602,6 +3603,7 @@ export const zhTW: TranslationKeys = {
mobileNavSettings: "設定", mobileNavSettings: "設定",
}, },
a11y: { a11y: {
sponsorLink: "在 GitHub Sponsors 上支持 SnapOtter",
skipToContent: "跳至主要內容", skipToContent: "跳至主要內容",
openSidebar: "開啟側邊欄", openSidebar: "開啟側邊欄",
closeSidebar: "關閉側邊欄", closeSidebar: "關閉側邊欄",
+19
View File
@@ -0,0 +1,19 @@
import { expect, test } from "./helpers";
const SPONSOR_URL = "https://github.com/sponsors/snapotter-hq";
test.describe("Sponsor button", () => {
// Pin a desktop viewport so the full pill (with visible text) renders,
// not the mobile icon-only form.
test.use({ viewport: { width: 1280, height: 720 } });
test("top nav links to GitHub Sponsors with safe rel", async ({ page }) => {
await page.goto("/");
const link = page.locator(`a[href="${SPONSOR_URL}"]`);
await expect(link).toBeVisible();
await expect(link).toHaveAttribute("target", "_blank");
await expect(link).toHaveAttribute("rel", "noopener noreferrer");
await expect(link).toContainText(/keep it free/i);
});
});
+3 -2
View File
@@ -2,8 +2,8 @@ import { ANALYTICS_EVENTS } from "@snapotter/shared";
import { describe, expect, it } from "vitest"; import { describe, expect, it } from "vitest";
describe("ANALYTICS_EVENTS", () => { describe("ANALYTICS_EVENTS", () => {
it("has exactly 13 event keys", () => { it("has exactly 14 event keys", () => {
expect(Object.keys(ANALYTICS_EVENTS)).toHaveLength(13); expect(Object.keys(ANALYTICS_EVENTS)).toHaveLength(14);
}); });
it("contains the expected keys", () => { it("contains the expected keys", () => {
@@ -20,6 +20,7 @@ describe("ANALYTICS_EVENTS", () => {
expect(ANALYTICS_EVENTS).toHaveProperty("AI_BUNDLE_PROMPTED"); expect(ANALYTICS_EVENTS).toHaveProperty("AI_BUNDLE_PROMPTED");
expect(ANALYTICS_EVENTS).toHaveProperty("BATCH_PROCESSED"); expect(ANALYTICS_EVENTS).toHaveProperty("BATCH_PROCESSED");
expect(ANALYTICS_EVENTS).toHaveProperty("FEEDBACK_SUBMITTED"); expect(ANALYTICS_EVENTS).toHaveProperty("FEEDBACK_SUBMITTED");
expect(ANALYTICS_EVENTS).toHaveProperty("SPONSOR_CLICKED");
}); });
it("all event values are strings", () => { it("all event values are strings", () => {