mirror of
https://github.com/PR0M3TH3AN/VoxVera.git
synced 2026-10-27 09:40:40 +00:00
Add an SVG favicon (no more /favicon.ico 404)
Link a small inline SVG (site/favicon.svg, a red tile with a white "V") from both index.html and board.html via a root-absolute href, so it resolves from "/" and from "/board/" under Vercel cleanUrls. With an icon link present, browsers stop auto-requesting (and 404ing on) /favicon.ico. No binary asset and no external dependency, consistent with the self-contained client. e2e asserts both pages declare the favicon and that /favicon.svg is served as valid SVG. Closes the last code-finishable item in the roadmap's smaller list. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
2f423ceed5
commit
23badb03ae
6 files changed
+22
-1
No files matched your search
@@ -28,6 +28,7 @@ site/
|
||||
locales.js
|
||||
board.html (bulletin board page)
|
||||
board.js
|
||||
favicon.svg (inline SVG site icon)
|
||||
CNAME
|
||||
vendor/
|
||||
nostr-tools/
|
||||
|
||||
+2
-1
@@ -240,7 +240,8 @@ should follow the board's trust model.
|
||||
varies with font availability and zoom; the
|
||||
[cheat sheet](flyer-field-limits.md) is explicitly approximate. Fine as-is;
|
||||
noted so it is not mistaken for a contract.
|
||||
- **No favicon** — browsers log a harmless `404 /favicon.ico`. Cosmetic.
|
||||
- **Favicon — ✅ done.** A small inline SVG (`site/favicon.svg`) is linked from
|
||||
both pages, so browsers no longer request (and 404 on) `/favicon.ico`.
|
||||
- **WebKit/Safari coverage in CI** needs `libavif16` on Linux runners
|
||||
(`sudo npx playwright install-deps`); headless WebKit is also not a perfect
|
||||
stand-in for real Safari/iOS print + clipboard behavior, so a real-device
|
||||
|
||||
@@ -104,6 +104,19 @@ test.describe("VoxVera static client", () => {
|
||||
expect(errors, errors.join("\n")).toHaveLength(0);
|
||||
});
|
||||
|
||||
test("both pages declare an SVG favicon (no /favicon.ico 404)", async ({ page }) => {
|
||||
for (const path of ["/", "/board.html"]) {
|
||||
await page.goto(path);
|
||||
const href = await page.locator('link[rel~="icon"]').first().getAttribute("href");
|
||||
expect(href, `${path} should link a favicon`).toBe("/favicon.svg");
|
||||
}
|
||||
// The asset itself is served and is valid SVG.
|
||||
const res = await page.request.get("/favicon.svg");
|
||||
expect(res.status()).toBe(200);
|
||||
expect(res.headers()["content-type"] || "").toContain("svg");
|
||||
expect(await res.text()).toContain("<svg");
|
||||
});
|
||||
|
||||
test("print media hides app chrome and keeps the flyer", async ({ page }, testInfo) => {
|
||||
await page.goto("/");
|
||||
await page.emulateMedia({ media: "print" });
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<!-- Root-absolute asset paths: with Vercel cleanUrls + trailingSlash this
|
||||
page is served at /board/, so relative paths would resolve to
|
||||
/board/... and 404. -->
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="/nostr-client.css">
|
||||
</head>
|
||||
<body class="board-page">
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-label="VoxVera">
|
||||
<rect width="32" height="32" rx="6" fill="#b80000"/>
|
||||
<path d="M9 9 L16 23 L23 9" fill="none" stroke="#ffffff" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 282 B |
@@ -4,6 +4,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>VoxVera Nostr Client</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||
<link rel="stylesheet" href="nostr-client.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
Reference in new issue
Block a user