openvibers/openvibe.run Commits

Run: the front page loads the showcase stylesheet from /shared (it 404ed) (#33)

OP OpenVibers committed 12 Oct 2026 · b3dcb331fc · 2 files, +8 −1

The front page linked `showcase.css` as a bare name (`href="showcase.css"`), which 404s, so openvibe.run's hero, steps and feature grid rendered without their styles. A depth-1 link check across the network found it. The page now links the pinned copy through `openvibe-shared/serve` (`/shared/showcase.css?v=<hash>`).

Test: `site.test.js` checks that the link is the content-addressed `/shared` URL and that it answers `text/css`.

Changes

ddiff --git a/server/web/home.js b/server/web/home.js
iindex d5bbf3c..83f3944 100644
---- a/server/web/home.js
++++ b/server/web/home.js
@@@ -12,6 +12,7 @@
const shell = require('openvibe-shared/shell');
const showcase = require('openvibe-shared/showcase');
const appIcon = require('openvibe-shared/app-icon');
++const ovServe = require('openvibe-shared/serve');
const SITE_NAME = 'OpenVibe.Run';
const NETWORK_URL = 'https://openvibe.network';
@@@ -55,7 +56,7 @@ function renderHome({ config }) {
canonical: `${config.baseUrl}/`, robots: 'index, follow',
navbar: nav, footer: { service: 'run', variant: 'full', mount: '#ov-footer', brandName: SITE_NAME }, home: '/',
navLinks: nav.links,
-- head: [appIcon.headTags({ site: 'run' }), '<link rel="manifest" href="/manifest.webmanifest">', `<link rel="stylesheet" href="${showcase.STYLESHEET}">`].join('\n'),
++ head: [appIcon.headTags({ site: 'run' }), '<link rel="manifest" href="/manifest.webmanifest">', `<link rel="stylesheet" href="${ovServe.url(showcase.STYLESHEET)}">`].join('\n'),
body: `<div id="navbar-mount"></div>\n<main id="main">${body()}</main>`,
});
}
ddiff --git a/test/site.test.js b/test/site.test.js
iindex 3d98b8a..9f2e220 100644
---- a/test/site.test.js
++++ b/test/site.test.js
@@@ -20,6 +20,12 @@ const { boot, check, done } = require('./helpers/app');
assert.ok(r.text.includes('POST /api/v1/jobs/:id/stream/ticket'), 'the stream ticket route as the API names it');
assert.ok(r.text.includes('&quot;artifact&quot;') || r.text.includes('"artifact"'), 'the example names an artifact, as the job contract requires');
assert.ok(!/coming soon|placeholder/i.test(r.text), 'no placeholder copy');
++ // The showcase stylesheet is the pinned copy under /shared, content-addressed, and it answers.
++ const css = /<link rel="stylesheet" href="(\/shared\/showcase\.css\?v=[0-9a-f]{12})">/.exec(r.text);
++ assert.ok(css, 'showcase.css is linked from /shared');
++ const sheet = await t.call('GET', css[1], { token: null });
++ assert.strictEqual(sheet.status, 200);
++ assert.match(sheet.headers.get('content-type'), /text\/css/);
});
await check('the legal pages, robots.txt, the sitemap, the icon and the manifest', async () => {
for (const p of ['/terms', '/privacy', '/dmca']) assert.strictEqual((await t.call('GET', p, { token: null })).status, 200, p);