diff --git a/app/[locale]/contact/page.tsx b/app/[locale]/contact/page.tsx index 16c941a..7fedcb6 100644 --- a/app/[locale]/contact/page.tsx +++ b/app/[locale]/contact/page.tsx @@ -1,5 +1,15 @@ +import type { Metadata } from 'next' import { getLocale } from 'next-intl/server' +export const metadata: Metadata = { + title: 'Contact Us', + description: 'Get in touch with Trump Alpha for questions, feedback, or support. We respond within 24 hours.', + alternates: { + canonical: `${process.env.NEXT_PUBLIC_SITE_URL || 'https://trumpsignal.com'}/en/contact`, + }, + robots: { index: false, follow: true }, // no SEO value in indexing a contact form +} + export default async function ContactPage() { const locale = await getLocale() const isZh = false // i18n shelved — Chinese branches kept as dead code for future revival; see messages/zh.json diff --git a/app/[locale]/glossary/page.tsx b/app/[locale]/glossary/page.tsx index 0a470fb..cde551e 100644 --- a/app/[locale]/glossary/page.tsx +++ b/app/[locale]/glossary/page.tsx @@ -294,7 +294,7 @@ export async function generateMetadata({ description: copy.ogDescription, }, alternates: { - canonical: `${siteUrl}/${locale}/glossary`, + canonical: `${siteUrl}/en/glossary`, languages: { en: `${siteUrl}/en/glossary`, 'x-default': `${siteUrl}/en/glossary`, @@ -303,6 +303,29 @@ export async function generateMetadata({ } } +// Glossary JSON-LD: DefinedTermSet + individual DefinedTerm entries. +// LLMs and Google's Knowledge Graph use this to understand what each term +// means *in context of this product*, which improves citation accuracy when +// users ask "what is [term]" in ChatGPT/Perplexity. +function buildGlossaryJsonLd(terms: { term: string; definition: string; extra?: string }[]) { + return { + '@context': 'https://schema.org', + '@type': 'DefinedTermSet', + '@id': `${siteUrl}/en/glossary#termset`, + name: 'Trump Alpha Crypto Glossary', + url: `${siteUrl}/en/glossary`, + description: 'Definitions of key terms, indicators, and signal concepts used in the Trump Alpha crypto intelligence platform.', + inLanguage: 'en', + hasDefinedTerm: terms.map(t => ({ + '@type': 'DefinedTerm', + name: t.term, + description: t.extra ? `${t.definition} ${t.extra}` : t.definition, + url: `${siteUrl}/en/glossary#${t.term.toLowerCase().replace(/[^a-z0-9]+/g, '-')}`, + inDefinedTermSet: `${siteUrl}/en/glossary#termset`, + })), + } +} + const CATEGORY_COLOR: Record = { 'Macro-bottom metric': '#a78bfa', '宏观底部指标': '#a78bfa', @@ -325,7 +348,15 @@ export default async function GlossaryPage({ params }: { params: Promise<{ local const copy = getCopy(locale) const categories = Array.from(new Set(copy.terms.map(t => t.category))) + const enTerms = locale === 'en' ? copy.terms : getCopy('en').terms + const glossaryJsonLd = buildGlossaryJsonLd(enTerms) + return ( + <> +