Skip to content

Commit fa11759

Browse files
committed
fix: move homepage preview off the legacy image URL
1 parent 36e942e commit fa11759

10 files changed

Lines changed: 17 additions & 17 deletions

File tree

‎DESIGN_SYSTEM.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ the current code pass.
8080

8181
### Social preview artwork
8282

83-
At the user's request, generated social previews abstract the Cloud campaign's sky, clouds, and birds through a flat cut-paper composition informed by modern abstract painting. This scope covers `src/shared/content/social-preview-image.tsx`, its artwork, and the default `/og-image.png`. Use a cobalt sky, oversized ivory cloud shapes, and birds reduced to asymmetric wing silhouettes. No eyes, feather detail, outlines, gradients, texture filters, or simulated depth. The original SVG must contain no embedded bitmaps.
83+
At the user's request, generated social previews abstract the Cloud campaign's sky, clouds, and birds through a flat cut-paper composition informed by modern abstract painting. This scope covers `src/shared/content/social-preview-image.tsx`, its artwork, and the default `/og/home/image.png`. Use a cobalt sky, oversized ivory cloud shapes, and birds reduced to asymmetric wing silhouettes. No eyes, feather detail, outlines, gradients, texture filters, or simulated depth. The original SVG must contain no embedded bitmaps.
8484

8585
Use Fraunces Black for both the title and the text-only Memos wordmark; Inter carries supporting copy at 34px, limited to one or two lines. Keep descriptions subordinate through regular weight and a softer ink color, not tiny type. Entry pages may supply concise image-only copy while retaining their full metadata descriptions. The wordmark sits independently at the lower left, aligned with the title and description. Omit section labels from the image rather than pairing mismatched type next to the brand. Keep the left text column clear of illustration and reserve the right side for an asymmetric, cropped composition. No logo icon or text shadows. This exception to sections 10–11 applies only to the fixed 1200 × 630 social image, not page styles. Serve PNG from the shared template for social crawler compatibility, and keep representative generated images below 300 KB. Verify short and long titles at full and card size.
8686

‎docs/architecture.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ infrastructure or a committed product roadmap.
3232
| `(app)` | Overview and connection settings; Clerk provider and account shell | Static client-auth shells, noindex |
3333
| `api/search` | Public docs search index, searched in the browser | Static |
3434
| `og/` | Generated Docs, Blog, and Changelog social images | Static, `nodejs` runtime |
35-
| `og-image.png` | Default social image, using the same SVG sky and text-only wordmark template | Static, `nodejs` runtime |
35+
| `og/home/image.png` | Default social image, using the same SVG sky and text-only wordmark template | Static, `nodejs` runtime |
3636
| `llms.txt`, `llms-full.txt`, `llms.mdx/[...slug]` | Public content indexes and Markdown exports | Static |
3737

3838
The site also generates `sitemap.xml` and `/blog/feed.xml`. There is no `(auth)`

