'use strict'; /** * openvibe-shared/shell — compose a whole server-rendered page from the pieces every OpenVibe site * already ships: the SEO head (`seo.headTags` / `seo.pageSummary`), the OpenVibe Frame * (`frame.noscriptNav`, `frame.footer`), the theme-loader before the first paint, and the deferred * web runtime (`web-runtime.js`, `navbar.js`, `footer.js`) booted from an escaped JSON blob. * * The shell adds no markup of its own — it is the composition the hand-written `` * layouts repeat, in one place, so a repo's `layout.js` can become a call to it (the T11 sweep). * * const shell = require('openvibe-shared/shell'); * res.type('html').send(shell.page({ * name: 'example', title: 'Example', description: '…', canonical: 'https://example.com/', * summary: 'One line an AI can read', * body: '
…
', * features: { chat: { scripts: ['/js/chat.js'] } }, * routes: [{ path: '^/chat', features: ['chat'] }], * })); * * page(o) the whole document: doctype, , . * scripts(o) just the scripts (theme-loader, the deferred runtime, the boot JSON and the * inline boot call). * * Every value that reaches markup is escaped: `seo` escapes the head, this module escapes `lang` and * the body attributes, and the runtime boot is `JSON.stringify(…).replace(/ and break out. */ const seo = require('./seo'); const frame = require('./frame'); const serve = require('./serve'); const social = require('./social'); const appIcons = require('./app-icons'); const esc = seo.esc; /** JSON that is safe inside a `, ``, ``, ``, // The footer this page renders (frame.footer) is started here too, a moment after the site's own scripts: a site // that starts it itself (OpenVibeFooter.init) keeps its own; one that does not gets its phone folds and its line. ``, ].join('\n'); } /** * Compose a whole page. Options: * name / service the site's service name (navbar init, noscript-nav brand, footer default) * lang ('en') `` * title, siteName, description, canonical, image, imageAlt, type, robots, keywords, author, * themeColor, twitterSite, locale, titleSuffix, alternates, jsonLd → `seo.headTags` * summary a one-line AI summary; when given, `seo.pageSummary`'s head goes in * and its