diff --git a/apps/web/package.json b/apps/web/package.json index 39d7835b..d94e87d8 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -45,6 +45,7 @@ "react-leaflet": "^4.2.1", "react-qr-code": "^2.0.15", "recharts": "^2.15.0", + "schema-dts": "^1.1.2", "superjson": "catalog:", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7", diff --git a/apps/web/src/app/(default)/bottles/[bottleId]/layout.tsx b/apps/web/src/app/(default)/bottles/[bottleId]/layout.tsx index d0fa0057..6c2552a5 100644 --- a/apps/web/src/app/(default)/bottles/[bottleId]/layout.tsx +++ b/apps/web/src/app/(default)/bottles/[bottleId]/layout.tsx @@ -4,9 +4,11 @@ import CollectionAction from "@peated/web/components/collectionAction"; import FlavorProfile from "@peated/web/components/flavorProfile"; import ShareButton from "@peated/web/components/shareButton"; import SkeletonButton from "@peated/web/components/skeletonButton"; +import { summarize } from "@peated/web/lib/markdown"; import { getTrpcClient } from "@peated/web/lib/trpc/client.server"; import { redirect } from "next/navigation"; import { Suspense, type ReactNode } from "react"; +import type { Product, WithContext } from "schema-dts"; import ModActions from "./modActions"; export default async function Layout({ @@ -30,8 +32,40 @@ export default async function Layout({ return redirect(`/bottles/${bottle.id}/`); } + const jsonLd: WithContext = { + "@context": "https://schema.org", + "@type": "Product", + name: bottle.fullName, + image: bottle.imageUrl ?? undefined, + description: summarize(bottle.description || "", 200), + brand: { + "@type": "Brand", + name: bottle.brand?.name, + }, + aggregateRating: bottle.totalTastings + ? { + "@type": "AggregateRating", + ratingValue: bottle.avgRating ?? 0, + reviewCount: bottle.totalTastings ?? 0, + } + : undefined, + offers: bottle.lastPrice + ? { + "@type": "AggregateOffer", + offerCount: 1, + lowPrice: bottle.lastPrice?.price, + highPrice: bottle.lastPrice?.price, + priceCurrency: bottle.lastPrice?.currency, + } + : undefined, + }; + return ( <> +