perf(web): serve one canonical host and a 61%-smaller product screenshot

Two things the site was paying for on every visit.

**www served the whole site.** `web/wrangler.jsonc` binds both `codewhale.net`
and `www.codewhale.net` to this worker as custom domains, and nothing
redirected between them — so every page had a second reachable, indexable URL
and the two hosts split whatever authority they earned. `middleware.ts` now
301s `www` to the apex before the locale and static-asset branches, so a
document that moves does not keep pulling subresources from the host it left.
The redirect keeps path and query, leaves the apex, localhost, and preview
hosts alone, and still carries the security headers.

Doing it in middleware rather than moving the route to the existing
`web/redirect` worker is deliberate: reassigning a custom domain between
workers has a window where `www` answers with nothing, and this ships
atomically with the next deploy.

**The LCP element was a 440 KB PNG.** `app/[locale]/page.tsx` marks the product
screenshot `priority`, so it is the largest contentful paint, and it was served
raw — `next/image` is wired up but the Cloudflare transform binding is not
enabled, so nothing resized or re-encoded it. Re-encoded as lossless WebP:

    440,507 -> 172,380 bytes  (-60.9%)

Verified pixel-identical before swapping, not assumed — decoded both and
compared: difference bbox `None`, max channel delta 0 across RGBA. A lossy
q88 encode was 41 KB but showed a max channel delta of 67, which is visible
artifacting on terminal text, so it was rejected.

`docs/public-surface-facts.json` holds the README and website screenshots to
one byte-identical canonical asset, so both move together — `assets/screenshot.webp`
is the same file, and the 19 READMEs and their source stamps follow. That
contract is why this is one commit and not two.

The contract test read dimensions from the PNG IHDR; it now parses the packed
14-bit fields of the lossless VP8L header, and still accepts PNG so the asset
can be swapped back without touching the test.

Enabling the Cloudflare Images binding would let `next/image` negotiate AVIF
and per-viewport widths on top of this, but it needs Images enabled on the
zone, so it is left for a deliberate infra change rather than smuggled in here.

