* wip * wip * refactor * add pathname * fix * fix: manually construct pathname for metadata functions Co-Authored-By: benny@cal.com <benny@cal.com> * fix: add pathname parameter to all metadata functions Co-Authored-By: benny@cal.com <benny@cal.com> * fix: add pathname parameter to remaining metadata functions Co-Authored-By: benny@cal.com <benny@cal.com> * fix * fix * fix type checks * Refactor * fix * fix --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: benny@cal.com <benny@cal.com>
134 lines
3.6 KiB
TypeScript
134 lines
3.6 KiB
TypeScript
import { type TFunction } from "i18next";
|
|
import { cookies, headers } from "next/headers";
|
|
|
|
import { getLocale } from "@calcom/features/auth/lib/getLocale";
|
|
import type { AppImageProps, MeetingImageProps } from "@calcom/lib/OgImages";
|
|
import { constructAppImage, constructGenericImage, constructMeetingImage } from "@calcom/lib/OgImages";
|
|
import { IS_CALCOM, WEBAPP_URL, APP_NAME, SEO_IMG_OGIMG, CAL_URL } from "@calcom/lib/constants";
|
|
import { buildCanonical } from "@calcom/lib/next-seo.config";
|
|
import { getTranslation } from "@calcom/lib/server/i18n";
|
|
import { truncateOnWord } from "@calcom/lib/text";
|
|
|
|
import { buildLegacyRequest } from "@lib/buildLegacyCtx";
|
|
|
|
export const getTranslate = async () => {
|
|
const locale = await getLocale(buildLegacyRequest(await headers(), await cookies()));
|
|
|
|
return await getTranslation(locale ?? "en", "common");
|
|
};
|
|
|
|
const _generateMetadataWithoutImage = async (
|
|
getTitle: (t: TFunction<string, undefined>) => string,
|
|
getDescription: (t: TFunction<string, undefined>) => string,
|
|
hideBranding?: boolean,
|
|
origin?: string,
|
|
pathname?: string
|
|
) => {
|
|
const _pathname = pathname ?? "";
|
|
const canonical = buildCanonical({ path: _pathname, origin: origin ?? CAL_URL });
|
|
const t = await getTranslate();
|
|
|
|
const title = getTitle(t);
|
|
const description = getDescription(t);
|
|
const titleSuffix = `| ${APP_NAME}`;
|
|
const displayedTitle = title.includes(titleSuffix) || hideBranding ? title : `${title} ${titleSuffix}`;
|
|
const metadataBase = new URL(IS_CALCOM ? "https://cal.com" : WEBAPP_URL);
|
|
|
|
return {
|
|
title: title.length === 0 ? APP_NAME : displayedTitle,
|
|
description,
|
|
alternates: { canonical },
|
|
openGraph: {
|
|
description: truncateOnWord(description, 158),
|
|
url: canonical,
|
|
type: "website",
|
|
siteName: APP_NAME,
|
|
title: displayedTitle,
|
|
},
|
|
metadataBase,
|
|
};
|
|
};
|
|
|
|
export const _generateMetadata = async (
|
|
getTitle: (t: TFunction<string, undefined>) => string,
|
|
getDescription: (t: TFunction<string, undefined>) => string,
|
|
hideBranding?: boolean,
|
|
origin?: string,
|
|
pathname?: string
|
|
) => {
|
|
const metadata = await _generateMetadataWithoutImage(
|
|
getTitle,
|
|
getDescription,
|
|
hideBranding,
|
|
origin,
|
|
pathname
|
|
);
|
|
const image =
|
|
SEO_IMG_OGIMG +
|
|
constructGenericImage({
|
|
title: metadata.title,
|
|
description: metadata.description,
|
|
});
|
|
|
|
return {
|
|
...metadata,
|
|
openGraph: {
|
|
...metadata.openGraph,
|
|
images: [image],
|
|
},
|
|
};
|
|
};
|
|
|
|
export const generateMeetingMetadata = async (
|
|
meeting: MeetingImageProps,
|
|
getTitle: (t: TFunction<string, undefined>) => string,
|
|
getDescription: (t: TFunction<string, undefined>) => string,
|
|
hideBranding?: boolean,
|
|
origin?: string,
|
|
pathname?: string
|
|
) => {
|
|
const metadata = await _generateMetadataWithoutImage(
|
|
getTitle,
|
|
getDescription,
|
|
hideBranding,
|
|
origin,
|
|
pathname
|
|
);
|
|
const image = SEO_IMG_OGIMG + constructMeetingImage(meeting);
|
|
|
|
return {
|
|
...metadata,
|
|
openGraph: {
|
|
...metadata.openGraph,
|
|
images: [image],
|
|
},
|
|
};
|
|
};
|
|
|
|
export const generateAppMetadata = async (
|
|
app: AppImageProps,
|
|
getTitle: (t: TFunction<string, undefined>) => string,
|
|
getDescription: (t: TFunction<string, undefined>) => string,
|
|
hideBranding?: boolean,
|
|
origin?: string,
|
|
pathname?: string
|
|
) => {
|
|
const metadata = await _generateMetadataWithoutImage(
|
|
getTitle,
|
|
getDescription,
|
|
hideBranding,
|
|
origin,
|
|
pathname
|
|
);
|
|
|
|
const image = SEO_IMG_OGIMG + constructAppImage({ ...app, description: metadata.description });
|
|
|
|
return {
|
|
...metadata,
|
|
openGraph: {
|
|
...metadata.openGraph,
|
|
images: [image],
|
|
},
|
|
};
|
|
};
|