Meta Tag Generator 2025

Complete SEO meta tag generator with AI assistance. Create optimized meta titles, descriptions, Open Graph tags, Twitter Cards, and Schema markup with real-time preview and character validation.

πŸ” Search Engine Results Preview

Kichwa cha Ukurasa Wako Kitaonekana Hapa
https://example.com/page
Your meta description will appear here to give users a preview of your page content.

πŸ“± Mobile Preview

Your Page Title...
https://example.com/page
Your meta description...

πŸ“˜ Open Graph (Facebook, LinkedIn)

🐦 Twitter Cards

πŸ“˜ Facebook Preview

Image Preview (1200x630px)
Kichwa Chako cha OG
EXAMPLE.COM
Your OG description will appear here.

🐦 Twitter Preview

Picha ya Kadi ya Twitter
Kichwa Chako cha Twitter
Your Twitter description.
@yourhandle

πŸ“Š Schema Markup Generator

πŸ“Š Schema Preview

Onyesho la Matokeo Tajiri
Chagua aina ya schema na jaza sehemu kuona onyesho

πŸ” Schema Validation

Jaribu msimbo wako wa schema na zana hizi rasmi

⚑ Bulk Meta Tag Generation

Upload a CSV file with your page data to generate meta tags for multiple pages at once.

πŸ“€ Upload CSV File

Required CSV columns:
β€’ title (page title)
β€’ description (meta description)
β€’ url (page URL)
β€’ keywords (optional)
β€’ author (optional)

πŸ“Š Bulk Options

πŸš€ Quick Start Templates

πŸ“ Blog Post
Imeboreshwa kwa makala za blogu na masoko ya maudhui
πŸ›οΈ Product Page
E-commerce product with reviews and pricing
πŸ’Ό Service Page
Ukurasa wa huduma au biashara ya kitaalamu
πŸ“ Local Business
Biashara ya mtaa na mahali na saa
🎟️ Event Page
Event with date, time, and location
πŸ“š How-To Guide
Step-by-step tutorial or guide

✨ Smart Nation's Core Infrastructure: WIA Code ✨

Drone・Robot delivery, autonomous driving, emergency rescue and more - Experience the future in 30 days, completely free for your nation!

Jifunze Zaidi Kuhusu Msimbo WIA

πŸ€– Chagua Msaidizi Wako wa AI

