Add FAQ, Rules, and Safety pages with corresponding routes and SEO metadata

- Introduced new links in ImprintContainer.vue for FAQ, Rules, and Safety pages.
- Added FaqView, RulesView, and SafetyView components to handle the new routes.
- Implemented SEO metadata for the new pages in routes-seo.js and router/index.js.
- Updated server routes to include the new paths for proper handling in production.

These changes enhance the site's informational resources and improve SEO visibility for user inquiries.
This commit is contained in:
Torsten Schulz (local)
2026-03-27 14:15:37 +01:00
parent 6909c7c45c
commit 06182a4a95
10 changed files with 500 additions and 5 deletions

View File

@@ -1,6 +1,9 @@
<template>
<div class="imprint-container">
<a href="/partners">Partner</a>
<a href="/faq">FAQ</a>
<a href="/regeln">Regeln</a>
<a href="/sicherheit">Sicherheit</a>
<a href="#" @click.prevent="showFeedback = true">Feedback</a>
<a href="#" @click.prevent="showImprint = true">Impressum</a>

View File

@@ -3,6 +3,9 @@ import ChatView from '../views/ChatView.vue';
import PartnersView from '../views/PartnersView.vue';
import MockupView from '../views/MockupView.vue';
import FeedbackView from '../views/FeedbackView.vue';
import FaqView from '../views/FaqView.vue';
import RulesView from '../views/RulesView.vue';
import SafetyView from '../views/SafetyView.vue';
const SITE_URL = 'https://www.ypchat.net';
const DEFAULT_IMAGE = `${SITE_URL}/static/favicon.png`;
@@ -44,6 +47,48 @@ const feedbackSchema = {
inLanguage: 'de-DE'
};
const faqSchema = {
'@context': 'https://schema.org',
'@type': 'FAQPage',
name: 'FAQ - SingleChat',
url: `${SITE_URL}/faq`,
description: 'Häufige Fragen zu SingleChat: Einstieg, Privatsphäre, Bildaustausch, Blockieren und mehr.',
isPartOf: {
'@type': 'WebSite',
name: 'SingleChat',
url: `${SITE_URL}/`
},
inLanguage: 'de-DE'
};
const rulesSchema = {
'@context': 'https://schema.org',
'@type': 'WebPage',
name: 'Regeln - SingleChat',
url: `${SITE_URL}/regeln`,
description: 'Chat-Regeln für ein respektvolles und sicheres Miteinander auf SingleChat.',
isPartOf: {
'@type': 'WebSite',
name: 'SingleChat',
url: `${SITE_URL}/`
},
inLanguage: 'de-DE'
};
const safetySchema = {
'@context': 'https://schema.org',
'@type': 'WebPage',
name: 'Sicherheit - SingleChat',
url: `${SITE_URL}/sicherheit`,
description: 'Hinweise zu Privatsphäre, Blockieren/Melden und sicherer Nutzung von SingleChat.',
isPartOf: {
'@type': 'WebSite',
name: 'SingleChat',
url: `${SITE_URL}/`
},
inLanguage: 'de-DE'
};
const routes = [
{
path: '/',
@@ -93,6 +138,54 @@ const routes = [
schema: feedbackSchema
}
},
{
path: '/faq',
name: 'faq',
component: FaqView,
meta: {
title: 'FAQ - SingleChat',
description: 'Häufige Fragen zu SingleChat: Einstieg, Privatsphäre, Bildaustausch, Blockieren und mehr.',
keywords: 'SingleChat FAQ, Hilfe, Privatsphäre, Blockieren, Bilder, Chat',
ogTitle: 'FAQ - SingleChat',
ogDescription: 'Antworten auf häufige Fragen rund um SingleChat.',
ogType: 'website',
image: DEFAULT_IMAGE,
robots: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1',
schema: faqSchema
}
},
{
path: '/regeln',
name: 'regeln',
component: RulesView,
meta: {
title: 'Regeln - SingleChat',
description: 'Chat-Regeln für ein respektvolles und sicheres Miteinander auf SingleChat.',
keywords: 'SingleChat Regeln, Chat Regeln, Community, Sicherheit',
ogTitle: 'Regeln - SingleChat',
ogDescription: 'Chat-Regeln für ein respektvolles und sicheres Miteinander.',
ogType: 'website',
image: DEFAULT_IMAGE,
robots: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1',
schema: rulesSchema
}
},
{
path: '/sicherheit',
name: 'sicherheit',
component: SafetyView,
meta: {
title: 'Sicherheit & Privatsphäre - SingleChat',
description: 'Hinweise zu Privatsphäre, Blockieren/Melden und sicherer Nutzung von SingleChat.',
keywords: 'SingleChat Sicherheit, Privatsphäre, Blockieren, Melden',
ogTitle: 'Sicherheit & Privatsphäre - SingleChat',
ogDescription: 'Hinweise zu Privatsphäre, Blockieren/Melden und sicherer Nutzung.',
ogType: 'website',
image: DEFAULT_IMAGE,
robots: 'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1',
schema: safetySchema
}
},
{
path: '/mockup-redesign',
name: 'mockup-redesign',

View File

@@ -8,7 +8,6 @@
<h1>Chat</h1>
</div>
</div>
<HeaderAdBanner />
<div v-if="chatStore.isLoggedIn" class="header-status">
<span class="header-status-chip">{{ chatStore.userName }}</span>
<span v-if="chatStore.isoCountryCode" class="header-status-chip">{{ chatStore.isoCountryCode }}</span>
@@ -90,7 +89,6 @@ import SearchView from '../components/SearchView.vue';
import InboxView from '../components/InboxView.vue';
import HistoryView from '../components/HistoryView.vue';
import ImprintContainer from '../components/ImprintContainer.vue';
import HeaderAdBanner from '../components/HeaderAdBanner.vue';
const chatStore = useChatStore();

View File

@@ -0,0 +1,85 @@
<template>
<div class="chat-container">
<header class="header">
<div class="app-brand">
<span class="app-brand-mark">S</span>
<div class="app-brand-copy">
<span class="app-brand-eyebrow">SingleChat</span>
<h1>FAQ</h1>
</div>
</div>
<HeaderAdBanner />
</header>
<main class="content-page">
<h2>Häufige Fragen (FAQ)</h2>
<p>
Hier beantworten wir die häufigsten Fragen zu SingleChat. Wenn dir etwas fehlt, nutze bitte die
<router-link to="/feedback">Feedback-Seite</router-link>.
</p>
<h3>Wie starte ich?</h3>
<p>
Wähle einen Nicknamen, gib Alter, Geschlecht und Land an und starte den Chat. Du kannst danach Benutzer suchen
und Unterhaltungen beginnen.
</p>
<h3>Welche Daten sollte ich nicht teilen?</h3>
<p>
Bitte teile keine sensiblen Daten wie Telefonnummer, Adresse, EMail, Passwörter oder Zahlungsinformationen im
Chat. Auch wenn du anonym bleiben möchtest: Nutze einen Nickname, der keine Rückschlüsse auf deine Identität
zulässt.
</p>
<h3>Wie funktioniert der Bildaustausch?</h3>
<p>
Du kannst im Chat ein Bild senden. Bitte sende nur Inhalte, für die du die Rechte hast, und vermeide Inhalte,
die andere belästigen oder gegen unsere Regeln verstoßen.
</p>
<h3>Was kann ich bei Belästigung tun?</h3>
<p>
Blockiere den Benutzer und beende die Unterhaltung. Wenn es schwerwiegende Fälle sind (Spam, Drohungen,
strafbare Inhalte), melde es über Feedback mit möglichst genauen Angaben.
</p>
<h3>Warum sehe ich manchmal keine Anzeigen?</h3>
<p>
Anzeigen werden nur auf Inhaltsseiten eingeblendet, nicht im eigentlichen Chat. Zusätzlich kann es je nach
Region, Browser-Einstellungen oder Ad-Blockern sein, dass keine Anzeige ausgeliefert wird.
</p>
</main>
<ImprintContainer />
</div>
</template>
<script setup>
import HeaderAdBanner from '../components/HeaderAdBanner.vue';
import ImprintContainer from '../components/ImprintContainer.vue';
</script>
<style scoped>
.content-page {
max-width: 980px;
margin: 0 auto;
padding: 20px 14px 36px;
line-height: 1.6;
color: #344038;
}
.content-page h2 {
margin: 0 0 10px;
color: #18201b;
}
.content-page h3 {
margin: 18px 0 6px;
color: #18201b;
}
.content-page a {
color: #245c3a;
}
</style>

View File

@@ -11,7 +11,23 @@
<HeaderAdBanner />
</header>
<FeedbackPanel />
<main class="feedback-page">
<section class="feedback-copy">
<h2>Öffentliches Feedback</h2>
<p>
Diese Seite ist für Vorschläge, Fehlerberichte und Ideen gedacht. Bitte schreibe nur Inhalte, die du auch
öffentlich sehen möchtest. Wir moderieren grob (Spam/Beleidigungen/illegaler Inhalt wird entfernt).
</p>
<h3>Tipps für gutes Feedback</h3>
<ul>
<li>Beschreibe kurz, was du erreichen wolltest und was stattdessen passiert ist.</li>
<li>Falls möglich: Browser/Device, Zeitpunkt und konkrete Schritte.</li>
<li>Keine privaten Daten posten (Telefon, Adresse, EMail, Passwörter).</li>
</ul>
</section>
<FeedbackPanel />
</main>
<ImprintContainer />
</div>
@@ -22,3 +38,35 @@ import FeedbackPanel from '../components/FeedbackPanel.vue';
import HeaderAdBanner from '../components/HeaderAdBanner.vue';
import ImprintContainer from '../components/ImprintContainer.vue';
</script>
<style scoped>
.feedback-page {
max-width: 1100px;
margin: 0 auto;
padding: 18px 14px 30px;
}
.feedback-copy {
background: #ffffff;
border: 1px solid #d7dfd9;
border-radius: 14px;
padding: 16px 16px 12px;
margin-bottom: 16px;
}
.feedback-copy h2 {
margin: 0 0 8px;
color: #18201b;
}
.feedback-copy h3 {
margin: 14px 0 8px;
color: #18201b;
}
.feedback-copy p,
.feedback-copy li {
color: #344038;
line-height: 1.55;
}
</style>

View File

@@ -19,6 +19,15 @@
<div class="content">
<div class="partners-view">
<h2>Partner</h2>
<p class="partners-intro">
Auf dieser Seite findest du Empfehlungen und befreundete Projekte. Wir verlinken nur Seiten, die wir als
sinnvoll für unsere Community einschätzen. Die Inhalte der verlinkten Seiten liegen in der Verantwortung der
jeweiligen Betreiber.
</p>
<p class="partners-intro">
Hinweis: Externe Links öffnen sich in einem neuen Tab. Wenn du Partner werden möchtest, schreib uns bitte
über die Feedback-Seite.
</p>
<div v-if="!chatStore.isLoggedIn" class="back-link">
<router-link to="/">Zurück zur Hauptseite</router-link>
</div>
@@ -27,6 +36,7 @@
<a :href="partner.url" target="_blank" rel="noopener noreferrer">
{{ partner['Page Name'] }}
</a>
<span class="partners-meta">Externer Link</span>
</li>
</ul>
</div>
@@ -60,3 +70,31 @@ onMounted(async () => {
}
});
</script>
<style scoped>
.partners-view {
padding: 20px;
max-width: 980px;
}
.partners-intro {
margin: 10px 0;
color: #344038;
line-height: 1.55;
}
.partners-list {
margin-top: 16px;
padding-left: 18px;
}
.partners-list li {
margin-bottom: 10px;
}
.partners-meta {
margin-left: 10px;
font-size: 12px;
color: #637067;
}
</style>

View File

@@ -0,0 +1,80 @@
<template>
<div class="chat-container">
<header class="header">
<div class="app-brand">
<span class="app-brand-mark">S</span>
<div class="app-brand-copy">
<span class="app-brand-eyebrow">SingleChat</span>
<h1>Regeln</h1>
</div>
</div>
<HeaderAdBanner />
</header>
<main class="content-page">
<h2>Chat-Regeln</h2>
<p>
Damit SingleChat freundlich und sicher bleibt, gelten ein paar einfache Regeln. Wer wiederholt dagegen
verstößt, kann blockiert oder vom Chat ausgeschlossen werden.
</p>
<h3>1) Respekt</h3>
<p>
Keine Beleidigungen, Hassrede, Diskriminierung oder gezielte Belästigung. Unterschiedliche Meinungen sind okay
respektloser Umgang nicht.
</p>
<h3>2) Keine illegalen Inhalte</h3>
<p>
Keine strafbaren Inhalte, keine Aufrufe zu Gewalt, keine extremistischen Inhalte. Bei klaren Verstößen behalten
wir uns weitere Schritte vor.
</p>
<h3>3) Keine unerwünschte Werbung/Spam</h3>
<p>
Kein Spam, keine Massen-Nachrichten und keine automatisierten Werbe-Links. Partnerlinks sind nur nach Absprache
erlaubt.
</p>
<h3>4) Bilder</h3>
<p>
Sende nur Bilder, für die du die Rechte hast. Keine belästigenden Inhalte. Wenn dein Gegenüber keine Bilder
möchte, respektiere das.
</p>
<h3>5) Privatsphäre</h3>
<p>
Teile keine privaten Daten (Telefon, Adresse, EMail, Passwörter). Bitte respektiere auch die Privatsphäre
anderer und veröffentliche keine Chat-Inhalte außerhalb der Plattform.
</p>
</main>
<ImprintContainer />
</div>
</template>
<script setup>
import HeaderAdBanner from '../components/HeaderAdBanner.vue';
import ImprintContainer from '../components/ImprintContainer.vue';
</script>
<style scoped>
.content-page {
max-width: 980px;
margin: 0 auto;
padding: 20px 14px 36px;
line-height: 1.6;
color: #344038;
}
.content-page h2 {
margin: 0 0 10px;
color: #18201b;
}
.content-page h3 {
margin: 18px 0 6px;
color: #18201b;
}
</style>

