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:
Jeroen Reumkens 2022-11-01 09:16:08 +01:00 committed by GitHub
parent b3ba89c074
commit b1ced10626
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 13 deletions

View File

@ -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,

View File

@ -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 });
}

View File

@ -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>
);

View File

@ -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,