Verified: `npx vitest run` — 31 files, 276 tests passing (5 new middleware
tests, confirmed failing without the redirect); `tsc --noEmit` clean;
`check-readme-translations.py` reports 18 in sync; `prepare-release.sh 0.9.10`
clean.
This commit is contained in:
CodeWhale Bot
2026-08-18 19:49:02 -07:00
parent 0b917dd68d
commit cfe4d21075
30 changed files with 138 additions and 46 deletions

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
وكيل برمجة مفتوح المصدر لطرفيّتك — أحضر نموذجك بنفسك.
@@ -29,7 +29,7 @@ reviewer على Kimi. اكتب أدوارك ودستور constitution خاصًا
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale يعمل في طرفية](assets/screenshot.png)
![Codewhale يعمل في طرفية](assets/screenshot.webp)
## التثبيت

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Un agent de programació de codi obert per al teu terminal — porta el teu propi model.
@@ -32,7 +32,7 @@ coses més útils que pots fer — mira [Contribuir](#contribuir).
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale en execució en un terminal](assets/screenshot.png)
![Codewhale en execució en un terminal](assets/screenshot.webp)
## Instal·lació

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Ein Open-Source-Programmieragent für Ihr Terminal — bringen Sie Ihr eigenes Modell mit.
@@ -36,7 +36,7 @@ eines der nützlichsten Dinge, die Sie tun können — siehe
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale läuft in einem Terminal](assets/screenshot.png)
![Codewhale läuft in einem Terminal](assets/screenshot.webp)
## Installation

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Un agente de programación de código abierto para tu terminal — trae tu propio modelo.
@@ -33,7 +33,7 @@ más útiles que puedes hacer — mira [Contribuir](#contribuir).
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale ejecutándose en una terminal](assets/screenshot.png)
![Codewhale ejecutándose en una terminal](assets/screenshot.webp)
## Instalación

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Un agent de programmation open source pour votre terminal — apportez votre propre modèle.
@@ -35,7 +35,7 @@ voir [Contribuer](#contribuer).
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale en cours d'exécution dans un terminal](assets/screenshot.png)
![Codewhale en cours d'exécution dans un terminal](assets/screenshot.webp)
## Installation

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
आपके टर्मिनल के लिए एक ओपन सोर्स कोडिंग एजेंट — मॉडल आप लाएँ।
@@ -32,7 +32,7 @@ Codewhale की शुरुआत DeepSeek के लिए एक नेट
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![टर्मिनल में चलता Codewhale](assets/screenshot.png)
![टर्मिनल में चलता Codewhale](assets/screenshot.webp)
## इंस्टॉल

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Sebuah coding agent sumber terbuka untuk terminal Anda — bawa model pilihan Anda sendiri.
@@ -18,7 +18,7 @@ Kami selalu membuka kesempatan bagi para kontributor dan cara untuk terus berkem
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale running in a terminal](assets/screenshot.png)
![Codewhale running in a terminal](assets/screenshot.webp)
## Instalasi

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Un agente di programmazione open source per il tuo terminale — porta il tuo modello.
@@ -33,7 +33,7 @@ tu possa fare — vedi [Contribuire](#contribuire).
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale in esecuzione in un terminale](assets/screenshot.png)
![Codewhale in esecuzione in un terminale](assets/screenshot.webp)
## Installazione

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
ターミナルで動くオープンソースのコーディングエージェント — モデルはあなたが持ち込む。
@@ -18,7 +18,7 @@ Codewhale は DeepSeek のためのネイティブ体験として始まりまし
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![ターミナルで動作する Codewhale](assets/screenshot.png)
![ターミナルで動作する Codewhale](assets/screenshot.webp)
## インストール

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
터미널에서 쓰는 오픈소스 코딩 에이전트 — 모델은 당신이 가져옵니다.
@@ -18,7 +18,7 @@ Codewhale은 DeepSeek을 위한 네이티브 경험으로 시작했습니다.
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![터미널에서 실행 중인 Codewhale](assets/screenshot.png)
![터미널에서 실행 중인 Codewhale](assets/screenshot.webp)
## 설치

View File

@@ -31,7 +31,7 @@ useful things you can do — see [Contributing](#contributing).
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale running in a terminal](assets/screenshot.png)
![Codewhale running in a terminal](assets/screenshot.webp)
## Install

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Otwartoźródłowy agent programistyczny do Twojego terminala — model przynosisz sam.
@@ -33,7 +33,7 @@ zrobić — zobacz [Współtworzenie](#współtworzenie).
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale działający w terminalu](assets/screenshot.png)
![Codewhale działający w terminalu](assets/screenshot.webp)
## Instalacja

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Um agente de programação de código aberto para o seu terminal — traga o seu próprio modelo.
@@ -33,7 +33,7 @@ uma das coisas mais úteis que você pode fazer — veja [Contribuindo](#contrib
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale rodando em um terminal](assets/screenshot.png)
![Codewhale rodando em um terminal](assets/screenshot.webp)
## Instalação

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Открытый агент для программирования в вашем терминале — модель приносите с собой.
@@ -35,7 +35,7 @@ harness станет вашим, а не нашим.
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale, запущенный в терминале](assets/screenshot.png)
![Codewhale, запущенный в терминале](assets/screenshot.webp)
## Установка

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Terminaliniz için açık kaynak bir kodlama ajanı — modeli siz getirin.
@@ -34,7 +34,7 @@ yapabileceğiniz en yararlı şeylerden biridir — bkz.
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Terminalde çalışan Codewhale](assets/screenshot.png)
![Terminalde çalışan Codewhale](assets/screenshot.webp)
## Kurulum

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Агент для програмування з відкритим кодом у вашому терміналі — модель приносите ви.
@@ -35,7 +35,7 @@ Codewhale починався як нативний інструмент для D
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale працює в терміналі](assets/screenshot.png)
![Codewhale працює в терміналі](assets/screenshot.webp)
## Встановлення

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
Một coding agent mã nguồn mở cho terminal của bạn — mang theo model của riêng bạn.
@@ -33,7 +33,7 @@ trong những điều hữu ích nhất bạn có thể làm — xem [Đóng gó
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale chạy trong terminal](assets/screenshot.png)
![Codewhale chạy trong terminal](assets/screenshot.webp)
## Cài đặt

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
一个面向终端的开源编程智能体——模型由你自带。
@@ -18,7 +18,7 @@ Codewhale 最初是为 DeepSeek 打造的原生体验,如今已成长为一个
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale 在终端中运行](assets/screenshot.png)
![Codewhale 在终端中运行](assets/screenshot.webp)
## 安装

