diff --git a/app/cars/fuel-types/[fuelType]/page.tsx b/app/cars/fuel-types/[fuelType]/page.tsx index ad5297a..b201051 100644 --- a/app/cars/fuel-types/[fuelType]/page.tsx +++ b/app/cars/fuel-types/[fuelType]/page.tsx @@ -16,7 +16,7 @@ import { capitaliseWords } from "@/utils/capitaliseWords"; import { fetchApi } from "@/utils/fetchApi"; import { mergeCarsByMake } from "@/utils/mergeCarsByMake"; import type { Metadata } from "next"; -import type { Dataset, WithContext } from "schema-dts"; +import type { WebPage, WithContext } from "schema-dts"; type Params = Promise<{ fuelType: string }>; type SearchParams = Promise<{ [key: string]: string | string[] | undefined }>; @@ -34,20 +34,30 @@ export const generateMetadata = async (props: { const latestMonth = await fetchApi(`${API_URL}/months/latest`); month = latestMonth.cars; } + + const title = `${capitaliseWords(fuelType)} Cars in Singapore`; + const description = `Explore registration trends and statistics for ${fuelType} in Singapore.`; const images = `${SITE_URL}/api/og?type=${fuelType}&month=${month}`; const pageUrl = `/cars/fuel-types/${fuelType}`; return { - title: capitaliseWords(fuelType), - description: `Car registration trends for ${fuelType} fuel type`, + title, + description, openGraph: { + title, + description, images, url: pageUrl, siteName: SITE_TITLE, locale: "en_SG", type: "website", }, - twitter: { images, creator: "@sgcarstrends" }, + twitter: { + title, + description, + images, + creator: "@sgcarstrends", + }, alternates: { canonical: pageUrl, }, @@ -81,24 +91,22 @@ const CarsByFuelTypePage = async (props: { const filteredCars = mergeCarsByMake(cars); - const structuredData: WithContext = { + const structuredData: WithContext = { "@context": "https://schema.org", - "@type": "Dataset", - name: `${capitaliseWords(fuelType)} Car Registrations in Singapore`, - description: `Overview and registration statistics for ${fuelType} cars in Singapore by make`, + "@type": "WebPage", + name: `${capitaliseWords(fuelType)} Car in Singapore`, + description: `Explore registration trends and statistics for ${fuelType} in Singapore.`, url: `${SITE_URL}/cars/fuel-types/${fuelType}`, - creator: { + publisher: { "@type": "Organization", name: SITE_TITLE, + url: SITE_URL, + }, + isPartOf: { + "@type": "WebSite", + name: SITE_TITLE, + url: SITE_URL, }, - // TODO: For future use - // distribution: [ - // { - // "@type": "DataDownload", - // encodingFormat: "image/png", - // contentUrl: `${SITE_URL}/images/${type}-car-stats.png`, - // }, - // ], }; return ( diff --git a/app/cars/makes/[make]/page.tsx b/app/cars/makes/[make]/page.tsx index 84ea015..7e8c034 100644 --- a/app/cars/makes/[make]/page.tsx +++ b/app/cars/makes/[make]/page.tsx @@ -16,7 +16,7 @@ import { type Car, type Make, RevalidateTags } from "@/types"; import { fetchApi } from "@/utils/fetchApi"; import { formatDateToMonthYear } from "@/utils/formatDateToMonthYear"; import type { Metadata } from "next"; -import type { Dataset, WithContext } from "schema-dts"; +import type { WebPage, WithContext } from "schema-dts"; type Params = Promise<{ [slug: string]: string }>; @@ -73,44 +73,17 @@ const CarMakePage = async (props: { params: Params }) => { const filteredCars = mergeCarData(cars); const formattedMake = decodeURIComponent(make); - const structuredData: WithContext = { + const structuredData: WithContext = { "@context": "https://schema.org", - "@type": "Dataset", + "@type": "WebPage", name: `${formattedMake} Car Registrations in Singapore`, description: `Historical trend and monthly breakdown of ${formattedMake} car registrations by fuel type and vehicle type in Singapore`, url: `${SITE_URL}/cars/makes/${make}`, - // TODO: Suggested by Google - // temporalCoverage: "2016-06/2024-07", - variableMeasured: [ - { - "@type": "PropertyValue", - name: "Month", - description: "Month of registration", - }, - { - "@type": "PropertyValue", - name: "Fuel Type", - description: "Type of fuel used by the vehicle", - }, - { - "@type": "PropertyValue", - name: "Vehicle Type", - description: `Type of ${formattedMake} vehicle`, - }, - { - "@type": "PropertyValue", - name: "Count", - description: "Number of registrations", - }, - ], - // TODO: For future use - // distribution: [ - // { - // "@type": "DataDownload", - // encodingFormat: "text/html", - // contentUrl: `https://sgcarstrends.com/cars/${make}-trends.png`, - // }, - // ], + publisher: { + "@type": "Organization", + name: SITE_TITLE, + url: SITE_URL, + }, }; return ( diff --git a/app/cars/page.tsx b/app/cars/page.tsx index 8e478b7..f939a15 100644 --- a/app/cars/page.tsx +++ b/app/cars/page.tsx @@ -16,7 +16,7 @@ import { import { fetchApi } from "@/utils/fetchApi"; import { formatDateToMonthYear } from "@/utils/formatDateToMonthYear"; import type { Metadata } from "next"; -import type { Dataset, Report, WithContext } from "schema-dts"; +import type { WebPage, WithContext } from "schema-dts"; type SearchParams = Promise<{ [key: string]: string | string[] | undefined }>; @@ -38,16 +38,32 @@ export const generateMetadata = async (props: { } const formattedDate = formatDateToMonthYear(month); + + const title = "Car Registrations"; + const description = `Breakdown of cars registered in ${formattedDate} by fuel types and vehicle types.`; const pageUrl = `/cars`; // const images = `/api/og?title=Car Registrations for ${formattedDate}`; return { - title: "Car Registrations", - description: `Breakdown of cars registered in ${formattedDate} by fuel types and vehicle types.`, - openGraph: { url: pageUrl }, - twitter: { card: "summary_large_image" }, - alternates: { canonical: pageUrl }, + title, + description, + openGraph: { + title, + description, + url: pageUrl, + siteName: SITE_TITLE, + locale: "en_SG", + type: "website", + }, + twitter: { + title, + description, + card: "summary_large_image", + }, + alternates: { + canonical: pageUrl, + }, }; }; @@ -111,68 +127,22 @@ const CarsPage = async (props: { searchParams: SearchParams }) => { findTopEntry(numberByVehicleType); const formattedMonth = formatDateToMonthYear(month); - const datasetJsonLd: WithContext = { + const structuredData: WithContext = { "@context": "https://schema.org", - "@type": "Dataset", - name: `Singapore Car Registrations ${formattedMonth}`, - description: `Comprehensive overview of car registrations in Singapore for ${formattedMonth}, including total registrations, fuel types, vehicle types, and top manufacturers.`, + "@type": "WebPage", + name: `${formattedMonth} Car Registrations in Singapore`, + description: `Breakdown of the cars registered in ${formattedMonth} by fuel type and vehicle type.`, url: `${SITE_URL}/cars`, - creator: { + publisher: { "@type": "Organization", name: SITE_TITLE, + url: SITE_URL, }, - variableMeasured: [ - { - "@type": "PropertyValue", - name: "Total Registrations", - value: total, - }, - { - "@type": "PropertyValue", - name: "Top Fuel Type", - value: `${topFuelType} (${topFuelTypeValue})`, - }, - { - "@type": "PropertyValue", - name: "Top Vehicle Type", - value: `${topVehicleType} (${topVehicleTypeValue})`, - }, - ], - }; - const reportJsonLd: WithContext = { - "@context": "https://schema.org", - "@type": "Report", - name: `Singapore Car Registrations Report - ${formattedMonth}`, - description: `Breakdown of the cars registered in ${formattedMonth} by fuel type and vehicle type`, - url: `${SITE_URL}/cars`, - author: { - "@type": "Organization", - name: "SGCarsTrends", - }, - genre: "Statistical Report", - mentions: [ - { - "@type": "Thing", - name: "Toyota", - description: "Top overall manufacturer with 652 registrations", - }, - { - "@type": "Thing", - name: `${topFuelType}`, - description: `Most popular fuel type with ${topFuelTypeValue} registrations`, - }, - { - "@type": "Thing", - name: `${topVehicleType}`, - description: `Most popular vehicle type with ${topVehicleTypeValue} registrations`, - }, - ], }; return ( <> - - +
diff --git a/app/cars/vehicle-types/[vehicleType]/page.tsx b/app/cars/vehicle-types/[vehicleType]/page.tsx index 7e93149..6cbcc49 100644 --- a/app/cars/vehicle-types/[vehicleType]/page.tsx +++ b/app/cars/vehicle-types/[vehicleType]/page.tsx @@ -16,7 +16,7 @@ import { capitaliseWords } from "@/utils/capitaliseWords"; import { fetchApi } from "@/utils/fetchApi"; import { mergeCarsByMake } from "@/utils/mergeCarsByMake"; import type { Metadata } from "next"; -import type { Dataset, WithContext } from "schema-dts"; +import type { WebPage, WithContext } from "schema-dts"; type Params = Promise<{ vehicleType: string }>; type SearchParams = Promise<{ [key: string]: string | string[] | undefined }>; @@ -27,13 +27,12 @@ export const generateMetadata = async (props: { const params = await props.params; let { vehicleType } = params; vehicleType = decodeURIComponent(vehicleType); - const description = `${capitaliseWords(vehicleType)} historical trends`; const images = `/api/og?title=Historical Trend&type=${vehicleType}`; const canonicalUrl = `/cars/vehicle-types/${vehicleType}`; return { - title: capitaliseWords(vehicleType), - description, + title: `${capitaliseWords(vehicleType)} Cars in Singapore`, + description: `Explore registration trends and statistics for ${vehicleType} in Singapore.`, openGraph: { images, url: canonicalUrl, @@ -85,24 +84,22 @@ const CarsByVehicleTypePage = async (props: { const filteredCars = mergeCarsByMake(cars); - const structuredData: WithContext = { + const structuredData: WithContext = { "@context": "https://schema.org", - "@type": "Dataset", - name: `${capitaliseWords(vehicleType)} Car Registrations in Singapore`, - description: `Overview and registration statistics for ${vehicleType} cars in Singapore by vehicle type`, + "@type": "WebPage", + name: `${capitaliseWords(vehicleType)} Cars in Singapore`, + description: `Explore registration trends and statistics for ${vehicleType} in Singapore.`, url: `${SITE_URL}/cars/vehicle-types/${vehicleType}`, - creator: { + publisher: { "@type": "Organization", name: SITE_TITLE, + url: SITE_URL, + }, + isPartOf: { + "@type": "WebSite", + name: SITE_TITLE, + url: SITE_URL, }, - // TODO: For future use - // distribution: [ - // { - // "@type": "DataDownload", - // encodingFormat: "image/png", - // contentUrl: `${SITE_URL}/images/${type}-car-stats.png`, - // }, - // ], }; return ( diff --git a/app/coe/(prices)/page.tsx b/app/coe/(prices)/page.tsx index 3ddb86c..ff4755a 100644 --- a/app/coe/(prices)/page.tsx +++ b/app/coe/(prices)/page.tsx @@ -10,7 +10,7 @@ import { CardHeader, CardTitle, } from "@/components/ui/card"; -import { API_URL, SITE_URL } from "@/config"; +import { API_URL, SITE_TITLE, SITE_URL } from "@/config"; import { type COEBiddingResult, type COEResult, @@ -23,14 +23,29 @@ import type { WebPage, WithContext } from "schema-dts"; type SearchParams = Promise<{ [key: string]: string | string[] | undefined }>; +const title = "COE Dashboard"; +const description = + "Explore historical trends and bidding results for COE in Singapore."; + export const generateMetadata = async (): Promise => { const pageUrl = "/coe"; return { - title: "COE Dashboard", - description: "COE bidding results and historical trends", - openGraph: { url: pageUrl }, - twitter: { card: "summary_large_image" }, + title, + description, + openGraph: { + url: pageUrl, + title: "COE Dashboard", + description, + siteName: SITE_TITLE, + locale: "en_SG", + type: "website", + }, + twitter: { + card: "summary_large_image", + title, + description, + }, alternates: { canonical: pageUrl, }, @@ -88,12 +103,13 @@ const COEPricesPage = async (props: { searchParams: SearchParams }) => { const structuredData: WithContext = { "@context": "https://schema.org", "@type": "WebPage", - name: "COE Dashboard", - description: "COE bidding results and historical trends", - url: `${SITE_URL}/car`, - author: { + name: title, + description, + url: `${SITE_URL}/coe`, + publisher: { "@type": "Organization", - name: "SGCarsTrends", + name: SITE_TITLE, + url: SITE_URL, }, };