-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fonts #1039
base: main
Are you sure you want to change the base?
Fonts #1039
Conversation
How does preloading pick the What's the reasoning behind considering subsetting a non-goal? It helps a lot when the font participates in LCP and is trivial to do when using google fonts directly. Moving to astro fonts in that case would be a downgrade. |
I think we can't choose the src to pick automatically, so that would preload everything? Not sure, have ideas in mind?
Only automatic subsetting is a non goal (eg. by analyzing the static content), subsetting is actually supported. I'll clarify the non goal |
<Font family='Lato' /> | ||
<style> | ||
h1 { | ||
font-family: var(--astro-font-inter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's gonna be important to make sure those variables are accessible correctly to things like Tailwind. It's a bit unclear with this API because the Tailwind CSS would be imported in the frontmatter, whereas the fonts are in the document.
Perhaps Vite will re-order it to make it work, not sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well since it's just some css, I don't think it will cause any issues? In Tailwind 3, you'd have to reference like so:
import defaultTheme from 'tailwindcss/defaultTheme'
export default {
theme: {
extend: {
fontFamily: {
sans: ['var(--astro-font-inter)', ...defaultTheme.fontFamily.sans],
},
}
}
}
provider: "adobe", | ||
weights: [200, 700], | ||
styles: ["italic"], | ||
subsets: [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would love an example with opentype fonts features
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that would be one key per setting? Something like the following:
{
fontKerning: "'kern' 1",
fontVariantAlternates: "1"
// etc...
}
MDN docs: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_fonts/OpenType_fonts_guide
myCustomFontProvider(), | ||
], | ||
defaults: { | ||
provider: "adobe", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how would you know the name of the provider here? Will it be... typed (👀) automatically based on what you put in providers
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes! Thanks to defineConfig()
being generic now, we can do a lot of cool stuff here. Providers would be easily typed
fontProviders.adobe({ apiKey: process.env.ADOBE_FONTS_API_KEY }), | ||
myCustomFontProvider(), | ||
], | ||
defaults: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think defaults
make this a nicer API overall, but I wonder how required it is, do people really have that much fonts that setting defaults is required 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have to admit I rarely use a lot of fonts but I guess that could be the case for more complex sites. IMO people will probably want this for setting a default provider in most cases, so why not support all the other properties I suppose!
|
||
#### Definition | ||
|
||
A provider allows to retrieve font faces data from a font family name from a given CDN or abstraction. It's a [unifont](https://github.com/unjs/unifont) provider. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think some people could have a concern with us exposing a third-party "API" like that in the config, but we already do for syntax highlighting themes, so I think it's okay. Plus, the default providers unifont provide are probably enough for 99.999% of people anyway.
|
||
| Path | Example (weight) | Advantage | Downside | | ||
| --------- | ------------------- | --------------------- | --------------------------------------------------------------------------------- | | ||
| Minimal | Only include `400` | Lightweight | People will probably struggle by expecting all weights to be available by default | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm team just 400, Google Fonts also gives you only 400 when you unselect the "give all options" setting
|
||
#### Why this API? | ||
|
||
1. **Coherent API**: a few things in Astro are using this pattern, namely integrations and vite plugins. It's simple to author as a library author, easy to use as a user |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree with this statement, this API is used only for integrations and vite plugins.
For example: middleware, actions, and content collections (we could consider them an exception though) don't follow this pattern. They use a known file to collect users' APIs. Same thing for @astrojs/db
(but that's integration).
I think that our configuration should inject as less runtime as possible, use good defaults, and maybe the custom providers could follow the same pattern we use with actions and middleware.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Image services, which are probably the most similar thing do work this way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably I missed something, please correct me if I misunderstood what you mean. Based on this docs page (https://docs.astro.build/en/reference/image-service-reference/#user-configuration), the image service uses an entry point API, which is different from the one proposed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, apologies, I misunderstood what you meant. Thought this was mostly about where they're configured.
Image services do use an entrypoint, but they're configured in the Astro config, when they have settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main advantage of having objects in the config directly for providers is typing support, which imo is super important
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My major concern is about the providers and the way they are injected. The rest is fine :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright so I guess you'd prefer such an API, am I right?
defineConfig({
fonts: {
providers: [fontProviders.adobe({ apiKey: "..." })]
// equal to { name: "adobe", entrypoint: "astro/assets/fonts/adobe", config: { apiKey: "..." } }
}
})
Seems doable
Summary
Have first-party support for fonts in Astro:
Links