Experience of building a complete? font optimization package for Astro websites
Rishi Raj Jain
Posted on January 11, 2024
Rishi is always in awe of how Vercel promotes open-source and use it as the medium to grow, staying relevant to developers. Not long ago, next/font
was released and it set a great bar of how fonts DX (and ultimately UX) shall be.
As you'd know, Rishi loves Astro, so he thought of bringing this automatic font optimization to the Astro ecosystem. He set out for building astro-font
inspired by next/font
which'd:
- let one specify a config and generate CSS based on off of it
- generate fallback font CSS preventing layout shifts
- allow to optionally preload fonts for best font loading practices
Rishi is an Astro Community Award Winner in 2022. Also, he's building LaunchFa.st - Astro Boilerplate.
On 15th December, 2023, Rishi released astro-font
the community first npm package that aimed at enabling font optimization in all runtimes with Astro. Today, the adpotion has scaled to 4.4K NPM Downloads, LaunchFa.st maintaining a changelog for astro-font
and people loving the ease of setting up Astro Font in their projects ππ»
Well, it's not all silver bullets. Here are some of the roadblocks Rishi faced in developing the ideal library for fonts (and still working on it):
1. Supporting all Astro adapters
As astro-font
is an Astro component (allowing greater granular control) and not an Astro integration, it became increasingly difficult to detect the runtime (Node, Deno, etc.) and adjust the operations such as fetching & reading font buffer, localizing fonts to the project repo, cache & save the generated CSS in the right output directory.
This is still the reason why astro-font
requires some work to support atomic + SSR-first Astro projects. Packages like carton aim at bridging this technical gap by allowing to render components in isolation, de-coupling it from the project specific requirements.
2. Detecting if read & writes are allowed
All of the sites today are built on two systems: user's local and on the cloud. Both runtimes use different OS (say developing on windows and deploying on ubuntu) AND read and write permissions (based on the cloud provider and configurations).
To detect this astro-font
tries and handles the failure to do so. For example to check if file system module is accessible and writes are allowed:
// Check if file system can be accessed
async function getFS(): Promise<typeof import('node:fs') | undefined> {
let fs
try {
fs = await import('node:fs')
return fs
} catch (e) {}
}
// Check if writing is permitted by the file system
async function ifFSOSWrites(dir: string): Promise<string | undefined> {
try {
const fs = await getFS()
if (fs) {
const testDir = join(dir, '.astro_font')
if (!fs.existsSync(testDir)) fs.mkdirSync(testDir)
fs.rmSync(testDir, { recursive: true, force: true })
return dir
}
} catch (e) {}
}
Well, that was it. Hope you gained some insight into what's going on with astro-font
and Rishi's excitement around it.
Drop your suggestions & feedback on Astro Font, or just some tips for someone learning to build a npm package and help developers!
Posted on January 11, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.