fonts

Activity, over time

Daily observations from the public event archive.

Attention

Daily stars & forks

Loading attention chart

Star accumulation

Cumulative stars

Loading star accumulation chart

Pull requests

Daily opens & merges

Loading pull requests chart

Conversations

Daily issues & comments

Loading conversations chart

Community

Daily accounts & reviews

Loading community chart

Releases

Daily releases

Loading releases chart

Mentions

4posts · 30d
Nov 31 post
  1. > Masthead set in Manufacturing Consent I like the description for Manufacturing Consent font: fonts.google.com github.com/google/fonts/blob/main/ofl/manufacturi…

  2. Reddit · · r/ArtCraftAI · u/PhobicPeople

    Free Font Downloader to get started (PowerShell)(Windows) A simple PowerShell script to fetch a curated collection of free/open-source fonts (great for fresh installs or lightweight suites). If the script confuses you or you don't trust it you can find links to each font at the end of the post. For people who don't have a lot of fonts or on a machine that has not had Office or Adobe installed before ArtCraft: I put together a little downloader of my favorite free fonts. This script will download around 30 of my favorite free fonts directly from their sources for you into a little folder named Phobic Favorite Free Fonts on your desktop. How to Run It (No Admin Rights Needed!) - Press the Windows Key, type PowerShell, and open Windows PowerShell (or Terminal). - Copy the script code provided below. - Right-click inside the PowerShell window to paste the code, then press Enter. - The script will automatically create a Phobic Favorite Free Fonts folder on your Desktop, download all the fonts directly from their official sources, and pop open the folder when it's done! - From the folder, you can review and install the fonts normally. All these fonts are free but some have different licenses. See bottom of the post. In particular Heatwave, Another Danger are free for personal use commercial use requires license, and Clash Grotesk liscence requires direct individual download which this script does (technically correct, though possibly not how it was originally intended). <# =============================================================================== PHOBIC FAVORITE FREE FONTS DOWNLOADER - LICENSE & USAGE BREAKDOWN =============================================================================== SIL Open Font License 1.1 (Free for personal & commercial use): - Inter, Montserrat, Open Sans, Poppins, JetBrains Mono, Fira Code, Merriweather, Playfair Display, Fraunces, Lora, Bricolage Grotesque, Overused Grotesk, Road Rage, Rubik Wet Paint, Sedgwick Ave Display, Jost, Manrope Apache License 2.0 (Free for personal & commercial use): - Roboto, Permanent Marker Vic Fieger Freeware (Free for personal & commercial use, not open-source): - Edo SZ ITF Free Font License (Free for personal & commercial use): - Clash Grotesk - Note: Fontshare terms require direct individual download, which this script executes directly. Do not re-host or redistribute the font file. Personal Use Only / Demo (Free for personal use / memes only): - Another Danger (Demo) - Commercial license sold separately by The Branded Quotes. Free Font (Personal use only): - Heatwave Free Font - Commercial license available via Maulana Creative. =============================================================================== #> $out = Join-Path ([Environment]::GetFolderPath("Desktop")) "Phobic Favorite Free Fonts" $licOut = Join-Path $out "Licenses" New-Item -ItemType Directory -Force -Path $out, $licOut | Out-Null [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $web = New-Object System.Net.WebClient $web.Headers.Add("User-Agent", "Mozilla/5.0") $web.Headers.Add("Referer", "dafont.com") # ---------- FONT FILES ---------- $fonts = @( @{ File = "Montserrat-Regular.ttf"; Url = "github.com/googlefonts/montserrat/raw/master/font…" }, @{ File = "Montserrat-Bold.ttf"; Url = "github.com/googlefonts/montserrat/raw/master/font…" }, @{ File = "OpenSans-Regular.ttf"; Url = "github.com/googlefonts/opensans/raw/main/fonts/tt…" }, @{ File = "OpenSans-Bold.ttf"; Url = "github.com/googlefonts/opensans/raw/main/fonts/tt…" }, @{ File = "Roboto-Regular.ttf"; Url = "github.com/googlefonts/roboto/raw/main/src/hinted…" }, @{ File = "Roboto-Bold.ttf"; Url = "github.com/googlefonts/roboto/raw/main/src/hinted…" }, @{ File = "Poppins-Regular.ttf"; Url = "github.com/google/fonts/raw/main/ofl/poppins/Popp…" }, @{ File = "Poppins-Bold.ttf"; Url = "github.com/google/fonts/raw/main/ofl/poppins/Popp…" }, @{ File = "JetBrainsMono-Regular.ttf"; Url = "github.com/JetBrains/JetBrainsMono/raw/master/fon…" }, @{ File = "PermanentMarker-Regular.ttf"; Url = "github.com/google/fonts/raw/main/apache/permanent…" }, @{ File = "EdoSZ.ttf"; Url = "github.com/adam-lynch/fonts/raw/master/edosz.ttf" }, @{ File = "Merriweather-Regular.ttf"; Url = "github.com/SorkinType/Merriweather/raw/master/fon…" }, @{ File = "PlayfairDisplay-Regular.ttf"; Url = "github.com/fonts/Playfair-Display/raw/master/TTF/…" }, @{ File = "Fraunces72pt-Regular.ttf"; Url = "github.com/googlefonts/fraunces/raw/master/fonts/…" }, @{ File = "Lora-Regular.ttf"; Url = "github.com/cyrealtype/Lora/raw/main/fonts/ttf/Lor…" }, @{ File = "BricolageGrotesque-Regular.ttf"; Url = "github.com/ateliertriay/bricolage/raw/main/fonts/…" }, @{ File = "BricolageGrotesque-Bold.ttf"; Url = "github.com/ateliertriay/bricolage/raw/main/fonts/…" }, @{ File = "OverusedGrotesk-Regular.ttf"; Url = "github.com/RandomMaerks/Overused-Grotesk/raw/HEAD…" }, @{ File = "OverusedGrotesk-Bold.ttf"; Url = "github.com/RandomMaerks/Overused-Grotesk/raw/HEAD…" }, @{ File = "RoadRage-Regular.ttf"; Url = "github.com/google/fonts/raw/main/ofl/roadrage/Roa…" }, @{ File = "RubikWetPaint-Regular.ttf"; Url = "github.com/google/fonts/raw/main/ofl/rubikwetpain…" }, @{ File = "SedgwickAveDisplay-Regular.ttf"; Url = "github.com/google/fonts/raw/main/ofl/sedgwickaved…" }, @{ File = "Jost-Regular.ttf"; Url = "github.com/indestructible-type/Jost/raw/master/fo…" }, @{ File = "Jost-Bold.ttf"; Url = "github.com/indestructible-type/Jost/raw/master/fo…" }, @{ File = "Manrope-Regular.ttf"; Url = "github.com/googlefonts/manrope/raw/master/fonts/t…" }, @{ File = "Manrope-Bold.ttf"; Url = "github.com/googlefonts/manrope/raw/master/fonts/t…" } ) foreach ($font in $fonts) { Write-Host "Downloading $($font.File)..." try { $web.DownloadFile($font.Url, (Join-Path $out $font.File)) } catch { Write-Warning "Failed: $($font.File) - $($_.Exception.Message)" } } # ---------- ZIPPED FONTS ---------- $zips = @( @{ Url = "github.com/rsms/inter/releases/download/v4.1/Inte…"; Files = @("Inter-Regular.ttf", "Inter-Bold.ttf") }, @{ Url = "github.com/tonsky/FiraCode/releases/download/6.2/…"; Files = @("FiraCode-Regular.ttf") }, @{ Url = "dl.dafont.com"; Files = @("Another Danger - Demo.otf", "Another Danger Slanted - Demo.otf") }, @{ Url = "dl.dafont.com"; Files = @("Heatwave Free Font.ttf") }, @{ Url = "api.fontshare.com"; Files = @("ClashGrotesk-Regular.otf", "ClashGrotesk-Bold.otf") } ) foreach ($zip in $zips) { Write-Host "Downloading $($zip.Files -join ', ')..." $zipPath = Join-Path $env:TEMP ([guid]::NewGuid().ToString() + ".zip") $extract = Join-Path $env:TEMP ([guid]::NewGuid().ToString()) try { $web.DownloadFile($zip.Url, $zipPath) Expand-Archive -LiteralPath $zipPath -DestinationPath $extract -Force foreach ($name in $zip.Files) { $found = Get-ChildItem -LiteralPath $extract -Recurse -Filter $name | Select-Object -First 1 if ($found) { Copy-Item -LiteralPath $found.FullName -Destination (Join-Path $out $name) -Force } else { Write-Warning "Could not find $name inside the zip" } } # Also grab any license/readme text files from the zip Get-ChildItem -LiteralPath $extract -Recurse -Include .txt,.md,LICENSE*,OFL* -ErrorAction SilentlyContinue | ForEach-Object { $destName = $_.Name if ($destName -match "license|ofl|readme" -or $_.Extension -eq ".txt") { Copy-Item $_.FullName (Join-Path $licOut $destName) -Force -ErrorAction SilentlyContinue } } } catch { Write-Warning "Failed zip: $($zip.Url) - $($_.Exception.Message)" } finally { Remove-Item -LiteralPath $zipPath -Force -ErrorAction SilentlyContinue Remove-Item -LiteralPath $extract -Recurse -Force -ErrorAction SilentlyContinue } } # ---------- LICENSE FILES ---------- $licenses = @( @{ Name = "Montserrat-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "OpenSans-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "Roboto-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "Poppins-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "JetBrainsMono-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "PermanentMarker-Apache.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "Merriweather-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "PlayfairDisplay-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "Fraunces-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "Lora-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "BricolageGrotesque-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "OverusedGrotesk-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "RoadRage-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "RubikWetPaint-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "SedgwickAveDisplay-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "Jost-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "Manrope-OFL.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "Inter-LICENSE.txt"; Url = "raw.githubusercontent.com" }, @{ Name = "FiraCode-LICENSE.txt"; Url = "raw.githubusercontent.com" } ) Write-Host "`nDownloading license files..." foreach ($lic in $licenses) { Write-Host " $($lic.Name)" try { $web.DownloadFile($lic.Url, (Join-Path $licOut $lic.Name)) } catch { Write-Warning " Failed: $($lic.Name) - $($_.Exception.Message)" } } $web.Dispose() Write-Host "`nDone." Write-Host "Fonts -> $out" Write-Host "Licenses -> $licOut" explorer $out Included Fonts & License Breakdown - SIL Open Font License 1.1 (Free for personal & commercial use): - Inter, Montserrat, Open Sans, Poppins, JetBrains Mono, Fira Code, Merriweather, Playfair Display, Fraunces, Lora, Bricolage Grotesque, Overused Grotesk, Road Rage, Rubik Wet Paint, Sedgwick Ave Display, Jost, Manrope. - Apache License 2.0 (Free for personal & commercial use): - Roboto, Permanent Marker. - Vic Fieger Freeware (Free for personal & commercial use, not open-source): - Edo SZ. - ITF Free Font License (Free for personal & commercial use; direct download via script): - Clash Grotesk (Note: Fontshare terms require direct individual download which this script does (technically correct but possibly not how it was intended); do not redistribute the file directly). - Personal Use Only / Demo (Free for personal use / memes only): - Another Danger (Demo) (Commercial license sold separately by The Branded Quotes). - Free Font (Commercial use requires a license): - Heatwave Free Font (Commercial license available via Maulana Creative). Included Fonts & Licenses - Inter — SIL Open Font License 1.1 (GitHub) - Montserrat — SIL Open Font License 1.1 (Google Fonts) - Open Sans — SIL Open Font License 1.1 (Google Fonts) - Poppins — SIL Open Font License 1.1 (Google Fonts) - JetBrains Mono — SIL Open Font License 1.1 (GitHub) - Fira Code — SIL Open Font License 1.1 (GitHub) - Merriweather — SIL Open Font License 1.1 (Google Fonts) - Playfair Display — SIL Open Font License 1.1 (Google Fonts) - Fraunces — SIL Open Font License 1.1 (Google Fonts) - Lora — SIL Open Font License 1.1 (Google Fonts) - Bricolage Grotesque — SIL Open Font License 1.1 (Google Fonts) - Overused Grotesk — SIL Open Font License 1.1 (GitHub) - Road Rage — SIL Open Font License 1.1 (Google Fonts) - Rubik Wet Paint — SIL Open Font License 1.1 (Google Fonts) - Sedgwick Ave Display — SIL Open Font License 1.1 (Google Fonts) - Jost — SIL Open Font License 1.1 (Google Fonts) - Manrope — SIL Open Font License 1.1 (Google Fonts) - Roboto — Apache License 2.0 (Google Fonts) - Permanent Marker — Apache License 2.0 (Google Fonts) - Edo SZ — Freeware: Free for personal & commercial use, not open-source (DaFont) - Clash Grotesk — ITF Free Font License: Direct individual download via script (technically correct, though possibly not how it was originally intended; do not redistribute directly) (Fontshare) - Another Danger (Demo) — Personal Use Only / Demo: Commercial license sold by The Branded Quotes (DaFont) - Heatwave — Free for personal use: Commercial use requires a license from Maulana Creative (DaFont) Also if you're on old hardware and find the launcher to be laggy check out my little powershell Artcraft App Updater: reddit.com

    20 points · 7 comments
  3. DEV · · @laurilllll

    How to self-host Google Fonts (and why your site should) Originally published on no-code.supply. TL;DR - Google Fonts is free, but the usual way of using it makes every visitor's browser contact Google before your page can look right. You can skip that by hosting the font files yourself. - It takes four steps: download the woff2 files, write an @font-face rule for each, preload the one or two files your page needs first, and check that DevTools shows zero requests to Google. - The result: fewer connections, one less privacy question, and a site that doesn't break when someone else's server has a bad day. - It's the same on every project I build, and this site does exactly this. Here's the whole thing in one block. The rest of the post explains each line. @font-face { font-family: "Geist"; font-style: normal; font-weight: 100 900; font-display: swap; src: url("/fonts/geist-normal-400-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } <link rel="preload" href="/fonts/geist-normal-400-latin.woff2" as="font" type="font/woff2" crossorigin /> 👉 [Skip to the step-by-step](#how-to-do-it-by-hand) --- Why bother The normal Google Fonts setup is one line of HTML. You paste a <link> tag, and the font works. It's popular because it's so easy. What that line does behind the scenes: your visitor's browser asks fonts.googleapis.com for a stylesheet, reads it, then asks fonts.gstatic.com for the actual font files. Two extra servers, both owned by someone else. Here's why I stopped doing that. Privacy Every request to Google's servers tells Google that this visitor, with this IP address, just opened your page. You didn't ask for that, and your visitor didn't agree to it. In Europe this has already been a legal question. On 20 January 2022 a Munich court (LG München I) decided that a website owner who loaded Google Fonts from Google's servers had passed a visitor's IP address to Google without permission, and ordered a €100 payment. It was one ruling in one country, and I'm not a lawyer, so don't take this as legal advice. But the fix is so cheap that I'd rather not find out how the next case goes. If you host the fonts yourself, there's nothing to ask about. The font comes from your own domain, like the rest of your page. Speed Loading from Google means your browser has to open new connections: look up the address of another server, set up a secure connection to it, and only then start the download. That's work your own server has already done by the time the page arrives. There was an old argument for the shared setup: if every site uses Google's copy of Roboto, a visitor probably has it cached from another site already. That stopped being true. Modern browsers keep a separate cache for each website, so a font cached while visiting site A isn't reused on site B. Chrome, Firefox and Safari all do this now (Chrome since 2020). So the shared cache saves you nothing, and you still pay for the extra connection. Self-hosting also lets you decide which files load first. More on that in a moment, because it's the part that made the biggest difference for me. Reliability If Google's servers are slow or blocked on someone's network, your text sits waiting, or falls back to a font you didn't pick. Files on your own domain share your site's fate. If the page loads, the font loads. Control The font files stay the same until you change them. You pick the weights, the languages and the format. Nobody can change the stylesheet under you. On this site it's also a written rule. The project's AGENTS.md says there are no third-party requests: no Google Fonts, no outside analytics, no embeds loaded on page view. (I wrote about those files in How to write an AGENTS.md your AI agent actually follows.) Fonts are the easiest of those to get right, so they were the first thing I fixed. --- How to do it by hand There are four steps. You can do it with no tools beyond a browser and a text editor. 1. Find out which files Google serves Open the Google Fonts page for your family and copy the embed URL. For Geist it looks like this: https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700;800&display=swap Open that URL directly in a browser tab. You'll see plain CSS: a list of @font-face rules, each with a src: url(https://fonts.gstatic.com/…woff2) line. Two things to notice: - The files are woff2. That's the compressed font format every current browser supports. It's the only one you need. (Older formats like ttf or woff are for browsers from a decade ago.) - There are several rules per weight, each with a comment like /* latin */ or /* latin-ext */ and a unicode-range line. That's the subsetting I'll come back to. Heads up: Google looks at who's asking and sends different CSS to different browsers. An old or unknown browser gets ttf files and no subsets. If you fetch the URL from a script, send a modern browser's User-Agent header, or you'll get the wrong thing. 2. Download the files Save each woff2 file into your project, for example public/fonts/ in a Next.js project, or /fonts/ in a plain site. Give them names you can read, like geist-normal-400-latin.woff2. Or use a tool. google-webfonts-helper lets you pick a family, weights and subsets and gives you the files plus the CSS. Fontsource packages the same fonts as npm packages, if you'd rather have them in node_modules: npm install @fontsource-variable/geist import "@fontsource-variable/geist"; The font's name in your CSS is then "Geist Variable", not "Geist". 3. Write the @font-face rules Here's one rule, with what each line does: @font-face { font-family: "Geist"; font-style: normal; font-weight: 400; font-display: swap; src: url("/fonts/geist-normal-400-latin.woff2") format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } - font-family: the name you'll use in the rest of your CSS (font-family: "Geist", sans-serif). - font-weight: which weight this file is for. - font-display: swap: show the text right away in a fallback font, then swap to the real one when it arrives. The other option is a blank space until the font loads, which is worse. - src: where the file is. It now points to your own domain, which is the whole point. - unicode-range: which characters this file covers. The browser only downloads the file if the page uses at least one of those characters. That last one is the clever part of what Google does. The latin file covers English and most of Western Europe, including Finnish ä and ö (they sit at U+00C4/U+00E4 and U+00D6/U+00F6, inside the latin range). The latin-ext file covers things like Polish, Czech and Turkish letters. You write one rule for each, and a page in English only ever downloads the first. Keep every subset you actually need. I keep latin and latin-ext and drop the rest (Cyrillic, for one) because this site doesn't use them. 4. Preload the files the page needs first Here's the catch. A browser finds a font file only after it has downloaded your CSS and worked out which rules apply. By then it has already drawn the page in the fallback font. When the real font arrives, the text changes size slightly and everything below it jumps. That jump is what Google's tools call layout shift (CLS). A preload link fixes it: it tells the browser about the file in the HTML, so the download starts right away, in parallel with the CSS. <link rel="preload" href="/fonts/geist-normal-400-latin.woff2" as="font" type="font/woff2" crossorigin /> Two details that trip people up: - crossorigin is required, even for files on your own domain. Fonts are always fetched in a mode that needs it. Without the attribute the browser downloads the file twice, once for the preload and once for the real use, and the preload is wasted. - Only preload what's above the fold. Every preloaded file competes with your other resources. I preload two files and nothing else. Here's the real example from this site. The homepage uses Geist for text and Geist Mono for small labels, so app/layout.tsx preloads the Latin file of each. The calls sit at the top of the root layout component, before it returns the page: import { preload } from "react-dom"; export default function RootLayout({ children }: { children: ReactNode }) { preload("/fonts/geist-normal-400-latin.woff2", { as: "font", type: "font/woff2", crossOrigin: "anonymous" }); preload("/fonts/geist-mono-normal-400-latin.woff2", { as: "font", type: "font/woff2", crossOrigin: "anonymous" }); return ( // <html>, <body> and the rest of the layout ); } preload from react-dom is how a React 19 app adds a <link rel="preload"> to the page's head, and it works in a server component like this layout. The two files are the Latin ones from app/fonts.css. crossOrigin: "anonymous" is the same thing as the crossorigin attribute above. Before I added these two lines, Lighthouse measured a layout shift of 0.104 on the homepage, caused by the font swap. After: 0. --- The variable font shortcut Geist is a variable font. One file holds every weight from thin to black, instead of one file per weight. You can see it in my files. public/fonts/ has just four woff2 files in total: Geist and Geist Mono, each in latin and latin-ext. Together they're about 84 KB (29.3 and 16.5 KB for Geist, 23.1 and 14.7 KB for Geist Mono). The stylesheet still has a rule per weight (400, 500, 600, 700, 800 for Geist), but every rule points to the same file. The 400 in the file names is a leftover from how my script named them; each file holds the whole weight range. If your font is variable, you can write one rule with a weight range instead. Google serves Geist with a range of 100 to 900: @font-face { font-family: "Geist"; font-weight: 100 900; src: url("/fonts/geist-normal-400-latin.woff2") format("woff2"); } The saving is real when you use several weights. Five static weights are five downloads. One variable file is one. Check the Google Fonts page for your family: if it shows a weight slider, it's variable. --- The fast way: a script The first time I did this by hand it was slow and fiddly. After that I wrote a script, and you can have it: fetch-google-fonts.mjs. It needs Node 18 or newer. You give it the Google Fonts URL and an output folder: node fetch-google-fonts.mjs \ "https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700;800&display=swap" \ public/fonts --url-prefix=/fonts/ --css=app/fonts.css Swap in the URL for your own family. --url-prefix is the path the browser will use for the files, and --css is where the stylesheet goes. It does what the four steps above do: 1. Fetches the CSS URL, pretending to be a current Chrome so Google answers with woff2 and the subsets. 2. Reads each @font-face block and keeps the subsets I ask for (latin and latin-ext by default). 3. Downloads each font file once, even when several weights share it, and writes it into the output folder. 4. Writes a new stylesheet with the URLs pointing at my own folder instead of Google's. Weights that share one file are merged into a single rule with a range. 5. Fetches each family's licence text and saves it in public/fonts/licenses/. 6. Writes a fonts.json that lists each family, its files and its licence. It's 99 lines of Node with no dependencies, so read it before you run it. If you'd rather not run anything, the manual steps above give the same result. --- In Next.js: next/font/google If you use Next.js there's a built-in route that does most of this for you: next/font/google. import { Geist } from "next/font/google"; const geist = Geist({ subsets: ["latin"] }); export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en" className={geist.className}> <body>{children}</body> </html> ); } At build time Next.js downloads the font from Google and serves it from your own domain with the rest of your static assets, so your visitors' browsers never contact Google. It also preloads the subsets you list and adds a size-adjusted fallback font to reduce layout shift, both on by default. For a variable font like Geist you don't need to set a weight; for a static one you do. It's a good choice, and if your site is Next.js and nothing else, use it. I still did my own for this site, for one reason: the templates come in plain HTML editions with no build step, so I wanted one method that works the same in every edition. Doing it by hand also keeps the files and the licence text visible in the repository, and gives me full control over what gets preloaded. --- Don't forget the licence Most Google Fonts use the SIL Open Font License (OFL). Geist does. Some use the Apache 2.0 licence instead, and a few (the Ubuntu fonts) use the Ubuntu Font Licence. Each family's folder in the google/fonts repository has its own licence file, which is the one to trust. In plain words, the OFL lets you use, copy, embed and ship the font for free, including in commercial projects and bundled with your own software, and that covers self-hosting. What it asks in return: - You can't sell the font files by themselves. - Keep the copyright notice and the licence text with the font. - If you modify the font, the modified version stays under the OFL, and it can't use the font's Reserved Font Name if the licence names one. So put the licence file next to the fonts. My public/fonts/licenses/ folder has geist-OFL.txt and geist-mono-OFL.txt, and a small fonts.json lists each family, its files and its licence. It takes almost no effort, and it saves a bad afternoon if someone ever asks. --- How to check it worked Don't trust that it worked. Look. 1. Open your site in Chrome and open DevTools (right-click, Inspect). 2. Go to the Network tab and tick Disable cache. 3. Type fonts in the filter box, or click the Font filter, and reload. 4. You should see only requests to your own domain, ending in .woff2. 5. Now filter for googleapis and then gstatic. Both should show zero requests. Some things to check at the same time: - [ ] No request goes to fonts.googleapis.com or fonts.gstatic.com. - [ ] Each font file loads once. Twice means a missing crossorigin on the preload. - [ ] The preloaded files are the first font requests in the list. - [ ] Run Lighthouse and look at the layout shift number. It should be 0 or very close. - [ ] Search your code for fonts.googleapis.com. Old <link> tags and @import lines in CSS files hide in surprising places, and one forgotten line keeps the whole thing going. --- FAQ Is self-hosting Google Fonts allowed? Yes. The fonts are open source, and the licences allow you to download them and serve them yourself. Google even offers a download button on every family's page. Keep the licence file with the fonts. Is it faster? Usually, yes, because there are no extra connections to set up, and you can preload the files you care about. Measure it on your own site: how much faster depends on where your server is and what else your page loads. I measured layout shift going from 0.104 to 0 here, but that came from the preload, not from self-hosting alone. Do I need to update the files when Google updates a font? No, nothing updates by itself. Your own copy stays exactly as you downloaded it. So ask yourself how often you really need a font updated, and whether you want it to change under a live design without you deciding. If you do want a new version, run the download again. Should I use woff2 only? Yes. Every current browser supports it, and it's the smallest format. You only need ttf or woff if you have to support very old browsers, which most sites don't. --- Wrap-up Self-hosting Google Fonts is a small job. You get a page that asks no one else for permission, loads in fewer steps, and has a font that stays put. If you read this far, thank you. 🙏 Every no-code.supply template ships with its fonts self-hosted, files and licences included, so a template works the same with or without a connection to anyone else's server.

  4. X · · @ericlu

    You can download the font here: mixfont/gothic-gumdrop And also track the submission status to Google Fonts here in case you are interested: fonts#10635

    28 views

Latest stargazers

The last 10 distinct accounts we observed this year.

Most active participants

PR, issue, comment & review events in the past year.

Packages

4
PackageVersionDownloads · 30dTrend · 30d
v0.5.0——
v0.7.11——
v0.4.20
≥13.1K
v0.7.11
≥44.8K

README badges

Embed a badge in your README or website.

  • google/fonts reached #1 in daily stars on gitwal · Mar 17, 2015
  • google/fonts reached #2 in weekly stars on gitwal · Week of Mar 9, 2015
Live mentions · last 30 days
google/fonts mentions in the last 30 days