type Platform = "TikTok" | "Instagram" | "YouTube Shorts" | "X" | "Universal"; type HashtagDatabase = { topics: Record; platforms: Record; intent: string[]; aliases?: Record; }; type Search = { topic: string; platform: Platform; count: number; createdAt: number }; declare const React: typeof import("react"); declare const ReactDOM: typeof import("react-dom/client"); const { useEffect, useMemo, useState } = React; const HISTORY_KEY = "vyroclips-hashtag-history"; const PLATFORMS: Platform[] = ["TikTok", "Instagram", "YouTube Shorts", "X", "Universal"]; const COUNTS = [10, 20, 30, 50]; const cleanTag = (value: string) => value.toLowerCase().replace(/[^a-z0-9]/g, ""); const shuffled = (items: T[]) => { const copy = [...items]; for (let i = copy.length - 1; i > 0; i -= 1) { const j = Math.floor(Math.random() * (i + 1)); [copy[i], copy[j]] = [copy[j], copy[i]]; } return copy; }; function matchedCategories(topic: string, db: HashtagDatabase): string[] { const phrase = cleanTag(topic); const words = topic.toLowerCase().split(/[^a-z0-9]+/).map(cleanTag).filter(word => word.length > 1); return Object.keys(db.topics).filter(category => { const categoryKey = cleanTag(category); const aliases = (db.aliases?.[category] ?? []).map(cleanTag); const keywords = [categoryKey, ...aliases]; return keywords.some(keyword => keyword === phrase || words.includes(keyword)); }); } function topicVariants(topic: string, intents: string[]): string[] { const phrase = cleanTag(topic); const words = topic.toLowerCase().split(/[^a-z0-9]+/).map(cleanTag).filter(word => word.length > 2); return [ phrase, ...words, ...intents.map(intent => `${phrase}${cleanTag(intent)}`), `${phrase}community`, `${phrase}content`, `${phrase}video`, `${phrase}news`, `${phrase}tips`, `${phrase}ideas`, `${phrase}guide`, `${phrase}explained`, `daily${phrase}`, `${phrase}daily`, `${phrase}life`, `${phrase}lover`, `${phrase}talk`, `${phrase}updates`, `${phrase}facts`, `${phrase}basics`, `${phrase}101`, `${phrase}trends`, `${phrase}strategy`, `${phrase}inspiration`, `${phrase}tutorial`, `${phrase}beginners`, `${phrase}expert`, `${phrase}world`, `best${phrase}`, `top${phrase}`, `learn${phrase}`, `discover${phrase}`, `${phrase}hacks`, `${phrase}lessons`, `${phrase}resources`, `${phrase}stories`, `${phrase}review`, `${phrase}reviews`, `${phrase}recommendations`, `${phrase}insights`, `${phrase}knowledge`, `${phrase}education`, `${phrase}questions`, `${phrase}answers`, `${phrase}howto`, `${phrase}deepdive`, `${phrase}spotlight`, `${phrase}forbeginners`, `${phrase}professionals`, `${phrase}enthusiast`, `${phrase}fans`, `${phrase}online`, `${phrase}today`, `${phrase}weekly`, `${phrase}update`, `${phrase}discussion`, `${phrase}explore`, `${phrase}focus`, `${phrase}skills`, `${phrase}goals` ]; } function generateHashtags(topic: string, platform: Platform, count: number, db: HashtagDatabase): string[] { const phrase = cleanTag(topic); const categories = matchedCategories(topic, db); const categoryTags = categories.flatMap(category => db.topics[category]); const derivedTags = topicVariants(topic, db.intent); // Make platform signals topic-specific instead of adding broad filler such as // #tiktokcreator or #trending. const platformTags: Record = { "TikTok": [`${phrase}tok`, `${phrase}tiktok`], "Instagram": [`${phrase}reels`, `${phrase}instagram`], "YouTube Shorts": [`${phrase}shorts`, `${phrase}youtube`], "X": [`${phrase}x`, `${phrase}twitter`], "Universal": [] }; const randomizedCategoryTags = shuffled(categoryTags); const pool = [ phrase, ...randomizedCategoryTags.slice(0, 8), ...platformTags[platform], ...randomizedCategoryTags.slice(8), ...derivedTags ]; const unique = [...new Set(pool.map(cleanTag).filter(Boolean))]; return unique.slice(0, count).map(tag => `#${tag}`); } function FieldLabel({ children }: React.PropsWithChildren) { return ; } function History({ items, onSelect }: { items: Search[]; onSelect: (item: Search) => void }) { if (!items.length) return null; return ( ); } function Results({ tags, onShuffle }: { tags: string[]; onShuffle: () => void }) { const [copied, setCopied] = useState(null); const copy = async (value: string, label: string) => { await navigator.clipboard.writeText(value); setCopied(label); window.setTimeout(() => setCopied(null), 1600); }; if (!tags.length) { return (
#

Your hashtags will appear here

Enter a topic and choose a platform. We’ll mix focused, discovery, and platform-native tags.

); } return (

Ready to post

{tags.length} unique hashtags

{tags.map(tag => ( ))}

Tip: tap any hashtag to copy it. Review your platform’s current hashtag guidance before publishing.

); } function HashtagGenerator() { const [db, setDb] = useState(null); const [topic, setTopic] = useState(""); const [platform, setPlatform] = useState("TikTok"); const [count, setCount] = useState(20); const [tags, setTags] = useState([]); const [error, setError] = useState(""); const [history, setHistory] = useState(() => { try { return JSON.parse(localStorage.getItem(HISTORY_KEY) ?? "[]"); } catch { return []; } }); useEffect(() => { fetch("/static/hashtags.json") .then(response => response.ok ? response.json() : Promise.reject(new Error("Database unavailable"))) .then(setDb) .catch(() => setError("The local hashtag library could not be loaded. Please refresh and try again.")); }, []); const canGenerate = useMemo(() => topic.trim().length >= 2 && Boolean(db), [topic, db]); const submit = (event?: React.FormEvent) => { event?.preventDefault(); if (!canGenerate || !db) { setError("Enter at least two characters for your topic."); return; } setError(""); setTags(generateHashtags(topic.trim(), platform, count, db)); const next = [{ topic: topic.trim(), platform, count, createdAt: Date.now() }, ...history.filter(item => !(item.topic.toLowerCase() === topic.trim().toLowerCase() && item.platform === platform))].slice(0, 10); setHistory(next); localStorage.setItem(HISTORY_KEY, JSON.stringify(next)); }; const selectHistory = (item: Search) => { setTopic(item.topic); setPlatform(item.platform); setCount(item.count); if (db) setTags(generateHashtags(item.topic, item.platform, item.count, db)); }; return (
Build your set

What is your post about?

Topic setTopic(event.target.value)} placeholder="e.g. podcast marketing" maxLength={80} autoFocus className="generator-input w-full rounded-2xl border border-gray-200 bg-white px-4 py-3.5 text-gray-900 outline-none transition placeholder:text-gray-400 focus:border-cyan-400 focus:ring-4 focus:ring-cyan-100" />
{["fitness", "small business", "travel", "AI tools"].map(example => )}
Platform
Number of hashtags
{error &&

{error}

}
setTags(shuffled(tags))} />
); } ReactDOM.createRoot(document.getElementById("hashtag-generator-root")!).render();