
Security News
Another Round of TEA Protocol Spam Floods npm, But It’s Not a Worm
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.
astro-font
Advanced tools
An Astro integration to optimize Local & Google fonts inspired by @next/font
astro-font will automatically optimize your Custom Fonts, Local Fonts, Fonts over any CDN and Google fonts for performance.
The project is inspired by the Next.js Font Optimization.
npm install astro-font
## or yarn
yarn add astro-font
## or pnpm
pnpm add astro-font
Automatically optimize any Google Font. To use the font in all your pages, add it to <head> file in an Astro layout:
---
import { AstroFont } from "astro-font";
---
<head>
<AstroFont
config={[
{
src: [],
name: "Poppins",
// Google Fonts URL
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>
---
import { AstroFont } from "astro-font";
---
<head>
<AstroFont
config={[
{
name: "Afacad",
src: [
{
style: 'bold',
weight: '700',
// Picked up font URL by manually visiting Google Fonts URL
path: 'https://fonts.gstatic.com/s/afacad/v1/6NUK8FKMIQOGaw6wjYT7ZHG_zsBBfvLqagk-80KjZfJ_uw.woff2'
},
],
preload: true,
display: "swap",
selector: "body",
fallback: "sans-serif",
},
]}
/>
</head>
---
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>
You can import and use multiple fonts in your application. There are two approaches you can take.
Just extend the array of the config to contain the new collection of the fonts:
---
import { join } from "node:path";
import { AstroFont } from "astro-font";
---
<head>
<AstroFont
config={[
{
name: "Afacad",
src: [
{
style: 'bold',
weight: '700',
path: 'https://fonts.gstatic.com/s/afacad/v1/6NUK8FKMIQOGaw6wjYT7ZHG_zsBBfvLqagk-80KjZfJ_uw.woff2'
},
],
preload: true,
display: "swap",
selector: "body",
fallback: "sans-serif",
},
{
name: "Inter",
src: [
{
weight: '400',
style: 'normal',
path: join(process.cwd(), 'public', 'fonts', 'Inter-Regular.ttf')
}
],
preload: true,
display: "swap",
selector: "body > span",
fallback: "serif",
},
]}
/>
</head>
The selector attribute per config object can be used to configure which CSS class will reflect the whole CSS (automatically including the references to fallback fonts CSS).
---
import { join } from "node:path"
---
<AstroFont
config={[
{
name: "Afacad",
src: [
{
style: 'bold',
weight: '700',
path: 'https://fonts.gstatic.com/s/afacad/v1/6NUK8FKMIQOGaw6wjYT7ZHG_zsBBfvLqagk-80KjZfJ_uw.woff2'
},
],
preload: true,
display: "swap",
fallback: "sans-serif",
// My Custom CSS Selector
// Type: ClassName
selector: ".custom_class",
},
{
name: "Inter",
src: [
{
weight: '400',
style: 'normal',
path: join(process.cwd(), 'public', 'fonts', 'Inter-Regular.ttf')
}
],
preload: true,
display: "swap",
fallback: "serif",
// My Custom CSS Selector
// Type: CSS Selector
selector: "body > span",
},
]}
/>
The cssVariable attribute per config object can be used to configure which CSS variable will reflect in your document's :root CSS selector (automatically including the references to fallback fonts CSS).
---
import { join } from "node:path"
---
<AstroFont
config={[
{
name: "Afacad",
src: [
{
style: 'bold',
weight: '700',
path: 'https://fonts.gstatic.com/s/afacad/v1/6NUK8FKMIQOGaw6wjYT7ZHG_zsBBfvLqagk-80KjZfJ_uw.woff2'
},
],
preload: true,
display: "swap",
fallback: "sans-serif",
// My Custom CSS Selector
// Type: ClassName
selector: ".custom_class",
},
{
name: "Inter",
src: [
{
weight: '400',
style: 'normal',
path: join(process.cwd(), 'public', 'fonts', 'Inter-Regular.ttf')
}
],
preload: true,
display: "swap",
fallback: "serif",
// My Custom CSS Variable
// Type: CSS Variable
cssVariable: "astro-font",
// and now use it as style="font-family: var(--astro-font)"
},
]}
/>
The fallbackName attribute per config object can be used to configure the fallback font's family name (in CSS).
---
import { join } from "node:path"
---
<AstroFont
config={[
{
name: "Afacad",
src: [
{
style: 'bold',
weight: '700',
path: 'https://fonts.gstatic.com/s/afacad/v1/6NUK8FKMIQOGaw6wjYT7ZHG_zsBBfvLqagk-80KjZfJ_uw.woff2'
},
],
preload: true,
display: "swap",
fallback: "sans-serif",
selector: ".custom_class",
// My Custom Fallback Font Name
fallbackName: "Afacad Override",
},
{
name: "Inter",
src: [
{
weight: '400',
style: 'normal',
path: join(process.cwd(), 'public', 'fonts', 'Inter-Regular.ttf')
}
],
preload: true,
display: "swap",
fallback: "serif",
cssVariable: "astro-font",
// My Custom Fallback Font Name
fallbackName: "Inter Custom Override",
},
]}
/>
astro-font uses the following node imports:
node:pathnode:bufferTo make sure that it works in Cloudflare Workers, please enable the node_compatibiliy flag per the guide https://developers.cloudflare.com/workers/runtime-apis/nodejs/#enable-nodejs-with-workers.
If the above guide fails to work, go to your Cloudflare project > Settings > Functions > Compatibility flags and add the flag (as follows).
Per Astro + Cloudflare docs, you'd need to modify the vite configuration to allow for the node:* import syntax:
// File: astro.config.mjs
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';
// https://astro.build/config
export default defineConfig({
output: 'server',
adapter: cloudflare(),
+ vite: {
+ ssr: {
+ external: ["buffer", "path", "fs", "os", "crypto", "async_hooks"].map((i) => `node:${i}`),
+ },
+ // make sure to use node:fs, node:path, or node:os if you are using it in your project instead of fs, path or os
+ },
});
As there's no access to the files in the public directory in the Cloudflare Pages (server-side render) context, you'd want to use fonts over CDN. To make the developer experience painless, use the following code snippet while setting up local fonts with Cloudflare in Astro:
---
import { join } from "node:path";
import { AstroFont } from "astro-font";
const fontPrefix = import.meta.env.PROD
? Astro.site.toString()
: join(process.cwd(), "public");
---
<AstroFont
config={[
{
name: "Editorial New",
src: [
{
style: "italic",
weight: "500",
path: join(
fontPrefix,
"fonts",
"PPEditorialNew-MediumItalic.woff2"
),
},
],
preload: true,
display: "swap",
selector: "body",
fallback: "sans-serif",
}
]}
/>
Let us say you want to self host the fonts but do not want to spend time fetching the fonts, setting up the right path, and do the hassle of bundling it in the application. That is where you would want to do the following steps:
Use the fetch: true in (per) font configuration. For example:
<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',
},
]}
/>
The fetch: true makes astro-font fetch the fonts specified.
Update your astro.config.* file to include the astroFont integration:
// File: astro.config.mjs
+ import { astroFont } from 'astro-font/integration'
// ...
integrations: [
+ astroFont()
]
// ...
The integration makes sure that all the directories containing the fetched fonts are bundled into the Astro build.
We love our contributors! Here's how you can contribute:
FAQs
An Astro integration to optimize Local & Google fonts inspired by @next/font
The npm package astro-font receives a total of 4,167 weekly downloads. As such, astro-font popularity was classified as popular.
We found that astro-font demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.

Security News
PyPI adds Trusted Publishing support for GitLab Self-Managed as adoption reaches 25% of uploads

Research
/Security News
A malicious Chrome extension posing as an Ethereum wallet steals seed phrases by encoding them into Sui transactions, enabling full wallet takeover.