openvibers/openvibe.computer Commits
Home: carry the site entity as JSON-LD (#48)
Changes
@@@ -1,6 +1,7 @@'use strict';const shell = require('openvibe-shared/shell');const serve = require('openvibe-shared/serve');++const seo = require('openvibe-shared/seo');const { esc } = require('./html');const NAV = [{ label: 'Home', href: '/' }, { label: 'Templates', href: '/templates' }, { label: 'Pricing', href: '/pricing' },@@@ -9,7 +10,7 @@ const NAV = [function page({ title, body, viewer, config, path = '/' }) {const nav = { service: 'computer', apiBase: config.networkUrl, links: NAV.map((x) => ({ ...x, active: path === x.href })), history: { type: 'page', title }, silentLogin: `${config.baseUrl}/auth/login?silent=1&next={url}`, sessionUrl: '/auth/me', loginUrl: '/auth/login?next={path}', logoutUrl: '/auth/logout?next={path}' };const footer = { service: 'computer', variant: 'full', brandName: 'OpenVibe.Computer' };-- return shell.page({ name: 'OpenVibe.Computer', lang: 'en', title: `${title} · OpenVibe.Computer`, titleSuffix: '', siteName: 'OpenVibe.Computer', description: 'A computer for you, your AI, or both.', canonical: `${config.baseUrl}${path}`, robots: 'index, follow', home: '/', navLinks: NAV, navbar: nav, footer,++ return shell.page({ name: 'OpenVibe.Computer', lang: 'en', title: `${title} · OpenVibe.Computer`, titleSuffix: '', siteName: 'OpenVibe.Computer', description: 'A computer for you, your AI, or both.', canonical: `${config.baseUrl}${path}`, robots: 'index, follow', jsonLd: [seo.jsonLd.website({ name: 'OpenVibe.Computer', url: `${config.baseUrl}/`, description: 'A computer for you, your AI, or both.' })], home: '/', navLinks: NAV, navbar: nav, footer,head: `<link rel="stylesheet" href="${serve.url('kit.css')}"><link rel="stylesheet" href="/css/computer.css"><meta name="referrer" content="strict-origin-when-cross-origin">`,body: `<div id="navbar-mount"></div><main id="main" class="computer-page">${body}</main>` });}@@@ -26,6 +26,8 @@ test('home renders signed out and signed in; sign-in and computer controls are vconst s = await serve({ run }); t.after(s.close);const guest = await fetch(s.base); assert.equal(guest.status, 200); assert.match(await guest.text(), /Sign in with OpenVibe/);const home = await fetch(s.base, { headers: { cookie: 'ov_token=person-a' } }); const html = await home.text();++ assert.match(html, /<script type="application\/ld\+json">[^<]*"@type":"WebSite"/, 'the home carries the site entity for search engines');++ assert.match(html, /"name":"OpenVibe\.Computer"/);assert.match(html, /Your computers/); assert.match(html, /Browser/); assert.match(html, /20 hours of cloud browser a month \(proposed\)/); assert.match(html, /Coming as Run adds them/); assert.doesNotMatch(html, /hero-art|account-line/);const detail = await fetch(`${s.base}/computers/ses_a`, { headers: { cookie: 'ov_token=person-a' } }); const page = await detail.text();assert.match(page, /person · usr_a/); assert.match(page, /Snapshots are not available on this machine/);
@@ -1,6 +1,7 @@
@@ -1,6 +1,7 @@
'use strict';
'use strict';
const shell = require('openvibe-shared/shell');
const shell = require('openvibe-shared/shell');
const serve = require('openvibe-shared/serve');
const serve = require('openvibe-shared/serve');
+const seo = require('openvibe-shared/seo');
const { esc } = require('./html');
const { esc } = require('./html');
const NAV = [
const NAV = [
{ label: 'Home', href: '/' }, { label: 'Templates', href: '/templates' }, { label: 'Pricing', href: '/pricing' },
{ label: 'Home', href: '/' }, { label: 'Templates', href: '/templates' }, { label: 'Pricing', href: '/pricing' },
@@ -9,7 +10,7 @@ const NAV = [
@@ -9,7 +10,7 @@ const NAV = [
function page({ title, body, viewer, config, path = '/' }) {
function page({ title, body, viewer, config, path = '/' }) {
const nav = { service: 'computer', apiBase: config.networkUrl, links: NAV.map((x) => ({ ...x, active: path === x.href })), history: { type: 'page', title }, silentLogin: `${config.baseUrl}/auth/login?silent=1&next={url}`, sessionUrl: '/auth/me', loginUrl: '/auth/login?next={path}', logoutUrl: '/auth/logout?next={path}' };
const nav = { service: 'computer', apiBase: config.networkUrl, links: NAV.map((x) => ({ ...x, active: path === x.href })), history: { type: 'page', title }, silentLogin: `${config.baseUrl}/auth/login?silent=1&next={url}`, sessionUrl: '/auth/me', loginUrl: '/auth/login?next={path}', logoutUrl: '/auth/logout?next={path}' };
const footer = { service: 'computer', variant: 'full', brandName: 'OpenVibe.Computer' };
const footer = { service: 'computer', variant: 'full', brandName: 'OpenVibe.Computer' };
- return shell.page({ name: 'OpenVibe.Computer', lang: 'en', title: `${title} · OpenVibe.Computer`, titleSuffix: '', siteName: 'OpenVibe.Computer', description: 'A computer for you, your AI, or both.', canonical: `${config.baseUrl}${path}`, robots: 'index, follow', home: '/', navLinks: NAV, navbar: nav, footer,
+ return shell.page({ name: 'OpenVibe.Computer', lang: 'en', title: `${title} · OpenVibe.Computer`, titleSuffix: '', siteName: 'OpenVibe.Computer', description: 'A computer for you, your AI, or both.', canonical: `${config.baseUrl}${path}`, robots: 'index, follow', jsonLd: [seo.jsonLd.website({ name: 'OpenVibe.Computer', url: `${config.baseUrl}/`, description: 'A computer for you, your AI, or both.' })], home: '/', navLinks: NAV, navbar: nav, footer,
head: `<link rel="stylesheet" href="${serve.url('kit.css')}"><link rel="stylesheet" href="/css/computer.css"><meta name="referrer" content="strict-origin-when-cross-origin">`,
head: `<link rel="stylesheet" href="${serve.url('kit.css')}"><link rel="stylesheet" href="/css/computer.css"><meta name="referrer" content="strict-origin-when-cross-origin">`,
body: `<div id="navbar-mount"></div><main id="main" class="computer-page">${body}</main>` });
body: `<div id="navbar-mount"></div><main id="main" class="computer-page">${body}</main>` });
}
}
@@ -26,6 +26,8 @@ test('home renders signed out and signed in; sign-in and computer controls are v
@@ -26,6 +26,8 @@ test('home renders signed out and signed in; sign-in and computer controls are v
const s = await serve({ run }); t.after(s.close);
const s = await serve({ run }); t.after(s.close);
const guest = await fetch(s.base); assert.equal(guest.status, 200); assert.match(await guest.text(), /Sign in with OpenVibe/);
const guest = await fetch(s.base); assert.equal(guest.status, 200); assert.match(await guest.text(), /Sign in with OpenVibe/);
const home = await fetch(s.base, { headers: { cookie: 'ov_token=person-a' } }); const html = await home.text();
const home = await fetch(s.base, { headers: { cookie: 'ov_token=person-a' } }); const html = await home.text();
+ assert.match(html, /<script type="application\/ld\+json">[^<]*"@type":"WebSite"/, 'the home carries the site entity for search engines');
+ assert.match(html, /"name":"OpenVibe\.Computer"/);
assert.match(html, /Your computers/); assert.match(html, /Browser/); assert.match(html, /20 hours of cloud browser a month \(proposed\)/); assert.match(html, /Coming as Run adds them/); assert.doesNotMatch(html, /hero-art|account-line/);
assert.match(html, /Your computers/); assert.match(html, /Browser/); assert.match(html, /20 hours of cloud browser a month \(proposed\)/); assert.match(html, /Coming as Run adds them/); assert.doesNotMatch(html, /hero-art|account-line/);
const detail = await fetch(`${s.base}/computers/ses_a`, { headers: { cookie: 'ov_token=person-a' } }); const page = await detail.text();
const detail = await fetch(`${s.base}/computers/ses_a`, { headers: { cookie: 'ov_token=person-a' } }); const page = await detail.text();
assert.match(page, /person · usr_a/); assert.match(page, /Snapshots are not available on this machine/);
assert.match(page, /person · usr_a/); assert.match(page, /Snapshots are not available on this machine/);