fix: og images avatars (#13790)
* fix og images avatars * Update OgImages.tsx * More fixes * Update getPublicEvent.ts * Update HeadSeo.tsx
This commit is contained in:
@@ -7,6 +7,7 @@ import { handleUserRedirection } from "@calcom/features/booking-redirect/handle-
|
||||
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
import { DEFAULT_DARK_BRAND_COLOR, DEFAULT_LIGHT_BRAND_COLOR } from "@calcom/lib/constants";
|
||||
import { getUsernameList } from "@calcom/lib/defaultEvents";
|
||||
import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
@@ -206,7 +207,10 @@ export const getServerSideProps: GetServerSideProps<UserPageProps> = async (cont
|
||||
|
||||
const profile = {
|
||||
name: user.name || user.username || "",
|
||||
image: user.avatar,
|
||||
image: getUserAvatarUrl({
|
||||
...user,
|
||||
profile: user.profile,
|
||||
}),
|
||||
theme: user.theme,
|
||||
brandColor: user.brandColor ?? DEFAULT_LIGHT_BRAND_COLOR,
|
||||
avatarUrl: user.avatarUrl,
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { AuthOptions, Session } from "next-auth";
|
||||
import { getToken } from "next-auth/jwt";
|
||||
|
||||
import checkLicense from "@calcom/features/ee/common/server/checkLicense";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import { UserRepository } from "@calcom/lib/server/repository/user";
|
||||
@@ -94,7 +94,10 @@ export async function getServerSession(options: {
|
||||
emailVerified: user.emailVerified,
|
||||
email_verified: user.emailVerified !== null,
|
||||
role: user.role,
|
||||
image: `${WEBAPP_URL}/${user.username}/avatar.png`,
|
||||
image: getUserAvatarUrl({
|
||||
...user,
|
||||
profile: user.profile,
|
||||
}),
|
||||
belongsToActiveTeam: token.belongsToActiveTeam,
|
||||
org: token.org,
|
||||
locale: user.locale ?? undefined,
|
||||
|
||||
@@ -8,19 +8,20 @@ import { getBookingFieldsWithSystemFields } from "@calcom/features/bookings/lib/
|
||||
import { getSlugOrRequestedSlug } from "@calcom/features/ee/organizations/lib/orgDomains";
|
||||
import { isRecurringEvent, parseRecurringEvent } from "@calcom/lib";
|
||||
import { getDefaultEvent, getUsernameList } from "@calcom/lib/defaultEvents";
|
||||
import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
|
||||
import { getBookerBaseUrlSync } from "@calcom/lib/getBookerUrl/client";
|
||||
import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
|
||||
import { UserRepository } from "@calcom/lib/server/repository/user";
|
||||
import type { PrismaClient } from "@calcom/prisma";
|
||||
import type { BookerLayoutSettings } from "@calcom/prisma/zod-utils";
|
||||
import {
|
||||
bookerLayoutOptions,
|
||||
EventTypeMetaDataSchema,
|
||||
customInputSchema,
|
||||
userMetadata as userMetadataSchema,
|
||||
bookerLayouts as bookerLayoutsSchema,
|
||||
BookerLayouts,
|
||||
EventTypeMetaDataSchema,
|
||||
bookerLayoutOptions,
|
||||
bookerLayouts as bookerLayoutsSchema,
|
||||
customInputSchema,
|
||||
teamMetadataSchema,
|
||||
userMetadata as userMetadataSchema,
|
||||
} from "@calcom/prisma/zod-utils";
|
||||
import type { UserProfile } from "@calcom/types/UserProfile";
|
||||
|
||||
@@ -163,7 +164,10 @@ export const getPublicEvent = async (
|
||||
username: users[0].username,
|
||||
name: users[0].name,
|
||||
weekStart: users[0].weekStart,
|
||||
image: `/${users[0].username}/avatar.png`,
|
||||
image: getUserAvatarUrl({
|
||||
...users[0],
|
||||
profile: users[0].profile,
|
||||
}),
|
||||
brandColor: users[0].brandColor,
|
||||
darkBrandColor: users[0].darkBrandColor,
|
||||
theme: null,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
|
||||
import { LOGO, WEBAPP_URL } from "./constants";
|
||||
import { CAL_URL, LOGO, WEBAPP_URL } from "./constants";
|
||||
|
||||
// Ensures tw prop is typed.
|
||||
declare module "react" {
|
||||
@@ -62,7 +62,7 @@ export const constructMeetingImage = (
|
||||
`?type=meeting`,
|
||||
`&title=${encodeURIComponent(title)}`,
|
||||
`&meetingProfileName=${encodeURIComponent(profile.name)}`,
|
||||
profile.image && `&meetingImage=${encodeURIComponent(WEBAPP_URL + profile.image)}`,
|
||||
profile.image && `&meetingImage=${encodeURIComponent(profile.image)}`,
|
||||
`${users.map((user) => `&names=${encodeURIComponent(user.name)}`).join("")}`,
|
||||
`${users.map((user) => `&usernames=${encodeURIComponent(user.username)}`).join("")}`,
|
||||
// Joining a multiline string for readability.
|
||||
@@ -125,7 +125,7 @@ export const Meeting = ({ title, users = [], profile }: MeetingImageProps) => {
|
||||
const avatars = attendees
|
||||
.map((user) => {
|
||||
if ("image" in user && user?.image) return user.image;
|
||||
if ("username" in user && user?.username) return `${WEBAPP_URL}/${user.username}/avatar.png`;
|
||||
if ("username" in user && user?.username) return `${CAL_URL}/${user.username}/avatar.png`;
|
||||
return null;
|
||||
})
|
||||
.filter(Boolean) as string[];
|
||||
|
||||
@@ -32,7 +32,11 @@ export const SENDER_NAME = process.env.NEXT_PUBLIC_SENDGRID_SENDER_NAME || "Cal.
|
||||
// This is the URL from which all Cal Links and their assets are served.
|
||||
// Use website URL to make links shorter(cal.com and not app.cal.com)
|
||||
// As website isn't setup for preview environments, use the webapp url instead
|
||||
export const CAL_URL = new URL(WEBAPP_URL).hostname.endsWith(".vercel.app") ? WEBAPP_URL : WEBSITE_URL;
|
||||
// If it's a .vercel.app domain, keep it.
|
||||
// Else use the website url if defined and finally fallback to the webapp url
|
||||
export const CAL_URL = new URL(WEBAPP_URL).hostname.endsWith(".vercel.app")
|
||||
? WEBAPP_URL
|
||||
: process.env.NEXT_PUBLIC_WEBSITE_URL || WEBAPP_URL;
|
||||
|
||||
export const IS_CALCOM =
|
||||
WEBAPP_URL &&
|
||||
@@ -73,15 +77,15 @@ export const JOIN_DISCORD = "https://go.cal.com/discord";
|
||||
export const POWERED_BY_URL = `${WEBSITE_URL}/?utm_source=embed&utm_medium=powered-by-button`;
|
||||
export const DOCS_URL = "https://cal.com/docs";
|
||||
export const DEVELOPER_DOCS = "https://developer.cal.com";
|
||||
export const SEO_IMG_DEFAULT = `${WEBSITE_URL}/og-image.png`;
|
||||
export const SEO_IMG_DEFAULT = `${CAL_URL}/og-image.png`;
|
||||
// The Dynamic OG Image is passed through Next's Image API to further optimize it.
|
||||
// This results in a 80% smaller image 🤯. It is however important that for the query
|
||||
// parameters you pass to the /api/social/og/image endpoint, you wrap them in encodeURIComponent
|
||||
// as well, otherwise the URL won't be valid.
|
||||
export const SEO_IMG_OGIMG = `${WEBAPP_URL}/_next/image?w=1200&q=100&url=${encodeURIComponent(
|
||||
export const SEO_IMG_OGIMG = `${CAL_URL}/_next/image?w=1200&q=100&url=${encodeURIComponent(
|
||||
"/api/social/og/image"
|
||||
)}`;
|
||||
export const SEO_IMG_OGIMG_VIDEO = `${WEBSITE_URL}/video-og-image.png`;
|
||||
export const SEO_IMG_OGIMG_VIDEO = `${CAL_URL}/video-og-image.png`;
|
||||
export const IS_STRIPE_ENABLED = !!(
|
||||
process.env.STRIPE_CLIENT_ID &&
|
||||
process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY &&
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { AVATAR_FALLBACK } from "@calcom/lib/constants";
|
||||
import type { User, Team } from "@calcom/prisma/client";
|
||||
import { AVATAR_FALLBACK, CAL_URL, WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import type { Team, User } from "@calcom/prisma/client";
|
||||
import type { UserProfile } from "@calcom/types/UserProfile";
|
||||
|
||||
/**
|
||||
* Gives an organization aware avatar url for a user
|
||||
* It ensures that the wrong avatar isn't fetched by ensuring that organizationId is always passed
|
||||
* It should always return a fully formed url
|
||||
*/
|
||||
export const getUserAvatarUrl = (
|
||||
user:
|
||||
@@ -16,11 +16,11 @@ export const getUserAvatarUrl = (
|
||||
| undefined
|
||||
) => {
|
||||
if (user?.avatarUrl) {
|
||||
return user.avatarUrl;
|
||||
return CAL_URL + user.avatarUrl;
|
||||
}
|
||||
if (!user?.username) return AVATAR_FALLBACK;
|
||||
if (!user?.username) return CAL_URL + AVATAR_FALLBACK;
|
||||
// avatar.png automatically redirects to fallback avatar if user doesn't have one
|
||||
return `${WEBAPP_URL}/${user.profile?.username}/avatar.png${
|
||||
return `${CAL_URL}/${user.profile?.username}/avatar.png${
|
||||
user.profile?.organizationId ? `?orgId=${user.profile.organizationId}` : ""
|
||||
}`;
|
||||
};
|
||||
|
||||
@@ -4,8 +4,8 @@ import { usePathname } from "next/navigation";
|
||||
|
||||
import type { AppImageProps, MeetingImageProps } from "@calcom/lib/OgImages";
|
||||
import { constructAppImage, constructGenericImage, constructMeetingImage } from "@calcom/lib/OgImages";
|
||||
import { APP_NAME, WEBSITE_URL, IS_CALCOM } from "@calcom/lib/constants";
|
||||
import { seoConfig, getSeoImage, buildCanonical } from "@calcom/lib/next-seo.config";
|
||||
import { APP_NAME, CAL_URL } from "@calcom/lib/constants";
|
||||
import { buildCanonical, getSeoImage, seoConfig } from "@calcom/lib/next-seo.config";
|
||||
import { truncateOnWord } from "@calcom/lib/text";
|
||||
|
||||
export type HeadSeoProps = {
|
||||
@@ -71,11 +71,8 @@ export const HeadSeo = (props: HeadSeoProps): JSX.Element => {
|
||||
const path = usePathname();
|
||||
// The below code sets the defaultUrl for our canonical tags
|
||||
// Get the router's path
|
||||
const selfHostedOrigin = WEBSITE_URL || "https://cal.com";
|
||||
// Set the default URL to either the current URL (if self-hosted) or https://cal.com canonical URL
|
||||
const defaultUrl = IS_CALCOM
|
||||
? buildCanonical({ path, origin: "https://cal.com" })
|
||||
: buildCanonical({ path, origin: selfHostedOrigin });
|
||||
const defaultUrl = buildCanonical({ path, origin: CAL_URL });
|
||||
|
||||
const {
|
||||
title,
|
||||
|
||||
Reference in New Issue
Block a user