diff --git a/docs/content/1.get-started/4.providers.md b/docs/content/1.get-started/4.providers.md
index 4ba92fb1..8948010c 100644
--- a/docs/content/1.get-started/4.providers.md
+++ b/docs/content/1.get-started/4.providers.md
@@ -17,6 +17,10 @@ Then, when you use a `font-family` in your CSS, we check to see whether it match
[Google Fonts](https://fonts.google.com/) is one of the best known public font APIs.
+### `googleicons`
+
+[Google Fonts Icons](https://fonts.google.com/icons) adds support for Material Symbols and Material Icons.
+
### `bunny`
[Bunny Fonts](https://fonts.bunny.net/) is provided by [bunny.net](https://bunny.net/) and is a drop-in Google Fonts compatible API, focusing on privacy.
diff --git a/playground/pages/providers/googleicons.vue b/playground/pages/providers/googleicons.vue
new file mode 100644
index 00000000..f4780e8b
--- /dev/null
+++ b/playground/pages/providers/googleicons.vue
@@ -0,0 +1,46 @@
+
+
+ Material Symbols Outlined:
+
+ search
+
+ Material Icons Outlined:
+
+ search
+
+
+
+
+
diff --git a/src/module.ts b/src/module.ts
index eaf72cdf..364387de 100644
--- a/src/module.ts
+++ b/src/module.ts
@@ -6,6 +6,7 @@ import { join, relative } from 'pathe'
import { withoutLeadingSlash } from 'ufo'
import local from './providers/local'
import google from './providers/google'
+import googleicons from './providers/googleicons'
import bunny from './providers/bunny'
import fontshare from './providers/fontshare'
import adobe from './providers/adobe'
@@ -93,6 +94,7 @@ export default defineNuxtModule({
local,
adobe,
google,
+ googleicons,
bunny,
fontshare,
fontsource,
diff --git a/src/providers/googleicons.ts b/src/providers/googleicons.ts
new file mode 100644
index 00000000..d5116174
--- /dev/null
+++ b/src/providers/googleicons.ts
@@ -0,0 +1,98 @@
+import { hash } from 'ohash'
+
+import type { FontProvider } from '../types'
+import { extractFontFaceData, addLocalFallbacks } from '../css/parse'
+import { cachedData } from '../cache'
+import { $fetch } from '../fetch'
+import { logger } from '../logger'
+
+export default {
+ async setup() {
+ await initialiseFontMeta()
+ },
+ async resolveFontFaces(fontFamily, defaults) {
+ if (!isGoogleIcon(fontFamily)) {
+ return
+ }
+
+ return {
+ fonts: await cachedData(`googleicons:${fontFamily}-${hash(defaults)}-data.json`, () => getFontDetails(fontFamily), {
+ onError(err) {
+ logger.error(`Could not fetch metadata for \`${fontFamily}\` from \`googleicons\`.`, err)
+ return []
+ },
+ }),
+ }
+ },
+} satisfies FontProvider
+
+/** internal */
+
+let fonts: string[]
+
+async function fetchFontMetadata() {
+ const response: { families: string[] } = JSON.parse((await $fetch(
+ 'https://fonts.google.com/metadata/icons?key=material_symbols&incomplete=true',
+ )).split('\n').slice(1).join('\n')) // remove the first line which makes it an invalid JSON
+
+ return response.families
+}
+
+async function initialiseFontMeta() {
+ fonts = await cachedData('googleicons:meta.json', fetchFontMetadata, {
+ onError() {
+ logger.error('Could not download `googleicons` font metadata. `@nuxt/fonts` will not be able to inject `@font-face` rules for googleicons.')
+ return []
+ },
+ })
+}
+
+function isGoogleIcon(family: string) {
+ return fonts.includes(family)
+}
+
+async function getFontDetails(family: string) {
+ let css = ''
+
+ if (family.includes('Icons')) {
+ css += await $fetch('/css2', {
+ baseURL: 'https://fonts.googleapis.com/icon',
+ query: {
+ family: family,
+ },
+ })
+ }
+
+ for (const extension in userAgents) {
+ // Legacy Material Icons
+ if (family.includes('Icons')) {
+ css += await $fetch('/icon', {
+ baseURL: 'https://fonts.googleapis.com',
+ headers: { 'user-agent': userAgents[extension as keyof typeof userAgents] },
+ query: {
+ family: family,
+ },
+ })
+ }
+ // New Material Symbols
+ else {
+ css += await $fetch('/css2', {
+ baseURL: 'https://fonts.googleapis.com',
+ headers: { 'user-agent': userAgents[extension as keyof typeof userAgents] },
+ query: {
+ family: family + ':' + 'opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200',
+ },
+ })
+ }
+ }
+
+ return addLocalFallbacks(family, extractFontFaceData(css))
+}
+
+const userAgents = {
+ woff2: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36',
+ ttf: 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.54.16 (KHTML, like Gecko) Version/5.1.4 Safari/534.54.16',
+ // eot: 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)',
+ // woff: 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0',
+ // svg: 'Mozilla/4.0 (iPad; CPU OS 4_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/4.1 Mobile/9A405 Safari/7534.48.3',
+}