Added generic image variant for og images and make meta description longer. (#5285)
* Added generic image variant for og images. * Made og and meta descriptions longer, removed difference between longer and shorter descriptions now we only have one variant. Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com>
This commit is contained in:
parent
b3ba89c074
commit
b1ced10626
|
@ -4,6 +4,7 @@ import { NextSeo, NextSeoProps } from "next-seo";
|
|||
import {
|
||||
AppImageProps,
|
||||
constructAppImage,
|
||||
constructGenericImage,
|
||||
constructMeetingImage,
|
||||
MeetingImageProps,
|
||||
} from "@calcom/lib/OgImages";
|
||||
|
@ -72,12 +73,11 @@ const buildSeoMeta = (pageProps: {
|
|||
|
||||
export const HeadSeo = (props: HeadSeoProps): JSX.Element => {
|
||||
const defaultUrl = getBrowserInfo()?.url;
|
||||
const image = getSeoImage("default");
|
||||
|
||||
const { title, description, siteName, canonical = defaultUrl, nextSeoProps = {}, app, meeting } = props;
|
||||
|
||||
const truncatedDescription = truncate(description, 24);
|
||||
const longerTruncatedDescriptionOnWords = truncateOnWord(description, 148);
|
||||
const image = getSeoImage("ogImage") + constructGenericImage({ title, description });
|
||||
const truncatedDescription = truncateOnWord(description, 158);
|
||||
|
||||
const pageTitle = title + " | Cal.com";
|
||||
let seoObject = buildSeoMeta({
|
||||
|
@ -101,7 +101,7 @@ export const HeadSeo = (props: HeadSeoProps): JSX.Element => {
|
|||
|
||||
if (app) {
|
||||
const pageImage =
|
||||
getSeoImage("ogImage") + constructAppImage({ ...app, description: longerTruncatedDescriptionOnWords });
|
||||
getSeoImage("ogImage") + constructAppImage({ ...app, description: truncatedDescription });
|
||||
seoObject = buildSeoMeta({
|
||||
title: pageTitle,
|
||||
description: truncatedDescription,
|
||||
|
|
|
@ -3,7 +3,7 @@ import { NextApiRequest } from "next";
|
|||
import type { SatoriOptions } from "satori";
|
||||
import { z } from "zod";
|
||||
|
||||
import { Meeting, App } from "@calcom/lib/OgImages";
|
||||
import { Meeting, App, Generic } from "@calcom/lib/OgImages";
|
||||
|
||||
const calFont = fetch(new URL("../../../../public/fonts/cal.ttf", import.meta.url)).then((res) =>
|
||||
res.arrayBuffer()
|
||||
|
@ -37,6 +37,12 @@ const appSchema = z.object({
|
|||
slug: z.string(),
|
||||
});
|
||||
|
||||
const genericSchema = z.object({
|
||||
imageType: z.literal("generic"),
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
});
|
||||
|
||||
export default async function handler(req: NextApiRequest) {
|
||||
const { searchParams } = new URL(`${req.url}`);
|
||||
const imageType = searchParams.get("type");
|
||||
|
@ -85,6 +91,17 @@ export default async function handler(req: NextApiRequest) {
|
|||
});
|
||||
return new ImageResponse(<App name={name} description={description} slug={slug} />, ogConfig);
|
||||
}
|
||||
|
||||
case "generic": {
|
||||
const { title, description } = genericSchema.parse({
|
||||
title: searchParams.get("title"),
|
||||
description: searchParams.get("description"),
|
||||
imageType,
|
||||
});
|
||||
|
||||
return new ImageResponse(<Generic title={title} description={description} />, ogConfig);
|
||||
}
|
||||
|
||||
default:
|
||||
return new Response("What you're looking for is not here..", { status: 404 });
|
||||
}
|
||||
|
|
|
@ -21,6 +21,11 @@ export interface AppImageProps {
|
|||
slug: string;
|
||||
}
|
||||
|
||||
export interface GenericImageProps {
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
const joinMultipleNames = (names: string[] = []) => {
|
||||
const lastName = names.pop();
|
||||
return `${names.length > 0 ? `${names.join(", ")} & ${lastName}` : lastName}`;
|
||||
|
@ -42,7 +47,7 @@ export const constructMeetingImage = ({ title, users = [], profile }: MeetingIma
|
|||
profile.image && `&meetingImage=${encodeURIComponent(profile.image)}`,
|
||||
`${users.map((user) => `&names=${encodeURIComponent(user.name)}`).join("")}`,
|
||||
`${users.map((user) => `&usernames=${encodeURIComponent(user.username)}`).join("")}`,
|
||||
// Joinining a multiline string for readability.
|
||||
// Joining a multiline string for readability.
|
||||
].join("");
|
||||
};
|
||||
|
||||
|
@ -56,7 +61,16 @@ export const constructAppImage = ({ name, slug, description }: AppImageProps): s
|
|||
`&name=${encodeURIComponent(name)}`,
|
||||
`&slug=${encodeURIComponent(slug)}`,
|
||||
`&description=${encodeURIComponent(description)}`,
|
||||
// Joinining a multiline string for readability.
|
||||
// Joining a multiline string for readability.
|
||||
].join("");
|
||||
};
|
||||
|
||||
export const constructGenericImage = ({ title, description }: GenericImageProps) => {
|
||||
return [
|
||||
`?type=generic`,
|
||||
`&title=${encodeURIComponent(title)}`,
|
||||
`&description=${encodeURIComponent(description)}`,
|
||||
// Joining a multiline string for readability.
|
||||
].join("");
|
||||
};
|
||||
|
||||
|
@ -199,3 +213,22 @@ export const App = ({ name, description, slug }: AppImageProps) => (
|
|||
</div>
|
||||
</Wrapper>
|
||||
);
|
||||
|
||||
export const Generic = ({ title, description }: GenericImageProps) => (
|
||||
<Wrapper>
|
||||
<div tw="h-full flex flex-col justify-start">
|
||||
<div tw="flex items-center justify-center" style={{ fontFamily: "cal", fontWeight: 300 }}>
|
||||
<img src={`${CAL_URL}/cal-logo-word-black.svg`} width="350" alt="Logo" />
|
||||
</div>
|
||||
|
||||
<div tw="relative flex text-[54px] w-full flex-col text-black mt-auto">
|
||||
<div tw="flex w-[1040px]" style={{ fontFamily: "cal" }}>
|
||||
{title}
|
||||
</div>
|
||||
<div tw="flex mt-3 w-[1040px]" style={{ fontFamily: "inter" }}>
|
||||
{description}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Wrapper>
|
||||
);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import merge from "lodash/merge";
|
||||
import { NextSeo, NextSeoProps } from "next-seo";
|
||||
|
||||
import { constructAppImage, constructMeetingImage } from "@calcom/lib/OgImages";
|
||||
import { constructAppImage, constructGenericImage, constructMeetingImage } from "@calcom/lib/OgImages";
|
||||
import { getBrowserInfo } from "@calcom/lib/browser/browser.utils";
|
||||
import { seoConfig, getSeoImage, HeadSeoProps } from "@calcom/lib/next-seo.config";
|
||||
import { truncate, truncateOnWord } from "@calcom/lib/text";
|
||||
import { truncateOnWord } from "@calcom/lib/text";
|
||||
|
||||
/**
|
||||
* Build full seo tags from title, desc, canonical and url
|
||||
|
@ -55,12 +55,11 @@ const buildSeoMeta = (pageProps: {
|
|||
|
||||
export const HeadSeo = (props: HeadSeoProps): JSX.Element => {
|
||||
const defaultUrl = getBrowserInfo()?.url;
|
||||
const image = getSeoImage("default");
|
||||
|
||||
const { title, description, siteName, canonical = defaultUrl, nextSeoProps = {}, app, meeting } = props;
|
||||
|
||||
const truncatedDescription = truncate(description, 24);
|
||||
const longerTruncatedDescriptionOnWords = truncateOnWord(description, 148);
|
||||
const image = getSeoImage("ogImage") + constructGenericImage({ title, description });
|
||||
const truncatedDescription = truncateOnWord(description, 158);
|
||||
|
||||
const pageTitle = title + " | Cal.com";
|
||||
let seoObject = buildSeoMeta({
|
||||
|
@ -84,7 +83,7 @@ export const HeadSeo = (props: HeadSeoProps): JSX.Element => {
|
|||
|
||||
if (app) {
|
||||
const pageImage =
|
||||
getSeoImage("ogImage") + constructAppImage({ ...app, description: longerTruncatedDescriptionOnWords });
|
||||
getSeoImage("ogImage") + constructAppImage({ ...app, description: truncatedDescription });
|
||||
seoObject = buildSeoMeta({
|
||||
title: pageTitle,
|
||||
description: truncatedDescription,
|
||||
|
|
Loading…
Reference in New Issue
Block a user