diff --git a/docs/configuration.md b/docs/configuration.md index e29dc80..4026c51 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -41,11 +41,12 @@ This part of the configuration concerns anything that can affect the whole site. - `ignorePatterns`: a list of [glob]() patterns that Quartz should ignore and not search through when looking for files inside the `content` folder. See [[private pages]] for more details. - `defaultDateType`: whether to use created, modified, or published as the default date to display on pages and page listings. - `theme`: configure how the site looks. - - `cdnCaching`: If `true` (default), use Google CDN to cache the fonts. This will generally will be faster. Disable (`false`) this if you want Quartz to download the fonts to be self-contained. + - `cdnCaching`: if `true` (default), use Google CDN to cache the fonts. This will generally be faster. Disable (`false`) this if you want Quartz to download the fonts to be self-contained. - `typography`: what fonts to use. Any font available on [Google Fonts](https://fonts.google.com/) works here. - - `header`: Font to use for headers - - `code`: Font for inline and block quotes. - - `body`: Font for everything + - `title`: font for the title of the site (optional, same as `header` by default) + - `header`: font to use for headers + - `code`: font for inline and block quotes + - `body`: font for everything - `colors`: controls the theming of the site. - `light`: page background - `lightgray`: borders diff --git a/quartz/components/Head.tsx b/quartz/components/Head.tsx index 60dce6e..23183ca 100644 --- a/quartz/components/Head.tsx +++ b/quartz/components/Head.tsx @@ -1,7 +1,7 @@ import { i18n } from "../i18n" import { FullSlug, getFileExtension, joinSegments, pathToRoot } from "../util/path" import { CSSResourceToStyleElement, JSResourceToScriptElement } from "../util/resources" -import { googleFontHref } from "../util/theme" +import { googleFontHref, googleFontSubsetHref } from "../util/theme" import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types" import { unescapeHTML } from "../util/escape" import { CustomOgImagesEmitterName } from "../plugins/emitters/ogImage" @@ -45,6 +45,9 @@ export default (() => { + {cfg.theme.typography.title && ( + + )} )} diff --git a/quartz/components/PageTitle.tsx b/quartz/components/PageTitle.tsx index 046dc52..53ee824 100644 --- a/quartz/components/PageTitle.tsx +++ b/quartz/components/PageTitle.tsx @@ -17,6 +17,7 @@ PageTitle.css = ` .page-title { font-size: 1.75rem; margin: 0; + font-family: var(--titleFont); } ` diff --git a/quartz/plugins/emitters/componentResources.ts b/quartz/plugins/emitters/componentResources.ts index 540a373..5dd67e6 100644 --- a/quartz/plugins/emitters/componentResources.ts +++ b/quartz/plugins/emitters/componentResources.ts @@ -9,7 +9,12 @@ import styles from "../../styles/custom.scss" import popoverStyle from "../../components/styles/popover.scss" import { BuildCtx } from "../../util/ctx" import { QuartzComponent } from "../../components/types" -import { googleFontHref, joinStyles, processGoogleFonts } from "../../util/theme" +import { + googleFontHref, + googleFontSubsetHref, + joinStyles, + processGoogleFonts, +} from "../../util/theme" import { Features, transform } from "lightningcss" import { transform as transpile } from "esbuild" import { write } from "./helpers" @@ -211,9 +216,16 @@ export const ComponentResources: QuartzEmitterPlugin = () => { // let the user do it themselves in css } else if (cfg.theme.fontOrigin === "googleFonts" && !cfg.theme.cdnCaching) { // when cdnCaching is true, we link to google fonts in Head.tsx - const response = await fetch(googleFontHref(ctx.cfg.configuration.theme)) + const theme = ctx.cfg.configuration.theme + const response = await fetch(googleFontHref(theme)) googleFontsStyleSheet = await response.text() + if (theme.typography.title) { + const title = ctx.cfg.configuration.pageTitle + const response = await fetch(googleFontSubsetHref(theme, title)) + googleFontsStyleSheet += `\n${await response.text()}` + } + if (!cfg.baseUrl) { throw new Error( "baseUrl must be defined when using Google Fonts without cfg.theme.cdnCaching", diff --git a/quartz/util/theme.ts b/quartz/util/theme.ts index 56261e3..4a06425 100644 --- a/quartz/util/theme.ts +++ b/quartz/util/theme.ts @@ -25,6 +25,7 @@ export type FontSpecification = export interface Theme { typography: { + title?: FontSpecification header: FontSpecification body: FontSpecification code: FontSpecification @@ -48,7 +49,10 @@ export function getFontSpecificationName(spec: FontSpecification): string { return spec.name } -function formatFontSpecification(type: "header" | "body" | "code", spec: FontSpecification) { +function formatFontSpecification( + type: "title" | "header" | "body" | "code", + spec: FontSpecification, +) { if (typeof spec === "string") { spec = { name: spec } } @@ -82,12 +86,19 @@ function formatFontSpecification(type: "header" | "body" | "code", spec: FontSpe } export function googleFontHref(theme: Theme) { - const { code, header, body } = theme.typography + const { header, body, code } = theme.typography const headerFont = formatFontSpecification("header", header) const bodyFont = formatFontSpecification("body", body) const codeFont = formatFontSpecification("code", code) - return `https://fonts.googleapis.com/css2?family=${bodyFont}&family=${headerFont}&family=${codeFont}&display=swap` + return `https://fonts.googleapis.com/css2?family=${headerFont}&family=${bodyFont}&family=${codeFont}&display=swap` +} + +export function googleFontSubsetHref(theme: Theme, text: string) { + const title = theme.typography.title || theme.typography.header + const titleFont = formatFontSpecification("title", title) + + return `https://fonts.googleapis.com/css2?family=${titleFont}&text=${encodeURIComponent(text)}&display=swap` } export interface GoogleFontFile { @@ -135,6 +146,7 @@ ${stylesheet.join("\n\n")} --highlight: ${theme.colors.lightMode.highlight}; --textHighlight: ${theme.colors.lightMode.textHighlight}; + --titleFont: "${getFontSpecificationName(theme.typography.title || theme.typography.header)}", ${DEFAULT_SANS_SERIF}; --headerFont: "${getFontSpecificationName(theme.typography.header)}", ${DEFAULT_SANS_SERIF}; --bodyFont: "${getFontSpecificationName(theme.typography.body)}", ${DEFAULT_SANS_SERIF}; --codeFont: "${getFontSpecificationName(theme.typography.code)}", ${DEFAULT_MONO};