chore: add canonical to the document via `PageWrapper` (#8639)
* add canonical to the document via `PageWrapper` * use WEBSITE_URL constant to create the canonical url value --------- Co-authored-by: Keith Williams <keithwillcode@gmail.com> Co-authored-by: Efraín Rochín <roae.85@gmail.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com>pull/9296/head^2
parent
8ad513e4ec
commit
174c730f1f
|
@ -5,6 +5,8 @@ import Script from "next/script";
|
|||
|
||||
import "@calcom/embed-core/src/embed-iframe";
|
||||
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { buildCanonical } from "@calcom/lib/next-seo.config";
|
||||
|
||||
import type { AppProps } from "@lib/app-providers";
|
||||
import AppProviders from "@lib/app-providers";
|
||||
|
@ -49,9 +51,24 @@ function PageWrapper(props: AppProps) {
|
|||
};
|
||||
// Use the layout defined at the page level, if available
|
||||
const getLayout = Component.getLayout ?? ((page) => page);
|
||||
|
||||
// Canonical: Check if the URL is from cal.com so that we set the canonical conditionally
|
||||
const isCalcom =
|
||||
WEBAPP_URL &&
|
||||
(new URL(WEBAPP_URL).hostname.endsWith("cal.com") || new URL(WEBAPP_URL).hostname.endsWith("cal.dev"));
|
||||
const path = router.asPath;
|
||||
|
||||
return (
|
||||
<AppProviders {...providerProps}>
|
||||
<DefaultSeo {...seoConfig.defaultNextSeo} />
|
||||
<DefaultSeo
|
||||
// Set canonical to https://cal.com or self-hosted URL
|
||||
canonical={
|
||||
isCalcom
|
||||
? buildCanonical({ path, origin: "https://cal.com" }) // cal.com & .dev
|
||||
: buildCanonical({ path, origin: WEBAPP_URL }) // self-hosted
|
||||
}
|
||||
{...seoConfig.defaultNextSeo}
|
||||
/>
|
||||
<I18nLanguageHandler />
|
||||
<Script
|
||||
nonce={nonce}
|
||||
|
|
|
@ -4,6 +4,7 @@ type BrowserInfo = {
|
|||
referrer: string;
|
||||
title: string;
|
||||
query: string;
|
||||
origin: string;
|
||||
};
|
||||
|
||||
export const getBrowserInfo = (): Partial<BrowserInfo> => {
|
||||
|
@ -16,5 +17,6 @@ export const getBrowserInfo = (): Partial<BrowserInfo> => {
|
|||
referrer: window.document?.referrer ?? undefined,
|
||||
title: window.document.title ?? undefined,
|
||||
query: window.document.location?.search,
|
||||
origin: window.document.location?.origin,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import type { DefaultSeoProps, NextSeoProps } from "next-seo";
|
||||
import type { Router } from "next/router";
|
||||
|
||||
import { APP_NAME, SEO_IMG_DEFAULT, SEO_IMG_OGIMG } from "@calcom/lib/constants";
|
||||
|
||||
|
@ -39,3 +40,13 @@ export const seoConfig: {
|
|||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* This function builds a canonical URL from a given host and path omitting the query params. Note: on homepage it omits the trailing slash
|
||||
* @param origin The protocol + host, e.g. `https://cal.com` or `https://cal.dev`
|
||||
* @param path NextJS' useRouter().asPath
|
||||
* @returns
|
||||
*/
|
||||
export const buildCanonical = ({ origin, path }: { origin: Location["origin"]; path: Router["asPath"] }) => {
|
||||
return `${origin}${path === "/" ? "" : path}`.split("?")[0];
|
||||
};
|
||||
|
|
|
@ -6,8 +6,8 @@ import { useRouter } from "next/router";
|
|||
import type { AppImageProps, MeetingImageProps } from "@calcom/lib/OgImages";
|
||||
import { constructAppImage, constructGenericImage, constructMeetingImage } from "@calcom/lib/OgImages";
|
||||
import { getBrowserInfo } from "@calcom/lib/browser/browser.utils";
|
||||
import { APP_NAME } from "@calcom/lib/constants";
|
||||
import { seoConfig, getSeoImage } from "@calcom/lib/next-seo.config";
|
||||
import { APP_NAME, WEBSITE_URL } from "@calcom/lib/constants";
|
||||
import { seoConfig, getSeoImage, buildCanonical } from "@calcom/lib/next-seo.config";
|
||||
import { truncateOnWord } from "@calcom/lib/text";
|
||||
|
||||
export type HeadSeoProps = {
|
||||
|
@ -73,16 +73,17 @@ export const HeadSeo = (props: HeadSeoProps): JSX.Element => {
|
|||
// The below code sets the defaultUrl for our canonical tags
|
||||
|
||||
// Get the current URL from the window object
|
||||
const url = getBrowserInfo()?.url;
|
||||
const { url } = getBrowserInfo();
|
||||
// Check if the URL is from cal.com
|
||||
const isCalcom =
|
||||
url && (new URL(url).hostname.endsWith("cal.com") || new URL(url).hostname.endsWith("cal.dev"));
|
||||
// Get the router's path
|
||||
const path = useRouter().asPath;
|
||||
// Build the canonical URL using the router's path, without query parameters. Note: on homepage it omits the trailing slash
|
||||
const calcomCanonical = `https://cal.com${path === "/" ? "" : path}`.split("?")[0];
|
||||
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 = isCalcom ? calcomCanonical : url;
|
||||
const defaultUrl = isCalcom
|
||||
? buildCanonical({ path, origin: "https://cal.com" })
|
||||
: buildCanonical({ path, origin: selfHostedOrigin });
|
||||
|
||||
const {
|
||||
title,
|
||||
|
|
Loading…
Reference in New Issue