openvibers/openvibe.blog Commits
Render Blog navigation in server HTML (#263)
Changes
@@@ -18,7 +18,7 @@"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.384.0","openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.7.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.133.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.183.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.184.0","pg": "^8.23.0"},"devDependencies": {@@@ -1210,9 +1210,9 @@}},"node_modules/openvibe-shared": {-- "version": "4.183.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.183.0",-- "integrity": "sha512-vp9gg++Dhyj3h0cwvBjujM6dSFYoeXdh1UXdZ6OXP/NjG672Fs7uRANV4MjT467JtFDN7r7qLI3OJAwGQxOuQw==",++ "version": "4.184.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.184.0",++ "integrity": "sha512-e5fwc+ywZUVNQhv9gFIcuRch5NbQyxwEWs+OyA80UodJR7WjQ+4cX1xdB1muk2RNzc1vgt++q32dkx45xlGy7A==","license": "MIT","dependencies": {"jsonwebtoken": "^9.0.0",@@@ -31,7 +31,7 @@"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.384.0","openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.7.0","openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.133.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.183.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.184.0","pg": "^8.23.0"},"devDependencies": {@@@ -2,7 +2,7 @@/*** The page shell (server/render/layout.js): the document is openvibe-publishing/layout's* (openvibe-shared/shell page()): one title, the canonical and robots from the gate's decision, the-- * JSON-LD, the feeds, the blog stylesheet, the Frame (navbar mount, noscript navigation, the++ * JSON-LD, the feeds, the blog stylesheet, the Frame (server navbar mount, the* server-rendered footer and its init), and a blog's theme preset on its content surface only.*/const assert = require('assert');@@@ -48,8 +48,9 @@ const split = (html) => ({ head: html.slice(0, html.indexOf('</head>')), body: hassert.ok(head.includes('<link rel="alternate" type="application/feed+json" href="/@eve/feed.json" title="Eve notes (JSON Feed)">'), 'JSON feed link');assert.ok(/<link rel="stylesheet" href="\/css\/blog\.css\?v=[0-9a-f]+">/.test(head), 'the blog stylesheet');assert.ok(/<meta name="ov-boost" content="blog@[^"]+">/.test(head), 'the boost marker');-- assert.ok(body.includes('<div id="navbar-mount"></div>'), 'the navbar mount');-- assert.ok(body.includes('<nav aria-label="Site"'), 'the noscript navigation');++ assert.ok(body.includes('<div id="navbar-mount"><nav class="openvibe-navbar" aria-label="Site"'), 'the server navbar mount');++ assert.ok(body.includes('data-ov-nav-link="true" href="/desks">AI desks</a>'), 'the blog places are in server HTML');++ assert.ok(body.includes('data-ov-nav-link="true" href="/write">Write</a>'), 'the writer link is in server HTML');assert.ok(body.includes('id="ov-footer"'), 'the server-rendered footer');assert.ok(body.includes('OpenVibeFooter.init(window.__OV_PAGE.footer)'), 'the footer is initialised');assert.ok(/<main id="main" class="page blog-surface" style="--[^"]+" data-blog-theme="paper">/.test(body), 'the theme preset stays on the content surface');@@@ -19,7 +19,7 @@ const BUDGETS = {htmlRawKB: 43.3, // 43.3: measured 41.3 with openvibe-shared 4.161.0, plus room for 4.162.0–4.163.0, 2026-11-09htmlBrotliKB: 10, // 9.2 with the short home (2026-10-30: the pick blocks' chips and the folds' scripts); 8.2 (2026-10-22 the richer home); 4.5jsFiles: 5, // 5 (theme-loader, web-runtime, navbar, footer, boost: openvibe-shared/shell adds web-runtime, 2026-10-04)-- jsRawKB: 375.1, // 375.1: measured 367.1 with openvibe-shared 4.161.0, plus room for 4.162.0–4.163.0, 2026-11-09++ jsRawKB: 375.4, // 375.4: measured 375.3 with Shared 4.184.0; server-nav hydration marker and atomic replacement, 2026-11-10jsBrotliKB: 89.5, // 89.5: measured 87.5 with openvibe-shared 4.163.0, plus room for 4.162.0–4.163.0, 2026-11-09cssFiles: 2, // 1cssRawKB: 54.5, // 54.5: measured 49.5 with openvibe-shared 4.161.0, plus room for 4.162.0–4.163.0, 2026-11-09
@@ -18,7 +18,7 @@
@@ -18,7 +18,7 @@
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.384.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.384.0",
"openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.7.0",
"openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.7.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.133.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.133.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.183.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.184.0",
"pg": "^8.23.0"
"pg": "^8.23.0"
},
},
"devDependencies": {
"devDependencies": {
@@ -1210,9 +1210,9 @@
@@ -1210,9 +1210,9 @@
}
}
},
},
"node_modules/openvibe-shared": {
"node_modules/openvibe-shared": {
- "version": "4.183.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.183.0",
- "integrity": "sha512-vp9gg++Dhyj3h0cwvBjujM6dSFYoeXdh1UXdZ6OXP/NjG672Fs7uRANV4MjT467JtFDN7r7qLI3OJAwGQxOuQw==",
+ "version": "4.184.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.184.0",
+ "integrity": "sha512-e5fwc+ywZUVNQhv9gFIcuRch5NbQyxwEWs+OyA80UodJR7WjQ+4cX1xdB1muk2RNzc1vgt++q32dkx45xlGy7A==",
"license": "MIT",
"license": "MIT",
"dependencies": {
"dependencies": {
"jsonwebtoken": "^9.0.0",
"jsonwebtoken": "^9.0.0",
@@ -31,7 +31,7 @@
@@ -31,7 +31,7 @@
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.384.0",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.384.0",
"openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.7.0",
"openvibe-publishing": "https://codeload.github.com/OpenVibers/OpenVibe.Publishing/tar.gz/refs/tags/v1.7.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.133.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.133.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.183.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.184.0",
"pg": "^8.23.0"
"pg": "^8.23.0"
},
},
"devDependencies": {
"devDependencies": {
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
/**
/**
* The page shell (server/render/layout.js): the document is openvibe-publishing/layout's
* The page shell (server/render/layout.js): the document is openvibe-publishing/layout's
* (openvibe-shared/shell page()): one title, the canonical and robots from the gate's decision, the
* (openvibe-shared/shell page()): one title, the canonical and robots from the gate's decision, the
- * JSON-LD, the feeds, the blog stylesheet, the Frame (navbar mount, noscript navigation, the
+ * JSON-LD, the feeds, the blog stylesheet, the Frame (server navbar mount, the
* server-rendered footer and its init), and a blog's theme preset on its content surface only.
* server-rendered footer and its init), and a blog's theme preset on its content surface only.
*/
*/
const assert = require('assert');
const assert = require('assert');
@@ -48,8 +48,9 @@ const split = (html) => ({ head: html.slice(0, html.indexOf('</head>')), body: h
@@ -48,8 +48,9 @@ const split = (html) => ({ head: html.slice(0, html.indexOf('</head>')), body: h
assert.ok(head.includes('<link rel="alternate" type="application/feed+json" href="/@eve/feed.json" title="Eve notes (JSON Feed)">'), 'JSON feed link');
assert.ok(head.includes('<link rel="alternate" type="application/feed+json" href="/@eve/feed.json" title="Eve notes (JSON Feed)">'), 'JSON feed link');
assert.ok(/<link rel="stylesheet" href="\/css\/blog\.css\?v=[0-9a-f]+">/.test(head), 'the blog stylesheet');
assert.ok(/<link rel="stylesheet" href="\/css\/blog\.css\?v=[0-9a-f]+">/.test(head), 'the blog stylesheet');
assert.ok(/<meta name="ov-boost" content="blog@[^"]+">/.test(head), 'the boost marker');
assert.ok(/<meta name="ov-boost" content="blog@[^"]+">/.test(head), 'the boost marker');
- assert.ok(body.includes('<div id="navbar-mount"></div>'), 'the navbar mount');
- assert.ok(body.includes('<nav aria-label="Site"'), 'the noscript navigation');
+ assert.ok(body.includes('<div id="navbar-mount"><nav class="openvibe-navbar" aria-label="Site"'), 'the server navbar mount');
+ assert.ok(body.includes('data-ov-nav-link="true" href="/desks">AI desks</a>'), 'the blog places are in server HTML');
+ assert.ok(body.includes('data-ov-nav-link="true" href="/write">Write</a>'), 'the writer link is in server HTML');
assert.ok(body.includes('id="ov-footer"'), 'the server-rendered footer');
assert.ok(body.includes('id="ov-footer"'), 'the server-rendered footer');
assert.ok(body.includes('OpenVibeFooter.init(window.__OV_PAGE.footer)'), 'the footer is initialised');
assert.ok(body.includes('OpenVibeFooter.init(window.__OV_PAGE.footer)'), 'the footer is initialised');
assert.ok(/<main id="main" class="page blog-surface" style="--[^"]+" data-blog-theme="paper">/.test(body), 'the theme preset stays on the content surface');
assert.ok(/<main id="main" class="page blog-surface" style="--[^"]+" data-blog-theme="paper">/.test(body), 'the theme preset stays on the content surface');
@@ -19,7 +19,7 @@ const BUDGETS = {
@@ -19,7 +19,7 @@ const BUDGETS = {
htmlRawKB: 43.3, // 43.3: measured 41.3 with openvibe-shared 4.161.0, plus room for 4.162.0–4.163.0, 2026-11-09
htmlRawKB: 43.3, // 43.3: measured 41.3 with openvibe-shared 4.161.0, plus room for 4.162.0–4.163.0, 2026-11-09
htmlBrotliKB: 10, // 9.2 with the short home (2026-10-30: the pick blocks' chips and the folds' scripts); 8.2 (2026-10-22 the richer home); 4.5
htmlBrotliKB: 10, // 9.2 with the short home (2026-10-30: the pick blocks' chips and the folds' scripts); 8.2 (2026-10-22 the richer home); 4.5
jsFiles: 5, // 5 (theme-loader, web-runtime, navbar, footer, boost: openvibe-shared/shell adds web-runtime, 2026-10-04)
jsFiles: 5, // 5 (theme-loader, web-runtime, navbar, footer, boost: openvibe-shared/shell adds web-runtime, 2026-10-04)
- jsRawKB: 375.1, // 375.1: measured 367.1 with openvibe-shared 4.161.0, plus room for 4.162.0–4.163.0, 2026-11-09
+ jsRawKB: 375.4, // 375.4: measured 375.3 with Shared 4.184.0; server-nav hydration marker and atomic replacement, 2026-11-10
jsBrotliKB: 89.5, // 89.5: measured 87.5 with openvibe-shared 4.163.0, plus room for 4.162.0–4.163.0, 2026-11-09
jsBrotliKB: 89.5, // 89.5: measured 87.5 with openvibe-shared 4.163.0, plus room for 4.162.0–4.163.0, 2026-11-09
cssFiles: 2, // 1
cssFiles: 2, // 1
cssRawKB: 54.5, // 54.5: measured 49.5 with openvibe-shared 4.161.0, plus room for 4.162.0–4.163.0, 2026-11-09
cssRawKB: 54.5, // 54.5: measured 49.5 with openvibe-shared 4.161.0, plus room for 4.162.0–4.163.0, 2026-11-09