const { Button, Card, Badge, GenerateOrb } = window.TaglyDesignSystem_1a793a; const { ResultsPanel } = window.TaglyResults; const PLATFORMS = ['YouTube', 'TikTok', 'Instagram', 'Facebook', 'LinkedIn', 'X', 'Threads', 'Pinterest', 'Reddit']; const DEFAULT_TRENDING_UPDATED = '27 Jul 2026'; const DEFAULT_TRENDING = { YouTube: ['travel vlog', 'gaming setup', 'study with me', 'morning routine'], TikTok: ['aesthetic room', 'day in my life', 'cooking hack', 'outfit ideas'], Instagram: ['real estate', 'coffee shop', 'skincare routine', 'small business'], Facebook: ['local business', 'community group', 'garage sale', 'family reunion'], LinkedIn: ['career advice', 'remote work', 'personal branding', 'job search tips'], X: ['tech news', 'personal finance', 'startup life', 'current events'], Threads: ['daily thoughts', 'hot takes', 'community updates', 'behind the scenes'], Pinterest: ['home decor', 'recipe ideas', 'wedding inspo', 'outfit boards'], Reddit: ['ask for advice', 'niche communities', 'product reviews', 'discussion threads'] }; const DEFAULT_TRENDING_DETAILED = { YouTube: [['travel vlog', 'up'], ['gaming setup', 'up'], ['study with me', 'steady'], ['morning routine', 'up'], ['ai tools 2026', 'up'], ['home workout', 'steady']], TikTok: [['aesthetic room', 'up'], ['day in my life', 'steady'], ['cooking hack', 'up'], ['outfit ideas', 'steady'], ['get ready with me', 'up'], ['desk setup', 'up']], Instagram: [['real estate', 'steady'], ['coffee shop', 'up'], ['skincare routine', 'up'], ['small business', 'steady'], ['photo dump', 'up'], ['minimal outfits', 'up']], Facebook: [['local business', 'steady'], ['community group', 'up'], ['garage sale', 'steady'], ['family reunion', 'steady'], ['neighborhood events', 'up'], ['home renovation', 'up']], LinkedIn: [['career advice', 'up'], ['remote work', 'steady'], ['personal branding', 'up'], ['job search tips', 'up'], ['ai in the workplace', 'up'], ['leadership lessons', 'steady']], X: [['tech news', 'up'], ['personal finance', 'steady'], ['startup life', 'up'], ['current events', 'up'], ['ai debate', 'up'], ['sports takes', 'steady']], Threads: [['daily thoughts', 'up'], ['hot takes', 'up'], ['community updates', 'steady'], ['behind the scenes', 'up'], ['creator news', 'steady'], ['weekend recap', 'up']], Pinterest: [['home decor', 'up'], ['recipe ideas', 'steady'], ['wedding inspo', 'up'], ['outfit boards', 'up'], ['travel moodboard', 'steady'], ['diy projects', 'up']], Reddit: [['ask for advice', 'up'], ['niche communities', 'steady'], ['product reviews', 'up'], ['discussion threads', 'up'], ['AMA', 'steady'], ['megathread', 'up']], }; /* runtime-loaded from trending-data.json — refreshed periodically; module-level objects hold the DEFAULT fallback until the fetch below resolves. */ let TRENDING = DEFAULT_TRENDING; let TRENDING_DETAILED = DEFAULT_TRENDING_DETAILED; let TRENDING_UPDATED = DEFAULT_TRENDING_UPDATED; const trendingListeners = []; fetch('trending-data.json').then(r => r.json()).then(data => { const flat = {}, detailed = {}; Object.entries(data.terms || {}).forEach(([k, arr]) => { flat[k] = arr.map(([term]) => term); detailed[k] = arr; }); TRENDING = flat; TRENDING_DETAILED = detailed; TRENDING_UPDATED = data.updated ? new Date(data.updated + 'T00:00:00').toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' }) : DEFAULT_TRENDING_UPDATED; trendingListeners.forEach(fn => fn()); }).catch(() => {}); function useTrendingData(){ const [, force] = React.useReducer(x => x + 1, 0); React.useEffect(() => { trendingListeners.push(force); return () => { const i = trendingListeners.indexOf(force); if (i > -1) trendingListeners.splice(i, 1); }; }, []); } const LEARN_GUIDES = [ { t: 'How many tags should you actually use', d: 'YouTube rewards 8–15 precise tags. TikTok and Instagram cap effective reach around 3–5 hero hashtags plus a handful of niche ones — dumping 30 generic tags reads as spam to both viewers and the algorithm. LinkedIn works best with 3–5 topic tags, not hashtag walls.' }, { t: 'Hashtags vs. keywords — different jobs', d: 'Hashtags are discovery hooks inside a platform\u2019s own search and feed. Keywords are what people type into Google or YouTube search before they ever open the app. Tagly generates both because a title needs keywords and a caption needs hashtags — using only one leaves reach on the table.' }, { t: 'Mix broad, niche, and long-tail', d: 'A broad tag (#travel) has huge volume and huge competition. A niche tag (#soloeurotrip) has less volume but a better shot at ranking. Long-tail phrases ("how to plan a solo trip on a budget") are what search engines reward. Tagly\u2019s Hashtags / Keywords / Long-tail tabs mirror this exact hierarchy — use all three, not just the biggest numbers.' }, { t: 'Match tags to the platform, not just the topic', d: 'The same topic needs different tags per platform: TikTok favors trend-tied tags (#fyp), Instagram favors community tags (#instagood), LinkedIn favors professional framing over hashtags at all. Switching the platform toggle before generating re-weights every tag for that platform\u2019s conventions.' }, ]; const PLATFORM_CHEATSHEET = [ { p: 'YouTube', count: '8–15 tags', style: 'Mix of broad + exact-match keywords in tags field; front-load the title with the primary keyword.' }, { p: 'TikTok', count: '3–5 hashtags', style: 'One trend tag (#fyp), one topic tag, one niche tag. Caption keywords matter as much as hashtags.' }, { p: 'Instagram', count: '3–8 hashtags', style: 'Community + niche tags outperform mega-tags. Reels captions should still read like sentences.' }, { p: 'Facebook', count: '1–2 hashtags', style: 'Hashtags barely affect reach — focus on the post text and group targeting instead.' }, { p: 'LinkedIn', count: '3–5 hashtags', style: 'Topic hashtags at the end of the post, framed around industry and role, not virality.' }, { p: 'X', count: '1–2 hashtags', style: 'One trending hashtag max — X rewards concise, discourse-driven text over tag stacking.' }, { p: 'Threads', count: '3–5 hashtags', style: 'Conversational tags; Threads favors reply-driven engagement over reach chasing.' }, { p: 'Pinterest', count: '6–8 hashtags', style: 'Descriptive, keyword-rich tags — Pinterest behaves like a visual search engine.' }, { p: 'Reddit', count: '0–2 keywords', style: 'No hashtags — pick the right subreddit and use keywords naturally in your title.' }, ]; const RECENT_KEY = 'tagly_recent_v1'; const RECENT_MAX = 5; const MAX_TOPIC_LEN = 60; function loadRecent() { try { const l = JSON.parse(localStorage.getItem(RECENT_KEY)); return Array.isArray(l) ? l.slice(0, RECENT_MAX) : []; } catch (e) { return []; } } function saveRecent(list) { try { localStorage.setItem(RECENT_KEY, JSON.stringify(list.slice(0, RECENT_MAX))); } catch (e) {} } /* strip control chars / collapse whitespace / hard cap length so nothing odd reaches the ranking engine or gets rendered back into the page */ function sanitizeTopic(raw) { return (raw || '').replace(/[\u0000-\u001f\u007f<>]/g, '').replace(/\s+/g, ' ').slice(0, MAX_TOPIC_LEN); } function hasContent(topic) { return /[a-z0-9]/i.test(topic); } function Toast({ message }) { if (!message) return null; return (
{message}
); } function ProModal({ onClose, onViewPricing }) { return (
e.stopPropagation()} style={{ width: 400, maxWidth: '100%' }}> Pro

Go Pro

Unlock the full tag set on every generation, CSV/API export, saved history, and an ad-free workspace.

Monthly$3.99/mo
Annual$29/yr
); } function SoonBadge() { return Soon; } function LanguageSwitcher({ lang, onChange }) { const { STRINGS } = window.TaglyI18n; return ( ); } function AppNav({ view, onNavigate, onGoPro, onGoHome, lang, onLangChange, t }) { const tabs = [['generate', t.nav_generate], ['trending', t.nav_trending], ['learn', t.nav_learn], ['pricing', t.nav_pricing]]; return (
# Tagly
); } function TrendingView({ onPick }) { useTrendingData(); const [platform, setPlatform] = React.useState('YouTube'); return (
Curated weekly · updated {TRENDING_UPDATED}

What creators are tagging right now

Pick a topic below to skip typing entirely — it jumps straight into a full ranked tag set for that platform.

{TRENDING_DETAILED[platform].map(([topic, momentum], i) => ( onPick(topic, platform)}>
#{i + 1} on {platform}
{topic}
{momentum === 'up' ? '↑ rising' : '→ steady'}
))}
); } const HOW_STEPS = [ { label: 'Pick a platform', detail: 'Choose YouTube, TikTok, Instagram, Facebook, LinkedIn, X, Threads, Pinterest, or Reddit.' }, { label: 'Type a topic', detail: 'Just a word or two — "travel vlog", "home workout", "small business".' }, { label: 'Get ranked tags', detail: 'Hashtags, keywords, and long-tail phrases appear instantly, grouped by purpose.' }, { label: 'Copy & post', detail: 'Click any tag to copy it, or copy the whole set in one click.' }, ]; function HowItWorksAnimated() { const [step, setStep] = React.useState(0); React.useEffect(() => { const id = setInterval(() => setStep(s => (s + 1) % HOW_STEPS.length), 2400); return () => clearInterval(id); }, []); const demoTags = ['#travelvlog', '#wanderlust', '#solotravel', '#travelgram']; return (
How Tagly works
{HOW_STEPS.map((s, i) => (
setStep(i)} style={{ cursor: 'pointer', display: 'flex', gap: 12, alignItems: 'flex-start', padding: '10px 12px', borderRadius: 'var(--radius-md)', background: step === i ? 'var(--surface-soft)' : 'transparent', transition: 'background 200ms ease' }}> {i + 1}
{s.label}
{step === i &&
{s.detail}
}
))}
{step === 0 && (
{['YouTube', 'TikTok', 'Instagram', 'X'].map((p, i) => ( {p} ))}
)} {step === 1 && (
travel vlog
)} {step === 2 && (
{demoTags.map((tag, i) => ( {tag} ))}
)} {step === 3 && (
Copied 4 tags!
)}
); } function LearnView({ onGenerate }) { return (
Tagging strategy, not filler

Get more from every tag set

Short, practical guides on why Tagly is organized the way it is — and how to use the results.

{LEARN_GUIDES.map((g, i) => (
{g.t}
{g.d}
))}
Platform cheat-sheet
Platform
Tag count
Style
{PLATFORM_CHEATSHEET.map((row, i) => (
{row.p}
{row.count}
{row.style}
))}
); } function FooterLink({ label, soon, onClick }) { if (soon) return ; return ; } function ExtensionView({ onGenerate, onDownload }) { return (
Chrome extension · beta

Tagly, one click from any tab.

Same ranking engine as the web app, in a popup — generate and copy tags without leaving YouTube Studio, TikTok, or Instagram.

Install it (not yet on the Chrome Web Store)
  1. Download the extension package below and unzip it.
  2. Open chrome://extensions and turn on Developer mode (top right).
  3. Click Load unpacked and select the unzipped chrome-extension folder.
  4. Pin Tagly from the extensions toolbar icon — it's ready.
); } function EmailCapture({ flashToast }) { const [email, setEmail] = React.useState(''); const [sent, setSent] = React.useState(false); async function submit(e) { e.preventDefault(); if (!/^\S+@\S+\.\S+$/.test(email)) { flashToast('Enter a valid email'); return; } try { const res = await fetch('/api/subscribe', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }) }); if (!res.ok) throw new Error(); setSent(true); } catch (e2) { flashToast('Could not save — needs the deployed Node server'); } } if (sent) return
You're on the list — thanks!
; return (
setEmail(e.target.value)} placeholder="you@email.com" aria-label="Email for launch updates" style={{ flex: 1, minWidth: 0, height: 36, borderRadius: 'var(--radius-full)', border: '1px solid var(--border-default)', padding: '0 14px', fontSize: 13, fontFamily: 'var(--font-sans)' }} />
); } function ProductHuntBadge() { return (
Tagly

Tagly

Optimized hashtags & keywords, instantly

Check it out on Product Hunt →
); } function ContactView({ flashToast }) { const [form, setForm] = React.useState({ name: '', email: '', message: '' }); const [sent, setSent] = React.useState(false); function update(k, v) { setForm(f => ({ ...f, [k]: v })); } async function submit(e) { e.preventDefault(); if (!form.name || !/^\S+@\S+\.\S+$/.test(form.email) || !form.message) { flashToast('Fill in all fields with a valid email'); return; } try { const res = await fetch('/api/contact', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(form) }); if (!res.ok) throw new Error(); setSent(true); } catch (e2) { window.location.href = `mailto:contactus@tagly.click?subject=${encodeURIComponent('Message from ' + form.name)}&body=${encodeURIComponent(form.message + '\n\n' + form.email)}`; } } return (
Get in touch

Contact Tagly

Questions, feedback, or partnership requests — reach us directly at contactus@tagly.click, or use the form below.

{sent ? (
Message sent
We'll get back to you at {form.email}.
) : (
update('name', e.target.value)} placeholder="Your name" aria-label="Your name" style={{ height: 42, borderRadius: 'var(--radius-md)', border: '1px solid var(--border-default)', padding: '0 14px', fontSize: 14, fontFamily: 'var(--font-sans)' }} /> update('email', e.target.value)} placeholder="you@email.com" aria-label="Your email" style={{ height: 42, borderRadius: 'var(--radius-md)', border: '1px solid var(--border-default)', padding: '0 14px', fontSize: 14, fontFamily: 'var(--font-sans)' }} />