openvibers/openvibe.network Commits

Say who OpenVibe is: Organization and llms.txt disambiguate the brand (#368)

OP OpenVibers committed 16 days ago · 0a46ea6cc0 · 5 files, +31 −4

* Say who OpenVibe is so AI and search engines cannot take it for something else: the Organization gets a description, other names, a disambiguating description and every main site; llms.txt opens the same way

* The home page's HTML budget takes the Organization's new facts (30.1 KB compressed)

Changes

ddiff --git a/public/index.html b/public/index.html
iindex 6efba53e..c84cfd18 100644
---- a/public/index.html
++++ b/public/index.html
@@@ -25,7 +25,7 @@
<meta name="twitter:image" content="__OV_CARD__">
<meta property="og:site_name" content="OpenVibe">
<link rel="canonical" href="https://openvibe.network/">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj","https://openvibe.live","https://openvibe.tools","https://openvibe.games","https://openvibe.media","https://openvibe.community","https://openvibe.space"]},{"@type":"WebSite","@id":"https://openvibe.network/#site","url":"https://openvibe.network/","name":"OpenVibe.Network","description":"One free account for every OpenVibe site: go live from your browser, online tools, chat, games, videos, jobs and an open platform to build on.","publisher":{"@id":"https://openvibe.network/#org"}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","alternateName":["OpenVibe Network","OpenVibers"],"url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","description":"OpenVibe is an open-source, community-run network of websites that share one free account: live streaming from the browser (OpenVibe.Live), more than 180 online tools (OpenVibe.Tools), chat and the Vibe assistant (OpenVibe.Chat), games, a wiki, news, reviews, deals and an open developer platform.","disambiguatingDescription":"The open-source network of websites at openvibe.network, made by OpenVibers; not the Openvibe mobile social-media aggregator app.","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj","https://openvibe.live","https://openvibe.tools","https://openvibe.chat","https://openvibe.games","https://openvibe.media","https://openvibe.video","https://openvibe.community","https://openvibe.space","https://openvibe.wiki","https://openvibe.blog","https://openvibe.news","https://openvibe.services","https://openre.stream"]},{"@type":"WebSite","@id":"https://openvibe.network/#site","url":"https://openvibe.network/","name":"OpenVibe.Network","description":"One free account for every OpenVibe site: go live from your browser, online tools, chat, games, videos, jobs and an open platform to build on.","publisher":{"@id":"https://openvibe.network/#org"}}]}</script>
<link rel="dns-prefetch" href="https://cdnjs.cloudflare.com">
<!-- Critical theme bootstrap (ov-theme-boot) — MUST stay inline and above the stylesheets.
Paints the cached theme synchronously so the default palette never flashes. Reads
ddiff --git a/server/home/render.js b/server/home/render.js
iindex 8f873d23..d9a2ee41 100644
---- a/server/home/render.js
++++ b/server/home/render.js
@@@ -301,7 +301,9 @@ function sendHome(req, res, { releaseId = '' } = {}) {
res.send(page.html);
}
--const llmsSummary = () => `OpenVibe is an open source, community-run network of sites that share one account: ${OPEN.map((site) => site.name.toLowerCase()).join(', ')}.`;
++// What OpenVibe is, said so an AI cannot mistake it (the owner, 2026-10-28: Google's AI Overview for "whois openvibe"
++// described an unrelated "Openvibe" mobile app): the network, what is on it, and what it is not.
++const llmsSummary = () => `OpenVibe (openvibe.network, made by OpenVibers) is an open source, community-run network of websites that share one free account: ${OPEN.map((site) => site.name.toLowerCase()).join(', ')}. It is not the Openvibe mobile social-media aggregator app, which is unrelated.`;
function llmsTxt() {
const { catalog } = toolsCatalog.peek();
ddiff --git a/server/stats/open.js b/server/stats/open.js
iindex c16d48e3..719a74ea 100644
---- a/server/stats/open.js
++++ b/server/stats/open.js
@@@ -323,7 +323,7 @@ ${require('../boost').meta(releaseId)}
${require('openvibe-shared/app-icon').headTags({ site: 'network', iconBase: '/assets' })}
<meta name="color-scheme" content="dark light">
<script src="/shared/theme-loader.js" defer></script>
--<script type="application/ld+json">${JSON.stringify({ '@context': 'https://schema.org', '@type': 'Dataset', name: title, description: desc, url: 'https://openvibe.network/stats', isAccessibleForFree: true, creator: { '@type': 'Organization', name: 'OpenVibe' }, distribution: [{ '@type': 'DataDownload', encodingFormat: 'application/json', contentUrl: 'https://openvibe.network/api/v1/stats' }, { '@type': 'DataDownload', encodingFormat: 'text/csv', contentUrl: 'https://openvibe.network/api/v1/stats/pageviews.csv' }] }).replace(/</g, '\\u003c')}</script>
++<script type="application/ld+json">${JSON.stringify({ '@context': 'https://schema.org', '@type': 'Dataset', name: title, description: desc, url: 'https://openvibe.network/stats', isAccessibleForFree: true, creator: { '@type': 'Organization', '@id': 'https://openvibe.network/#org', name: 'OpenVibe' }, distribution: [{ '@type': 'DataDownload', encodingFormat: 'application/json', contentUrl: 'https://openvibe.network/api/v1/stats' }, { '@type': 'DataDownload', encodingFormat: 'text/csv', contentUrl: 'https://openvibe.network/api/v1/stats/pageviews.csv' }] }).replace(/</g, '\\u003c')}</script>
<style>
*,*::before,*::after{box-sizing:border-box}
:root{--bg-primary:#0a0f1c;--bg-secondary:#101828;--bg-card:#0f1729;--border:#1f2d47;--accent:#3b82f6;--text-primary:#e6edf7;--text-secondary:#96a7c2;--text-muted:#7386a3;--up:#22c55e;--down:#f87171}
ddiff --git a/test/brand-disambiguation.test.js b/test/brand-disambiguation.test.js
nnew file mode 100644
iindex 00000000..e87774e2
---- /dev/null
++++ b/test/brand-disambiguation.test.js
@@@ -0,0 +1,25 @@
++'use strict';
++// Who OpenVibe is, said so search engines and AI cannot take it for something else (the owner, 2026-10-28: Google's AI
++// Overview for "whois openvibe" described an unrelated "Openvibe" mobile app). The home page's Organization names the
++// network, its other names, what it is and what it is not, and its sites; llms.txt opens the same way.
++const assert = require('assert');
++const fs = require('fs');
++const path = require('path');
++
++const html = fs.readFileSync(path.join(__dirname, '..', 'public', 'index.html'), 'utf8');
++const blocks = [...html.matchAll(/<script type="application\/ld\+json">([\s\S]*?)<\/script>/g)].map((m) => JSON.parse(m[1]));
++const graph = blocks.flatMap((b) => b['@graph'] || [b]);
++const org = graph.find((x) => x['@type'] === 'Organization');
++assert.ok(org, 'the home page has the Organization');
++assert.strictEqual(org['@id'], 'https://openvibe.network/#org', 'the one @id every site\'s pages point at');
++assert.deepStrictEqual(org.alternateName, ['OpenVibe Network', 'OpenVibers']);
++assert.ok(/open-source, community-run network of websites/.test(org.description) && /OpenVibe\.Live/.test(org.description) && /OpenVibe\.Tools/.test(org.description), 'what it is');
++assert.ok(/not the Openvibe mobile social-media aggregator app/.test(org.disambiguatingDescription), 'what it is not');
++['https://github.com/OpenVibers', 'https://openvibe.live', 'https://openvibe.tools', 'https://openvibe.chat', 'https://openvibe.wiki', 'https://openre.stream']
++ .forEach((u) => assert.ok(org.sameAs.includes(u), `sameAs ${u}`));
++
++const llms = require('../server/home/render').llmsTxt();
++assert.ok(/^# OpenVibe Network/m.test(llms));
++assert.ok(llms.includes('OpenVibe (openvibe.network, made by OpenVibers) is an open source, community-run network of websites'), 'llms.txt says what it is');
++assert.ok(llms.includes('It is not the Openvibe mobile social-media aggregator app, which is unrelated.'), 'and what it is not');
++console.log('brand disambiguation: Organization and llms.txt ok');
ddiff --git a/test/perf-budget.test.js b/test/perf-budget.test.js
iindex fc1707c1..c7403a4d 100644
---- a/test/perf-budget.test.js
++++ b/test/perf-budget.test.js
@@@ -13,7 +13,7 @@ const { measure, check, format } = require('openvibe-shared/perf-budget');
const BUDGETS = {
htmlRawKB: 157, // 152.4 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 147.9 with the home's FAQ (six questions and their FAQPage JSON-LD), the numbers panel and the service map's group headings (2026-10-22); 141.2 with Tips and VIP open (contracts 0.200.0, 37 sites; the Opening next section is gone); 134 with Play (contracts 0.172.1); 128.3 with Events, AI and Search added (31 sites, contracts 0.135.0); 122.3 (shared 2.21.0: a real glyph for every product card, where ten drew the 'V'); was 110.6 with 33 live sites (contracts 0.119.0). The home page lists every site, so it grows with the network
-- htmlBrotliKB: 30, // 28.5 with the FAQ, numbers and groups (2026-10-22); 26.1 with Play; 25.1 (31 sites, contracts 0.135.0); 24.1 (shared 2.21.0, the same glyphs); 20.5 (contracts 0.116.0)
++ htmlBrotliKB: 31, // 30.1 with the Organization saying who OpenVibe is (description, other names, what it is not, 15 sites; 2026-10-28); 28.5 with the FAQ, numbers and groups (2026-10-22); 26.1 with Play; 25.1 (31 sites, contracts 0.135.0); 24.1 (shared 2.21.0, the same glyphs); 20.5 (contracts 0.116.0)
jsFiles: 8, // 7 with boost.js, was 6 (2026-10-13, plan T11 step 3: one more script on every boosted page; it loads route-transition.js on the first move only)
jsRawKB: 298, // 293.1 Shared 4.17.0: OpenCoins and Vibes chips (wallet: true) in the navbar; 279.1 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 269.3 with shared 4.11.0's seasonal navbar (Pumpkin Night and the season badge, +2.6); 249.8 with boost.js (13.1); 228.3
jsBrotliKB: 75, // 73.3 Shared 4.17.0: OpenCoins and Vibes chips (wallet: true) in the navbar; 70.7 openvibe-shared 4.15 footer: the compact footer opens into the whole one, and the pulse line; 68.0 with shared 4.12.0 (light/dark switch, seasonal mark, theme pairs); 64.5 with shared 4.11.0's navbar; 60.3 with boost.js (3.8); 53.9