astro-font

repository·master·Indexed 41 days ago

https://github.com/rishi-raj-jain/astro-font

An optimization tool for Astro projects that automatically handles loading custom, local, and Google fonts. It manages performance-critical aspects such as preloading, fallback management, and self-hosting Google Fonts by fetching them during the build process. The library provides an <AstroFont /> component for layout integration and a corresponding Astro integration to manage font assets.

Tokens
4.4K
Snippets
19
Records
20
Agent score
53%

What's inside astro-font

  1. Configure CSS Selectors and Variables in AstroFont

    master

    The AstroFont configuration allows you to control how font styles are applied to your document via CSS selectors or variables.

    • selector: Defines a CSS class or selector (e.g., .custom_class or body > span) that will reflect the generated CSS, including fallback font references.
    • cssVariable: Defines a CSS variable name (e.g., astro-font) that will be injected into the :root selector. You can then use it in your styles as font-family: var(--astro-font).
    <AstroFont
      config={[
        {
          name: "Afacad",
          // ... other config
          selector: ".custom_class",
        },
        {
          name: "Inter",
          // ... other config
          cssVariable: "astro-font",
        },
      ]}
    />
  2. Setup AstroFont for Cloudflare Workers

    master

    Because astro-font relies on Node.js built-ins (node:path, node:buffer), you must configure your Cloudflare environment to support them.

    1. Enable nodejs_compat: In your Cloudflare project settings (or via compatibility flags), enable the nodejs_compat flag.
    2. Configure Vite SSR: Modify your astro.config.mjs to mark Node.js built-ins as external in the Vite SSR configuration to prevent bundling errors.
    3. Handle Local Fonts in SSR: Since Cloudflare Pages/Workers may not have access to the public directory at runtime, use a conditional fontPrefix to switch between local paths (development) and CDN URLs (production).
    // astro.config.mjs
    export default defineConfig({
        output: 'server',
        adapter: cloudflare(),
        vite: {
            ssr: {
              external: ["buffer", "path", "fs", "os", "crypto", "async_hooks"].map((i) => `node:${i}`),
            },
        },
    });
  3. Handle CDN and `build.assetsPrefix` with AstroFont

    master

    If your fonts are served from a CDN or a non-root path (e.g., using Astro's build.assetsPrefix), use the assetsPrefix property to ensure preload links and @font-face URLs are correctly generated.

    • Component-level assetsPrefix: Applies to all fonts in the config array unless overridden.
    • Per-font assetsPrefix: Overrides the component-level prefix for a specific font entry.

    Utility API

    For custom implementations (like Satori), use generatePublicUrl and getFontURLs from astro-font/utils to resolve paths and URLs.

    --- 
    import { join } from 'node:path'
    import { AstroFont } from 'astro-font'
    const assetsPrefix = import.meta.env.PUBLIC_ASSETS_PREFIX ?? Astro.site?.toString()
    ---
    
    <AstroFont
      assetsPrefix={assetsPrefix}
      config={[
        {
          name: 'Inter',
          src: [{ path: join(process.cwd(), 'public', 'fonts', 'Inter-Regular.ttf'), style: 'normal', weight: '400' }],
          preload: true,
          display: 'swap',
          fallback: 'sans-serif',
        },
      ]}
    />
  4. Optimize Google Fonts with AstroFont

    master

    You can optimize Google Fonts by providing the Google Fonts CSS URL directly or by manually specifying the font file paths (e.g., from fonts.gstatic.com). Add the <AstroFont /> component to your layout's <head> section.

    Using a Google Fonts URL directly

    Pass the full CSS URL to the googleFontsURL property in the config object.

    Picking fonts from a Google Fonts URL

    Manually provide the specific font file paths in the src array for more granular control.

    --- 
    import { AstroFont } from "astro-font";
    ---
    
    <head>
        <AstroFont
          config={[
            {
              src: [],
              name: "Poppins",
              googleFontsURL: 'https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,400;0,600;1,400;1,700&display=swap',
              preload: true,
              display: "swap",
              selector: "body",
              fallback: "sans-serif",
            },
          ]}
        />
    </head>
  5. Self-host Google Fonts by fetching them dynamically

    master

    You can use astro-font to self-host fonts without manually downloading and managing files. By setting fetch: true in your font configuration and providing a googleFontsURL, astro-font will fetch the fonts during the build process and bundle them locally.

    To use this feature:

    1. Set fetch: true in the font configuration object.
    2. Provide the googleFontsURL (the CSS URL from Google Fonts).
    3. Specify a cacheDir (e.g., '.cache') where the fetched files will be stored.
    4. Ensure the astroFont integration is added to your astro.config.* file so the fetched directories are correctly bundled into the Astro build.
    <AstroFont
      config={[
        {
          src: [],
          preload: true,
          display: 'swap',
          name: 'vazirmatn',
          fallback: 'monospace',
          fetch: true,
          verbose: true,
          cacheDir: '.cache',
          googleFontsURL: 'https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100..900&display=swap',
        },
        {
          src: [],
          preload: true,
          display: 'block',
          name: 'material-icon-outlined',
          fallback: 'monospace',
          fetch: true,
          verbose: true,
          cacheDir: '.cache',
          googleFontsURL: 'https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0',
        },
      ]}
    />
  6. Optimize Local Fonts with AstroFont

    master

    To use local font files, provide an array of src objects containing the path to the font files. It is recommended to use node:path's join and process.cwd() to ensure correct absolute paths during the build process.

    ---
    import { join } from "node:path";
    import { AstroFont } from "astro-font";
    ---
    
    <head>
        <AstroFont
          config={[
            {
              name: "Afacad",
              src: [
                {
                  style: 'normal',
                  weight: '400',
                  path: join(process.cwd(), 'public', 'fonts', 'Afacad-Regular.ttf')
                },
                {
                  style: 'medium',
                  weight: '500',
                  path: join(process.cwd(), 'public', 'fonts', 'Afacad-Medium.ttf')
                },
              ],
              preload: false,
              display: "swap",
              selector: "body",
              fallback: "sans-serif",
            },
          ]}
        />
    </head>
  7. Install and configure the astro-font integration

    master

    To use astro-font in your Astro project, import the astroFont function and add it to the integrations array in your astro.config.mjs file. This integration optimizes font loading by managing font assets during the build process.

    import { defineConfig } from 'astro/config';
    import { astroFont } from 'astro-font';
    
    export default defineConfig({
      integrations: [astroFont()],
    });
  8. Configure the AstroFont Source interface

    master

    The Source interface defines an individual font file within a collection.

    Properties:

    • path: The file path or URL to the font file.
    • preload: Whether this specific source should be preloaded.
    • css: A record of additional CSS properties to apply to the @font-face rule.
    • style: The font style (e.g., 'normal', 'italic', 'oblique', or CSS GlobalValues).
    • weight: The font weight (e.g., 400, 'bold', or numeric strings).
    export interface Source {
      path: string
      preload?: boolean
      css?: Record<string, string>
      style: 'normal' | 'italic' | 'oblique' | `oblique ${number}deg` | GlobalValues | (string & {})
      weight?: 
        | 'normal' | 'bold' | 'lighter' | 'bolder' | GlobalValues
        | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
        | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900'
        | (string & {})
        | (number & {})
    }
  9. Configure the AstroFont Config interface

    master

    The Config interface is the primary way to define a font collection for optimization. It allows you to specify local or remote sources, fallback behaviors, and CSS generation settings.

    Key properties:

    • name: The name of the font family.
    • src: An array of Source objects defining the font files.
    • fetch: If true, the library will attempt to download font files (useful for Google Fonts).
    • fallback: The generic CSS fallback category ('serif' | 'sans-serif' | 'monospace').
    • fallbackName: Optional custom name for the generated fallback font face.
    • cssVariable: A string or boolean to enable CSS variable generation (e.g., --astro-font).
    • display: Sets the font-display CSS property (e.g., 'swap', 'fallback').
    • assetsPrefix: A prefix for public font URLs (e.g., a CDN origin or Astro's build.assetsPrefix).
    • basePath: The directory where fonts are served from (defaults to ./public).
    export interface Config {
      name: string
      src: Source[]
      fetch?: boolean
      verbose?: boolean
      selector?: string
      preload?: boolean
      cacheDir?: string
      basePath?: string
      fallbackName?: string
      googleFontsURL?: string
      cssVariable?: string | boolean
      fallback: 'serif' | 'sans-serif' | 'monospace'
      display: 'auto' | 'block' | 'swap' | 'fallback' | 'optional' | (string & {})
      assetsPrefix?: string
    }