Marketing site (bargevasat.ir) + admin-editable store links + subdomain split
- New standalone Next.js marketing site under site/ (static export, SEO): landing, download/install guide (Bazaar/Myket/iOS-PWA/web), FAQ (JSON-LD), privacy, terms, support, /admin link editor. fa RTL, sitemap/robots/manifest. - Backend: SiteLinksService (JSON-file persisted) + GET /api/site/links (public) + POST /api/admin/site/links (X-Admin-Token). ADMIN_TOKEN + Site__DataDir via env. - compose: hokm-site service (:1520) + hokm_data volume for links JSON. - CI deploy job builds + deploys the site container. - deploy/SUBDOMAIN_SPLIT.md: nginx blocks, cert reissue, DNS, ENV split. - Exclude site/ from root tsc + web docker context. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import "./globals.css";
|
||||
import { BRAND, SITE_URL } from "@/lib/site";
|
||||
import { Nav } from "@/components/Nav";
|
||||
import { Footer } from "@/components/Footer";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL(SITE_URL),
|
||||
title: {
|
||||
default: `${BRAND.nameFa} | بازی حکم آنلاین رایگان`,
|
||||
template: `%s | ${BRAND.nameFa}`,
|
||||
},
|
||||
description: BRAND.descFa,
|
||||
keywords: [
|
||||
"حکم",
|
||||
"بازی حکم",
|
||||
"حکم آنلاین",
|
||||
"بازی ورق ایرانی",
|
||||
"برگ وسط",
|
||||
"بازی کارتی آنلاین",
|
||||
"حکم با دوستان",
|
||||
"Hokm",
|
||||
"Barg-e Vasat",
|
||||
],
|
||||
applicationName: BRAND.nameFa,
|
||||
authors: [{ name: BRAND.nameFa }],
|
||||
alternates: { canonical: "/" },
|
||||
openGraph: {
|
||||
type: "website",
|
||||
locale: "fa_IR",
|
||||
url: SITE_URL,
|
||||
siteName: BRAND.nameFa,
|
||||
title: `${BRAND.nameFa} | بازی حکم آنلاین رایگان`,
|
||||
description: BRAND.descFa,
|
||||
images: [{ url: "/og.png", width: 1200, height: 630, alt: BRAND.nameFa }],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: `${BRAND.nameFa} | بازی حکم آنلاین`,
|
||||
description: BRAND.descFa,
|
||||
images: ["/og.png"],
|
||||
},
|
||||
icons: { icon: "/icon.svg", apple: "/icon.svg" },
|
||||
manifest: "/manifest.webmanifest",
|
||||
};
|
||||
|
||||
export const viewport: Viewport = {
|
||||
themeColor: "#070b18",
|
||||
width: "device-width",
|
||||
initialScale: 1,
|
||||
};
|
||||
|
||||
const jsonLd = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "VideoGame",
|
||||
name: "برگ وسط",
|
||||
alternateName: "Barg-e Vasat",
|
||||
description: BRAND.descFa,
|
||||
url: SITE_URL,
|
||||
applicationCategory: "GameApplication",
|
||||
genre: "بازی کارتی",
|
||||
operatingSystem: "Android, iOS, Web",
|
||||
inLanguage: "fa-IR",
|
||||
offers: { "@type": "Offer", price: "0", priceCurrency: "IRR" },
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html lang="fa" dir="rtl">
|
||||
<body>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
|
||||
/>
|
||||
<Nav />
|
||||
<main>{children}</main>
|
||||
<Footer />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user