-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathtemplate.js
More file actions
82 lines (81 loc) · 3.92 KB
/
template.js
File metadata and controls
82 lines (81 loc) · 3.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { sanitizeString } from '../shared/sanitizeString'
import environment from './environment'
import integrities from './integrities'
import { absolute, cdn, cdnOrAbsolute } from './links'
import project from './project'
import renderAttributes from './renderAttributes'
import settings from './settings'
export default function ({ head, body, nextMeta, context, instances }) {
const { page, router, worker, params } = context
const canonical = absolute(page.canonical || router.url)
const image = cdnOrAbsolute(page.image)
const serializableContext = {}
const blacklist = ['scope', 'router', 'page', 'environment', 'settings', 'worker', 'params', 'project', 'instances']
for (const [key, value] of Object.entries(context)) {
if (!blacklist.includes(key) && typeof value !== 'function') {
serializableContext[key] = value
}
}
const serializableInstances = {}
for (const [key, value] of Object.entries(instances)) {
if (Object.keys(value).length) {
serializableInstances[key] = value
}
}
const serializedWorker = {
...worker,
staleWhileRevalidate: worker.staleWhileRevalidate.map((matcher) => matcher.toString()),
cacheFirst: worker.cacheFirst.map((matcher) => matcher.toString()),
}
const state = {
page,
environment,
settings,
worker: serializedWorker,
params,
project,
instances: environment.mode === 'spa' ? {} : serializableInstances,
context: environment.mode === 'spa' ? {} : serializableContext,
}
return `<!DOCTYPE html>
<html lang="${page.locale || ''}" ${renderAttributes(nextMeta.html)}>
<head>
<meta charset="utf-8">
<meta name="generator" content="Created with Nullstack - https://nullstack.app" />
<title>${page.title || ''}</title>
<meta property="og:image" content="${image}">
<meta property="og:description" content="${page.description || ''}">
<meta name="description" content="${page.description || ''}">
<meta property="og:title" content="${page.title || ''}">
${project.type ? `<meta property="og:type" content="${project.type}">` : ''}
${project.name ? `<meta property="og:site_name" content="${project.name}">` : ''}
<meta property="og:url" content="${canonical}">
<link rel="canonical" href="${canonical}">
<meta property="og:locale" content="${page.locale || ''}">
<link rel="shortcut icon" href="${cdn(project.favicon)}" type="image/png">
<link rel="icon" href="${cdn(project.favicon)}" type="image/png">
<link rel="manifest" href="/manifest.webmanifest" integrity="${integrities['manifest.webmanifest'] || ''}">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
${project.name ? `<meta name="application-name" content="${project.name}">` : ''}
${project.name ? `<meta name="apple-mobile-web-app-title" content="${project.name}">` : ''}
${page.robots ? `<meta name="robots" content="${page.robots}" />` : ''}
<meta name="msapplication-starturl" content="/">
${project.viewport ? `<meta name="viewport" content="${project.viewport}">` : ''}
<link rel="stylesheet" href="${cdn(`/client.css?fingerprint=${environment.key}`)}" integrity="${
integrities['client.css'] || ''
}">
${page.schema ? `<script type="application/ld+json">${JSON.stringify(page.schema)}</script>` : ''}
${project.icons['180'] ? `<link rel="apple-touch-icon" sizes="180x180" href="${cdn(project.icons['180'])}">` : ''}
<meta name="msapplication-TileColor" content="${project.backgroundColor || project.color}">
<meta name="nullstack" content="${encodeURIComponent(sanitizeString(JSON.stringify(state)))}">
${head.split('<!--#-->').join('')}
<script src="${cdn(`/client.js?fingerprint=${environment.key}`)}" integrity="${
integrities['client.js'] || ''
}" defer></script>
</head>
<body ${renderAttributes(nextMeta.body)}>
${environment.mode === 'spa' ? '<div id="application"></div>' : body}
</body>
</html>`
}