#How to use Experimental fonts API with CSS file?

1 messages · Page 1 of 1 (latest)

loud dagger
#

My main objective is use import font via Experimental fonts API to CSS file and apply like this

.noto-sans-enabled {
  font-family: 'Noto Sans', 'Noto Sans JP', 'Noto Sans Thai Looped', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

under condition "Noto Sans font series must use font from Experimental fonts API"

modest mossBOT
#

Hi @loud dagger. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To use the Experimental Fonts API in Astro and apply the imported font via a CSS file, you need to:

  1. Configure the font in astro.config.mjs using the Experimental Fonts API.
  2. Use the generated CSS variable in your CSS file for the font-family.

Here’s how you can do it:

1. Configure the font in astro.config.mjs

For example, to use "Noto Sans" from Google Fonts:

import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({
  experimental: {
    fonts: [
      {
        provider: fontProviders.google(),
        name: "Noto Sans",
        cssVariable: "--font-noto-sans"
      }
    ]
  }
});

This will make the font available as a CSS variable (--font-noto-sans) in your project Experimental fonts API usage.

2. Use the CSS variable in your CSS file

You should reference the CSS variable in your CSS, not the font name directly. For your use case, update your CSS like this:

.noto-sans-enabled {
  font-family: var(--font-noto-sans), 'Noto Sans JP', 'Noto Sans Thai Looped', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

This ensures that the "Noto Sans" font loaded via the Experimental Fonts API is used first, and the rest are fallbacks.

3. Add the <Font /> component to your <head>

In your layout or head component, import and use the <Font /> component to inject the font and preload it:

---import { Font } from 'astro:assets';---
<Font cssVariable="--font-noto-sans" preload />

Summary

#
  • Do not use the font name directly in your CSS if you want to use the Experimental Fonts API.
  • Use the CSS variable (e.g., var(--font-noto-sans)) provided by your Astro config.
  • Add the <Font /> component to your head to ensure the font is loaded and available.

For more details, see the Astro Experimental Fonts API documentation and the usage example for CSS files which demonstrates this approach.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@loud dagger Kapa.ai is still learning and improving, please let me know how I did by reacting below.

loud dagger
#

@modest moss

var(--font-noto-sans)

this part can be use many time like this?

.noto-sans-enabled {
  font-family: var(--font-noto-sans), var(--font-noto-sans-jp), var(--font-noto-sans-thai-looped), system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
modest mossBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

The knowledge sources confirm that you should use the CSS variable (e.g., var(--font-noto-sans)) generated by the Experimental Fonts API in your CSS, but they do not explicitly state whether you can use multiple different font CSS variables in a single font-family declaration as you described.

However, the API allows you to register multiple fonts, each with its own cssVariable (e.g., --font-noto-sans, --font-noto-sans-jp, --font-noto-sans-thai-looped) in your Astro config. You can then reference these variables in your CSS, just like any other CSS variable:

.noto-sans-enabled {
  font-family: var(--font-noto-sans), var(--font-noto-sans-jp), var(--font-noto-sans-thai-looped), system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}

This approach is consistent with the documented usage of the API, which shows using the CSS variable in the font-family property, and there is no restriction mentioned against using multiple variables in one declaration Experimental fonts API usage.

In summary:
Yes, you can use multiple var(--font-...) CSS variables in your font-family declaration, provided each variable is registered via the Experimental Fonts API in your Astro config. The browser will use the first available font in the list, as with any standard font-family fallback chain.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@loud dagger Kapa.ai is still learning and improving, please let me know how I did by reacting below.

loud dagger
#

@modest moss So when I apply to css file (I apply to main file), should I still add font as component?

modest mossBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Yes, you still need to add the <Font /> component to your <head>, even if you apply the font using a CSS variable in your main CSS file. The <Font /> component is responsible for injecting the necessary style tags and preload links for the font, making the CSS variable (e.g., --font-noto-sans) available for use in your CSS. Without the <Font /> component, the font will not be loaded and the CSS variable will not be defined, so your CSS rule will not work as intended Experimental fonts API usage <Font /> component reference.

Summary:

  • Use the CSS variable in your main CSS file.
  • Always include the <Font /> component in your <head> to ensure the font is loaded and the variable is available.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@loud dagger Kapa.ai is still learning and improving, please let me know how I did by reacting below.

loud dagger
#

@modest moss Ok, have any additional config for CSS file?

modest mossBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

No, there are no additional or special configuration steps required specifically for using the Experimental Fonts API with a CSS file beyond what has already been described. The knowledge sources state that you should:

  1. Register your fonts in astro.config.mjs using the Experimental Fonts API and assign a cssVariable for each font.
  2. Use the generated CSS variable (e.g., var(--font-noto-sans)) in your CSS file wherever you want to apply the font.
  3. Add the <Font /> component to your <head> to ensure the font and CSS variable are available.

There is no mention of any extra configuration needed for CSS files. You can use the CSS variable in any CSS file, and Astro will handle the rest as long as the above steps are followed Experimental fonts API usage.

If you are using Tailwind CSS, you can also reference the variable in your Tailwind config, but for plain CSS, no further steps are required.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@loud dagger Kapa.ai is still learning and improving, please let me know how I did by reacting below.

loud dagger
#

@modest moss is API can use with Japanese font?

modest mossBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Yes, the Experimental Fonts API in Astro can be used with Japanese fonts. The documentation specifically mentions support for subsets such as "latin", "cyrillic", and others, and provides an example of using the subsets property to load only certain character sets. It also describes using the unicodeRange property to load fonts for specific Unicode ranges, which is useful for localization, such as serving Japanese fonts only on pages that need them. For example:

subsets: ["latin", "japanese"]

or

unicodeRange: ["U+3040-309F", "U+30A0-30FF"] // Hiragana and Katakana

This allows you to efficiently load Japanese fonts using the API, either from remote providers (like Google Fonts) or as local files Remote font properties.

So, you can use the API with Japanese fonts and control which subsets or Unicode ranges are loaded for optimal performance.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@loud dagger Kapa.ai is still learning and improving, please let me know how I did by reacting below.

loud dagger
#

@modest moss convert this to proper unicode range

\u3040-\u309F\u30A0-\u30FF\u4E00-\u9FAF\u3000-\u303F\uFF00-\uFFEF\u2000-\u206F\u2600-\u26FF\u2700-\u27BF
modest mossBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

I'm sorry, but the knowledge sources provided do not contain a detailed mapping or conversion guide for Unicode escape sequences (like \u3040-\u309F) to the format required by the Astro Experimental Fonts API's unicodeRange property. The documentation only gives a brief example, such as:

unicodeRange: ["U+26"]

and mentions that you can specify ranges for localization purposes Remote font properties.

If you need to convert your ranges, you would typically write them in the format U+XXXX-U+YYYY, but the knowledge sources do not explicitly confirm this for multiple or complex ranges. Therefore, I cannot provide a fully confident answer based solely on the provided documentation.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@loud dagger Kapa.ai is still learning and improving, please let me know how I did by reacting below.

loud dagger
#

@modest moss how to use <Font> tag with multi-font?

modest mossBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

To use the <Font /> component with multiple fonts in Astro’s Experimental Fonts API, you should add a separate <Font /> tag for each font you have registered in your astro.config.mjs. Each <Font /> tag should reference the corresponding cssVariable for the font you want to load.

For example, if you have registered two fonts in your config:

import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({
  experimental: {
    fonts: [
      {
        provider: fontProviders.google(),
        name: "Roboto",
        cssVariable: "--font-roboto"
      },
      {
        provider: fontProviders.google(),
        name: "Noto Sans JP",
        cssVariable: "--font-noto-sans-jp"
      }
    ]
  }
});

You would use the <Font /> component for each font in your <head> (e.g., in your Head.astro):

---import { Font } from 'astro:assets';---
<Font cssVariable="--font-roboto" preload />
<Font cssVariable="--font-noto-sans-jp" preload />

This ensures both fonts are loaded and their CSS variables are available for use in your stylesheets <Font /> component reference.

The knowledge sources do not mention a way to load multiple fonts with a single <Font /> tag, so you must use one tag per font.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@loud dagger Kapa.ai is still learning and improving, please let me know how I did by reacting below.

loud dagger
#

@modest moss can I use getFontData() with multi-font?

modest mossBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Yes, you can use getFontData() with multiple fonts. The function getFontData(cssVariable) returns font data for the provided CSS variable, and you can call it multiple times with different CSS variables—one for each font you have registered using the Experimental Fonts API. The documentation shows getFontData() being used with a single font, but there is no restriction mentioned against calling it for multiple fonts. You simply need to call the function separately for each font’s CSS variable Accessing font data programmatically.

For example:

const robotoData = getFontData("--font-roboto");
const notoSansJPData = getFontData("--font-noto-sans-jp");

Each call will return the font data for the specified font.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@loud dagger Kapa.ai is still learning and improving, please let me know how I did by reacting below.

loud dagger
#

@modest moss can you help me to migrate script to use Experimental fonts API?

modest mossBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Absolutely! Here’s how you can migrate your script to use Astro’s Experimental Fonts API, based strictly on the knowledge sources:


1. Register Fonts in astro.config.mjs

First, configure your fonts using the Experimental Fonts API in your astro.config.mjs. For example, to use Google’s "Noto Sans" and "Noto Sans JP":

import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({
  experimental: {
    fonts: [
      {
        provider: fontProviders.google(),
        name: "Noto Sans",
        cssVariable: "--font-noto-sans"
      },
      {
        provider: fontProviders.google(),
        name: "Noto Sans JP",
        cssVariable: "--font-noto-sans-jp"
      }
    ]
  }
});

See usage example


2. Add <Font /> Components to Your <head>

In your layout or head component (e.g., src/components/Head.astro), import and use the <Font /> component for each font:

---import { Font } from 'astro:assets';---
<Font cssVariable="--font-noto-sans" preload />
<Font cssVariable="--font-noto-sans-jp" preload />

See <Font /> component reference


3. Update Your CSS to Use the CSS Variables

In your CSS file, use the CSS variables you defined in the config:

.noto-sans-enabled {
  font-family: var(--font-noto-sans), var(--font-noto-sans-jp), system-ui, sans-serif;
}

See usage with CSS


4. (Optional) Use getFontData() Programmatically

If your script needs to access font data (e.g., for generating images), use getFontData() with the relevant CSS variable:

#
import { getFontData } from "astro:assets";
const notoSansData = getFontData("--font-noto-sans");
const notoSansJPData = getFontData("--font-noto-sans-jp");

See getFontData() usage


Summary:

  • Register fonts in astro.config.mjs with cssVariable.
  • Add a <Font /> component for each font in your <head>.
  • Use the CSS variables in your styles.
  • Use getFontData() for programmatic access if needed.

If you share your current script, I can provide a more tailored migration example!

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@loud dagger Kapa.ai is still learning and improving, please let me know how I did by reacting below.

loud dagger
#

@modest moss here's my OpenGraph images generator, this script use takumi (@takumi-rs/core and @takumi-rs/helpers) for generate and can migrate from Satori nearly drop-in replacement

modest mossBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Based on the knowledge sources, here’s how you can migrate your OpenGraph image generator script to use Astro’s Experimental Fonts API for font loading, similar to the Satori example provided in the documentation.

1. Register Your Fonts in astro.config.mjs

Add your desired fonts (e.g., "Noto Sans" and "Noto Sans JP") to the experimental.fonts array, specifying a unique cssVariable for each:

import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({
  experimental: {
    fonts: [
      {
        provider: fontProviders.google(),
        name: "Noto Sans",
        cssVariable: "--font-noto-sans"
      },
      {
        provider: fontProviders.google(),
        name: "Noto Sans JP",
        cssVariable: "--font-noto-sans-jp"
      }
    ]
  }
});

Usage examples


2. Use getFontData() to Access Font Data

In your OpenGraph image generator (e.g., src/pages/og.png.ts), use getFontData() to retrieve the font data for each font you want to use. The documentation provides an example for Satori, but the same approach applies for other libraries that require font buffers:

import type { APIRoute } from "astro";
import { getFontData } from "astro:assets";
// import { createImage } from "@takumi-rs/core"; // Example import for Takumi

export const GET: APIRoute = async (context) => {
  const notoSans = getFontData("--font-noto-sans");
  const notoSansJP = getFontData("--font-noto-sans-jp");

  // Example: Fetch the font buffer for each font
  const notoSansBuffer = await fetch(new URL(notoSans[0].src[0].url, context.url.origin)).then(res => res.arrayBuffer());
  const notoSansJPBuffer = await fetch(new URL(notoSansJP[0].src[0].url, context.url.origin)).then(res => res.arrayBuffer());
#

// Pass these buffers to your Takumi image generator as needed
// (Replace this with your actual Takumi usage)
// const image = await createImage({
// fonts: [
// { name: "Noto Sans", data: notoSansBuffer, weight: 400, style: "normal" },
// { name: "Noto Sans JP", data: notoSansJPBuffer, weight: 400, style: "normal" }
// ],
// ...
// });

// return new Response(image, { headers: { "Content-Type": "image/png" } });
};

[Accessing font data programmatically](<https://docs.astro.build/en/reference/experimental-flags/fonts/#accessing-font-data-programmatically>)

---

**Key Points:**
- Use `getFontData(cssVariable)` for each font you need.
- Fetch the font buffer using the `src[0].url` property.
- Pass the font buffer(s) to your image generator (Takumi) as required by its API.

**Note:**  
The knowledge sources do not provide Takumi-specific integration details, but the process for obtaining font buffers is the same as shown for Satori. You should adapt the buffer usage to Takumi’s API as needed.

If you need further help with the Takumi-specific part, please provide the relevant code snippet for how Takumi expects font data.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
#

@loud dagger Kapa.ai is still learning and improving, please let me know how I did by reacting below.

loud dagger
#

@modest moss ok, here is my another script, this script use Satori and Sharp for generator

modest mossBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

To migrate your script that uses Satori and Sharp for OpenGraph image generation to use Astro’s Experimental Fonts API, follow these steps based on the official documentation:


1. Register Fonts in astro.config.mjs

Add your required fonts (e.g., "Noto Sans", "Noto Sans JP") to the experimental.fonts array, each with a unique cssVariable:

import { defineConfig, fontProviders } from "astro/config";
export default defineConfig({
  experimental: {
    fonts: [
      {
        provider: fontProviders.google(),
        name: "Noto Sans",
        cssVariable: "--font-noto-sans"
      },
      {
        provider: fontProviders.google(),
        name: "Noto Sans JP",
        cssVariable: "--font-noto-sans-jp"
      }
    ]
  }
});

Usage examples


2. Use getFontData() to Retrieve Font Buffers

In your API route (e.g., src/pages/og.png.ts), use getFontData() to get the font data for each font. The documentation provides a Satori example, which you can adapt for your use case:

import type { APIRoute } from "astro";
import { getFontData } from "astro:assets";
import satori from "satori";
import sharp from "sharp";

export const GET: APIRoute = async (context) => {
  const notoSans = getFontData("--font-noto-sans");
  const notoSansJP = getFontData("--font-noto-sans-jp");

  // Fetch font buffers
  const notoSansBuffer = await fetch(new URL(notoSans[0].src[0].url, context.url.origin)).then(res => res.arrayBuffer());
  const notoSansJPBuffer = await fetch(new URL(notoSansJP[0].src[0].url, context.url.origin)).then(res => res.arrayBuffer());
#

// Generate SVG with Satori
const svg = await satori(
<div style={{ fontFamily: "Noto Sans, Noto Sans JP" }}>Hello, world</div>,
{
width: 1200,
height: 630,
fonts: [
{ name: "Noto Sans", data: notoSansBuffer, weight: 400, style: "normal" },
{ name: "Noto Sans JP", data: notoSansJPBuffer, weight: 400, style: "normal" }
]
}
);

// Convert SVG to PNG with Sharp
const png = await sharp(Buffer.from(svg)).png().toBuffer();

return new Response(png, {
headers: { "Content-Type": "image/png" }
});
};

[Accessing font data programmatically](<https://docs.astro.build/en/reference/experimental-flags/fonts/#accessing-font-data-programmatically>)

---

**Summary:**  
- Register each font in your Astro config with a unique `cssVariable`.
- Use `getFontData()` for each font and fetch the buffer.
- Pass the buffers to Satori as shown in the documentation.
- Use Sharp as usual to convert the SVG to PNG.

This approach is directly supported by the knowledge sources and matches the documented Satori usage. If you need to support more fonts, repeat the process for each additional font.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
#

@loud dagger Kapa.ai is still learning and improving, please let me know how I did by reacting below.

loud dagger
#

@modest moss can i config font's weight in config as variable font, but config in OpenGraph images generator script as static font?
example: on config file i setup as weights: ["100 900"], on config file but i want to OpenGraph images generator script load just weight 400 and 700

modest mossBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Based on the knowledge sources, you can configure a variable font in your Astro config using a weight range, such as weights: ["100 900"], which will make the full range of weights available for your project Remote font properties.

When using getFontData() in your OpenGraph images generator script, the function returns an array of FontData objects, each containing information about the available weights and styles for the font as configured. You can then select and use only the specific weights you need (e.g., 400 and 700) in your script by filtering the returned data or by only passing those weights to your image generator (such as Satori or Takumi) Accessing font data programmatically.

However, the knowledge sources do not explicitly state whether configuring a wide weight range in the Astro config will result in all those font files being downloaded and included in the build, even if you only use a subset of weights in your script. The documentation does show that you can specify a range in the config and then use only certain weights programmatically, but it does not clarify if this optimizes the build output to include only the used weights.

Summary:

  • You can configure a variable font with a weight range in your config (e.g., weights: ["100 900"]).
  • In your OpenGraph image generator script, you can use only the weights you need (e.g., 400 and 700) by selecting those from the data returned by getFontData().
  • The documentation does not explicitly confirm whether unused weights are excluded from the build output.
#

If you need to optimize for only certain weights, it is safest to specify just those weights in your Astro config.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: