openvibers/openvibe.games Commits

Client pages name an icon: public/favicon.svg, the network's app icon in the Games colours (openvibe-shared/app-icon favicon({ site: 'games' })), linked from index, play and editor. Without it the browser asked for /favicon.ico, which answers 404: a console error on every visit, found by the browser check (Host scripts/browser-check.js, WS-Q task 3). Test: apps/client/src/pages/pageIcon.test.ts

OP OpenVibers committed 26 Sept 2026 · 0f297696c7 · 5 files, +35 −0


Changes

ddiff --git a/apps/client/editor.html b/apps/client/editor.html
iindex ef6265c..9fa8f2b 100644
---- a/apps/client/editor.html
++++ b/apps/client/editor.html
@@@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
++ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>Scraplandia Map Editor — OpenVibe.Games</title>
<meta
name="description"
ddiff --git a/apps/client/index.html b/apps/client/index.html
iindex c84cb1d..6f6d402 100644
---- a/apps/client/index.html
++++ b/apps/client/index.html
@@@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
++ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>OpenVibe.Games — browser games on the OpenVibe network</title>
<meta
name="description"
ddiff --git a/apps/client/play.html b/apps/client/play.html
iindex e7739a5..8fdfdab 100644
---- a/apps/client/play.html
++++ b/apps/client/play.html
@@@ -3,6 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
++ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>Scraplandia — OpenVibe.Games</title>
<meta
name="description"
ddiff --git a/apps/client/public/favicon.svg b/apps/client/public/favicon.svg
nnew file mode 100644
iindex 0000000..3f26eeb
---- /dev/null
++++ b/apps/client/public/favicon.svg
@@@ -0,0 +1,8 @@
++<svg xmlns="http://www.w3.org/2000/svg" viewBox="-32 -32 64 64"><defs><linearGradient id="ring" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#a78bfa"/><stop offset="1" stop-color="#2563eb"/></linearGradient>
++<radialGradient id="glow"><stop offset="0" stop-color="#a78bfa" stop-opacity=".34"/><stop offset="1" stop-color="#a78bfa" stop-opacity="0"/></radialGradient>
++<radialGradient id="bg" cx=".5" cy=".38" r=".8"><stop offset="0" stop-color="#16223a"/><stop offset=".6" stop-color="#0a0f1c"/><stop offset="1" stop-color="#060912"/></radialGradient></defs><rect x="-32" y="-32" width="64" height="64" rx="15" fill="url(#bg)"/><g transform="scale(1.22)">
++<circle r="21" fill="url(#glow)"/>
++<circle r="18" fill="none" stroke="url(#ring)" stroke-width="4" opacity=".38"/>
++<path d="M0,-18 A18,18 0 0,1 17.4,4.6" fill="none" stroke="url(#ring)" stroke-width="4.4" stroke-linecap="round"/>
++<path d="M-9.5,-7 L0,10 L9.5,-7" fill="none" stroke="#fff" stroke-width="4.8" stroke-linecap="round" stroke-linejoin="round"/>
++<circle cx="17.4" cy="4.6" r="3.2" fill="#facc15"/></g></svg>
\\ No newline at end of file
ddiff --git a/apps/client/src/pages/pageIcon.test.ts b/apps/client/src/pages/pageIcon.test.ts
nnew file mode 100644
iindex 0000000..484c3a6
---- /dev/null
++++ b/apps/client/src/pages/pageIcon.test.ts
@@@ -0,0 +1,24 @@
++/**
++ * Every page of the client names its icon, and the file is in public/. Without a
++ * <link rel="icon"> the browser asks for /favicon.ico, which the server answers
++ * 404: a console error on every visit, found by the browser check
++ * (OpenVibe.Host scripts/browser-check.js, roadmap WS-Q task 3). The icon is the
++ * network's app icon in the Games colours (openvibe-shared/app-icon favicon({ site: 'games' })).
++ */
++import { readFileSync, existsSync } from 'node:fs'
++import { fileURLToPath } from 'node:url'
++import { describe, expect, it } from 'vitest'
++
++const client = (path: string) => fileURLToPath(new URL(`../../${path}`, import.meta.url))
++
++describe('page icon', () => {
++ it.each(['index.html', 'play.html', 'editor.html'])('%s links /favicon.svg', (page) => {
++ const html = readFileSync(client(page), 'utf8')
++ expect(html).toContain('<link rel="icon" type="image/svg+xml" href="/favicon.svg" />')
++ })
++
++ it('public/favicon.svg exists and is an SVG', () => {
++ expect(existsSync(client('public/favicon.svg'))).toBe(true)
++ expect(readFileSync(client('public/favicon.svg'), 'utf8')).toMatch(/^<svg xmlns="http:\/\/www\.w3\.org\/2000\/svg"/)
++ })
++})