View File

@@ -1,4 +1,4 @@
<!-- source: README.md sha256:79856d0c10be -->
<!-- source: README.md sha256:acee66e62ab0 -->
# Codewhale
給終端機用的開源程式設計智能體——模型由你自備。
@@ -18,7 +18,7 @@ Codewhale 起初是為 DeepSeek 打造的原生體驗,如今已成長為社群
[![npm](https://img.shields.io/npm/v/codewhale?label=npm)](https://www.npmjs.com/package/codewhale)
[![Discord](https://img.shields.io/badge/Discord-join%20the%20community-5865F2?logo=discord&logoColor=white)](https://discord.gg/37gfS3ksug)
![Codewhale 在終端機中執行](assets/screenshot.png)
![Codewhale 在終端機中執行](assets/screenshot.webp)
## 安裝

Binary file not shown.

Before

Width:  |  Height:  |  Size: 430 KiB

BIN
assets/screenshot.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

View File

@@ -230,8 +230,8 @@
]
},
"screenshot": {
"readme": "assets/screenshot.png",
"website": "web/public/codewhale-tui.png",
"readme": "assets/screenshot.webp",
"website": "web/public/codewhale-tui.webp",
"sourceVersion": null,
"sourceCommit": null,
"terminal": "unrecorded",

View File

@@ -159,7 +159,7 @@ export default async function HomePage({ params }: { params: Promise<{ locale: s
<span>{d.shotSession}</span>
</div>
<Image
src="/codewhale-tui.png"
src="/codewhale-tui.webp"
alt={d.screenshotAlt}
width={1562}
height={1256}

View File

@@ -255,7 +255,7 @@ describe("homepage integration", () => {
// (plain "Unreleased", per docs/design/WEB_VOICE.md).
expect(homepage).toContain("d.sourceCandidate");
expect(getHome("en").sourceCandidate).toBe("Unreleased");
expect(homepage).toContain('src="/codewhale-tui.png"');
expect(homepage).toContain('src="/codewhale-tui.webp"');
for (const label of ["Plan", "Act", "Operate", "Ask", "Auto-Review", "Full Access"]) {
expect(homepage).toContain(label);
}

View File

@@ -18,7 +18,7 @@
* "Plan · Work · Operate", "Ask · Auto-Review · Full Access",
* "TUI · exec · web · API", "Codewhale", "GitHub", "Issues",
* `npm install -g codewhale`, `cargo test --locked`, `codewhale exec`,
* package-manager proper nouns, mirror names, and `/codewhale-tui.png`.
* package-manager proper nouns, mirror names, and `/codewhale-tui.webp`.
*/
export interface ChromeDict {
@@ -214,7 +214,7 @@ export interface HomeDict {
/** Screenshot toolbar label, e.g. "Current session". */
shotSession: string;
/** Screenshot alt text for /codewhale-tui.png. */
/** Screenshot alt text for /codewhale-tui.webp. */
screenshotAlt: string;
/** Screenshot figcaption. */
figcaption: string;

View File

@@ -0,0 +1,50 @@
import { describe, expect, it } from "vitest";
import { NextRequest } from "next/server";
import { middleware } from "../middleware";
/**
* `www.codewhale.net` and `codewhale.net` are both bound to this worker as
* custom domains, so without a canonical-host redirect the whole site is
* reachable — and indexable — twice.
*/
function request(url: string, host: string, headers: Record<string, string> = {}) {
return new NextRequest(new URL(url), {
headers: new Headers({ host, ...headers }),
});
}
describe("canonical host", () => {
it("301s www to the apex, preserving path and query", () => {
const res = middleware(
request("https://www.codewhale.net/en/docs/hooks?x=1", "www.codewhale.net"),
);
expect(res.status).toBe(301);
expect(res.headers.get("location")).toBe("https://codewhale.net/en/docs/hooks?x=1");
});
it("redirects assets and API routes too, so a moved document stops pulling from www", () => {
for (const path of ["/_next/static/chunk.js", "/api/curated", "/opengraph-image"]) {
const res = middleware(request(`https://www.codewhale.net${path}`, "www.codewhale.net"));
expect(res.status, path).toBe(301);
expect(res.headers.get("location"), path).toBe(`https://codewhale.net${path}`);
}
});
it("leaves the apex host alone", () => {
const res = middleware(request("https://codewhale.net/en", "codewhale.net"));
expect(res.status).not.toBe(301);
});
it("leaves localhost and preview hosts alone", () => {
for (const host of ["localhost:3000", "codewhale-web.pages.dev"]) {
const res = middleware(request("https://example.test/en", host));
expect(res.status, host).not.toBe(301);
}
});
it("still applies security headers to the redirect", () => {
const res = middleware(request("https://www.codewhale.net/en", "www.codewhale.net"));
expect(res.headers.get("X-Content-Type-Options")).toBe("nosniff");
expect(res.headers.get("Strict-Transport-Security")).toContain("max-age=");
});
});

View File

@@ -113,6 +113,22 @@ function pngDimensions(image: Buffer): [number, number] {
return [image.readUInt32BE(16), image.readUInt32BE(20)];
}
/**
* Dimensions of the canonical product screenshot. It is a lossless VP8L WebP,
* so the size lives in the 14-bit-packed VP8L header rather than a PNG IHDR;
* PNG is still accepted so this keeps working if the asset is ever swapped back.
*/
function imageDimensions(image: Buffer): [number, number] {
if (image.subarray(1, 4).toString("ascii") === "PNG") return pngDimensions(image);
expect(image.subarray(0, 4).toString("ascii")).toBe("RIFF");
expect(image.subarray(8, 12).toString("ascii")).toBe("WEBP");
const chunk = image.subarray(12, 16).toString("ascii");
expect(chunk, "expected a lossless VP8L screenshot").toBe("VP8L");
// VP8L: 1 signature byte, then width-1 and height-1 as 14-bit LE fields.
const bits = image.readUInt32LE(21);
return [(bits & 0x3fff) + 1, ((bits >> 14) & 0x3fff) + 1];
}
function comparableVersion(value: string): number {
const [major = 0, minor = 0, patch = 0] = value.split(".").map((n) => Number.parseInt(n, 10) || 0);
return major * 1_000_000 + minor * 1_000 + patch;
@@ -585,14 +601,14 @@ done
const digest = (image: Buffer) => createHash("sha256").update(image).digest("hex");
expect(digest(readmeImage)).toBe(digest(websiteImage));
expect(pngDimensions(readmeImage)).toEqual([1562, 1256]);
expect(imageDimensions(readmeImage)).toEqual([1562, 1256]);
expect(statSync(new URL(matrix.screenshot.readme, root)).size).toBeLessThan(500_000);
expect(matrix.screenshot.terminal).toBe("unrecorded");
const readme = text("README.md");
const homepage = text("web/app/[locale]/page.tsx");
expect(readme).toContain("assets/screenshot.png");
expect(homepage).toContain('src="/codewhale-tui.png"');
expect(readme).toContain("assets/screenshot.webp");
expect(homepage).toContain('src="/codewhale-tui.webp"');
// Alt text and figcaption are dictionary-backed (#4934); the screenshot
// contract now runs through the EN reference value and the page's use of
// it, and every routed locale must caption the same session honestly.

View File

@@ -17,9 +17,35 @@ function applySecurityHeaders(res: NextResponse): NextResponse {
return res;
}
/**
* The one host this site is indexed under. `www` is also bound to this worker
* as a custom domain, so without this guard the entire site answers on two
* hosts and every page has a duplicate URL a crawler can reach.
*
* This runs before the locale and static-asset branches on purpose: the
* canonical host has to win for assets and API routes too, or a `www` page
* keeps pulling subresources from `www` after the document moved.
*/
const CANONICAL_HOST = "codewhale.net";
function canonicalHostRedirect(req: NextRequest): NextResponse | null {
const host = req.headers.get("host");
if (!host) return null;
// Compare without the port so local and preview hosts are untouched.
const bare = host.split(":")[0].toLowerCase();
if (bare !== `www.${CANONICAL_HOST}`) return null;
const url = req.nextUrl.clone();
url.host = CANONICAL_HOST;
url.port = "";
return NextResponse.redirect(url, 301);
}
export function middleware(req: NextRequest) {
const { pathname } = req.nextUrl;
const canonical = canonicalHostRedirect(req);
if (canonical) return applySecurityHeaders(canonical);
// Skip API routes, static files, _next, and the dot-less metadata route
// for the shared OG image (but still apply security headers).
if (

Binary file not shown.

Before

Width:  |  Height:  |  Size: 430 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB