Resolve share URLs from the instance host and ship 1200×630 Open Graph images.
Staging no longer advertises production canonicals, and Slack/social previews get a default hero card with template and article overrides. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
47625b1c82
commit
751f2e9343
22 files changed
+340
-16
No files matched your search
@@ -1,13 +1,17 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import metadataMessages from "../../messages/en/metadata.json";
|
||||
import {
|
||||
articleShareImages,
|
||||
buildRobots,
|
||||
metadataBaseUrl,
|
||||
NO_INDEX_ROBOTS,
|
||||
originFromHost,
|
||||
PRODUCTION_SITE_ORIGIN,
|
||||
resolveRequestHost,
|
||||
robotsForPublishedRule,
|
||||
routeMetadata,
|
||||
sitemapUrl,
|
||||
templatesShareImages,
|
||||
} from "../../lib/siteMetadata";
|
||||
|
||||
const ORIGINAL_SITE_INDEXING = process.env.SITE_INDEXING;
|
||||
@@ -27,6 +31,13 @@ afterEach(() => {
|
||||
});
|
||||
|
||||
describe("routeMetadata", () => {
|
||||
const defaultImage = {
|
||||
url: "/assets/marketing/og-image.png",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: metadataMessages.shareImage.defaultAlt,
|
||||
};
|
||||
|
||||
it("sets a path canonical, stripping trailing slashes and query strings", () => {
|
||||
expect(routeMetadata("/about").alternates?.canonical).toBe("/about");
|
||||
expect(routeMetadata("/about/").alternates?.canonical).toBe("/about");
|
||||
@@ -37,14 +48,54 @@ describe("routeMetadata", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("sets og:url from the same path so metadataBase can add the host", () => {
|
||||
expect(routeMetadata("/about").openGraph?.url).toBe("/about");
|
||||
expect(routeMetadata("/").openGraph?.url).toBe("/");
|
||||
});
|
||||
|
||||
it("ships a 1200×630 default share image on og and twitter", () => {
|
||||
const meta = routeMetadata("/learn");
|
||||
expect(meta.openGraph?.images).toEqual([defaultImage]);
|
||||
expect(meta.twitter?.images).toEqual([defaultImage.url]);
|
||||
});
|
||||
|
||||
it("keeps caller metadata while overriding a parent canonical", () => {
|
||||
expect(
|
||||
routeMetadata("/learn", { title: "Learn", description: "Copy" }),
|
||||
).toEqual({
|
||||
const meta = routeMetadata("/learn", {
|
||||
title: "Learn",
|
||||
description: "Copy",
|
||||
alternates: { canonical: "/learn" },
|
||||
});
|
||||
expect(meta.title).toBe("Learn");
|
||||
expect(meta.description).toBe("Copy");
|
||||
expect(meta.alternates?.canonical).toBe("/learn");
|
||||
expect(meta.openGraph?.url).toBe("/learn");
|
||||
});
|
||||
|
||||
it("lets templates and articles replace the default share image", () => {
|
||||
const templates = templatesShareImages();
|
||||
const templateMeta = routeMetadata("/templates", {
|
||||
openGraph: { images: templates },
|
||||
});
|
||||
expect(templateMeta.openGraph?.images).toEqual(templates);
|
||||
expect(templateMeta.twitter?.images).toEqual([templates[0]?.url]);
|
||||
|
||||
const article = articleShareImages(
|
||||
"how-chaos-concentrates-control",
|
||||
"How Chaos Concentrates Control",
|
||||
);
|
||||
const articleMeta = routeMetadata("/blog/how-chaos-concentrates-control", {
|
||||
openGraph: { images: article },
|
||||
});
|
||||
expect(articleMeta.openGraph?.images).toEqual([
|
||||
{
|
||||
url: "/content/blog/how-chaos-concentrates-control-og.png",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "How Chaos Concentrates Control",
|
||||
},
|
||||
]);
|
||||
expect(articleMeta.twitter?.images).toEqual([
|
||||
"/content/blog/how-chaos-concentrates-control-og.png",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -70,6 +121,30 @@ describe("resolveRequestHost", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("originFromHost", () => {
|
||||
it("uses CLOUDRON_APP_ORIGIN when no host is given", () => {
|
||||
process.env.CLOUDRON_APP_ORIGIN = "https://staging.communityrule.info";
|
||||
expect(originFromHost(null)).toBe("https://staging.communityrule.info");
|
||||
expect(metadataBaseUrl().origin).toBe("https://staging.communityrule.info");
|
||||
});
|
||||
|
||||
it("falls back to production when neither host nor app origin is set", () => {
|
||||
delete process.env.CLOUDRON_APP_ORIGIN;
|
||||
expect(originFromHost(null)).toBe(PRODUCTION_SITE_ORIGIN);
|
||||
});
|
||||
|
||||
it("builds https origins from public hostnames", () => {
|
||||
expect(originFromHost("staging.communityrule.info")).toBe(
|
||||
"https://staging.communityrule.info",
|
||||
);
|
||||
expect(originFromHost("communityrule.com")).toBe(PRODUCTION_SITE_ORIGIN);
|
||||
});
|
||||
|
||||
it("keeps http for localhost so local previews resolve", () => {
|
||||
expect(originFromHost("localhost:3000")).toBe("http://localhost:3000");
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildRobots", () => {
|
||||
it("disallows crawlers on staging and unknown hosts", () => {
|
||||
expect(buildRobots("staging.communityrule.info")).toEqual({
|
||||
|
||||
Reference in new issue
Block a user