‎next.config.mjs‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,10 +288,6 @@ const config = {
288288
},
289289
async headers() {
290290
return [
291-
{
292-
source: "/og-image.png",
293-
headers: CORS_HEADERS,
294-
},
295291
{
296292
source: "/og/:path*",
297293
headers: CORS_HEADERS,

‎public/_headers‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
Cache-Control: public,max-age=31536000,immutable
2424

2525
# CORS for OG images: keep in sync with CORS_HEADERS in next.config.mjs,
26-
# which covers the generated /og-image.png and /og/:path* routes.
27-
/og-image.png
26+
# which covers the generated /og/home/image.png and /og/:path* routes.
27+
/og/home/image.png
2828
Cache-Control: public,max-age=86400,stale-while-revalidate=604800
2929
Access-Control-Allow-Origin: *
3030
Access-Control-Allow-Methods: GET, HEAD, OPTIONS

‎scripts/smoke-test.mjs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ const checks = [
4545
cacheControlIncludes: "max-age=31536000",
4646
openNextCacheAbsent: true,
4747
},
48-
{ path: "/og-image.png", type: "png", cacheControlIncludes: "max-age=86400", openNextCache: "HIT" },
48+
{ path: "/og-image.png", status: 404, type: "html" },
49+
{ path: "/og/home/image.png", type: "png", cacheControlIncludes: "max-age=86400", openNextCache: "HIT" },
4950
{ path: "/og/blog/best-practices-to-write-tag/image.png", type: "png" },
5051
{ path: "/og/blog/20k-github-stars-in-2-years/image.png", status: 404, type: "html" },
5152
{

‎scripts/static-headers.test.mjs‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,14 @@ function matchesRoute(pattern, route) {
6868
return route.startsWith(prefix) && route.endsWith(suffix);
6969
}
7070

71-
test("static Open Graph image keeps only its specific cache rule", async () => {
72-
const headers = await readHeadersBlock("/og-image.png");
71+
test("generated homepage Open Graph image keeps its cache rule", async () => {
72+
const headers = await readHeadersBlock("/og/home/image.png");
7373

7474
assert.equal(headers.get("cache-control"), "public,max-age=86400,stale-while-revalidate=604800");
75-
assert.equal(headers.has("access-control-allow-origin"), false);
76-
assert.equal(headers.has("access-control-allow-methods"), false);
7775
});
7876

79-
test("static Open Graph image allows cross-origin reads from inherited static headers", async () => {
80-
const headers = await readEffectiveHeaders("/og-image.png");
77+
test("generated homepage Open Graph image allows cross-origin reads", async () => {
78+
const headers = await readEffectiveHeaders("/og/home/image.png");
8179

8280
assert.equal(headers.get("access-control-allow-origin"), "*");
8381
assert.equal(headers.get("access-control-allow-methods"), "GET, HEAD, OPTIONS");

‎src/shared/content/social-preview-image.test.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { readFile } from "node:fs/promises";
33
import { renderToStaticMarkup } from "react-dom/server";
44
import { describe, expect, it } from "vitest";
5-
import { GET as getDefaultImage } from "@/app/og-image.png/route";
5+
import { GET as getDefaultImage } from "@/app/og/home/image.png/route";
66
import { getDocsSocialPreview } from "@/features/docs/lib/social-preview";
77
import { BRAND_DESCRIPTION, BRAND_TAGLINE_LINES } from "@/shared/lib/branding";
88
import { buildContentMetadata } from "./social-preview";

‎src/shared/lib/seo.test.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
22
import {
33
absoluteUrl,
44
buildBreadcrumbItems,
5+
buildDefaultOpenGraphImages,
56
buildFaqJsonLd,
67
buildSiteNavigationJsonLd,
78
SITE_NAV_DEMO,
@@ -10,6 +11,10 @@ import {
1011
} from "./seo";
1112

1213
describe("seo", () => {
14+
it("uses a new homepage image URL instead of the retired static image", () => {
15+
expect(buildDefaultOpenGraphImages()[0].url).toBe("https://usememos.com/og/home/image.png");
16+
});
17+
1318
it("groups the primary site navigation around visitor tasks", () => {
1419
expect(SITE_NAV_ITEMS.map((item) => item.name)).toEqual(["Features", "Use Cases", "Docs", "Resources"]);
1520
expect(SITE_NAV_LINKS.map((item) => item.name)).toEqual([

‎src/shared/lib/seo.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export const BASE_URL = "https://usememos.com";
55
export const SITE_NAME = "Memos";
66
export const GITHUB_REPO_URL = "https://github.com/usememos/memos";
77
export const GITHUB_STAR_COUNT_PLACEHOLDER = "60K+";
8-
export const DEFAULT_OG_IMAGE = `${BASE_URL}/og-image.png`;
8+
export const DEFAULT_OG_IMAGE = `${BASE_URL}/og/home/image.png`;
99
export const DEFAULT_OG_IMAGE_ALT = BRAND_TITLE;
1010

1111
export interface SiteNavLink {

0 commit comments

Comments
 (0)