import { readFileSync, existsSync } from 'fs'; import { join, resolve } from 'path'; import { loadFeedback } from './feedback-store.js'; const SITE_URL = 'https://www.ypchat.net'; const DEFAULT_IMAGE = `${SITE_URL}/static/favicon.png`; const SEO_LOCALES = [ { code: 'de', label: 'Deutsch' }, { code: 'en', label: 'English' }, { code: 'fr', label: 'Francais' }, { code: 'es', label: 'Espanol' }, { code: 'it', label: 'Italiano' }, { code: 'ja', label: 'Japanese' }, { code: 'zh', label: 'Chinese' }, { code: 'th', label: 'Thai' }, { code: 'tl', label: 'Tagalog' } ]; const LOCALE_SEO_META = { de: { title: 'SingleChat: Kostenloser Single Chat, privat & anonym', description: 'Kostenloser Single Chat für private und anonyme Gespräche. Lerne neue Kontakte kennen und teile Bilder sicher online.', keywords: 'single chat, kostenloser chat, privat chatten, anonym chat, free chat, private chat, anonymous chat, online chat' }, en: { title: 'SingleChat: Free Private & Anonymous Single Chat', description: 'Free single chat for private and anonymous conversations. Meet new people and share images safely online.', keywords: 'single chat, free chat, private chat, anonymous chat, online chat, meet singles' }, fr: { title: 'SingleChat: Chat célibataire gratuit, privé et anonyme', description: 'Chat célibataire gratuit pour des conversations privées et anonymes. Rencontrez de nouvelles personnes en toute sécurité.', keywords: 'chat célibataire, chat gratuit, chat privé, chat anonyme, rencontre en ligne' }, es: { title: 'SingleChat: Chat gratis, privado y anónimo', description: 'Chat gratis para solteros con conversaciones privadas y anónimas. Conoce gente nueva y comparte imágenes de forma segura.', keywords: 'chat gratis, chat privado, chat anónimo, chat para solteros, conocer gente' }, it: { title: 'SingleChat: Chat single gratis, privata e anonima', description: 'Chat single gratis per conversazioni private e anonime. Conosci nuove persone e condividi immagini in sicurezza.', keywords: 'chat single, chat gratis, chat privata, chat anonima, incontri online' }, ja: { title: 'SingleChat: 無料・匿名・プライベートのシングルチャット', description: '無料で使えるシングルチャット。匿名かつプライベートに会話でき、画像共有も安全です。', keywords: 'シングルチャット, 無料チャット, 匿名チャット, プライベートチャット, オンラインチャット' }, zh: { title: 'SingleChat:免费、私密、匿名的单身聊天', description: '免费单身聊天,支持私密和匿名交流,安全分享图片并结识新朋友。', keywords: '单身聊天, 免费聊天, 私密聊天, 匿名聊天, 在线聊天' }, th: { title: 'SingleChat: แชตคนโสดฟรี แบบส่วนตัวและไม่ระบุตัวตน', description: 'แชตคนโสดฟรี สำหรับการสนทนาแบบส่วนตัวและไม่ระบุตัวตน พบผู้คนใหม่ ๆ และแชร์รูปได้อย่างปลอดภัย', keywords: 'แชตคนโสด, แชตฟรี, แชตส่วนตัว, แชตไม่ระบุตัวตน, แชตออนไลน์' }, tl: { title: 'SingleChat: Libreng private at anonymous na single chat', description: 'Libreng single chat para sa private at anonymous na usapan. Kumilala ng bagong tao at magbahagi ng larawan nang ligtas.', keywords: 'single chat, libreng chat, private chat, anonymous chat, online chat' } }; const seoData = { '/': { title: 'SingleChat: Kostenloser Single Chat, privat & anonym', description: 'Kostenloser Single Chat für private und anonyme Gespräche. Lerne neue Kontakte kennen und teile Bilder sicher online.', keywords: 'single chat, kostenloser chat, privat chatten, anonym chat, free chat, private chat, anonymous chat, online chat', ogTitle: 'SingleChat: Kostenloser Single Chat, privat & anonym', ogDescription: 'Kostenlos chatten, privat bleiben und neue Kontakte kennenlernen - mit sicherem Bildaustausch.', ogType: 'website', ogUrl: `${SITE_URL}/`, ogImage: DEFAULT_IMAGE, robots: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1', schema: { '@context': 'https://schema.org', '@type': 'WebSite', name: 'SingleChat', url: `${SITE_URL}/`, description: 'Kostenloser Single Chat für private und anonyme Gespräche. Lerne neue Kontakte kennen und tausche Bilder sicher aus.', inLanguage: 'de-DE' } }, '/partners': { title: 'Partner für Single Chat & Community - SingleChat', description: 'Partnerseiten rund um Single Chat, Community und Online-Kontakte. Entdecke weitere Angebote und hilfreiche Ressourcen.', keywords: 'single chat partner, chat community, kontaktseiten, single-chat links, online dating chat', ogTitle: 'Partner für Single Chat & Community - SingleChat', ogDescription: 'Befreundete Seiten und Ressourcen rund um Chat, Kontakte und Community.', ogType: 'website', ogUrl: `${SITE_URL}/partners`, ogImage: DEFAULT_IMAGE, robots: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1', schema: { '@context': 'https://schema.org', '@type': 'CollectionPage', name: 'Partner - SingleChat', url: `${SITE_URL}/partners`, description: 'Partnerseiten rund um Single Chat, Community und Online-Kontakte. Entdecke weitere Angebote und hilfreiche Ressourcen.', isPartOf: { '@type': 'WebSite', name: 'SingleChat', url: `${SITE_URL}/` }, inLanguage: 'de-DE' } }, '/feedback': { title: 'Feedback zur Chat-Plattform - SingleChat', description: 'Öffentliches Feedback zu SingleChat: Meinungen, Vorschläge und Erfahrungsberichte für einen besseren privaten Chat.', keywords: 'chat feedback, single chat erfahrungen, rückmeldung chat, verbesserungsvorschläge', ogTitle: 'Feedback zur Chat-Plattform - SingleChat', ogDescription: 'Teile deine Erfahrungen und Verbesserungsvorschläge für SingleChat.', ogType: 'website', ogUrl: `${SITE_URL}/feedback`, ogImage: DEFAULT_IMAGE, robots: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1', schema: { '@context': 'https://schema.org', '@type': 'CollectionPage', name: 'Feedback - SingleChat', url: `${SITE_URL}/feedback`, description: 'Öffentliches Feedback zu SingleChat: Meinungen, Vorschläge und Erfahrungsberichte für einen besseren privaten Chat.', isPartOf: { '@type': 'WebSite', name: 'SingleChat', url: `${SITE_URL}/` }, inLanguage: 'de-DE' } }, '/faq': { title: 'FAQ: Kostenlos, privat und anonym chatten - SingleChat', description: 'FAQ zum kostenlosen Single Chat: anonym chatten, Privatsphäre schützen, Bilder sicher teilen und Nutzer blockieren.', keywords: 'single chat faq, kostenlos chatten, anonym chatten, privater chat, safe chat', ogTitle: 'FAQ: Kostenlos, privat und anonym chatten - SingleChat', ogDescription: 'Antworten auf Fragen zu Sicherheit, Privatsphäre und Funktionen im Single Chat.', ogType: 'website', ogUrl: `${SITE_URL}/faq`, ogImage: DEFAULT_IMAGE, robots: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1', schema: { '@context': 'https://schema.org', '@type': 'FAQPage', name: 'FAQ - SingleChat', url: `${SITE_URL}/faq`, description: 'FAQ zum kostenlosen Single Chat: anonym chatten, Privatsphäre schützen, Bilder sicher teilen und Nutzer blockieren.', isPartOf: { '@type': 'WebSite', name: 'SingleChat', url: `${SITE_URL}/` }, inLanguage: 'de-DE' } }, '/regeln': { title: 'Chat-Regeln für sicheren Single Chat - SingleChat', description: 'Regeln für respektvollen, privaten und sicheren Single Chat. Hinweise zu Verhalten, Spam und verbotenen Inhalten.', keywords: 'chat regeln, single chat regeln, sicher chatten, spam vermeiden, community richtlinien', ogTitle: 'Chat-Regeln für sicheren Single Chat - SingleChat', ogDescription: 'Unsere Richtlinien für respektvolle und sichere Gespräche im Chat.', ogType: 'website', ogUrl: `${SITE_URL}/regeln`, ogImage: DEFAULT_IMAGE, robots: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1', schema: { '@context': 'https://schema.org', '@type': 'WebPage', name: 'Regeln - SingleChat', url: `${SITE_URL}/regeln`, description: 'Regeln für respektvollen, privaten und sicheren Single Chat. Hinweise zu Verhalten, Spam und verbotenen Inhalten.', isPartOf: { '@type': 'WebSite', name: 'SingleChat', url: `${SITE_URL}/` }, inLanguage: 'de-DE' } }, '/sicherheit': { title: 'Sicherheit & Privatsphäre im privaten Chat - SingleChat', description: 'Sicherheitsseite für privaten und anonymen Chat: Privatsphäre, Schutz vor Spam, Blockieren und Melden.', keywords: 'privatsphäre chat, anonym chat sicherheit, blockieren melden, private chat safety', ogTitle: 'Sicherheit & Privatsphäre im privaten Chat - SingleChat', ogDescription: 'So schützt du deine Daten und chattest sicher und anonym.', ogType: 'website', ogUrl: `${SITE_URL}/sicherheit`, ogImage: DEFAULT_IMAGE, robots: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1', schema: { '@context': 'https://schema.org', '@type': 'WebPage', name: 'Sicherheit & Privatsphäre - SingleChat', url: `${SITE_URL}/sicherheit`, description: 'Sicherheitsseite für privaten und anonymen Chat: Privatsphäre, Schutz vor Spam, Blockieren und Melden.', isPartOf: { '@type': 'WebSite', name: 'SingleChat', url: `${SITE_URL}/` }, inLanguage: 'de-DE' } } }; for (const locale of SEO_LOCALES) { const meta = LOCALE_SEO_META[locale.code] || LOCALE_SEO_META.de; seoData[`/${locale.code}`] = { title: meta.title, description: meta.description, keywords: meta.keywords, ogTitle: meta.title, ogDescription: meta.description, ogType: 'website', ogUrl: `${SITE_URL}/${locale.code}`, ogImage: DEFAULT_IMAGE, robots: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1', schema: { '@context': 'https://schema.org', '@type': 'WebSite', name: 'SingleChat', url: `${SITE_URL}/${locale.code}`, description: meta.description, inLanguage: locale.code } }; } function buildSitemapXml() { const currentDate = new Date().toISOString().split('T')[0]; const urls = Object.entries(seoData) .map(([route, meta]) => { const priority = route === '/' ? '1.0' : '0.8'; const changefreq = route === '/' ? 'daily' : 'weekly'; return ` ${meta.ogUrl} ${currentDate} ${changefreq} ${priority} `; }) .join('\n'); return ` ${urls} `; } function escapeHtml(value = '') { return String(value) .replace(/&/g, '&') .replace(/"/g, '"') .replace(//g, '>'); } function upsertMetaTag(html, name, content, attribute = 'name') { const escapedContent = escapeHtml(content); const regex = new RegExp(`]*>`, 'g'); const tag = ``; if (regex.test(html)) { return html.replace(regex, tag); } return html.replace('', ` ${tag}\n`); } function upsertLinkTag(html, rel, href) { const escapedHref = escapeHtml(href); const regex = new RegExp(`]*>`, 'g'); const tag = ``; if (regex.test(html)) { return html.replace(regex, tag); } return html.replace('', ` ${tag}\n`); } function upsertJsonLd(html, schema) { const tag = schema ? `` : ''; if (html.includes('id="seo-json-ld"')) { return html.replace(/