feat : add sitemao and some SEO
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
# Public site origin used for SEO metadata, sitemap, and robots.txt.
|
||||
BASE_URL=https://guide.sudloh.com
|
||||
|
||||
# Local-only demo mode serves sanitized fixtures and bypasses external services.
|
||||
# Keep this false in every deployed environment.
|
||||
BUZZ_DEMO_MODE=false
|
||||
|
||||
+3
-1
@@ -4,6 +4,7 @@ import { Anuphan, Geist_Mono } from "next/font/google";
|
||||
import { DeploymentUpdateNotifier } from "@/components/deployment-update-notifier";
|
||||
import { PageProgress } from "@/components/page-progress";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import { siteUrl } from "@/lib/site-url";
|
||||
|
||||
import "./globals.css";
|
||||
|
||||
@@ -19,12 +20,13 @@ const geistMono = Geist_Mono({
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL("https://guide.sudloh.com"),
|
||||
metadataBase: new URL(siteUrl),
|
||||
title: {
|
||||
default: "Buzz Guide",
|
||||
template: "%s",
|
||||
},
|
||||
description: "ไกด์ตัวละครจากช่องเกนชินไม่ใช่เกมมือถือ",
|
||||
keywords: ["เกนชิน", "เกนชินไม่ใช่เกมมือถือ", "Buzz", "ไกด์", "สุดหล่อ"],
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }: LayoutProps<"/">) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { MetadataRoute } from "next";
|
||||
|
||||
import { siteUrl } from "@/lib/site-url";
|
||||
|
||||
export default function robots(): MetadataRoute.Robots {
|
||||
return {
|
||||
rules: {
|
||||
@@ -7,5 +9,6 @@ export default function robots(): MetadataRoute.Robots {
|
||||
allow: "/",
|
||||
disallow: ["/admin", "/api", "/register"],
|
||||
},
|
||||
sitemap: `${siteUrl}/sitemap.xml`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { MetadataRoute } from "next";
|
||||
import { connection } from "next/server";
|
||||
|
||||
import { getCachedPublicGuideCards } from "@/lib/cache/public";
|
||||
import { siteUrl } from "@/lib/site-url";
|
||||
|
||||
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
|
||||
await connection();
|
||||
const guides = await getCachedPublicGuideCards();
|
||||
|
||||
return [
|
||||
{ url: siteUrl },
|
||||
...guides.map((guide) => ({
|
||||
url: `${siteUrl}/${encodeURIComponent(guide.slug)}`,
|
||||
})),
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
const configuredBaseUrl = process.env.BASE_URL?.trim();
|
||||
|
||||
if (!configuredBaseUrl) {
|
||||
throw new Error("BASE_URL is required for site metadata and sitemaps.");
|
||||
}
|
||||
|
||||
export const siteUrl = new URL(configuredBaseUrl).origin;
|
||||
Reference in New Issue
Block a user