View File

@@ -0,0 +1,75 @@
<template>
<div class="chat-container">
<header class="header">
<div class="app-brand">
<span class="app-brand-mark">S</span>
<div class="app-brand-copy">
<span class="app-brand-eyebrow">SingleChat</span>
<h1>Sicherheit</h1>
</div>
</div>
<HeaderAdBanner />
</header>
<main class="content-page">
<h2>Sicherheit &amp; Privatsphäre</h2>
<p>
SingleChat ist auf schnellen Einstieg ausgelegt trotzdem ist uns Sicherheit wichtig. Diese Hinweise helfen dir
dabei, deine Privatsphäre zu schützen und gute Entscheidungen im Chat zu treffen.
</p>
<h3>Empfehlungen für sichere Nutzung</h3>
<ul>
<li>Nutze einen Nickname, der dich nicht identifiziert.</li>
<li>Teile keine Kontakt- oder Zahlungsdaten.</li>
<li>Sei vorsichtig bei Links/Dateien von unbekannten Personen.</li>
<li>Beende Gespräche, die dir unangenehm sind.</li>
</ul>
<h3>Blockieren und melden</h3>
<p>
Du kannst Benutzer blockieren. Für harte Fälle (Spam, Belästigung, strafbare Inhalte) nutze bitte die
<router-link to="/feedback">Feedback-Seite</router-link> und gib Zeitpunkt, Nickname und eine kurze Beschreibung
an.
</p>
<h3>Datenschutz</h3>
<p>
Details findest du im Impressum/Datenschutz-Hinweis unten auf der Seite. Wenn du Fragen hast, kontaktiere uns
gern über Feedback.
</p>
</main>
<ImprintContainer />
</div>
</template>
<script setup>
import HeaderAdBanner from '../components/HeaderAdBanner.vue';
import ImprintContainer from '../components/ImprintContainer.vue';
</script>
<style scoped>
.content-page {
max-width: 980px;
margin: 0 auto;
padding: 20px 14px 36px;
line-height: 1.6;
color: #344038;
}
.content-page h2 {
margin: 0 0 10px;
color: #18201b;
}
.content-page h3 {
margin: 18px 0 6px;
color: #18201b;
}
.content-page a {
color: #245c3a;
}
</style>

