From 1cfae2861f44f4917c1728368c747bc2b437f895 Mon Sep 17 00:00:00 2001 From: Ru Chern Chong Date: Sun, 8 Dec 2024 03:09:17 +0800 Subject: [PATCH 1/2] Refactor route group --- app/{(dashboard) => (default)}/(home)/page.tsx | 0 app/{(dashboard) => (default)}/@breadcrumbs/[...slug]/page.tsx | 0 app/{(dashboard) => (default)}/@breadcrumbs/default.tsx | 0 app/{(dashboard) => (default)}/about/page.tsx | 0 app/{(dashboard) => (default)}/cars/DistributionPieChart.tsx | 0 app/{(dashboard) => (default)}/cars/TrendChart.tsx | 0 .../cars/fuel-types/[fuelType]/page.tsx | 2 +- app/{(dashboard) => (default)}/cars/makes/[make]/TrendChart.tsx | 0 app/{(dashboard) => (default)}/cars/makes/[make]/columns.tsx | 0 app/{(dashboard) => (default)}/cars/makes/[make]/page.tsx | 2 +- app/{(dashboard) => (default)}/cars/page.tsx | 0 app/{(dashboard) => (default)}/cars/utils/fetchMonths.ts | 0 .../cars/vehicle-types/[vehicleType]/page.tsx | 2 +- app/{(dashboard) => (default)}/coe/(prices)/TrendTable.tsx | 2 +- app/{(dashboard) => (default)}/coe/(prices)/columns.tsx | 0 app/{(dashboard) => (default)}/coe/(prices)/page.tsx | 2 +- app/{(dashboard) => (default)}/coe/bidding/page.tsx | 0 app/{(dashboard) => (default)}/contact/page.tsx | 0 app/{(dashboard) => (default)}/layout.tsx | 0 app/components/CarOverviewTrends.tsx | 2 +- components/StatisticsCard.tsx | 2 +- 21 files changed, 7 insertions(+), 7 deletions(-) rename app/{(dashboard) => (default)}/(home)/page.tsx (100%) rename app/{(dashboard) => (default)}/@breadcrumbs/[...slug]/page.tsx (100%) rename app/{(dashboard) => (default)}/@breadcrumbs/default.tsx (100%) rename app/{(dashboard) => (default)}/about/page.tsx (100%) rename app/{(dashboard) => (default)}/cars/DistributionPieChart.tsx (100%) rename app/{(dashboard) => (default)}/cars/TrendChart.tsx (100%) rename app/{(dashboard) => (default)}/cars/fuel-types/[fuelType]/page.tsx (98%) rename app/{(dashboard) => (default)}/cars/makes/[make]/TrendChart.tsx (100%) rename app/{(dashboard) => (default)}/cars/makes/[make]/columns.tsx (100%) rename app/{(dashboard) => (default)}/cars/makes/[make]/page.tsx (98%) rename app/{(dashboard) => (default)}/cars/page.tsx (100%) rename app/{(dashboard) => (default)}/cars/utils/fetchMonths.ts (100%) rename app/{(dashboard) => (default)}/cars/vehicle-types/[vehicleType]/page.tsx (98%) rename app/{(dashboard) => (default)}/coe/(prices)/TrendTable.tsx (93%) rename app/{(dashboard) => (default)}/coe/(prices)/columns.tsx (100%) rename app/{(dashboard) => (default)}/coe/(prices)/page.tsx (98%) rename app/{(dashboard) => (default)}/coe/bidding/page.tsx (100%) rename app/{(dashboard) => (default)}/contact/page.tsx (100%) rename app/{(dashboard) => (default)}/layout.tsx (100%) diff --git a/app/(dashboard)/(home)/page.tsx b/app/(default)/(home)/page.tsx similarity index 100% rename from app/(dashboard)/(home)/page.tsx rename to app/(default)/(home)/page.tsx diff --git a/app/(dashboard)/@breadcrumbs/[...slug]/page.tsx b/app/(default)/@breadcrumbs/[...slug]/page.tsx similarity index 100% rename from app/(dashboard)/@breadcrumbs/[...slug]/page.tsx rename to app/(default)/@breadcrumbs/[...slug]/page.tsx diff --git a/app/(dashboard)/@breadcrumbs/default.tsx b/app/(default)/@breadcrumbs/default.tsx similarity index 100% rename from app/(dashboard)/@breadcrumbs/default.tsx rename to app/(default)/@breadcrumbs/default.tsx diff --git a/app/(dashboard)/about/page.tsx b/app/(default)/about/page.tsx similarity index 100% rename from app/(dashboard)/about/page.tsx rename to app/(default)/about/page.tsx diff --git a/app/(dashboard)/cars/DistributionPieChart.tsx b/app/(default)/cars/DistributionPieChart.tsx similarity index 100% rename from app/(dashboard)/cars/DistributionPieChart.tsx rename to app/(default)/cars/DistributionPieChart.tsx diff --git a/app/(dashboard)/cars/TrendChart.tsx b/app/(default)/cars/TrendChart.tsx similarity index 100% rename from app/(dashboard)/cars/TrendChart.tsx rename to app/(default)/cars/TrendChart.tsx diff --git a/app/(dashboard)/cars/fuel-types/[fuelType]/page.tsx b/app/(default)/cars/fuel-types/[fuelType]/page.tsx similarity index 98% rename from app/(dashboard)/cars/fuel-types/[fuelType]/page.tsx rename to app/(default)/cars/fuel-types/[fuelType]/page.tsx index 8e3d288..d22281b 100644 --- a/app/(dashboard)/cars/fuel-types/[fuelType]/page.tsx +++ b/app/(default)/cars/fuel-types/[fuelType]/page.tsx @@ -1,5 +1,5 @@ import dynamic from "next/dynamic"; -import { fetchMonths } from "@/app/(dashboard)/cars/utils/fetchMonths"; +import { fetchMonths } from "@/app/(default)/cars/utils/fetchMonths"; import { EmptyData } from "@/components/EmptyData"; import { StructuredData } from "@/components/StructuredData"; import Typography from "@/components/Typography"; diff --git a/app/(dashboard)/cars/makes/[make]/TrendChart.tsx b/app/(default)/cars/makes/[make]/TrendChart.tsx similarity index 100% rename from app/(dashboard)/cars/makes/[make]/TrendChart.tsx rename to app/(default)/cars/makes/[make]/TrendChart.tsx diff --git a/app/(dashboard)/cars/makes/[make]/columns.tsx b/app/(default)/cars/makes/[make]/columns.tsx similarity index 100% rename from app/(dashboard)/cars/makes/[make]/columns.tsx rename to app/(default)/cars/makes/[make]/columns.tsx diff --git a/app/(dashboard)/cars/makes/[make]/page.tsx b/app/(default)/cars/makes/[make]/page.tsx similarity index 98% rename from app/(dashboard)/cars/makes/[make]/page.tsx rename to app/(default)/cars/makes/[make]/page.tsx index ae56728..15a0e83 100644 --- a/app/(dashboard)/cars/makes/[make]/page.tsx +++ b/app/(default)/cars/makes/[make]/page.tsx @@ -1,5 +1,5 @@ import dynamic from "next/dynamic"; -import { columns } from "@/app/(dashboard)/cars/makes/[make]/columns"; +import { columns } from "@/app/(default)/cars/makes/[make]/columns"; import { MakeSelector } from "@/app/components/MakeSelector"; import { EmptyData } from "@/components/EmptyData"; import { StructuredData } from "@/components/StructuredData"; diff --git a/app/(dashboard)/cars/page.tsx b/app/(default)/cars/page.tsx similarity index 100% rename from app/(dashboard)/cars/page.tsx rename to app/(default)/cars/page.tsx diff --git a/app/(dashboard)/cars/utils/fetchMonths.ts b/app/(default)/cars/utils/fetchMonths.ts similarity index 100% rename from app/(dashboard)/cars/utils/fetchMonths.ts rename to app/(default)/cars/utils/fetchMonths.ts diff --git a/app/(dashboard)/cars/vehicle-types/[vehicleType]/page.tsx b/app/(default)/cars/vehicle-types/[vehicleType]/page.tsx similarity index 98% rename from app/(dashboard)/cars/vehicle-types/[vehicleType]/page.tsx rename to app/(default)/cars/vehicle-types/[vehicleType]/page.tsx index a9cd54f..4cde65f 100644 --- a/app/(dashboard)/cars/vehicle-types/[vehicleType]/page.tsx +++ b/app/(default)/cars/vehicle-types/[vehicleType]/page.tsx @@ -1,5 +1,5 @@ import dynamic from "next/dynamic"; -import { fetchMonths } from "@/app/(dashboard)/cars/utils/fetchMonths"; +import { fetchMonths } from "@/app/(default)/cars/utils/fetchMonths"; import { EmptyData } from "@/components/EmptyData"; import { StructuredData } from "@/components/StructuredData"; import Typography from "@/components/Typography"; diff --git a/app/(dashboard)/coe/(prices)/TrendTable.tsx b/app/(default)/coe/(prices)/TrendTable.tsx similarity index 93% rename from app/(dashboard)/coe/(prices)/TrendTable.tsx rename to app/(default)/coe/(prices)/TrendTable.tsx index ed3beb2..35a9710 100644 --- a/app/(dashboard)/coe/(prices)/TrendTable.tsx +++ b/app/(default)/coe/(prices)/TrendTable.tsx @@ -1,7 +1,7 @@ "use client"; import { useMemo } from "react"; -import { columns } from "@/app/(dashboard)/coe/(prices)/columns"; +import { columns } from "@/app/(default)/coe/(prices)/columns"; import useStore from "@/app/store"; import { DataTable } from "@/components/ui/data-table"; import type { COEResult } from "@/types"; diff --git a/app/(dashboard)/coe/(prices)/columns.tsx b/app/(default)/coe/(prices)/columns.tsx similarity index 100% rename from app/(dashboard)/coe/(prices)/columns.tsx rename to app/(default)/coe/(prices)/columns.tsx diff --git a/app/(dashboard)/coe/(prices)/page.tsx b/app/(default)/coe/(prices)/page.tsx similarity index 98% rename from app/(dashboard)/coe/(prices)/page.tsx rename to app/(default)/coe/(prices)/page.tsx index bd9edab..8f5d190 100644 --- a/app/(dashboard)/coe/(prices)/page.tsx +++ b/app/(default)/coe/(prices)/page.tsx @@ -1,4 +1,4 @@ -import { TrendTable } from "@/app/(dashboard)/coe/(prices)/TrendTable"; +import { TrendTable } from "@/app/(default)/coe/(prices)/TrendTable"; import { COECategories } from "@/components/COECategories"; import { COEPremiumChart } from "@/components/COEPremiumChart"; import { StructuredData } from "@/components/StructuredData"; diff --git a/app/(dashboard)/coe/bidding/page.tsx b/app/(default)/coe/bidding/page.tsx similarity index 100% rename from app/(dashboard)/coe/bidding/page.tsx rename to app/(default)/coe/bidding/page.tsx diff --git a/app/(dashboard)/contact/page.tsx b/app/(default)/contact/page.tsx similarity index 100% rename from app/(dashboard)/contact/page.tsx rename to app/(default)/contact/page.tsx diff --git a/app/(dashboard)/layout.tsx b/app/(default)/layout.tsx similarity index 100% rename from app/(dashboard)/layout.tsx rename to app/(default)/layout.tsx diff --git a/app/components/CarOverviewTrends.tsx b/app/components/CarOverviewTrends.tsx index 04d6ac7..8921eb3 100644 --- a/app/components/CarOverviewTrends.tsx +++ b/app/components/CarOverviewTrends.tsx @@ -13,7 +13,7 @@ interface Props { } const DataTable = dynamic(() => import("@/components/DataTable")); -const TrendChart = dynamic(() => import("@/app/(dashboard)/cars/TrendChart")); +const TrendChart = dynamic(() => import("@/app/(default)/cars/TrendChart")); export const CarOverviewTrends = ({ cars }: Props) => { const total = cars.reduce((acc, curr) => acc + curr.number, 0); diff --git a/components/StatisticsCard.tsx b/components/StatisticsCard.tsx index 8eb7dc3..b99f9f6 100644 --- a/components/StatisticsCard.tsx +++ b/components/StatisticsCard.tsx @@ -25,7 +25,7 @@ import { formatPercent } from "@/utils/formatPercent"; import { slugify } from "@/utils/slugify"; const DistributionPieChart = dynamic( - () => import("@/app/(dashboard)/cars/DistributionPieChart"), + () => import("@/app/(default)/cars/DistributionPieChart"), ); export const StatisticsCard = ({ From 819176e25f87c3f8253df047e0872cb7982abe02 Mon Sep 17 00:00:00 2001 From: Ru Chern Chong Date: Sun, 8 Dec 2024 03:30:27 +0800 Subject: [PATCH 2/2] Fix some SEO details --- .../cars/fuel-types/[fuelType]/page.tsx | 20 +++++++++------- app/(default)/cars/makes/[make]/page.tsx | 23 ++++++++++-------- app/(default)/cars/page.tsx | 20 +++++++++------- .../cars/vehicle-types/[vehicleType]/page.tsx | 24 +++++++++++-------- app/(default)/coe/(prices)/page.tsx | 13 +++++----- app/(default)/layout.tsx | 9 ++++--- 6 files changed, 61 insertions(+), 48 deletions(-) diff --git a/app/(default)/cars/fuel-types/[fuelType]/page.tsx b/app/(default)/cars/fuel-types/[fuelType]/page.tsx index d22281b..9a9da28 100644 --- a/app/(default)/cars/fuel-types/[fuelType]/page.tsx +++ b/app/(default)/cars/fuel-types/[fuelType]/page.tsx @@ -33,18 +33,17 @@ export const generateMetadata = async (props: { const formattedFuelType = deslugify(fuelType); const title = `${formattedFuelType} Cars in Singapore`; - const description = `Explore registration trends and statistics for ${formattedFuelType} cars in Singapore.`; - const pageUrl = `/cars/fuel-types/${fuelType}`; + const description = `${formattedFuelType} cars registrations by month. Explore registration trends, statistics and distribution by fuel type for the month in Singapore.`; + const canonical = `/cars/fuel-types/${fuelType}`; return { - metadataBase: new URL(SITE_URL), title, description, openGraph: { title, description, - images: "/opengraph-image.png", - url: pageUrl, + images: `${SITE_URL}/opengraph-image.png`, + url: canonical, siteName: SITE_TITLE, locale: "en_SG", type: "website", @@ -53,12 +52,12 @@ export const generateMetadata = async (props: { card: "summary_large_image", title, description, - images: "/opengraph-image.png", + images: `${SITE_URL}/twitter-image.png`, site: "@sgcarstrends", creator: "@sgcarstrends", }, alternates: { - canonical: pageUrl, + canonical, }, }; }; @@ -91,11 +90,14 @@ const CarsByFuelTypePage = async (props: { const filteredCars = mergeCarsByMake(cars); const formattedFuelType = deslugify(fuelType); + + const title = `${formattedFuelType} Cars in Singapore`; + const description = `${formattedFuelType} cars overview. Explore registration trends, statistics and distribution by fuel type for the month in Singapore.`; const structuredData: WithContext = { "@context": "https://schema.org", "@type": "WebPage", - name: `${formattedFuelType} Car in Singapore`, - description: `Explore registration trends and statistics for ${formattedFuelType} cars in Singapore.`, + name: title, + description, url: `${SITE_URL}/cars/fuel-types/${fuelType}`, publisher: { "@type": "Organization", diff --git a/app/(default)/cars/makes/[make]/page.tsx b/app/(default)/cars/makes/[make]/page.tsx index 15a0e83..6f76ba0 100644 --- a/app/(default)/cars/makes/[make]/page.tsx +++ b/app/(default)/cars/makes/[make]/page.tsx @@ -31,29 +31,29 @@ export const generateMetadata = async (props: { const { make } = params; const formattedMake = deslugify(make).toUpperCase(); - const description = `Historical trends and monthly breakdown of ${formattedMake} cars by fuel and vehicle types in Singapore.`; + const title = `${formattedMake} Cars Overview`; + const description = `${formattedMake} cars overview. Historical car registrations trends and monthly breakdown by fuel and vehicle types in Singapore.`; // const images = `/api/og?title=Historical Trend&make=${make}`; - const canonicalUrl = `/cars/makes/${make}`; + const canonical = `/cars/makes/${make}`; return { - metadataBase: new URL(SITE_URL), - title: formattedMake, + title, description, openGraph: { - images: "/opengraph-image.png", - url: canonicalUrl, + images: `${SITE_URL}/opengraph-image.png`, + url: canonical, siteName: SITE_TITLE, locale: "en_SG", type: "website", }, twitter: { card: "summary_large_image", - images: "/opengraph-image.png", + images: `${SITE_URL}/twitter-image.png`, site: "@sgcarstrends", creator: "@sgcarstrends", }, alternates: { - canonical: canonicalUrl, + canonical, }, }; }; @@ -81,11 +81,14 @@ const CarMakePage = async (props: { params: Params }) => { const filteredCars = mergeCarData(cars); const formattedMake = deslugify(make).toUpperCase(); + + const title = `${formattedMake} Cars Overview`; + const description = `${formattedMake} cars overview. Historical car registrations trends and monthly breakdown by fuel and vehicle types in Singapore.`; const structuredData: WithContext = { "@context": "https://schema.org", "@type": "WebPage", - name: `${formattedMake} Car Registrations in Singapore`, - description: `Historical trends and monthly breakdown of ${formattedMake} cars by fuel and vehicle types in Singapore.`, + name: title, + description, url: `${SITE_URL}/cars/makes/${make}`, publisher: { "@type": "Organization", diff --git a/app/(default)/cars/page.tsx b/app/(default)/cars/page.tsx index 93a7cc3..0d9ae30 100644 --- a/app/(default)/cars/page.tsx +++ b/app/(default)/cars/page.tsx @@ -33,31 +33,30 @@ export const generateMetadata = async (props: { const formattedMonth = formatDateToMonthYear(month); - const title = `${formattedMonth} Car Registrations in Singapore`; + const title = "Car Registrations in Singapore"; const description = `Discover ${formattedMonth} car registrations in Singapore. See detailed stats by fuel type, vehicle type, and top brands.`; - const pageUrl = `/cars`; + const canonical = `/cars`; // const images = `/api/og?title=Car Registrations for ${formattedMonth}`; return { - metadataBase: new URL(SITE_URL), title, description, openGraph: { - images: "/opengraph-image.png", - url: pageUrl, + images: `${SITE_URL}/opengraph-image.png`, + url: canonical, siteName: SITE_TITLE, locale: "en_SG", type: "website", }, twitter: { card: "summary_large_image", - images: "/opengraph-image.png", + images: `${SITE_URL}/twitter-image.png`, site: "@sgcarstrends", creator: "@sgcarstrends", }, alternates: { - canonical: pageUrl, + canonical, }, }; }; @@ -126,11 +125,14 @@ const CarsPage = async (props: { searchParams: SearchParams }) => { findTopEntry(numberByVehicleType); const formattedMonth = formatDateToMonthYear(month); + + const title = "Car Registrations in Singapore"; + const description = `Discover ${formattedMonth} car registrations in Singapore. See detailed stats by fuel type, vehicle type, and top brands.`; const structuredData: WithContext = { "@context": "https://schema.org", "@type": "WebPage", - name: `${formattedMonth} Car Registrations in Singapore`, - description: `Discover ${formattedMonth} car registrations in Singapore. See detailed stats by fuel type, vehicle type, and top brands.`, + name: title, + description, url: `${SITE_URL}/cars`, publisher: { "@type": "Organization", diff --git a/app/(default)/cars/vehicle-types/[vehicleType]/page.tsx b/app/(default)/cars/vehicle-types/[vehicleType]/page.tsx index 4cde65f..0237204 100644 --- a/app/(default)/cars/vehicle-types/[vehicleType]/page.tsx +++ b/app/(default)/cars/vehicle-types/[vehicleType]/page.tsx @@ -31,28 +31,29 @@ export const generateMetadata = async (props: { const { vehicleType } = params; const formattedVehicleType = deslugify(vehicleType); + const title = `${formattedVehicleType} Cars in Singapore`; + const description = `${formattedVehicleType} cars registrations by month. Explore registration trends, statistics and distribution by vehicle type for the month in Singapore.`; // const images = `/api/og?title=Historical Trend&type=${vehicleType}`; - const canonicalUrl = `/cars/vehicle-types/${vehicleType}`; + const canonical = `/cars/vehicle-types/${vehicleType}`; return { - metadataBase: new URL(SITE_URL), - title: `${formattedVehicleType} Cars in Singapore`, - description: `Explore registration trends and statistics for ${formattedVehicleType} cars in Singapore.`, + title, + description, openGraph: { - images: "/opengraph-image.png", - url: canonicalUrl, + images: `${SITE_URL}/opengraph-image.png`, + url: canonical, siteName: SITE_TITLE, locale: "en_SG", type: "website", }, twitter: { card: "summary_large_image", - images: "/opengraph-image.png", + images: `${SITE_URL}/twitter-image.png`, site: "@sgcarstrends", creator: "@sgcarstrends", }, alternates: { - canonical: canonicalUrl, + canonical, }, }; }; @@ -92,11 +93,14 @@ const CarsByVehicleTypePage = async (props: { const filteredCars = mergeCarsByMake(cars); const formattedVehicleType = deslugify(vehicleType); + + const title = `${formattedVehicleType} Cars in Singapore`; + const description = `${formattedVehicleType} cars registrations by month. Explore registration trends, statistics and distribution by vehicle type for the month in Singapore.`; const structuredData: WithContext = { "@context": "https://schema.org", "@type": "WebPage", - name: `${formattedVehicleType} Cars in Singapore`, - description: `Explore registration trends and statistics for ${formattedVehicleType} cars in Singapore.`, + name: title, + description, url: `${SITE_URL}/cars/vehicle-types/${vehicleType}`, publisher: { "@type": "Organization", diff --git a/app/(default)/coe/(prices)/page.tsx b/app/(default)/coe/(prices)/page.tsx index 8f5d190..dcf19ea 100644 --- a/app/(default)/coe/(prices)/page.tsx +++ b/app/(default)/coe/(prices)/page.tsx @@ -25,31 +25,30 @@ type SearchParams = Promise<{ [key: string]: string | string[] | undefined }>; const title = "COE Result"; const description = - "Explore historical trends and bidding results for COE in Singapore."; + "Explore historical Certificate of Entitlement (COE) price trends and bidding results for car registrations in Singapore."; export const generateMetadata = async (): Promise => { - const pageUrl = "/coe"; + const canonical = "/coe"; // const images = "/api/og?title=COE Result"; return { - metadataBase: new URL(SITE_URL), title, description, openGraph: { - images: "/opengraph-image.png", - url: pageUrl, + images: `${SITE_URL}/opengraph-image.png`, + url: canonical, siteName: SITE_TITLE, locale: "en_SG", type: "website", }, twitter: { card: "summary_large_image", - images: "/opengraph-image.png", + images: `${SITE_URL}/twitter-image.png`, site: "@sgcarstrends", creator: "@sgcarstrends", }, alternates: { - canonical: pageUrl, + canonical, }, }; }; diff --git a/app/(default)/layout.tsx b/app/(default)/layout.tsx index eb04a2e..5332501 100644 --- a/app/(default)/layout.tsx +++ b/app/(default)/layout.tsx @@ -20,13 +20,16 @@ const url = new URL(SITE_URL); export const metadata: Metadata = { metadataBase: url, - title, + title: { + template: `%s - ${SITE_TITLE}`, + default: SITE_TITLE, + }, description, robots: { index: true, follow: true }, openGraph: { title, description, - images: "/opengraph-image.png", + images: `${SITE_URL}/opengraph-image.png`, url, siteName: title, locale: "en_SG", @@ -36,7 +39,7 @@ export const metadata: Metadata = { card: "summary_large_image", title, description, - images: "/opengraph-image.png", + images: `${SITE_URL}/twitter-image.png`, site: "@sgcarstrends", creator: "@sgcarstrends", },