diff --git a/quartz/components/Head.tsx b/quartz/components/Head.tsx index d0d7c5980..b6a7e8d07 100644 --- a/quartz/components/Head.tsx +++ b/quartz/components/Head.tsx @@ -1,8 +1,8 @@ import { i18n } from "../i18n" import { FullSlug, joinSegments, pathToRoot } from "../util/path" import { CSSResourceToStyleElement, JSResourceToScriptElement } from "../util/resources" -import { getFontSpecificationName, googleFontHref } from "../util/theme"  -import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"  +import { getFontSpecificationName, googleFontHref } from "../util/theme" +import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import satori, { SatoriOptions } from "satori" import { loadEmoji, getIconCode } from "../util/emoji" import fs from "fs" @@ -15,7 +15,7 @@ import { unescapeHTML } from "../util/escape" * @param opts options for generating image */ async function generateSocialImage( - { cfg, description, fileName, fontsPromise, title, fileData }: ImageOptions,  + { cfg, description, fileName, fontsPromise, title, fileData }: ImageOptions, userOpts: SocialImageOptions, imageDir: string, ) { @@ -25,11 +25,11 @@ async function generateSocialImage( // JSX that will be used to generate satori svg const imageComponent = userOpts.imageStructure(cfg, userOpts, title, description, fonts, fileData) - const svg = await satori(imageComponent, {  + const svg = await satori(imageComponent, { width, height, fonts, - loadAdditionalAsset: async (languageCode: string, segment: string) => {  + loadAdditionalAsset: async (languageCode: string, segment: string) => { if (languageCode === "emoji") { return `data:image/svg+xml;base64,${btoa(await loadEmoji(getIconCode(segment)))}` } @@ -66,7 +66,7 @@ export default (() => { externalResources, ctx, }: QuartzComponentProps) => { - // Initialize options if not set  + // Initialize options if not set if (!fullOptions) { if (typeof cfg.generateSocialImages !== "boolean") { fullOptions = { ...defaultOptions, ...cfg.generateSocialImages } @@ -91,7 +91,7 @@ export default (() => { fileData.description?.trim() ?? i18n(cfg.locale).propertyDefaults.description const titleSuffix = cfg.pageTitleSuffix ?? "" const title = - (fileData.frontmatter?.title ?? i18n(cfg.locale).propertyDefaults.title) + titleSuffix  + (fileData.frontmatter?.title ?? i18n(cfg.locale).propertyDefaults.title) + titleSuffix let description = "" if (fdDescription) { description = unescapeHTML(fdDescription) @@ -132,22 +132,22 @@ export default (() => { const { css, js, additionalHead } = externalResources const url = new URL(`https://${cfg.baseUrl ?? "example.com"}`) - const path = url.pathname as FullSlug  + const path = url.pathname as FullSlug const baseDir = fileData.slug === "404" ? path : pathToRoot(fileData.slug!) - const iconPath = joinSegments(baseDir, "static/icon.png")   + const iconPath = joinSegments(baseDir, "static/icon.png") const ogImageDefaultPath = `https://${cfg.baseUrl}/static/og-image.png` // "static/social-images/slug-filename.md.webp" - const ogImageGeneratedPath = `https://${cfg.baseUrl}/${fileDir.replace(  + const ogImageGeneratedPath = `https://${cfg.baseUrl}/${fileDir.replace( `${ctx.argv.output}/`, "", )}/${fileName}.${extension}` // Use default og image if filePath doesnt exist (for autogenerated paths with no .md file) - const useDefaultOgImage = fileName === undefined || !cfg.generateSocialImages  + const useDefaultOgImage = fileName === undefined || !cfg.generateSocialImages - // Path to og/social image (priority: frontmatter > generated image (if enabled) > default image)  + // Path to og/social image (priority: frontmatter > generated image (if enabled) > default image) let ogImagePath = useDefaultOgImage ? ogImageDefaultPath : ogImageGeneratedPath // TODO: could be improved to support external images in the future @@ -155,31 +155,37 @@ export default (() => { const frontmatterImgUrl = fileData.frontmatter?.socialImage // Override with default og image if config option is set - if (fileData.slug === "index") {  + if (fileData.slug === "index") { ogImagePath = ogImageDefaultPath } // Override with frontmatter url if existing - if (frontmatterImgUrl) {  - ogImagePath = `https://${cfg.baseUrl}/static/${frontmatterImgUrl}`  + if (frontmatterImgUrl) { + ogImagePath = `https://${cfg.baseUrl}/static/${frontmatterImgUrl}` } // Url of current page const socialUrl = - fileData.slug === "404" ? url.toString() : joinSegments(url.toString(), fileData.slug!)  + fileData.slug === "404" ? url.toString() : joinSegments(url.toString(), fileData.slug!) return ( - {title}  -    - -     + {title} + + {cfg.theme.cdnCaching && cfg.theme.fontOrigin === "googleFonts" && ( + <> + + + + + )} + {/* OG/Twitter meta tags */} -   +