feat(web): add SEO optimization — JSON-LD, dynamic sitemap, meta tags for listings
Add comprehensive SEO support for property listing pages to improve organic search visibility and social sharing. Changes: - Convert listing detail page from client-only to server component wrapper with generateMetadata() for per-listing title, description, OG tags, canonical URLs, and hreflang alternates - Add JSON-LD structured data (Schema.org RealEstateListing) with price, location, property specs, and breadcrumb markup - Add Website JSON-LD with SearchAction to root layout - Upgrade sitemap.xml to dynamically include all active listings across both locales (vi, en) with ISR revalidation - Improve robots.txt with pagination/sort exclusions and GPTBot block - Create server-side fetch utility (listings-server.ts) for SSR data - Extract client UI into ListingDetailClient component Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -5,6 +5,8 @@ import { getMessages, getTranslations } from 'next-intl/server';
|
||||
import { AuthProvider } from '@/components/providers/auth-provider';
|
||||
import { QueryProvider } from '@/components/providers/query-provider';
|
||||
import { ThemeProvider } from '@/components/providers/theme-provider';
|
||||
import { WebVitals } from '@/components/providers/web-vitals';
|
||||
import { JsonLd, generateWebsiteJsonLd } from '@/components/seo/json-ld';
|
||||
import type { Locale } from '@/i18n/config';
|
||||
import { routing } from '@/i18n/routing';
|
||||
import '../globals.css';
|
||||
@@ -99,6 +101,7 @@ export default async function LocaleLayout({
|
||||
return (
|
||||
<html lang={locale} suppressHydrationWarning>
|
||||
<body>
|
||||
<JsonLd data={generateWebsiteJsonLd(siteUrl)} />
|
||||
<a
|
||||
href="#main-content"
|
||||
className="fixed left-2 top-2 z-[100] -translate-y-16 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-lg transition-transform focus:translate-y-0"
|
||||
@@ -108,7 +111,10 @@ export default async function LocaleLayout({
|
||||
<NextIntlClientProvider messages={messages}>
|
||||
<ThemeProvider>
|
||||
<QueryProvider>
|
||||
<AuthProvider>{children}</AuthProvider>
|
||||
<AuthProvider>
|
||||
<WebVitals />
|
||||
{children}
|
||||
</AuthProvider>
|
||||
</QueryProvider>
|
||||
</ThemeProvider>
|
||||
</NextIntlClientProvider>
|
||||
|
||||
Reference in New Issue
Block a user