From 42d3a7de1711bbd40a2b6857e3bf7ff17685f5d9 Mon Sep 17 00:00:00 2001 From: Jacky Zhao Date: Thu, 1 Jun 2023 17:35:31 -0400 Subject: [PATCH] scss support --- index.d.ts | 4 + package-lock.json | 213 +++++++++++++++++++++--- package.json | 1 + quartz.config.ts | 62 ++++--- quartz/bootstrap.mjs | 6 +- quartz/cfg.ts | 36 +--- quartz/components/Head.tsx | 4 + quartz/plugins/emitters/contentPage.tsx | 19 ++- quartz/plugins/transformers/index.ts | 2 + quartz/plugins/transformers/ofm.ts | 26 +-- quartz/plugins/types.ts | 3 +- quartz/processors/emit.ts | 2 +- quartz/styles/base.scss | 207 +++++++++++++++++++++++ quartz/styles/syntax.scss | 29 ++++ quartz/theme.ts | 59 +++++++ 15 files changed, 574 insertions(+), 99 deletions(-) create mode 100644 index.d.ts create mode 100644 quartz/styles/base.scss create mode 100644 quartz/styles/syntax.scss create mode 100644 quartz/theme.ts diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 000000000..a74b5f59e --- /dev/null +++ b/index.d.ts @@ -0,0 +1,4 @@ +declare module '*.scss' { + const content: string + export = content +} diff --git a/package-lock.json b/package-lock.json index 76d74ce2b..cf60c68ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@napi-rs/simple-git": "^0.1.8", "chalk": "^4.1.2", "cli-spinner": "^0.2.10", + "esbuild-sass-plugin": "^2.9.0", "globby": "^13.1.4", "gray-matter": "^4.0.3", "hast-util-to-jsx-runtime": "^1.2.0", @@ -62,7 +63,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "android" @@ -78,7 +78,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "android" @@ -94,7 +93,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "android" @@ -110,7 +108,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -126,7 +123,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -142,7 +138,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -158,7 +153,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "freebsd" @@ -174,7 +168,6 @@ "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -190,7 +183,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -206,7 +198,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "linux" @@ -222,7 +213,6 @@ "cpu": [ "loong64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -238,7 +228,6 @@ "cpu": [ "mips64el" ], - "dev": true, "optional": true, "os": [ "linux" @@ -254,7 +243,6 @@ "cpu": [ "ppc64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -270,7 +258,6 @@ "cpu": [ "riscv64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -286,7 +273,6 @@ "cpu": [ "s390x" ], - "dev": true, "optional": true, "os": [ "linux" @@ -302,7 +288,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -318,7 +303,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "netbsd" @@ -334,7 +318,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "openbsd" @@ -350,7 +333,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "sunos" @@ -366,7 +348,6 @@ "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -382,7 +363,6 @@ "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -398,7 +378,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -1024,6 +1003,18 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -1055,6 +1046,14 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -1120,6 +1119,32 @@ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/cli-spinner": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/cli-spinner/-/cli-spinner-0.2.10.tgz", @@ -1315,7 +1340,6 @@ "version": "0.17.19", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz", "integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==", - "dev": true, "hasInstallScript": true, "bin": { "esbuild": "bin/esbuild" @@ -1348,6 +1372,18 @@ "@esbuild/win32-x64": "0.17.19" } }, + "node_modules/esbuild-sass-plugin": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/esbuild-sass-plugin/-/esbuild-sass-plugin-2.9.0.tgz", + "integrity": "sha512-D7c8Ub+C4RfaqhOoo9EEWprYmP5ZCmpmcodmYDtpvCfPZLgsSbLaLHPXdul4TUWUMH5eJ6POw+aes/s42ffwrA==", + "dependencies": { + "resolve": "^1.22.2", + "sass": "^1.62.0" + }, + "peerDependencies": { + "esbuild": "^0.17.17" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -1496,6 +1532,24 @@ "node": ">=0.4.x" } }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1568,6 +1622,17 @@ "node": ">=6.0" } }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1807,6 +1872,11 @@ "node": ">= 4" } }, + "node_modules/immutable": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", + "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==" + }, "node_modules/inline-style-parser": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", @@ -1823,6 +1893,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -1845,6 +1926,17 @@ "node": ">=4" } }, + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -2899,6 +2991,14 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -2945,6 +3045,11 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, "node_modules/path-scurry": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.9.2.tgz", @@ -3058,6 +3163,17 @@ "node": ">= 0.6" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/rehype-katex": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-6.0.3.tgz", @@ -3221,6 +3337,22 @@ "node": ">=0.10.0" } }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/retext": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/retext/-/retext-8.1.0.tgz", @@ -3352,6 +3484,22 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/sass": { + "version": "1.62.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz", + "integrity": "sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==", + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/section-matter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", @@ -3440,6 +3588,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", @@ -3531,6 +3687,17 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", diff --git a/package.json b/package.json index 155f00dbd..8212ce42b 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "@napi-rs/simple-git": "^0.1.8", "chalk": "^4.1.2", "cli-spinner": "^0.2.10", + "esbuild-sass-plugin": "^2.9.0", "globby": "^13.1.4", "gray-matter": "^4.0.3", "hast-util-to-jsx-runtime": "^1.2.0", diff --git a/quartz.config.ts b/quartz.config.ts index b36b0aab1..1208e4d1a 100644 --- a/quartz.config.ts +++ b/quartz.config.ts @@ -1,14 +1,41 @@ import { buildQuartz } from "./quartz" import Head from "./quartz/components/Head" -import { ContentPage, CreatedModifiedDate, Description, FrontMatter, GitHubFlavoredMarkdown, Katex, RemoveDrafts } from "./quartz/plugins" -import { ResolveLinks } from "./quartz/plugins/transformers/links" -import { ObsidianFlavoredMarkdown } from "./quartz/plugins/transformers/ofm" +import { ContentPage, CreatedModifiedDate, Description, FrontMatter, GitHubFlavoredMarkdown, Katex, ObsidianFlavoredMarkdown, RemoveDrafts, ResolveLinks } from "./quartz/plugins" export default buildQuartz({ configuration: { siteTitle: "🪴 Quartz 4.0", enableSPA: true, ignorePatterns: ["private", "templates"], + theme: { + typography: { // loaded from Google Fonts + header: "Schibsted Grotesk", + body: "Source Sans Pro", + code: "IBM Plex Mono", + }, + colors: { + lightMode: { + light: '#faf8f8', + lightgray: '#e8e8e8', + gray: '#dadada', + darkgray: '#4e4e4e', + dark: '#141021', + secondary: '#284b63', + tertiary: '#84a59d', + highlight: 'rgba(143, 159, 169, 0.15)', + }, + darkMode: { + light: '#1e1e21', + lightgray: '#292629', + gray: '#343434', + darkgray: '#d4d4d4', + dark: '#fbfffe', + secondary: '#7b97aa', + tertiary: '#84a59d', + highlight: 'rgba(143, 159, 169, 0.15)', + }, + } + } }, plugins: { transformers: [ @@ -31,33 +58,4 @@ export default buildQuartz({ }) ] }, - theme: { - typography: { // loaded from Google Fonts - header: "Schibsted Grotesk", - body: "Source Sans Pro", - code: "IBM Plex Mono", - }, - colors: { - lightMode: { - light: '#faf8f8', - lightgray: '#e8e8e8', - gray: '#dadada', - darkgray: '#4e4e4e', - dark: '#141021', - secondary: '#284b63', - tertiary: '#84a59d', - highlight: 'rgba(143, 159, 169, 0.15)', - }, - darkMode: { - light: '#1e1e21', - lightgray: '#292629', - gray: '#343434', - darkgray: '#d4d4d4', - dark: '#fbfffe', - secondary: '#7b97aa', - tertiary: '#84a59d', - highlight: 'rgba(143, 159, 169, 0.15)', - }, - } - } }) diff --git a/quartz/bootstrap.mjs b/quartz/bootstrap.mjs index 1fa4538d1..8b429ca14 100755 --- a/quartz/bootstrap.mjs +++ b/quartz/bootstrap.mjs @@ -5,6 +5,7 @@ import { hideBin } from 'yargs/helpers' import esbuild from 'esbuild' import chalk from 'chalk' import requireFromString from 'require-from-string' +import { sassPlugin } from 'esbuild-sass-plugin' const fp = "./quartz.config.ts" const { version } = JSON.parse(readFileSync("./package.json").toString()) @@ -59,7 +60,10 @@ yargs(hideBin(process.argv)) format: "cjs", jsx: "automatic", jsxImportSource: "preact", - external: ["@napi-rs/simple-git"] + external: ["@napi-rs/simple-git"], + plugins: [sassPlugin({ + type: 'css-text' + })] }).catch(err => { console.error(`${chalk.red("Couldn't parse Quartz configuration:")} ${fp}`) console.log(`Reason: ${chalk.grey(err)}`) diff --git a/quartz/cfg.ts b/quartz/cfg.ts index 2ed5867c4..140640208 100644 --- a/quartz/cfg.ts +++ b/quartz/cfg.ts @@ -1,34 +1,16 @@ import { PluginTypes } from "./plugins/types" +import { Theme } from "./theme" -export interface ColorScheme { - light: string, - lightgray: string, - gray: string, - darkgray: string, - dark: string, - secondary: string, - tertiary: string, - highlight: string +export interface GlobalConfiguration { + siteTitle: string, + /** Whether to enable single-page-app style rendering. this prevents flashes of unstyled content and improves smoothness of Quartz */ + enableSPA: boolean, + /** Glob patterns to not search */ + ignorePatterns: string[], + theme: Theme } export interface QuartzConfig { - configuration: { - siteTitle: string, - /** Whether to enable single-page-app style rendering. this prevents flashes of unstyled content and improves smoothness of Quartz */ - enableSPA: boolean, - /** Glob patterns to not search */ - ignorePatterns: string[], - }, + configuration: GlobalConfiguration, plugins: PluginTypes, - theme: { - typography: { - header: string, - body: string, - code: string - }, - colors: { - lightMode: ColorScheme, - darkMode: ColorScheme - } - } } diff --git a/quartz/components/Head.tsx b/quartz/components/Head.tsx index 82c434731..c4deb8b6b 100644 --- a/quartz/components/Head.tsx +++ b/quartz/components/Head.tsx @@ -11,6 +11,7 @@ export interface HeadProps { export default function({ title, description, slug, externalResources }: HeadProps) { const { css, js } = externalResources const baseDir = resolveToRoot(slug) + const stylePath = baseDir + "/index.css" const iconPath = baseDir + "/static/icon.png" const ogImagePath = baseDir + "/static/og-image.png" return @@ -26,6 +27,9 @@ export default function({ title, description, slug, externalResources }: HeadPro + + + {css.map(href => )} {js.filter(resource => resource.loadTime === "beforeDOMReady").map(resource =>