Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 9 additions & 13 deletions src/content/docs/en/guides/fonts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -275,23 +275,20 @@ You can also opt out of the default optimization by setting [`font.optimizedFall

## Accessing font data programmatically

Astro exposes a low-level API for accessing font family data programmatically through the [`fontData`](/en/reference/modules/astro-assets/#fontdata) object. This can be useful for advanced use cases where you need direct access to font files, such as generating OpenGraph images with [Satori](https://github.com/vercel/satori) in an [API Route](/en/guides/endpoints/#server-endpoints-api-routes).
Astro exposes low-level APIs for accessing data programmatically:

This low-level API gives you access to all font files downloaded by Astro for your project, along with their metadata. This means that you are responsible for filtering font files to find the specific file you need, and for resolving the file path to use based on the build output structure.
- Font family data through the [`fontData`](/en/reference/modules/astro-assets/#fontdata) object
- Font file URLs with [`experimental_getFontFileURL()`](/en/reference/modules/astro-assets/#experimental_getfontfileurl) function.
Comment thread
florian-lefebvre marked this conversation as resolved.
Outdated

:::note
The current API has a [known limitation that requires you to manually load the font file](https://github.com/withastro/astro/issues/16139) from the output path at build time.
This can be useful for advanced use cases where you need direct access to font files, such as generating OpenGraph images with [Satori](https://github.com/vercel/satori) in an [API Route](/en/guides/endpoints/#server-endpoints-api-routes).

A new API is being developed to simplify this process and will be available in a future release. You can subscribe to the GitHub issue to follow its progress.
:::
This low-level API gives you access to all font files downloaded by Astro for your project, along with their metadata. This means that you are responsible for filtering font files to find the specific file you need, and for fetching data after resolving URLs.
Comment thread
florian-lefebvre marked this conversation as resolved.
Outdated

The following example generates an OpenGraph image in a static file endpoint, assuming that only [one font and its format have been configured](/en/reference/configuration-reference/#fontformats) with a [format supported by Satori](https://github.com/vercel/satori?tab=readme-ov-file#fonts):

```tsx title="src/pages/og.png.ts" {2} "fontData[\"--font-roboto\"]"
```tsx title="src/pages/og.png.ts" {2,14-15} "fontData[\"--font-roboto\"]"
import type { APIRoute } from "astro";
import { fontData } from "astro:assets";
import { outDir } from "astro:config/server";
import { readFile } from "node:fs/promises";
import { fontData, experimental_getFontFileURL } from "astro:assets";
import satori from "satori";
import { html } from "satori-html";
import sharp from "sharp";
Expand All @@ -303,9 +300,8 @@ export const GET: APIRoute = async (context) => {
throw new Error("Cannot find the font path.");
}

const data = import.meta.env.DEV
? await fetch(new URL(fontPath, context.url.origin)).then(async (res) => res.arrayBuffer())
: await readFile(new URL(`.${fontPath}`, outDir));
const url = experimental_getFontFileURL(fontPath, context.url);
const data = await fetch(url).then((res) => res.arrayBuffer());

const svg = await satori(
html`<div style="color: black;">hello, world</div>`,
Expand Down
39 changes: 39 additions & 0 deletions src/content/docs/en/reference/modules/astro-assets.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
getConfiguredImageService,
imageConfig,
fontData,
experimental_getFontFileURL,
} from 'astro:assets';
```

Expand Down Expand Up @@ -711,6 +712,44 @@ import { fontData } from "astro:assets"
const data = fontData["--font-roboto"]
```

### `experimental_getFontFileURL()`

<p>

**Type:** `(url: string, requestUrl?: URL) => Promise<string>`
<Since v="6.2.0" />
</p>

Resolves a font file URL obtained from [`fontData`](#fontdata):

```ts " experimental_getFontFileURL " {9}
import { fontData, experimental_getFontFileURL } from "astro:assets";

const fontPath = fontData["--font-roboto"][0]?.src[0]?.url;

if (fontPath === undefined) {
throw new Error("Cannot find the font path.");
}

const url = experimental_getFontFileURL(fontPath);
const buffer = await fetch(url).then((res) => res.arrayBuffer());
```

When called on a route [rendered on-demand](/en/guides/on-demand-rendering/), the request URL needs to be provided:

```ts "context.url"
import type { APIRoute } from "astro";
import { fontData, experimental_getFontFileURL } from "astro:assets"

export const prerender = false; // Not needed in 'server' mode

Comment thread
florian-lefebvre marked this conversation as resolved.
export const GET: APIRoute = async (context) => {
// ...
const url = experimental_getFontFileURL(fontPath, context.url);
// ...
};
```

## `astro:assets` types

The following types are imported from the virtual assets module:
Expand Down
Loading