diff --git a/public/thumbnail.png b/public/thumbnail.png new file mode 100644 index 00000000..1039a867 Binary files /dev/null and b/public/thumbnail.png differ diff --git a/src/app/(content-pages)/about/layout.tsx b/src/app/(content-pages)/about/layout.tsx index e1d76ec5..9c4298cf 100644 --- a/src/app/(content-pages)/about/layout.tsx +++ b/src/app/(content-pages)/about/layout.tsx @@ -1,6 +1,15 @@ -export const metadata = { - title: "About", -}; +import { generateMetadata } from "@/utilities/generateMetaData"; + +const title = "About"; +const description = + "Philadelphia has a gun violence problem. Clean & Green Philly empowers Philadelphians to take action to solve it."; +const url = "/about"; + +export const metadata = generateMetadata({ + title, + description, + url, +}); const AboutLayout = ({ children }: { children: React.ReactNode }) => { return <>{children}; diff --git a/src/app/(content-pages)/gentrification/layout.tsx b/src/app/(content-pages)/gentrification/layout.tsx index 06385c61..e110c3d1 100644 --- a/src/app/(content-pages)/gentrification/layout.tsx +++ b/src/app/(content-pages)/gentrification/layout.tsx @@ -1,6 +1,15 @@ -export const metadata = { - title: "Gentrification", -}; +import { generateMetadata } from "@/utilities/generateMetaData"; + +const title = "Gentrification"; +const url = "/gentrification"; +const description = + "At Clean & Green Philly, we try to avoid contributing to green gentrification here in Philadelphia."; + +export const metadata = generateMetadata({ + title, + url, + description, +}); const GentrificationLayout = ({ children }: { children: React.ReactNode }) => { return <>{children}; diff --git a/src/app/(content-pages)/get-access/layout.tsx b/src/app/(content-pages)/get-access/layout.tsx index 09837f0a..30c7ebf6 100644 --- a/src/app/(content-pages)/get-access/layout.tsx +++ b/src/app/(content-pages)/get-access/layout.tsx @@ -1,6 +1,15 @@ -export const metadata = { - title: "Get Access", -}; +import { generateMetadata } from "@/utilities/generateMetaData"; + +const title = "Get Access"; +const description = + "In order to intervene in a property, you need to have some kind of legal access to do so."; +const url = "/get-access"; + +export const metadata = generateMetadata({ + title, + description, + url, +}); const GetAccessLayout = ({ children }: { children: React.ReactNode }) => { return <>{children}; diff --git a/src/app/(content-pages)/legal-disclaimer/layout.tsx b/src/app/(content-pages)/legal-disclaimer/layout.tsx index 99f85e06..b39a5fbd 100644 --- a/src/app/(content-pages)/legal-disclaimer/layout.tsx +++ b/src/app/(content-pages)/legal-disclaimer/layout.tsx @@ -1,6 +1,14 @@ -export const metadata = { - title: "Legal Disclaimer", -}; +import { generateMetadata } from "@/utilities/generateMetaData"; + +const title = "Legal Disclaimer"; +const description = "Acceptance of Terms and Conditions of Use"; +const url = "/legal-disclaimer"; + +export const metadata = generateMetadata({ + title, + description, + url, +}); const LegalDisclaimerLayout = ({ children }: { children: React.ReactNode }) => { return <>{children}; diff --git a/src/app/(content-pages)/methodology/layout.tsx b/src/app/(content-pages)/methodology/layout.tsx index 8609d49c..a6dd8224 100644 --- a/src/app/(content-pages)/methodology/layout.tsx +++ b/src/app/(content-pages)/methodology/layout.tsx @@ -1,6 +1,15 @@ -export const metadata = { - title: "Methodology", -}; +import { generateMetadata } from "@/utilities/generateMetaData"; + +const title = "Methodology"; +const description = + "Clean & Green Philly combines several public datasets to categorize Philadelphia’s vacant properties based on how important it is that someone intervene there."; +const url = "/methodology"; + +export const metadata = generateMetadata({ + title, + description, + url, +}); const MethodologyLayout = ({ children }: { children: React.ReactNode }) => { return <>{children}; diff --git a/src/app/(content-pages)/request-removal/layout.tsx b/src/app/(content-pages)/request-removal/layout.tsx index 15c8bb7f..278cf3e3 100644 --- a/src/app/(content-pages)/request-removal/layout.tsx +++ b/src/app/(content-pages)/request-removal/layout.tsx @@ -1,6 +1,14 @@ -export const metadata = { - title: "Request Removal", -}; +import { generateMetadata } from "@/utilities/generateMetaData"; + +const title = "Request Removal"; +const description = "Request to Remove a Property Listing"; +const url = "/request-removal"; + +export const metadata = generateMetadata({ + title, + description, + url, +}); const RequestRemovalLayout = ({ children }: { children: React.ReactNode }) => { return <>{children}; diff --git a/src/app/(content-pages)/take-action-overview/layout.tsx b/src/app/(content-pages)/take-action-overview/layout.tsx index 889e2f2f..2aee1c4c 100644 --- a/src/app/(content-pages)/take-action-overview/layout.tsx +++ b/src/app/(content-pages)/take-action-overview/layout.tsx @@ -1,6 +1,15 @@ -export const metadata = { - title: "Overview", -}; +import { generateMetadata } from "@/utilities/generateMetaData"; + +const title = "Overview"; +const description = + "Clean & Green Philly can help you prioritize vacant properties to return to productive use."; +const url = "/take-action-overview"; + +export const metadata = generateMetadata({ + title, + description, + url, +}); const OverviewLayout = ({ children }: { children: React.ReactNode }) => { return <>{children}; diff --git a/src/app/(content-pages)/transform-property/layout.tsx b/src/app/(content-pages)/transform-property/layout.tsx index d86075b8..47d63d2d 100644 --- a/src/app/(content-pages)/transform-property/layout.tsx +++ b/src/app/(content-pages)/transform-property/layout.tsx @@ -1,6 +1,15 @@ -export const metadata = { - title: "Transform a Property", -}; +import { generateMetadata } from "@/utilities/generateMetaData"; + +const title = "Transform a Property"; +const description = + "After gaining access to the property, you can transform a property to improve the quality of life in the neighborhood."; +const url = "/transform-property"; + +export const metadata = generateMetadata({ + title, + description, + url, +}); const TransformPropertyLayout = ({ children, diff --git a/src/app/find-properties/[[...opa_id]]/layout.tsx b/src/app/find-properties/[[...opa_id]]/layout.tsx index c8be3f11..909d321a 100644 --- a/src/app/find-properties/[[...opa_id]]/layout.tsx +++ b/src/app/find-properties/[[...opa_id]]/layout.tsx @@ -1,10 +1,17 @@ import { Header, Hotjar } from "@/components"; +import { generateMetadata } from "@/utilities/generateMetaData"; import CookieConsentBanner from "@/components/CookieConsentBanner"; -export const metadata = { - title: "Find Properties", -}; +const title = "Find Properties"; +const url = "/find-properties"; +const description = + "You can search and find vacant properties that match your goals. Use our data to understand those properties and how to take action."; +export const metadata = generateMetadata({ + title, + url, + description, +}); const MapLayout = ({ children }: { children: React.ReactNode }) => { return (
diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 8a4e65f0..140ad64d 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -3,16 +3,41 @@ import "./globals.css"; import { CookieProviderWrapper } from "./CookieProviderWrapper"; import { FilterProviderWrapper } from "./FilterProviderWrapper"; +const defaultTitle = + "Clean & Green Philly - Helping communities clean vacant properties"; +const description = + "The ultimate toolkit to help community groups clean and green vacant properties to reduce gun violence in Philadelphia."; +const siteUrl = new URL("https://staging.cleanandgreenphilly.org/"); + +/* REPLACE WITH URL BELOW BEFORE PUSHING TO PRODUCTION +const siteUrl = new URL("https://cleanandgreenphilly.org/"); +*/ + export const metadata: Metadata = { title: { - default: "Clean & Green Philly", + default: defaultTitle, template: "%s - Clean & Green Philly", }, - description: - "Reduce the gun violence in Philadelphia by finding vacant properties to clean and green them.", + description: description, icons: { icon: "/favicon.ico", }, + metadataBase: siteUrl, + openGraph: { + type: "website", + url: "/", + title: defaultTitle, + description: description, + images: [ + { + url: "/thumbnail.png", + width: 1200, + height: 630, + alt: "Clean & Green Philly", + }, + ], + siteName: "Clean & Green Philly", + }, }; export default function RootLayout({ diff --git a/src/utilities/generateMetaData.ts b/src/utilities/generateMetaData.ts new file mode 100644 index 00000000..3e81d1bc --- /dev/null +++ b/src/utilities/generateMetaData.ts @@ -0,0 +1,38 @@ +import type { Metadata } from "next"; +import { metadata as globalMetadata } from "../app/layout"; + +//imageUrl and imageAlt included to allow different images to be used for different pages in the future if desired + +export function generateMetadata({ + title, + description, + url, + imageUrl, + imageAlt, +}: { + title: string; + description?: string; + url: string; + imageUrl?: string; + imageAlt?: string; +}): Metadata { + return { + ...globalMetadata, + title, + description, + openGraph: { + ...globalMetadata.openGraph, + url, + title: `${title} - Clean & Green Philly`, + description, + images: [ + { + url: imageUrl || "/thumbnail.png", + width: 1200, + height: 630, + alt: imageAlt || "Clean & Green Philly", + }, + ], + }, + }; +}