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
Richard Poelderl 2023-06-02 20:28:03 +02:00 committed by GitHub
parent 8ad513e4ec
commit 174c730f1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 7 deletions

View File

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

View File

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

View File

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

View File

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