diff --git a/app/create-trip/layout.tsx b/app/create-trip/layout.tsx new file mode 100644 index 0000000..911b0e5 --- /dev/null +++ b/app/create-trip/layout.tsx @@ -0,0 +1,13 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Buat Open Trip", + description: + "Buat open trip pendakian gunung di SeTrip. Atur itinerary, harga, dan ajak pendaki lain ikut serta.", + alternates: { canonical: "/create-trip" }, + robots: { index: false, follow: false }, +}; + +export default function CreateTripLayout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/app/layout.tsx b/app/layout.tsx index 93c0a7d..bfb10f9 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -2,6 +2,7 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import { SessionProvider } from "@/components/providers/session-provider"; import { Navbar } from "@/components/shared/navbar"; +import { siteConfig, siteUrl } from "@/lib/site"; import "./globals.css"; const geistSans = Geist({ @@ -15,9 +16,50 @@ const geistMono = Geist_Mono({ }); export const metadata: Metadata = { - title: "SeTrip", - description: - "Cari open trip pendakian gunung, gabung bareng, nikmati petualangan ke gunung-gunung Jawa Barat.", + metadataBase: new URL(siteUrl), + title: { + default: `${siteConfig.name} — Open Trip Pendakian Gunung`, + template: `%s · ${siteConfig.name}`, + }, + description: siteConfig.description, + applicationName: siteConfig.name, + keywords: [...siteConfig.keywords], + authors: [{ name: siteConfig.name }], + creator: siteConfig.name, + publisher: siteConfig.name, + alternates: { canonical: "/" }, + openGraph: { + type: "website", + locale: "id_ID", + url: "/", + siteName: siteConfig.name, + title: `${siteConfig.name} — Open Trip Pendakian Gunung`, + description: siteConfig.description, + images: [ + { + url: "/images/SeTrip.png", + width: 1200, + height: 630, + alt: `${siteConfig.name} — ${siteConfig.slogan}`, + }, + ], + }, + twitter: { + card: "summary_large_image", + title: `${siteConfig.name} — Open Trip Pendakian Gunung`, + description: siteConfig.description, + images: ["/images/SeTrip.png"], + }, + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + "max-image-preview": "large", + "max-snippet": -1, + }, + }, icons: { icon: "/SeTrip.ico", apple: "/images/SeTrip.png", diff --git a/app/login/layout.tsx b/app/login/layout.tsx new file mode 100644 index 0000000..85ab886 --- /dev/null +++ b/app/login/layout.tsx @@ -0,0 +1,13 @@ +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Masuk", + description: + "Masuk ke akun SeTrip untuk gabung open trip pendakian dan kelola perjalananmu.", + alternates: { canonical: "/login" }, + robots: { index: false, follow: true }, +}; + +export default function LoginLayout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/app/page.tsx b/app/page.tsx index 4a29a25..9eabe88 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,7 +1,20 @@ +import type { Metadata } from "next"; import Link from "next/link"; import Image from "next/image"; import { tripService } from "@/server/services/trip.service"; import { TripCard } from "@/features/trip/components/trip-card"; +import { siteConfig, siteUrl, absoluteUrl } from "@/lib/site"; + +export const metadata: Metadata = { + title: "Cari Open Trip Pendakian Gunung Bareng", + description: `${siteConfig.slogan} ${siteConfig.description}`, + alternates: { canonical: "/" }, + openGraph: { + title: `${siteConfig.name} — Open Trip Pendakian Gunung Bareng`, + description: siteConfig.slogan, + url: "/", + }, +}; export default async function HomePage() { const trips = await tripService.getOpenTrips(); @@ -25,8 +38,41 @@ export default async function HomePage() { .filter((t) => !shownIds.has(t.id) && t.price <= 300000) .slice(0, 3); + const orgJsonLd = { + "@context": "https://schema.org", + "@graph": [ + { + "@type": "Organization", + "@id": `${siteUrl}/#organization`, + name: siteConfig.name, + url: siteUrl, + logo: absoluteUrl("/images/SeTrip.png"), + slogan: siteConfig.slogan, + description: siteConfig.description, + }, + { + "@type": "WebSite", + "@id": `${siteUrl}/#website`, + url: siteUrl, + name: siteConfig.name, + description: siteConfig.description, + publisher: { "@id": `${siteUrl}/#organization` }, + inLanguage: "id-ID", + potentialAction: { + "@type": "SearchAction", + target: `${siteUrl}/trips?q={search_term_string}`, + "query-input": "required name=search_term_string", + }, + }, + ], + }; + return (
+