πŸ’¬ ChatGPT
Most versatile β€’ Best for general meta tag optimization
🧠 Claude
Best reasoning β€’ Perfect for SEO analysis and optimization
✨ Gemini BURE
Free daily limits β€’ Built-in SEO chat assistant
`; document.getElementById('schema-output').textContent = schemaOutput; // Generate complete output generateAllFormats(); // Show results document.getElementById('resultContainer').style.display = 'block'; trackEvent('schema_generated', { type: schemaType }); showNotification('Schema markup generated successfully!', 'success'); } function generateAllFormats() { const htmlOutput = document.getElementById('html-output').textContent; const ogOutput = document.getElementById('og-output').textContent; const twitterOutput = document.getElementById('twitter-output').textContent; const schemaOutput = document.getElementById('schema-output').textContent; let completeOutput = ` \n\n\n \n \n\n`; if (htmlOutput && htmlOutput.trim() !== '') { completeOutput += ` ${htmlOutput.replace(/\n/g, '\n ')}\n`; } if (ogOutput && ogOutput.trim() !== '') { completeOutput += ` ${ogOutput.replace(/\n/g, '\n ')}\n`; } if (twitterOutput && twitterOutput.trim() !== '') { completeOutput += ` ${twitterOutput.replace(/\n/g, '\n ')}\n`; } if (schemaOutput && schemaOutput.trim() !== '') { completeOutput += ` ${schemaOutput.replace(/\n/g, '\n ')}\n`; } completeOutput += `\n\n \n \n`; document.getElementById('all-output').textContent = completeOutput; } // ========== BULK GENERATION ========== function handleCSVUpload(event) { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(e) { const csv = e.target.result; parseBulkCSV(csv); }; reader.readAsText(file); } function parseBulkCSV(csv) { const lines = csv.split('\n'); const headers = lines[0].split(',').map(h => h.trim().toLowerCase()); // Validate required columns const requiredColumns = ['title', 'description', 'url']; const missingColumns = requiredColumns.filter(col => !headers.includes(col)); if (missingColumns.length > 0) { showNotification(`Missing required columns: ${missingColumns.join(', ')}`, 'error'); return; } bulkData = []; for (let i = 1; i < lines.length; i++) { const line = lines[i].trim(); if (!line) continue; const values = parseCSVLine(line); if (values.length < headers.length) continue; const row = {}; headers.forEach((header, index) => { row[header] = values[index] || ''; }); bulkData.push(row); } if (bulkData.length === 0) { showNotification('No valid data found in CSV file', 'error'); return; } document.getElementById('bulkGenerateBtn').disabled = false; showNotification(`Loaded ${bulkData.length} rows from CSV`, 'success'); } function parseCSVLine(line) { const result = []; let current = ''; let inQuotes = false; for (let i = 0; i < line.length; i++) { const char = line[i]; if (char === '"') { inQuotes = !inQuotes; } else if (char === ',' && !inQuotes) { result.push(current.trim()); current = ''; } else { current += char; } } result.push(current.trim()); return result; } function processBulkGeneration() { if (bulkData.length === 0) { showNotification('Please upload a CSV file first', 'error'); return; } const siteName = document.getElementById('bulkSiteName').value.trim(); const defaultImage = document.getElementById('bulkOgImage').value.trim(); const schemaType = document.getElementById('bulkSchemaType').value; bulkResults = []; // Show progress document.getElementById('bulk-results').style.display = 'block'; document.getElementById('progress-text').textContent = 'Processing...'; let processed = 0; bulkData.forEach((row, index) => { setTimeout(() => { const result = generateMetaForRow(row, siteName, defaultImage, schemaType); bulkResults.push(result); processed++; const progress = (processed / bulkData.length) * 100; document.getElementById('progress-bar').style.width = progress + '%'; document.getElementById('progress-text').textContent = `Processed ${processed} of ${bulkData.length} pages`; if (processed === bulkData.length) { document.getElementById('downloadBtn').style.display = 'block'; showNotification('Bulk generation completed!', 'success'); trackEvent('bulk_generation_completed', { count: bulkData.length }); } }, index * 100); // Stagger processing for better UX }); } function generateMetaForRow(row, siteName, defaultImage, schemaType) { const title = row.title || ''; const description = row.description || ''; const url = row.url || ''; const keywords = row.keywords || ''; const author = row.author || ''; const image = row.image || defaultImage; let metaTags = ''; // Basic meta tags metaTags += `${escapeHtml(title)}\n`; metaTags += `\n`; if (keywords) { metaTags += `\n`; } if (author) { metaTags += `\n`; } metaTags += `\n\n`; // Open Graph metaTags += `\n`; metaTags += `\n`; metaTags += `\n`; metaTags += `\n`; if (image) { metaTags += `\n`; } if (siteName) { metaTags += `\n`; } metaTags += `\n`; // Twitter Cards metaTags += `\n`; metaTags += `\n`; metaTags += `\n`; if (image) { metaTags += `\n`; } // Schema markup if (schemaType !== 'none') { const schema = { "@context": "https://schema.org", "@type": schemaType, "name": title, "description": description, "url": url }; if (image) { schema.image = image; } if (author) { schema.author = { "@type": "Mtu", "name": author }; } metaTags += `\n\n`; } return { url: url, title: title, description: description, metaTags: metaTags }; } function downloadBulkResults() { if (bulkResults.length === 0) { showNotification('No results to download', 'error'); return; } let csvContent = 'URL,Title,Description,MetaTags\n'; bulkResults.forEach(result => { const metaTagsEscaped = result.metaTags.replace(/"/g, '""'); csvContent += `"${result.url}","${result.title}","${result.description}","${metaTagsEscaped}"\n`; }); const blob = new Blob([csvContent], { type: 'text/csv' }); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'meta-tags-results.csv'; a.click(); window.URL.revokeObjectURL(url); trackEvent('bulk_results_downloaded'); } function downloadSampleCSV() { const sampleData = `title,description,url,keywords,author "Best SEO Tips for 2025","Learn the latest SEO strategies and techniques to improve your website rankings in 2025","https://example.com/seo-tips-2025","SEO, tips, 2025, rankings","John Doe" "Meta Tag Generator Guide","Complete guide to generating optimized meta tags for better search engine visibility","https://example.com/meta-tag-guide","meta tags, SEO, optimization","Jane Smith" "Schema Markup Tutorial","Step-by-step tutorial on implementing schema markup for rich snippets","https://example.com/schema-tutorial","schema markup, rich snippets, structured data","Bob Johnson"`; const blob = new Blob([sampleData], { type: 'text/csv' }); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'meta-tags-sample.csv'; a.click(); window.URL.revokeObjectURL(url); } // ========== SAMPLE TEMPLATES ========== function useSample(sampleType) { const samples = { 'blog': { title: 'Mwongozo Kamili wa Lebo za Meta 2025: Mbinu Bora za SEO', description: 'Learn how to create optimized meta tags that improve search rankings and click-through rates. Includes examples, tools, and 2025 best practices for better SEO.', keywords: 'meta tags, SEO, search optimization, SERP, click-through rates', url: 'https://yoursite.com/meta-tags-guide-2025', author: 'SEO Expert', ogTitle: 'Complete Guide to Meta Tags in 2025', ogDescription: 'Master meta tag optimization with our comprehensive 2025 guide. Boost your search rankings and CTR with proven strategies.', ogImage: 'https://yoursite.com/images/meta-tags-guide.jpg', siteName: 'Your SEO Blog', twitterCardType: 'summary_large_image', twitterSite: '@yourseosite', schemaType: 'Blog Posting' }, 'product': { title: 'Vichwa vya Simu Bila Waya vya Premium - Vizuia Kelele | Duka Lako', description: 'Premium wireless headphones with active noise cancelling, 30-hour battery life, and superior sound quality. Free shipping and 2-year warranty included.', keywords: 'wireless headphones, noise cancelling, premium audio, bluetooth headphones', url: 'https://yourstore.com/premium-wireless-headphones', author: 'YourStore Team', ogTitle: 'Premium Wireless Headphones - Noise Cancelling', ogDescription: 'Experience superior sound with our premium wireless headphones. Active noise cancelling, 30-hour battery, free shipping.', ogImage: 'https://yourstore.com/images/headphones-hero.jpg', siteName: 'YourStore', twitterCardType: 'summary_large_image', twitterSite: '@yourstore', schemaType: 'Bidhaa' }, 'service': { title: 'Huduma za SEO za Kitaalamu - Boresha Nafasi Yako | Wakala wa Dijitali', description: 'Professional SEO services that deliver results. Increase organic traffic, improve search rankings, and grow your business with our proven strategies.', keywords: 'SEO services, search engine optimization, digital marketing, organic traffic', url: 'https://agency.com/seo-services', author: 'Digital Marketing Team', ogTitle: 'Professional SEO Services - Boost Your Rankings', ogDescription: 'Get professional SEO services that deliver real results. Increase traffic and rankings with our proven optimization strategies.', ogImage: 'https://agency.com/images/seo-services.jpg', siteName: 'Digital Agency', twitterCardType: 'summary_large_image', twitterSite: '@digitalagency', schemaType: 'Ukurasa wa Tovuti' }, 'local': { title: 'Mgahawa Bora wa Piza Mjini | Mario's's Pizzeria', description: 'Authentic Italian pizza made fresh daily. Located in downtown, open 7 days a week. Order online for delivery or visit our cozy restaurant.', keywords: 'pizza restaurant, Italian food, downtown dining, pizza delivery', url: 'https://mariospizza.com', author: 'Mario\'s Pizzeria', ogTitle: 'Best Pizza Restaurant in Downtown', ogDescription: 'Authentic Italian pizza made fresh daily. Downtown location, open 7 days. Order online for delivery!', ogImage: 'https://mariospizza.com/images/pizza-hero.jpg', siteName: 'Mario\'s Pizzeria', twitterCardType: 'summary_large_image', twitterSite: '@mariospizza', schemaType: 'Biashara ya Mtaa' }, 'event': { title: 'Mkutano wa Masoko ya Dijitali 2025 - Jifunze kutoka kwa Wataalamu', description: 'Join 500+ marketers at the Digital Marketing Summit 2025. Two days of expert sessions, networking, and latest industry insights. Register now!', keywords: 'digital marketing summit, marketing conference, industry experts, networking', url: 'https://marketingsummit.com/2025', author: 'Summit Organizers', ogTitle: 'Digital Marketing Summit 2025', ogDescription: 'Join 500+ marketers for two days of expert sessions and networking. Learn the latest digital marketing strategies and trends.', ogImage: 'https://marketingsummit.com/images/summit-2025.jpg', siteName: 'Marketing Summit', twitterCardType: 'summary_large_image', twitterSite: '@marketingsummit', schemaType: 'Tukio' }, 'howto': { title: 'Jinsi ya Kuboresha Lebo za Meta kwa Nafasi Bora za SEO', description: 'Step-by-step guide to optimizing meta tags for improved search engine rankings. Learn title tag best practices, meta description writing, and more.', keywords: 'meta tag optimization, SEO tutorial, search rankings, title tags', url: 'https://seoguide.com/optimize-meta-tags', author: 'SEO Tutorial Team', ogTitle: 'How to Optimize Meta Tags for Better SEO', ogDescription: 'Complete step-by-step guide to meta tag optimization. Improve your search rankings with proven techniques and best practices.', ogImage: 'https://seoguide.com/images/meta-tags-tutorial.jpg', siteName: 'SEO Guide', twitterCardType: 'summary_large_image', twitterSite: '@seoguide', schemaType: 'How To' } }; const sample = samples[sampleType]; if (!sample) return; // Fill basic fields document.getElementById('pageTitle').value = sample.title; document.getElementById('metaDescription').value = sample.description; document.getElementById('keywords').value = sample.keywords; document.getElementById('pageUrl').value = sample.url; document.getElementById('author').value = sample.author; // Fill social media fields if they exist if (document.getElementById('ogTitle')) { document.getElementById('ogTitle').value = sample.ogTitle; document.getElementById('ogDescription').value = sample.ogDescription; document.getElementById('ogImage').value = sample.ogImage; document.getElementById('siteName').value = sample.siteName; document.getElementById('twitterCardType').value = sample.twitterCardType; document.getElementById('twitterSite').value = sample.twitterSite; } // Update schema type if in schema tab if (document.getElementById('schemaType')) { document.getElementById('schemaType').value = sample.schemaType; updateSchemaFields(); } // Update character counts and previews updateCharCount('pageTitle', 'title-count', 60, 100); updateCharCount('metaDescription', 'desc-count', 160, 300); updatePreviews(); // Smooth scroll to action button document.querySelector('.btn').scrollIntoView({ behavior: 'smooth', block: 'center' }); showNotification(`${sampleType.charAt(0).toUpperCase() + sampleType.slice(1)} template loaded!`, 'success'); } // ========== UTILITY FUNCTIONS ========== function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } // Copy to clipboard function copyToClipboard(elementId) { const element = document.getElementById(elementId); const text = element.textContent; navigator.clipboard.writeText(text).then(() => { showNotification('Copied to clipboard!', 'success'); }).catch(() => { // Fallback for older browsers const textArea = document.createElement('textarea'); textArea.value = text; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); showNotification('Copied to clipboard!', 'success'); }); } // Show error function showError(elementId, message) { const errorElement = document.getElementById(elementId); if (errorElement) { errorElement.textContent = message; } } // Clear errors function clearErrors() { document.querySelectorAll('.error').forEach(el => el.textContent = ''); } // Show notification toast function showNotification(message, type = 'success') { const toast = document.createElement('div'); toast.className = `toast ${type}`; toast.textContent = message; document.body.appendChild(toast); setTimeout(() => { toast.remove(); }, 3000); } // Analytics tracking function trackEvent(eventName, data = {}) { if (typeof gtag !== 'undefined') { gtag('event', eventName, { 'event_category': TOOL_CONFIG.category, 'event_label': TOOL_CONFIG.name, ...data }); } } // ========== AI ASSISTANT FUNCTIONS ========== // AI λͺ¨λ‹¬ μ—΄κΈ° function openAIModal() { const modal = document.getElementById('aiModal'); modal.classList.add('show'); // ν˜„μž¬ μƒνƒœμ— 따라 μ μ ˆν•œ ν™”λ©΄ ν‘œμ‹œ if (aiModalState.apiKey && aiModalState.currentView === 'gemini') { showGeminiChat(); } else { showAISelector(); } updateAPIKeyStatus(); } // AI λͺ¨λ‹¬ λ‹«κΈ° function closeAIModal() { const modal = document.getElementById('aiModal'); modal.classList.remove('show'); // 300ms ν›„ μƒνƒœ 리셋 (μ• λ‹ˆλ©”μ΄μ…˜ μ™„λ£Œ ν›„) setTimeout(() => { aiModalState.currentView = 'selector'; showAISelector(); }, 300); } // AI 선택 ν™”λ©΄ ν‘œμ‹œ function showAISelector() { document.getElementById('aiModalTitle').textContent = 'Chagua Msaidizi Wako wa AI'; document.getElementById('aiSelector').style.display = 'flex'; document.getElementById('geminiChat').style.display = 'none'; document.getElementById('apiKeySetup').style.display = 'none'; aiModalState.currentView = 'selector'; } // Gemini μ±„νŒ… ν™”λ©΄ ν‘œμ‹œ function showGeminiChat() { document.getElementById('aiModalTitle').innerHTML = '✨ Gemini AI Assistant'; document.getElementById('aiSelector').style.display = 'none'; document.getElementById('geminiChat').style.display = 'flex'; document.getElementById('apiKeySetup').style.display = 'none'; aiModalState.currentView = 'gemini'; // 초기 λ©”μ‹œμ§€κ°€ μ—†μœΌλ©΄ μΆ”κ°€ const chatMessages = document.getElementById('chatMessages'); if (!chatMessages.innerHTML.trim()) { addMessage('assistant', `Hello! I can help you with: β€’ Meta tag optimization strategies β€’ SEO best practices for 2025 β€’ Open Graph and Twitter Cards setup β€’ Schema markup implementation β€’ Character limits and SERP previews β€’ Bulk generation techniques What would you like to know about meta tag optimization?`); } } // API ν‚€ μ„€μ • ν™”λ©΄ ν‘œμ‹œ function showAPIKeySetup() { document.getElementById('aiModalTitle').textContent = 'Setup Gemini API'; document.getElementById('aiSelector').style.display = 'none'; document.getElementById('geminiChat').style.display = 'none'; document.getElementById('apiKeySetup').style.display = 'block'; aiModalState.currentView = 'setup'; } // AI 선택 처리 function selectAI(aiType) { switch(aiType) { case 'chatgpt': const toolContext = `I need help with meta tag optimization and SEO. I'm using a meta tag generator tool that creates HTML meta tags, Open Graph tags, Twitter Cards, and Schema markup. Please help me optimize my meta tags for better search engine rankings and social media sharing.`; const chatUrl = `https://chat.openai.com/?q=${encodeURIComponent(toolContext)}`; window.open(chatUrl, '_blank'); closeAIModal(); trackEvent('ai_selection', { ai_type: 'chatgpt' }); break; case 'claude': const claudeContext = `I need help with meta tag optimization and SEO. I'm using a meta tag generator tool that creates HTML meta tags, Open Graph tags, Twitter Cards, and Schema markup. Please help me optimize my meta tags for better search engine rankings and social media sharing.`; const claudeUrl = `https://claude.ai/chat?q=${encodeURIComponent(claudeContext)}`; window.open(claudeUrl, '_blank'); closeAIModal(); trackEvent('ai_selection', { ai_type: 'claude' }); break; case 'gemini': if (!aiModalState.apiKey) { showAPIKeySetup(); } else { showGeminiChat(); } trackEvent('ai_selection', { ai_type: 'gemini' }); break; } } // API ν‚€ μ €μž₯ function saveGeminiApiKey() { const apiKey = document.getElementById('geminiApiKeyInput').value.trim(); if (apiKey) { localStorage.setItem('geminiApiKey', apiKey); aiModalState.apiKey = apiKey; showGeminiChat(); updateAPIKeyStatus(); } else { alert('Please enter a valid API key'); } } // API ν‚€ μƒνƒœ μ—…λ°μ΄νŠΈ function updateAPIKeyStatus() { const statusEl = document.getElementById('apiKeyStatus'); if (aiModalState.apiKey) { statusEl.innerHTML = 'Badilisha Ufunguo wa API'; } else { statusEl.textContent = 'No API key set'; } } // μ±„νŒ… λ©”μ‹œμ§€ μΆ”κ°€ function addMessage(type, content) { const chatMessages = document.getElementById('chatMessages'); const messageDiv = document.createElement('div'); messageDiv.className = `message ${type}`; if (type === 'user') { messageDiv.innerHTML = `You: ${content}`; } else { messageDiv.innerHTML = `✨ Gemini:
${content.replace(/\n/g, '
')}`; } chatMessages.appendChild(messageDiv); chatMessages.scrollTop = chatMessages.scrollHeight; } // Gemini에 λ©”μ‹œμ§€ 전솑 async function sendToGemini() { const input = document.getElementById('geminiInput'); const message = input.value.trim(); if (!message) return; // μ‚¬μš©μž λ©”μ‹œμ§€ μΆ”κ°€ addMessage('user', message); input.value = ''; // λ‘œλ”© ν‘œμ‹œ const loadingMsg = document.createElement('div'); loadingMsg.className = 'message assistant'; loadingMsg.innerHTML = '✨ Gemini:
Thinking...'; loadingMsg.id = 'loading-message'; document.getElementById('chatMessages').appendChild(loadingMsg); try { const currentData = getCurrentFormData(); const contextPrompt = `Context: User is using a meta tag generator tool. Current form data: ${JSON.stringify(currentData, null, 2)} Meta tag optimization knowledge: - Title tags should be 50-60 characters for optimal display - Meta descriptions should be 150-160 characters - Open Graph images should be 1200x630 pixels - Schema markup helps with rich snippets - Twitter Cards improve social sharing User question: ${message} Please provide helpful advice about meta tag optimization, SEO best practices, or how to improve their current meta tags.`; const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=${aiModalState.apiKey}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ contents: [{ parts: [{ text: contextPrompt }] }], generationConfig: { temperature: 0.7, maxOutputTokens: 1000 } }) }); const data = await response.json(); // λ‘œλ”© λ©”μ‹œμ§€ 제거 document.getElementById('loading-message').remove(); if (data.candidates && data.candidates[0] && data.candidates[0].content) { const reply = data.candidates[0].content.parts[0].text; addMessage('assistant', reply); } else { addMessage('assistant', 'Sorry, I could not generate a response. Please try again.'); } } catch (error) { // λ‘œλ”© λ©”μ‹œμ§€ 제거 document.getElementById('loading-message')?.remove(); if (error.message.includes('API key')) { addMessage('error', 'Invalid API key. Please check your API key and try again.'); showAPIKeySetup(); } else { addMessage('error', 'Failed to connect to Gemini. Please check your internet connection and try again.'); } } } function getCurrentFormData() { return { title: document.getElementById('pageTitle')?.value || '', description: document.getElementById('metaDescription')?.value || '', url: document.getElementById('pageUrl')?.value || '', keywords: document.getElementById('keywords')?.value || '', author: document.getElementById('author')?.value || '', language: document.getElementById('language')?.value || '', ogTitle: document.getElementById('ogTitle')?.value || '', ogDescription: document.getElementById('ogDescription')?.value || '', ogImage: document.getElementById('ogImage')?.value || '', siteName: document.getElementById('siteName')?.value || '', schemaType: document.getElementById('schemaType')?.value || '' }; } // ========== EVENT LISTENERS ========== // Enter key support for inputs document.addEventListener('DOMContentLoaded', function() { // Character count listeners document.getElementById('pageTitle').addEventListener('input', () => updateCharCount('pageTitle', 'title-count', 60, 100)); document.getElementById('metaDescription').addEventListener('input', () => updateCharCount('metaDescription', 'desc-count', 160, 300)); // Clear errors on input document.querySelectorAll('.input-field').forEach(input => { input.addEventListener('input', clearErrors); }); // AI λ²„νŠΌ 이벀트 document.getElementById('aiBtn').addEventListener('click', openAIModal); // λͺ¨λ‹¬ μ™ΈλΆ€ ν΄λ¦­μ‹œ λ‹«κΈ° document.getElementById('aiModal').addEventListener('click', function(e) { if (e.target === this) { closeAIModal(); } }); // μ—”ν„° ν‚€ 지원 및 ESC ν‚€λ‘œ λͺ¨λ‹¬ λ‹«κΈ° document.addEventListener('keydown', function(e) { if (e.key === 'Enter') { const geminiInput = document.getElementById('geminiInput'); if (document.activeElement === geminiInput) { sendToGemini(); } } // ESC ν‚€λ‘œ λͺ¨λ‹¬ λ‹«κΈ° if (e.key === 'Escape') { closeAIModal(); } }); // 초기 API ν‚€ μƒνƒœ μ—…λ°μ΄νŠΈ updateAPIKeyStatus(); updateCurrentYear(); updateToolCount(); // Initialize schema fields updateSchemaFields(); }); // Track tool usage document.querySelectorAll('a[href*="wia"]').forEach(link => { link.addEventListener('click', function() { trackEvent('wia_link_click', { link: link.textContent }); }); }); // ========== DYNAMIC TOOL COUNT ========== // Update tool count dynamically async function updateToolCount() { try { const response = await fetch('/api/tool-count.php'); const data = await response.json(); // Update dynamic tools description document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${data.count}+ free online tools in 206 languages. No signup, no fees, just tools that work.`; }); // Update "All X+ Tools" links document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${data.count}+ ${suffix}`; }); } catch (error) { // Fallback: use current actual count from server const fallbackCount = 333; document.querySelectorAll('.dynamic-tools-count').forEach(el => { el.textContent = `${fallbackCount}+ free online tools in 206 languages. No signup, no fees, just tools that work.`; }); document.querySelectorAll('.dynamic-count').forEach(el => { const prefix = el.getAttribute('data-text') || ''; const suffix = el.getAttribute('data-suffix') || ''; const icon = el.textContent.split(' ')[0] || ''; el.textContent = `${icon} ${prefix} ${fallbackCount}+ ${suffix}`; }); console.log('Tool count API not available, using current count:', fallbackCount); } } // Update current year dynamically function updateCurrentYear() { const currentYear = new Date().getFullYear(); document.querySelectorAll('.current-year').forEach(el => { el.textContent = currentYear; }); } // ========== ANALYTICS ========== // Google Analytics window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-XXXXXXXXX'); // Track page view trackEvent('page_view', { tool: TOOL_CONFIG.name, category: TOOL_CONFIG.category });