withastro / roadmap

Ideas, suggestions, and formal RFC proposals for the Astro project.
305 stars 30 forks source link

Fonts #1037

Open florian-lefebvre opened 1 week ago

florian-lefebvre commented 1 week ago

Summary

Have first-party support for fonts in Astro.

Background & Motivation

Fonts is one of those basic things when making a website, but also an annoying one to deal with. Should I just use a link to a remote font? Or download it locally? How should I handle preloads then?

The goal is to improve the DX around using fonts in Astro.

Why not using fontsource?

Fontsource is great! But it's not intuitive to preload, and more importantly, doesn't have all fonts. The goal is to have a more generic API for fonts (eg. you want to use a paid provider like adobe).

Goals

Non-Goals

florian-lefebvre commented 1 week ago

I think we should have a config that can be easily used, but customized as needed. For example, here is an example of minimal usage:

// astro config
export default defineConfig({
    fonts: {
        families: ["Roboto", "Lato"]
    }
})
---
// layouts/Layout.astro
import { Font } from "astro:fonts"
---
<head>
    <Font family="Inter" preload />
    <Font family="Lato" />
    <style>
        h1 {
            font-family: var(--astro-font-inter);
        }
        p {
            font-family: var(--astro-font-lato);
        }
    </style>
</head>

That would try pulling fonts from Google fonts by default.


Here is an example of a more involved fonts config that I think would be nice to support

import { fontProviders } from "astro/config"

// astro config
export default defineConfig({
    fonts: {
        providers: [fontProviders.adobe({ apiKey: "ADOBE_API_KEY" })],
        local: {
            directories: ['./my-custom-directory']
        },
        defaults: {
            provider: "local",
            weights: [800,900]
        },
        families: [
            "Roboto", // From local provider
            {
                // From local provider
                name: "Lato",
                weights: [400,600]
            },
            {
                name: "Inter",
                provider: "google",
                subsets: ["latin"]
            },
            {
                name: "...",
                provider: "adobe"
            }
        ]
    }
})

I don't go into details regarding what's involved code wise, since that's a Stage 3 topic

ematipico commented 1 week ago

Some comments regarding the proposal.

I would consider astro:assets instead of astro:fonts. The name "assets" was designed to incorporate any asset of the web, and fonts are part of it.

Ideally, users should only need to use a little configuration to enable them to import their fonts. I think something like:

// astro config
export default defineConfig({
    fonts: ["Roboto"]
})

Something more involved?

// astro config
export default defineConfig({
    fonts: [{
            // the key is the name of the font
            "Roboto": {

            }
    }]
})

As for the providers, it seems to be something very technical and for developers that know what they are doing. I would consider a different approach, different from using a configuration:

Nickersoft commented 3 days ago

Just found this proposal, and I love this! I think consuming Google Fonts in Astro w/ built-in preloading would be fantastic. A bit of prior art on this as well: https://github.com/rishi-raj-jain/astro-font, though we'd most likely want a cleaner API.

florian-lefebvre commented 3 days ago

Yes that's a good example! It was linked in the Stage 1 RFC but never hurts to bring some projects/ideas to our attention :)