A Google font picker component for React.
- No dependencies (other than React)
- No Google API key required
- 1600+ Google fonts, customisable
- Fast, high quality font previews from pre-generated SVG images
- Optionally autoloads fonts
Forked from https://github.com/Mikk3lRo/vue-fontpicker/
A live demo including usage is available at: https://ae9is.github.io/react-fontpicker/
# npm
npm i react-fontpicker-ts
# yarn
yarn add react-fontpicker-ts
# much smaller package with fewer fonts
npm i react-fontpicker-ts-lite
Then, import the component and stylesheet:
import FontPicker from 'react-fontpicker-ts'
import 'react-fontpicker-ts/dist/index.css'
See css classnames in: packages/fontpicker/src/components/FontPicker.css
An example restyling the font picker
An example integrating the font picker into an actual app: ae9is/uimix
The font picker project lives in this Turborepo monorepo at packages/fontpicker/
The live demo is a Vite app you can run yourself via npm run dev
and which builds to /docs
. Uses tsconfig.json
.
The font picker component itself builds via tsup
(i.e. esbuild
) to /dist
with type definitions generated via tsc
according to tsconfig.types.json
.
The font preview generation script downloads font files to /font-cache
and builds font image previews to /font-preview
.
The font picker previews work by loading font preview image files in CSS. The fonts are split across many image files for faster initial preview.
Once the dropdown select is opened, all the preview image files are retrieved enabling smooth scrolling and searching.
No requests are made to the Google fonts API unless the font picker is set to autoload, in which case the currently selected font is appended to the page header. (The previously selected font link is not removed.)
For example:
<head>
...
<link
rel="stylesheet"
id="google-font-rock_salt-all"
href="https://fonts.googleapis.com/css2?family=Rock Salt:ital,wght@0,400&display=swap"
/>
</head>
The big trade-off of this approach is that the component's bundle is quite large due to all the font image previews: 8 MB in compressed SVG images for 1633 fonts. Make sure you serve compressed SVGs! See here for an example for Vite.
If you're looking for a lighter weight option, you can use react-fontpicker-ts-lite
instead which is around 180 KB.
Or, for a different font picker following an on demand approach, check out: https://github.com/samuelmeuli/font-picker-react
font-picker-react
requires a Google API key, and works best at the default font limit of 50 (fonts to choose from).
Note: most users shouldn't need to rebuild the font previews, but this section is included for convenience if you need to grab the latest fonts or edit the previews.
Get a Google API key here https://developers.google.com/fonts/docs/developer_api#APIKey and create a new file called GOOGLE_API_KEY
in react-fontpicker/packages/fontpicker/scripts
, in the same directory as the scripts/buildFontPreviews.ts
script.
To generate font previews for all currently available Google fonts (latin font families only, minus Kumar One
).
cd react-fontpicker/packages/fontpicker
npm run build-font-previews
Note: For 1600 fonts, budget 20-30 minutes and 800 MB to download all the fonts. Compiling the image previews themselves should be less than a minute. When re-running, the script only retrieves new font info if it's older than 1 week and skips downloading cached fonts.
To generate font previews for custom fonts you'll need some info about the fonts and paths to the font file downloaded in TTF format.
buildFontPreviews.ts output-dir "font-name|font-category|font-variants-info|font-file" "font-name-2..."
Where font-variants-info is an array of values like 0,400 and 1,700 joined by +. The first value denotes a normal (0) or italic (1) font. The second value is the font weight (i.e. 100 = thin, 400 = normal, 700 = bold, 900 = heavy).
For example:
buildFontPreviews.ts output-dir "FontName|sans-serif|0,400+0,700+1,400+1,700|/path/to/font.ttf" "Font2|serif|0,400|/path/to/font2.ttf"
See the build-font-previews-manual
run script in: packages/fontpicker/package.json
This monorepo uses Turborepo.
The app uses Vitest and Cypress for testing. Make sure to setup the prerequisites for Cypress on your system.
On Ubuntu:
apt install libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb