Fitting Text, Anywhere

There are many JavaScript libraries for fitting text to fill a container by finding the ideal font size, but these libraries don’t work well in environments outside the browser, e.g. static site generators, dynamic code that runs on a server, etc.

@altano/satori-fit-text bridges the gap by allowing you to fit text to a container in any environment that vercel/satori supports1.

Demonstration

Hard-coded font size

@altano/satori-fit-text font size

Unfitted Text Fitted Text

Installation

Terminal window
# Using NPM
npm install @altano/satori-fit-text
# Using Yarn
yarn add @altano/satori-fit-text
# Using PNPM
pnpm add @altano/satori-fit-text

Example: Open Graph Card

If you’re rendering open graph cards in something like Next.js you may want the text of your cards to be dynamic text (e.g. the title of a blog post) but also fill up the entire card. Instead of hard-coding the font size, which isn’t feasible in this case, use @altano/satori-fit-text in opengraph-image.tsx:

import { findLargestUsableFontSize, type Font } from "@altano/satori-fit-text";
async function getInter(): Promise<Font> {
// ...
}
export default async function Image() {
const title = "The homepage of this site.";
const font = await getInter();
const opengraphDimensions = {
width: 1200,
height: 630,
};
const titleFontSize = await findLargestUsableFontSize({
text: title,
font: font,
maxWidth: opengraphDimensions.width,
maxHeight: opengraphDimensions.height,
});
const card = (
<main
style={{
lineHeight,
padding: 0,
margin: 0,
}}
>
<h1
style={{
margin: 0,
fontSize: titleFontSize,
}}
>
{title}
</h1>
</main>
);
return new ImageResponse(card, {
...opengraphDimensions,
fonts: [font],
});
}

Here is a fully-fleshed out, basic example codesandbox.

You can find a more complicated example here that I use on this website where I have a title and a subtitle and I use multiple font weights.

Example: Node.js CLI App

Check out this codesandbox if you want to see a Node.js CLI app that computes the ideal font size for certain dimensions.

Example: Browser/React Component

There are less roundabout solutions2 if you’re going to only fit text in a browser, but the library does technically work just fine there.

NOTE: The sandbox below will NOT work in Firefox before version 126 (the Intl.Segmenter API was not yet implemented).


Footnotes

  1. vercel/satori can currently “be used in browser, Node.js (>= 16), and Web Workers.”

  2. @altano/textfit doesn’t require intermediate svg files and can more quickly fit text using only the DOM.


<-Find more writing back at https://alan.norbauer.com