diff --git a/docs/custom/config-fonts.md b/docs/custom/config-fonts.md
index 89810e531c..fa6faf392f 100644
--- a/docs/custom/config-fonts.md
+++ b/docs/custom/config-fonts.md
@@ -18,7 +18,7 @@ fonts:
And that's all.
-Fonts will be **imported automatically from [Google Fonts](https://fonts.google.com/)**. That means you can use any fonts available on Google Fonts directly.
+Fonts will be **imported automatically from a provider via CDN, by default it is [Google Fonts](https://fonts.google.com/)**. That means you can use any fonts available on Google Fonts directly.
## Local Fonts
@@ -92,10 +92,10 @@ fonts:
## Providers
-- Options: `google` | `none`
+- Options: `google` | `coollabs` | `none`
- Default: `google`
-Currently, only Google Fonts is supported, we are planning to add more providers in the future. Specify to `none` will disable the auto-importing feature entirely and treat all the fonts locally.
+Currently, only [Google Fonts](https://fonts.google.com/) and [coolLabs](https://fonts.coollabs.io/) supported, we are planning to add more providers in the future. Specify to `none` will disable the auto-importing feature entirely and treat all the fonts locally.
```yaml
---
diff --git a/packages/slidev/node/setups/indexHtml.ts b/packages/slidev/node/setups/indexHtml.ts
index 56b6c3c342..4c0668bcd7 100644
--- a/packages/slidev/node/setups/indexHtml.ts
+++ b/packages/slidev/node/setups/indexHtml.ts
@@ -7,7 +7,7 @@ import { escapeHtml } from 'markdown-it/lib/common/utils.mjs'
import { version } from '../../package.json'
import { getSlideTitle } from '../commands/shared'
import { toAtFS } from '../resolver'
-import { generateGoogleFontsUrl } from '../utils'
+import { generateCoollabsFontsUrl, generateGoogleFontsUrl } from '../utils'
function toAttrValue(unsafe: unknown) {
return JSON.stringify(escapeHtml(String(unsafe)))
@@ -49,8 +49,13 @@ export default function setupIndexHtml({ mode, entry, clientRoot, userRoot, root
if (data.features.tweet)
body += '\n'
- if (data.config.fonts.webfonts.length && data.config.fonts.provider !== 'none')
- head += `\n`
+ if (data.config.fonts.webfonts.length) {
+ const { provider } = data.config.fonts
+ if (provider === 'google')
+ head += `\n`
+ else if (provider === 'coollabs')
+ head += `\n`
+ }
if (data.headmatter.lang)
main = main.replace('', ``)
diff --git a/packages/slidev/node/utils.ts b/packages/slidev/node/utils.ts
index cc78985538..981d5d93c3 100644
--- a/packages/slidev/node/utils.ts
+++ b/packages/slidev/node/utils.ts
@@ -21,16 +21,23 @@ export function stringifyMarkdownTokens(tokens: Token[]) {
.join(' ')
}
-export function generateGoogleFontsUrl(options: ResolvedFontOptions) {
+export function generateFontParams(options: ResolvedFontOptions) {
const weights = options.weights
.flatMap(i => options.italic ? [`0,${i}`, `1,${i}`] : [`${i}`])
.sort()
.join(';')
- const fonts = options.webfonts
+ const fontParams = options.webfonts
.map(i => `family=${i.replace(/^(['"])(.*)\1$/, '$1').replace(/\s+/g, '+')}:${options.italic ? 'ital,' : ''}wght@${weights}`)
.join('&')
+ return fontParams
+}
+
+export function generateGoogleFontsUrl(options: ResolvedFontOptions) {
+ return `https://fonts.googleapis.com/css2?${generateFontParams(options)}&display=swap`
+}
- return `https://fonts.googleapis.com/css2?${fonts}&display=swap`
+export function generateCoollabsFontsUrl(options: ResolvedFontOptions) {
+ return `https://api.fonts.coollabs.io/fonts?${generateFontParams(options)}&display=swap`
}
/**
diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts
index 05f2737c14..39e61a6027 100644
--- a/packages/types/src/config.ts
+++ b/packages/types/src/config.ts
@@ -18,7 +18,7 @@ export interface ResolvedFontOptions {
serif: string[]
weights: string[]
italic: boolean
- provider: 'none' | 'google'
+ provider: 'none' | 'google' | 'coollabs'
webfonts: string[]
local: string[]
}
diff --git a/packages/types/src/frontmatter.ts b/packages/types/src/frontmatter.ts
index a9ae54f123..941a2234b0 100644
--- a/packages/types/src/frontmatter.ts
+++ b/packages/types/src/frontmatter.ts
@@ -398,7 +398,7 @@ export interface FontOptions {
/**
* @default 'google'
*/
- provider?: 'none' | 'google'
+ provider?: 'none' | 'google' | 'coollabs'
/**
* Specify web fonts names, will detect from `sans`, `mono`, `serif` if not provided
*/
diff --git a/packages/vscode/schema/headmatter.json b/packages/vscode/schema/headmatter.json
index ea664d20f4..1a3082e1d3 100644
--- a/packages/vscode/schema/headmatter.json
+++ b/packages/vscode/schema/headmatter.json
@@ -712,7 +712,8 @@
"type": "string",
"enum": [
"none",
- "google"
+ "google",
+ "coollabs"
],
"default": "google"
},
diff --git a/test/__snapshots__/utils.test.ts.snap b/test/__snapshots__/utils.test.ts.snap
index 6961c93c7c..e3e0d04865 100644
--- a/test/__snapshots__/utils.test.ts.snap
+++ b/test/__snapshots__/utils.test.ts.snap
@@ -1,5 +1,9 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+exports[`utils > coollabs-fonts 1`] = `"https://api.fonts.coollabs.io/fonts?family=Fira+Code:wght@200;400;600&family=PT+Serif:wght@200;400;600&display=swap"`;
+
+exports[`utils > coollabs-fonts 2`] = `"https://api.fonts.coollabs.io/fonts?family=Fira+Code:ital,wght@0,200;0,400;0,600;1,200;1,400;1,600&family=PT+Serif:ital,wght@0,200;0,400;0,600;1,200;1,400;1,600&display=swap"`;
+
exports[`utils > google-fonts 1`] = `"https://fonts.googleapis.com/css2?family=Fira+Code:wght@200;400;600&family=PT+Serif:wght@200;400;600&display=swap"`;
exports[`utils > google-fonts 2`] = `"https://fonts.googleapis.com/css2?family=Fira+Code:ital,wght@0,200;0,400;0,600;1,200;1,400;1,600&family=PT+Serif:ital,wght@0,200;0,400;0,600;1,200;1,400;1,600&display=swap"`;
diff --git a/test/utils.test.ts b/test/utils.test.ts
index c6854504d3..1d17f7a99c 100644
--- a/test/utils.test.ts
+++ b/test/utils.test.ts
@@ -6,7 +6,7 @@ import { describe, expect, it } from 'vitest'
import YAML from 'yaml'
import { parseAspectRatio, parseRangeString } from '../packages/parser/src'
import { getRoots } from '../packages/slidev/node/resolver'
-import { generateGoogleFontsUrl, stringifyMarkdownTokens, updateFrontmatterPatch } from '../packages/slidev/node/utils'
+import { generateCoollabsFontsUrl, generateGoogleFontsUrl, stringifyMarkdownTokens, updateFrontmatterPatch } from '../packages/slidev/node/utils'
describe('utils', () => {
it('page-range', () => {
@@ -61,6 +61,25 @@ describe('utils', () => {
).toMatchSnapshot()
})
+ it('coollabs-fonts', () => {
+ expect(
+ generateCoollabsFontsUrl({
+ webfonts: ['Fira Code', 'PT Serif'],
+ weights: ['200', '400', '600'],
+ provider: 'google',
+ } as ResolvedFontOptions),
+ ).toMatchSnapshot()
+
+ expect(
+ generateCoollabsFontsUrl({
+ webfonts: ['Fira Code', 'PT Serif'],
+ weights: ['200', '400', '600'],
+ italic: true,
+ provider: 'google',
+ } as ResolvedFontOptions),
+ ).toMatchSnapshot()
+ })
+
it('roots', async () => {
const { cliRoot, clientRoot, userRoot, userWorkspaceRoot } = await getRoots(resolve('slides.md'))
const expectRelative = (v: string) => expect(slash(relative(__dirname, v)))