From c730fa703511d7f55039c45c7676b09125905fe3 Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Mon, 19 Aug 2024 13:03:46 +0200 Subject: [PATCH 1/6] feat(SW-266): Replacing static metadata with data from Contentstack on Loyalty pages and Account Pages --- .../(protected)/my-pages/[...path]/page.tsx | 10 ++- .../(public)/[contentType]/[uid]/page.tsx | 19 +++++ app/[lang]/(live)/layout.tsx | 10 +-- .../Fragments/LoyaltyPage/MetaData.graphql | 17 ++++ .../Fragments/MyPages/MetaData.graphql | 17 ++++ lib/graphql/Query/MetaDataLoyaltyPage.graphql | 12 +++ lib/graphql/Query/MetaDataMyPages.graphql | 12 +++ server/routers/contentstack/index.ts | 2 + .../contentstack/loyaltyPage/output.ts | 1 + .../routers/contentstack/loyaltyPage/query.ts | 1 + server/routers/contentstack/metadata/index.ts | 5 ++ .../routers/contentstack/metadata/output.ts | 62 +++++++++++++++ server/routers/contentstack/metadata/query.ts | 78 +++++++++++++++++++ server/routers/contentstack/metadata/utils.ts | 34 ++++++++ types/components/metadata/index.ts | 5 ++ utils/generateMetadata.ts | 39 ++++++++++ 16 files changed, 316 insertions(+), 8 deletions(-) create mode 100644 lib/graphql/Fragments/LoyaltyPage/MetaData.graphql create mode 100644 lib/graphql/Fragments/MyPages/MetaData.graphql create mode 100644 lib/graphql/Query/MetaDataLoyaltyPage.graphql create mode 100644 lib/graphql/Query/MetaDataMyPages.graphql create mode 100644 server/routers/contentstack/metadata/index.ts create mode 100644 server/routers/contentstack/metadata/output.ts create mode 100644 server/routers/contentstack/metadata/query.ts create mode 100644 server/routers/contentstack/metadata/utils.ts create mode 100644 types/components/metadata/index.ts create mode 100644 utils/generateMetadata.ts diff --git a/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx b/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx index b35861357..584e0922b 100644 --- a/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx @@ -5,11 +5,20 @@ import Title from "@/components/TempDesignSystem/Text/Title" import TrackingSDK from "@/components/TrackingSDK" import { getIntl } from "@/i18n" import { setLang } from "@/i18n/serverContext" +import { generateMetadata as generateBaseMetadata } from "@/utils/generateMetadata" import styles from "./page.module.css" import type { LangParams, PageArgs } from "@/types/params" +export async function generateMetadata({ params }: PageArgs) { + const accountPageRes = await serverClient().contentstack.accountPage.get() + return generateBaseMetadata({ + params, + pageTitle: accountPageRes?.accountPage?.title, + }) +} + export default async function MyPages({ params, }: PageArgs) { @@ -34,7 +43,6 @@ export default async function MyPages({

{formatMessage({ id: "No content published" })}

)} - ) diff --git a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx index 0e8e98a05..c5b13354b 100644 --- a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx +++ b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx @@ -1,9 +1,12 @@ import { notFound } from "next/navigation" +import { serverClient } from "@/lib/trpc/server" + import ContentPage from "@/components/ContentType/ContentPage" import HotelPage from "@/components/ContentType/HotelPage/HotelPage" import LoyaltyPage from "@/components/ContentType/LoyaltyPage/LoyaltyPage" import { setLang } from "@/i18n/serverContext" +import { generateMetadata as generateBaseMetadata } from "@/utils/generateMetadata" import { ContentTypeParams, @@ -12,6 +15,22 @@ import { UIDParams, } from "@/types/params" +export async function generateMetadata({ + params, +}: PageArgs) { + switch (params.contentType) { + case "loyalty-page": + const loyaltyPageRes = await serverClient().contentstack.loyaltyPage.get() + return generateBaseMetadata({ + params, + pageTitle: loyaltyPageRes?.loyaltyPage?.title, + }) + // Add case "hotel-pages" etc when needed + default: + return + } +} + export default async function ContentTypePage({ params, }: PageArgs) { diff --git a/app/[lang]/(live)/layout.tsx b/app/[lang]/(live)/layout.tsx index 2da54eb0a..9f9a9263c 100644 --- a/app/[lang]/(live)/layout.tsx +++ b/app/[lang]/(live)/layout.tsx @@ -12,15 +12,11 @@ import { preloadUserTracking } from "@/components/TrackingSDK" import { getIntl } from "@/i18n" import ServerIntlProvider from "@/i18n/Provider" import { getLang, setLang } from "@/i18n/serverContext" - -import type { Metadata } from "next" +import { generateMetadata } from "@/utils/generateMetadata" import type { LangParams, LayoutArgs } from "@/types/params" -export const metadata: Metadata = { - description: "New web", - title: "Scandic Hotels", -} +export { generateMetadata } export default async function RootLayout({ children, @@ -33,8 +29,8 @@ export default async function RootLayout({ >) { setLang(params.lang) preloadUserTracking() - const { defaultLocale, locale, messages } = await getIntl() + return ( diff --git a/lib/graphql/Fragments/LoyaltyPage/MetaData.graphql b/lib/graphql/Fragments/LoyaltyPage/MetaData.graphql new file mode 100644 index 000000000..dcb0c704d --- /dev/null +++ b/lib/graphql/Fragments/LoyaltyPage/MetaData.graphql @@ -0,0 +1,17 @@ +#import "../Image.graphql" + +fragment LoyaltyPageMetaData on LoyaltyPage { + web { + seo_metadata { + title + description + imageConnection { + edges { + node { + ...Image + } + } + } + } + } +} diff --git a/lib/graphql/Fragments/MyPages/MetaData.graphql b/lib/graphql/Fragments/MyPages/MetaData.graphql new file mode 100644 index 000000000..1971efe3f --- /dev/null +++ b/lib/graphql/Fragments/MyPages/MetaData.graphql @@ -0,0 +1,17 @@ +#import "../Image.graphql" + +fragment MyPagesMetaData on AccountPage { + web { + seo_metadata { + title + description + imageConnection { + edges { + node { + ...Image + } + } + } + } + } +} diff --git a/lib/graphql/Query/MetaDataLoyaltyPage.graphql b/lib/graphql/Query/MetaDataLoyaltyPage.graphql new file mode 100644 index 000000000..9b6ba5d77 --- /dev/null +++ b/lib/graphql/Query/MetaDataLoyaltyPage.graphql @@ -0,0 +1,12 @@ +#import "../Fragments/LoyaltyPage/MetaData.graphql" + +query GetLoyaltyPageMetaData($locale: String!, $url: String!) { + all_loyalty_page(locale: $locale, where: { url: $url }) { + items { + ...LoyaltyPageMetaData + system { + uid + } + } + } +} diff --git a/lib/graphql/Query/MetaDataMyPages.graphql b/lib/graphql/Query/MetaDataMyPages.graphql new file mode 100644 index 000000000..14e255f02 --- /dev/null +++ b/lib/graphql/Query/MetaDataMyPages.graphql @@ -0,0 +1,12 @@ +#import "../Fragments/MyPages/MetaData.graphql" + +query GetMyPagesMetaData($locale: String!, $url: String!) { + all_account_page(locale: $locale, where: { url: $url }) { + items { + ...MyPagesMetaData + system { + uid + } + } + } +} diff --git a/server/routers/contentstack/index.ts b/server/routers/contentstack/index.ts index be1ef1ed3..2394251b3 100644 --- a/server/routers/contentstack/index.ts +++ b/server/routers/contentstack/index.ts @@ -6,6 +6,7 @@ import { breadcrumbsRouter } from "./breadcrumbs" import { hotelPageRouter } from "./hotelPage" import { languageSwitcherRouter } from "./languageSwitcher" import { loyaltyPageRouter } from "./loyaltyPage" +import { metaDataRouter } from "./metadata" import { myPagesRouter } from "./myPages" export const contentstackRouter = router({ @@ -16,4 +17,5 @@ export const contentstackRouter = router({ languageSwitcher: languageSwitcherRouter, loyaltyPage: loyaltyPageRouter, myPages: myPagesRouter, + metaData: metaDataRouter, }) diff --git a/server/routers/contentstack/loyaltyPage/output.ts b/server/routers/contentstack/loyaltyPage/output.ts index 205509a4c..a95b2e341 100644 --- a/server/routers/contentstack/loyaltyPage/output.ts +++ b/server/routers/contentstack/loyaltyPage/output.ts @@ -190,6 +190,7 @@ const loyaltyPageSidebarItem = z.discriminatedUnion("__typename", [ ]) export const validateLoyaltyPageSchema = z.object({ + title: z.string(), heading: z.string().nullable(), blocks: z.array(loyaltyPageBlockItem).nullable(), sidebar: z.array(loyaltyPageSidebarItem).nullable(), diff --git a/server/routers/contentstack/loyaltyPage/query.ts b/server/routers/contentstack/loyaltyPage/query.ts index c23422c4a..7f4fee2e9 100644 --- a/server/routers/contentstack/loyaltyPage/query.ts +++ b/server/routers/contentstack/loyaltyPage/query.ts @@ -209,6 +209,7 @@ export const loyaltyPageQueryRouter = router({ : null const loyaltyPage = { + title: response.data.loyalty_page.title, heading: response.data.loyalty_page.heading, system: response.data.loyalty_page.system, blocks, diff --git a/server/routers/contentstack/metadata/index.ts b/server/routers/contentstack/metadata/index.ts new file mode 100644 index 000000000..fa2618123 --- /dev/null +++ b/server/routers/contentstack/metadata/index.ts @@ -0,0 +1,5 @@ +import { mergeRouters } from "@/server/trpc" + +import { metaDataQueryRouter } from "./query" + +export const metaDataRouter = mergeRouters(metaDataQueryRouter) diff --git a/server/routers/contentstack/metadata/output.ts b/server/routers/contentstack/metadata/output.ts new file mode 100644 index 000000000..ae0367a3c --- /dev/null +++ b/server/routers/contentstack/metadata/output.ts @@ -0,0 +1,62 @@ +import { z } from "zod" + +export const getMetaDataSchema = z.object({ + title: z.string().optional(), + description: z.string().optional(), + imageConnection: z + .object({ + edges: z.array( + z.object({ + node: z.object({ + url: z.string(), + }), + }) + ), + }) + .optional(), +}) + +const page = z.object({ + web: z.object({ + seo_metadata: z.object({ + title: z.string().optional(), + description: z.string().optional(), + imageConnection: z + .object({ + edges: z.array( + z.object({ + node: z.object({ + url: z.string(), + }), + }) + ), + }) + .optional(), + }), + }), + system: z.object({ + uid: z.string(), + }), +}) + +export type Page = z.infer + +const metaDataItems = z.object({ + items: z.array(page), +}) + +export const validateMyPagesMetaDataContentstackSchema = z.object({ + all_account_page: metaDataItems, +}) + +export type GetMyPagesMetaDataData = z.infer< + typeof validateMyPagesMetaDataContentstackSchema +> + +export const validateLoyaltyPageMetaDataContentstackSchema = z.object({ + all_loyalty_page: metaDataItems, +}) + +export type GetLoyaltyPageMetaDataData = z.infer< + typeof validateLoyaltyPageMetaDataContentstackSchema +> diff --git a/server/routers/contentstack/metadata/query.ts b/server/routers/contentstack/metadata/query.ts new file mode 100644 index 000000000..3dbc2f2a2 --- /dev/null +++ b/server/routers/contentstack/metadata/query.ts @@ -0,0 +1,78 @@ +import { GetLoyaltyPageMetaData } from "@/lib/graphql/Query/MetaDataLoyaltyPage.graphql" +import { GetMyPagesMetaData } from "@/lib/graphql/Query/MetaDataMyPages.graphql" +import { contentstackExtendedProcedureUID, router } from "@/server/trpc" + +import { + type GetLoyaltyPageMetaDataData, + type GetMyPagesMetaDataData, + validateLoyaltyPageMetaDataContentstackSchema, + validateMyPagesMetaDataContentstackSchema, +} from "./output" +import { getMetaData, getResponse, Variables } from "./utils" + +import { PageTypeEnum } from "@/types/requests/pageType" + +async function getLoyaltyPageMetaData(variables: Variables) { + const response = await getResponse( + GetLoyaltyPageMetaData, + variables + ) + + if (!response.data.all_loyalty_page.items[0].web?.seo_metadata?.title) { + return null + } + const validatedMetaDataData = + validateLoyaltyPageMetaDataContentstackSchema.safeParse(response.data) + + if (!validatedMetaDataData.success) { + console.error( + `Failed to validate Loyaltypage MetaData Data - (url: ${variables.url})` + ) + console.error(validatedMetaDataData.error) + return null + } + + return getMetaData(validatedMetaDataData.data.all_loyalty_page.items[0]) +} + +async function getMyPagesMetaData(variables: Variables) { + const response = await getResponse( + GetMyPagesMetaData, + variables + ) + + if (!response.data.all_account_page.items[0].web?.seo_metadata?.title) { + return [] + } + + const validatedMetaDataData = + validateMyPagesMetaDataContentstackSchema.safeParse(response.data) + + if (!validatedMetaDataData.success) { + console.error( + `Failed to validate My Page MetaData Data - (url: ${variables.url})` + ) + console.error(validatedMetaDataData.error) + return null + } + + return getMetaData(validatedMetaDataData.data.all_account_page.items[0]) +} + +export const metaDataQueryRouter = router({ + get: contentstackExtendedProcedureUID.query(async ({ ctx }) => { + const variables = { + locale: ctx.lang, + url: ctx.pathname, + } + + switch (ctx.contentType) { + case PageTypeEnum.accountPage: + return await getMyPagesMetaData(variables) + case PageTypeEnum.loyaltyPage: + return await getLoyaltyPageMetaData(variables) + default: + return [] + } + }), +}) diff --git a/server/routers/contentstack/metadata/utils.ts b/server/routers/contentstack/metadata/utils.ts new file mode 100644 index 000000000..f2e80b604 --- /dev/null +++ b/server/routers/contentstack/metadata/utils.ts @@ -0,0 +1,34 @@ +import { Lang } from "@/constants/languages" +import { request } from "@/lib/graphql/request" +import { internalServerError, notFound } from "@/server/errors/trpc" + +import { getMetaDataSchema, Page } from "./output" + +export type Variables = { + locale: Lang + url: string +} + +export async function getResponse(query: string, variables: Variables) { + const response = await request(query, variables) + if (!response.data) { + throw notFound(response) + } + + return response +} + +export function getMetaData(page: Page) { + const pageMetaData = { + title: page.web.seo_metadata.title, + description: page.web.seo_metadata.description, + imageConnection: page.web.seo_metadata.imageConnection, + uid: page.system.uid, + } + const validatedMetaData = getMetaDataSchema.safeParse(pageMetaData) + if (!validatedMetaData.success) { + throw internalServerError(validatedMetaData.error) + } + + return validatedMetaData.data +} diff --git a/types/components/metadata/index.ts b/types/components/metadata/index.ts new file mode 100644 index 000000000..bcc71f13f --- /dev/null +++ b/types/components/metadata/index.ts @@ -0,0 +1,5 @@ +import { z } from "zod" + +import { getMetaDataSchema } from "@/server/routers/contentstack/metadata/output" + +export interface MetaData extends z.infer {} diff --git a/utils/generateMetadata.ts b/utils/generateMetadata.ts new file mode 100644 index 000000000..e44e14354 --- /dev/null +++ b/utils/generateMetadata.ts @@ -0,0 +1,39 @@ +import { Metadata } from "next" + +import { serverClient } from "@/lib/trpc/server" + +import { MetaData } from "@/types/components/metadata" +import { LangParams, PageArgs } from "@/types/params" + +export async function generateMetadata({ + params, + pageTitle, +}: PageArgs & { pageTitle?: string }): Promise { + console.log("PARAMS", params) + const metaData: MetaData | never[] | null = + await serverClient().contentstack.metaData.get() + + if (Array.isArray(metaData)) { + return { + title: pageTitle ?? "", + description: "", + openGraph: { + images: [], + }, + } + } + const title = metaData?.title ?? pageTitle ?? "" + const description = metaData?.description ?? "" + const images = + metaData?.imageConnection?.edges?.map((edge) => ({ + url: edge.node.url, + })) || [] + + return { + title, + description, + openGraph: { + images, + }, + } +} From b3f4ba822c031913f45921ea3f8ca91cd7bf2e40 Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Tue, 20 Aug 2024 10:57:30 +0200 Subject: [PATCH 2/6] feat(SW-266): updated to use breadcrumbs title as default --- app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx | 7 +++++-- app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx | 8 ++++++-- utils/generateMetadata.ts | 5 +++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx b/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx index 584e0922b..c153db1a4 100644 --- a/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx @@ -12,10 +12,13 @@ import styles from "./page.module.css" import type { LangParams, PageArgs } from "@/types/params" export async function generateMetadata({ params }: PageArgs) { - const accountPageRes = await serverClient().contentstack.accountPage.get() + const breadcrumbs = await serverClient().contentstack.breadcrumbs.get() + if (!breadcrumbs?.length) { + return null + } return generateBaseMetadata({ params, - pageTitle: accountPageRes?.accountPage?.title, + pageTitle: breadcrumbs.at(-1)?.title, }) } diff --git a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx index c5b13354b..a4976c22d 100644 --- a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx +++ b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx @@ -20,11 +20,15 @@ export async function generateMetadata({ }: PageArgs) { switch (params.contentType) { case "loyalty-page": - const loyaltyPageRes = await serverClient().contentstack.loyaltyPage.get() + const breadcrumbs = await serverClient().contentstack.breadcrumbs.get() + if (!breadcrumbs?.length) { + return null + } return generateBaseMetadata({ params, - pageTitle: loyaltyPageRes?.loyaltyPage?.title, + pageTitle: breadcrumbs.at(-1)?.title, }) + // Add case "hotel-pages" etc when needed default: return diff --git a/utils/generateMetadata.ts b/utils/generateMetadata.ts index e44e14354..11a09d34f 100644 --- a/utils/generateMetadata.ts +++ b/utils/generateMetadata.ts @@ -8,8 +8,9 @@ import { LangParams, PageArgs } from "@/types/params" export async function generateMetadata({ params, pageTitle, -}: PageArgs & { pageTitle?: string }): Promise { - console.log("PARAMS", params) +}: PageArgs & { + pageTitle?: string +}): Promise { const metaData: MetaData | never[] | null = await serverClient().contentstack.metaData.get() From 09639badb42a5dd5fb297a5c16ce5915cf523de6 Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Wed, 21 Aug 2024 14:55:02 +0200 Subject: [PATCH 3/6] feat(SW-266): removed comment --- app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx index a4976c22d..655f34ee1 100644 --- a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx +++ b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx @@ -28,8 +28,6 @@ export async function generateMetadata({ params, pageTitle: breadcrumbs.at(-1)?.title, }) - - // Add case "hotel-pages" etc when needed default: return } From a0fede38758755a16d26c9f69592118ff03887cf Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Wed, 21 Aug 2024 15:27:44 +0200 Subject: [PATCH 4/6] feat(SW-266): Moved logic for breadcrumbs since I cant pass custom prop to generateMetadata --- .env.test | 2 ++ .../(protected)/my-pages/[...path]/page.tsx | 12 ----------- .../(public)/[contentType]/[uid]/page.tsx | 21 ------------------- utils/generateMetadata.ts | 13 +++++------- 4 files changed, 7 insertions(+), 41 deletions(-) diff --git a/.env.test b/.env.test index 8d70bab9d..801c4336b 100644 --- a/.env.test +++ b/.env.test @@ -12,6 +12,7 @@ CURITY_CLIENT_SECRET_SERVICE="test" CURITY_CLIENT_ID_USER="test" CURITY_CLIENT_SECRET_USER="test" CURITY_ISSUER_USER="test" +CURITY_ISSUER_SERVICE="test" CYPRESS_API_BASEURL="test" CYPRESS_CURITY_USERNAME="test" CYPRESS_CURITY_PASSWORD="test" @@ -35,3 +36,4 @@ SEAMLESS_LOGOUT_FI="test" SEAMLESS_LOGOUT_NO="test" SEAMLESS_LOGOUT_SV="test" WEBVIEW_ENCRYPTION_KEY="test" +BOOKING_ENCRYPTION_KEY="test" diff --git a/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx b/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx index c153db1a4..012c40de2 100644 --- a/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/[...path]/page.tsx @@ -5,23 +5,11 @@ import Title from "@/components/TempDesignSystem/Text/Title" import TrackingSDK from "@/components/TrackingSDK" import { getIntl } from "@/i18n" import { setLang } from "@/i18n/serverContext" -import { generateMetadata as generateBaseMetadata } from "@/utils/generateMetadata" import styles from "./page.module.css" import type { LangParams, PageArgs } from "@/types/params" -export async function generateMetadata({ params }: PageArgs) { - const breadcrumbs = await serverClient().contentstack.breadcrumbs.get() - if (!breadcrumbs?.length) { - return null - } - return generateBaseMetadata({ - params, - pageTitle: breadcrumbs.at(-1)?.title, - }) -} - export default async function MyPages({ params, }: PageArgs) { diff --git a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx index 655f34ee1..0e8e98a05 100644 --- a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx +++ b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx @@ -1,12 +1,9 @@ import { notFound } from "next/navigation" -import { serverClient } from "@/lib/trpc/server" - import ContentPage from "@/components/ContentType/ContentPage" import HotelPage from "@/components/ContentType/HotelPage/HotelPage" import LoyaltyPage from "@/components/ContentType/LoyaltyPage/LoyaltyPage" import { setLang } from "@/i18n/serverContext" -import { generateMetadata as generateBaseMetadata } from "@/utils/generateMetadata" import { ContentTypeParams, @@ -15,24 +12,6 @@ import { UIDParams, } from "@/types/params" -export async function generateMetadata({ - params, -}: PageArgs) { - switch (params.contentType) { - case "loyalty-page": - const breadcrumbs = await serverClient().contentstack.breadcrumbs.get() - if (!breadcrumbs?.length) { - return null - } - return generateBaseMetadata({ - params, - pageTitle: breadcrumbs.at(-1)?.title, - }) - default: - return - } -} - export default async function ContentTypePage({ params, }: PageArgs) { diff --git a/utils/generateMetadata.ts b/utils/generateMetadata.ts index 11a09d34f..6f321f853 100644 --- a/utils/generateMetadata.ts +++ b/utils/generateMetadata.ts @@ -3,16 +3,12 @@ import { Metadata } from "next" import { serverClient } from "@/lib/trpc/server" import { MetaData } from "@/types/components/metadata" -import { LangParams, PageArgs } from "@/types/params" -export async function generateMetadata({ - params, - pageTitle, -}: PageArgs & { - pageTitle?: string -}): Promise { +export async function generateMetadata(): Promise { const metaData: MetaData | never[] | null = await serverClient().contentstack.metaData.get() + const breadcrumbs = await serverClient().contentstack.breadcrumbs.get() + const pageTitle = breadcrumbs?.at(-1)?.title if (Array.isArray(metaData)) { return { @@ -23,7 +19,8 @@ export async function generateMetadata({ }, } } - const title = metaData?.title ?? pageTitle ?? "" + + const title = pageTitle ?? metaData?.title ?? "" // Use pageTitle first const description = metaData?.description ?? "" const images = metaData?.imageConnection?.edges?.map((edge) => ({ From ab3feb367be3129cfe4d51155d39c478ffc1046c Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Thu, 22 Aug 2024 11:16:17 +0200 Subject: [PATCH 5/6] feat(SW-266): removed unused field --- server/routers/contentstack/loyaltyPage/query.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/server/routers/contentstack/loyaltyPage/query.ts b/server/routers/contentstack/loyaltyPage/query.ts index 7f4fee2e9..c23422c4a 100644 --- a/server/routers/contentstack/loyaltyPage/query.ts +++ b/server/routers/contentstack/loyaltyPage/query.ts @@ -209,7 +209,6 @@ export const loyaltyPageQueryRouter = router({ : null const loyaltyPage = { - title: response.data.loyalty_page.title, heading: response.data.loyalty_page.heading, system: response.data.loyalty_page.system, blocks, From 5c81ff13f7c5237aad2741221944c83325410a8a Mon Sep 17 00:00:00 2001 From: Pontus Dreij Date: Thu, 22 Aug 2024 14:45:19 +0200 Subject: [PATCH 6/6] feat(SW-266): Added breadcrumbs to metadata fragment --- app/[lang]/(live)/layout.tsx | 3 +-- lib/graphql/Fragments/LoyaltyPage/MetaData.graphql | 3 +++ lib/graphql/Fragments/MyPages/MetaData.graphql | 3 +++ server/routers/contentstack/loyaltyPage/output.ts | 1 - server/routers/contentstack/metadata/output.ts | 4 ++++ server/routers/contentstack/metadata/query.ts | 7 ------- server/routers/contentstack/metadata/utils.ts | 1 + utils/generateMetadata.ts | 6 ++---- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/[lang]/(live)/layout.tsx b/app/[lang]/(live)/layout.tsx index f19388e72..c159e3926 100644 --- a/app/[lang]/(live)/layout.tsx +++ b/app/[lang]/(live)/layout.tsx @@ -14,11 +14,10 @@ import { preloadUserTracking } from "@/components/TrackingSDK" import { getIntl } from "@/i18n" import ServerIntlProvider from "@/i18n/Provider" import { getLang, setLang } from "@/i18n/serverContext" -import { generateMetadata } from "@/utils/generateMetadata" import type { LangParams, LayoutArgs } from "@/types/params" -export { generateMetadata } +export { generateMetadata } from "@/utils/generateMetadata" export default async function RootLayout({ children, diff --git a/lib/graphql/Fragments/LoyaltyPage/MetaData.graphql b/lib/graphql/Fragments/LoyaltyPage/MetaData.graphql index dcb0c704d..a169b5182 100644 --- a/lib/graphql/Fragments/LoyaltyPage/MetaData.graphql +++ b/lib/graphql/Fragments/LoyaltyPage/MetaData.graphql @@ -13,5 +13,8 @@ fragment LoyaltyPageMetaData on LoyaltyPage { } } } + breadcrumbs { + title + } } } diff --git a/lib/graphql/Fragments/MyPages/MetaData.graphql b/lib/graphql/Fragments/MyPages/MetaData.graphql index 1971efe3f..644594401 100644 --- a/lib/graphql/Fragments/MyPages/MetaData.graphql +++ b/lib/graphql/Fragments/MyPages/MetaData.graphql @@ -13,5 +13,8 @@ fragment MyPagesMetaData on AccountPage { } } } + breadcrumbs { + title + } } } diff --git a/server/routers/contentstack/loyaltyPage/output.ts b/server/routers/contentstack/loyaltyPage/output.ts index a95b2e341..205509a4c 100644 --- a/server/routers/contentstack/loyaltyPage/output.ts +++ b/server/routers/contentstack/loyaltyPage/output.ts @@ -190,7 +190,6 @@ const loyaltyPageSidebarItem = z.discriminatedUnion("__typename", [ ]) export const validateLoyaltyPageSchema = z.object({ - title: z.string(), heading: z.string().nullable(), blocks: z.array(loyaltyPageBlockItem).nullable(), sidebar: z.array(loyaltyPageSidebarItem).nullable(), diff --git a/server/routers/contentstack/metadata/output.ts b/server/routers/contentstack/metadata/output.ts index ae0367a3c..12024b3c6 100644 --- a/server/routers/contentstack/metadata/output.ts +++ b/server/routers/contentstack/metadata/output.ts @@ -1,6 +1,7 @@ import { z } from "zod" export const getMetaDataSchema = z.object({ + breadcrumbsTitle: z.string().optional(), title: z.string().optional(), description: z.string().optional(), imageConnection: z @@ -33,6 +34,9 @@ const page = z.object({ }) .optional(), }), + breadcrumbs: z.object({ + title: z.string(), + }), }), system: z.object({ uid: z.string(), diff --git a/server/routers/contentstack/metadata/query.ts b/server/routers/contentstack/metadata/query.ts index 3dbc2f2a2..38d773248 100644 --- a/server/routers/contentstack/metadata/query.ts +++ b/server/routers/contentstack/metadata/query.ts @@ -18,9 +18,6 @@ async function getLoyaltyPageMetaData(variables: Variables) { variables ) - if (!response.data.all_loyalty_page.items[0].web?.seo_metadata?.title) { - return null - } const validatedMetaDataData = validateLoyaltyPageMetaDataContentstackSchema.safeParse(response.data) @@ -41,10 +38,6 @@ async function getMyPagesMetaData(variables: Variables) { variables ) - if (!response.data.all_account_page.items[0].web?.seo_metadata?.title) { - return [] - } - const validatedMetaDataData = validateMyPagesMetaDataContentstackSchema.safeParse(response.data) diff --git a/server/routers/contentstack/metadata/utils.ts b/server/routers/contentstack/metadata/utils.ts index f2e80b604..661c2b89d 100644 --- a/server/routers/contentstack/metadata/utils.ts +++ b/server/routers/contentstack/metadata/utils.ts @@ -20,6 +20,7 @@ export async function getResponse(query: string, variables: Variables) { export function getMetaData(page: Page) { const pageMetaData = { + breadcrumbsTitle: page.web.breadcrumbs.title, title: page.web.seo_metadata.title, description: page.web.seo_metadata.description, imageConnection: page.web.seo_metadata.imageConnection, diff --git a/utils/generateMetadata.ts b/utils/generateMetadata.ts index 6f321f853..547c5ccd6 100644 --- a/utils/generateMetadata.ts +++ b/utils/generateMetadata.ts @@ -7,12 +7,10 @@ import { MetaData } from "@/types/components/metadata" export async function generateMetadata(): Promise { const metaData: MetaData | never[] | null = await serverClient().contentstack.metaData.get() - const breadcrumbs = await serverClient().contentstack.breadcrumbs.get() - const pageTitle = breadcrumbs?.at(-1)?.title if (Array.isArray(metaData)) { return { - title: pageTitle ?? "", + title: "", description: "", openGraph: { images: [], @@ -20,7 +18,7 @@ export async function generateMetadata(): Promise { } } - const title = pageTitle ?? metaData?.title ?? "" // Use pageTitle first + const title = metaData?.breadcrumbsTitle ?? metaData?.title ?? "" const description = metaData?.description ?? "" const images = metaData?.imageConnection?.edges?.map((edge) => ({