diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 7163b0d..53129b6 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -32,6 +32,7 @@ module.exports = { }, ], "@typescript-eslint/naming-convention": 1, + "@typescript-eslint/strict-boolean-expressions": "warn" }, settings: { react: { version: "18.2.0" }, diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index d02b5c0..03f1bf7 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -11,6 +11,19 @@ import LoudspeakerIcon from "@/assets/graphics/loudspeaker_icon.webp"; import LightbulbIcon from "@/assets/graphics/lightbulb_icon.webp"; import Image from "next/image"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "now-u | About Us", + openGraph: { + images: [ + { + url: Elgars.src, + alt: "Picture of the founders – siblings James and Lizzie Elgar", + }, + ], + } +} const icons = [ { @@ -36,7 +49,6 @@ const icons = [ const About = (): JSX.Element => { return ( <> - now-u | About Us
; +} + +export async function generateMetadata( + { params }: MetadataProps, + parent: ResolvingMetadata, +): Promise { + const slug = (await params).slug; + const blog = await getPostBySlug(slug); + + if (blog !== undefined) { + const author = blog.author?.full_name; + const headerImage = blog.headerImage; + + return { + title: `${blog.title} - now-u Blog`, + description: blog.subtitle, + authors: author !== undefined ? [{ name: author }] : [], + openGraph: { + type: "article", + images: [ + { + url: headerImage, + }, + ], + locale: "en_GB", + publishedTime: blog.publishedDate, + modifiedTime: blog.updateDate, + expirationTime: blog.archiveDate, + }, + }; + } else { + return { + title: "Unknown Blog Post", + }; + } +} + function AuthorTile(props: { name: string; description: string; @@ -50,12 +93,11 @@ export default async function Page({ if (blog === undefined) { notFound(); } - const archiveDate: number = Date.parse(blog.archiveDate ?? "") + const archiveDate: number = Date.parse(blog.archiveDate ?? ""); const blogIsArchived = isNaN(archiveDate) ? false : Date.now() > archiveDate; return ( <> - {`now-u | ${blog.title}`}
@@ -65,13 +107,19 @@ export default async function Page({ {/* Archived Warning Banner */} - { blogIsArchived && -
- -

The article you are looking at is archived and possibly outdated!

-
- } - + {blogIsArchived && ( +
+ +

+ The article you are looking at is archived and possibly + outdated! +

+
+ )} +
{ const remotePosts = await getBlogPosts(); @@ -23,8 +28,6 @@ async function Blog(): Promise { return ( <> - now-u | Blog -
{ headerImage: blog.header_image.url, readingTime: blog.reading_time.toString(), publishedDate: blog.release_at, + updateDate: blog.updated_at, archiveDate: blog.end_at ?? undefined } } else { diff --git a/src/app/causes/page.tsx b/src/app/causes/page.tsx index c3a1ecd..4edd1c9 100644 --- a/src/app/causes/page.tsx +++ b/src/app/causes/page.tsx @@ -4,6 +4,11 @@ import { Header } from "@/components/Header"; import { Newsletter } from "@/components/Newsletter"; import Image from "next/image"; import { type Cause, getCauses } from "@/services/api"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Causes | now-u" +} const CauseTile = (props: { cause: Cause }): JSX.Element => { const { header_image: headerImage, title } = props.cause; @@ -34,8 +39,6 @@ export default async function CausesPage(): Promise { return ( <> - now-u | Causes -
- now-u | Charity Partnership
=> { @@ -9,8 +14,6 @@ const PartnersPage = async (): Promise => { return ( <> - now-u | Collaborations -
diff --git a/src/app/faq/page.tsx b/src/app/faq/page.tsx index a52f7bc..10e2704 100644 --- a/src/app/faq/page.tsx +++ b/src/app/faq/page.tsx @@ -3,6 +3,11 @@ import Link from "next/link"; import { Header } from "@/components/Header"; import { getFaqs } from "@/services/api"; import { FAQBlock } from "@/app/faq/FAQBlock"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "FAQs | now-u" +} async function FAQPage(): Promise { @@ -10,8 +15,6 @@ async function FAQPage(): Promise { return ( <> - now-u | FAQs -

diff --git a/src/app/get-in-touch/page.tsx b/src/app/get-in-touch/page.tsx index 74e154d..24bccbb 100644 --- a/src/app/get-in-touch/page.tsx +++ b/src/app/get-in-touch/page.tsx @@ -9,6 +9,11 @@ import { import { Header } from "@/components/Header"; import { ContactTile } from "./ContactTile"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Get In Touch | now-u" +} const contacts = [ { @@ -36,8 +41,6 @@ const contacts = [ const GetInTouch = (): JSX.Element => { return ( <> - now-u | Get In Touch -

diff --git a/src/app/info/cookie-policy/page.tsx b/src/app/info/cookie-policy/page.tsx index c377660..cc1df08 100644 --- a/src/app/info/cookie-policy/page.tsx +++ b/src/app/info/cookie-policy/page.tsx @@ -1,6 +1,11 @@ import React from "react"; import fs from "fs"; import md from "markdown-it"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Cookie Policy | now-u" +} export default async function Page(): Promise { const cookiePolicyFile = fs.readFileSync( @@ -10,8 +15,6 @@ export default async function Page(): Promise { return ( <> - {`now-u | Cookie Policy`} -

Cookie Policy

{ const privacyNoticeFile = fs.readFileSync( @@ -10,8 +15,6 @@ export default async function Page(): Promise { return ( <> - {`now-u | Privacy Notice`} -

Privacy Notice

{ const termsFile = fs.readFileSync( @@ -10,8 +15,6 @@ export default async function Page(): Promise { return ( <> - {`now-u | Terms and Conditions for Users`} -
await import("@/components/Analytics")); @@ -40,6 +42,21 @@ const ppPangram = localFont({ variable: '--font-pppangram' }) +export const metadata: Metadata = { + metadataBase: new URL('https://www.now-u.com'), + title: "now-u", + description: "Learn more about this non-profit with a mission to inform, involve and inspire people to help tackle some of the world's most pressing social and environmental issues.", + openGraph: { + siteName: "now-u", + images: [ + { + url: OGImage.src, + } + ], + type: "website" + } +} + interface RootLayoutProps { children: React.ReactNode; } diff --git a/src/app/page.tsx b/src/app/page.tsx index e98a8c5..74fce5a 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -13,6 +13,12 @@ import GlobeIcon from "@/assets/graphics/globe_icon.webp"; import Image from "next/image"; import { AppStoreBadge, PlayStoreBadge } from "@/components/AppStoreBadge"; import { Newsletter } from "@/components/Newsletter"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Drive Changes | now-u" +} + const icons = [ { @@ -38,8 +44,6 @@ const icons = [ function Home(): JSX.Element { return ( <> - now-u | Home -
diff --git a/src/app/press/page.tsx b/src/app/press/page.tsx index cc46156..51f8d9c 100644 --- a/src/app/press/page.tsx +++ b/src/app/press/page.tsx @@ -6,6 +6,11 @@ import Image from "next/image"; import Link from "next/link"; import { PRESS_EMAIL } from "@/utils/constants"; import { type PressArticle, pressArticles } from "./pressArticles"; +import type { Metadata } from "next"; + +export const metadata: Metadata = { + title: "Press | now-u" +} interface PressPack { title: string; @@ -95,7 +100,6 @@ export default async function Press(): Promise { return ( <> - now-u | Press
diff --git a/src/assets/graphics/og-image.png b/src/assets/graphics/og-image.png new file mode 100644 index 0000000..820c19d Binary files /dev/null and b/src/assets/graphics/og-image.png differ