View File

@@ -136,12 +136,12 @@ setupBroadcast(io, __dirname);
// SPA-Fallback muss nach allen anderen Routen stehen
if (IS_PRODUCTION) {
const distPath = join(__dirname, '../docroot/dist');
const KNOWN_SPA_ROUTES = new Set(['/', '/partners', '/feedback', '/mockup-redesign']);
const KNOWN_SPA_ROUTES = new Set(['/', '/partners', '/feedback', '/faq', '/regeln', '/sicherheit', '/mockup-redesign']);
app.use(express.static(distPath));
// Fallback für Vue Router (SPA) - muss am Ende stehen
app.get('*', (req, res) => {
// Überspringe SEO-Routes in Production (werden bereits von setupSEORoutes behandelt)
if (IS_PRODUCTION && (req.path === '/' || req.path === '/partners')) {
if (IS_PRODUCTION && (req.path === '/' || req.path === '/partners' || req.path === '/feedback' || req.path === '/faq' || req.path === '/regeln' || req.path === '/sicherheit')) {
return; // Route wurde bereits behandelt
}
// In Production: /src/ Pfade sollten nicht existieren (404)

View File

@@ -72,6 +72,78 @@ const seoData = {
},
inLanguage: 'de-DE'
}
},
'/faq': {
title: 'FAQ - SingleChat',
description: 'Häufige Fragen zu SingleChat: Einstieg, Privatsphäre, Bildaustausch, Blockieren und mehr.',
keywords: 'SingleChat FAQ, Hilfe, Privatsphäre, Blockieren, Bilder, Chat',
ogTitle: 'FAQ - SingleChat',
ogDescription: 'Antworten auf häufige Fragen rund um SingleChat.',
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: 'Häufige Fragen zu SingleChat: Einstieg, Privatsphäre, Bildaustausch, Blockieren und mehr.',
isPartOf: {
'@type': 'WebSite',
name: 'SingleChat',
url: `${SITE_URL}/`
},
inLanguage: 'de-DE'
}
},
'/regeln': {
title: 'Regeln - SingleChat',
description: 'Chat-Regeln für ein respektvolles und sicheres Miteinander auf SingleChat.',
keywords: 'SingleChat Regeln, Chat Regeln, Community, Sicherheit',
ogTitle: 'Regeln - SingleChat',
ogDescription: 'Chat-Regeln für ein respektvolles und sicheres Miteinander.',
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: 'Chat-Regeln für ein respektvolles und sicheres Miteinander auf SingleChat.',
isPartOf: {
'@type': 'WebSite',
name: 'SingleChat',
url: `${SITE_URL}/`
},
inLanguage: 'de-DE'
}
},
'/sicherheit': {
title: 'Sicherheit & Privatsphäre - SingleChat',
description: 'Hinweise zu Privatsphäre, Blockieren/Melden und sicherer Nutzung von SingleChat.',
keywords: 'SingleChat Sicherheit, Privatsphäre, Blockieren, Melden',
ogTitle: 'Sicherheit & Privatsphäre - SingleChat',
ogDescription: 'Hinweise zu Privatsphäre, Blockieren/Melden und sicherer Nutzung.',
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: 'Hinweise zu Privatsphäre, Blockieren/Melden und sicherer Nutzung von SingleChat.',
isPartOf: {
'@type': 'WebSite',
name: 'SingleChat',
url: `${SITE_URL}/`
},
inLanguage: 'de-DE'
}
}
};
@@ -231,6 +303,9 @@ export function setupSEORoutes(app, __dirname) {
Allow: /
Allow: /partners
Allow: /feedback
Allow: /faq
Allow: /regeln
Allow: /sicherheit
Disallow: /api/
Disallow: /static/logs/
Disallow: /mockup-redesign