Is it possible to apply font based on text language?
Unanswered
Chum salmon posted this in #help-forum
Chum salmonOP
Do you guys have some tricks to automatically detect language and apply different font accordingly?
So far I have two fonts in my layout.tsx like this:
In global.css, I have something like this:
The problem is it will only use one font depending on the lang property in the <html> tag of the layout.
Is it even possible to apply the correct font based on the language of the characters?
So far I have two fonts in my layout.tsx like this:
<html lang="en" className={`${inter.variable} ${aktiv.variable} antialiased`}>
In global.css, I have something like this:
@layer base {
html:lang(en) {
font-family: var(--font-inter), sans-serif;
}
html:lang(th) {
font-family: var(--font-aktiv), sans-serif;
}
The problem is it will only use one font depending on the lang property in the <html> tag of the layout.
Is it even possible to apply the correct font based on the language of the characters?
12 Replies
American black bear
store locale somewhere in state such as url, localstorage, database or combination of these. Let's call this variable
Then we can use
locale
and create a hook or set of functions to access and change it easily.Then we can use
next/font
to import multiple fonts and switch based on locale in the root layout. With url
ordatabase
implementation you can probably do this whole thing server side e.g www.example.com/[locale]/your-app
import { Inter, Roboto_Mono } from 'next/font/google'
export const inter = Inter({
subsets: ['latin'],
display: 'swap',
})
export const roboto = Roboto_Mono({
subsets: ['latin'],
display: 'swap',
})
export default function Layout({ children }: { children: React.ReactNode }) {
// store in url, database, localstorage, etc.
// depending on your use case
const locale = getLocale()
const font = locale === "en" ? inter.className : roboto.className
return (
<html lang="en" className={font}>
<body>
<div>{children}</div>
</body>
</html>
)
}
Are you using i18n for translations?
If so you can also use https://www.i18next.com/overview/api#resolvedlanguage
Chum salmonOP
correct me if I'm wrong but from what I read both of the above methods apply 1 font to the entire page based on the language.
This is not what I'm aiming for.
I want to use 2 fonts in 1 page and apply them to specific language.
For example, the navbar has HOME | ABOUT | CONTACT and I want to keep it Inter font. Then the content of the page have some Thai language on it and I want to apply Aktiv font only to those Thai letters.
I can manually do it but I'm looking for a way to automatically apply a specific font to a specific language.
This is not what I'm aiming for.
I want to use 2 fonts in 1 page and apply them to specific language.
For example, the navbar has HOME | ABOUT | CONTACT and I want to keep it Inter font. Then the content of the page have some Thai language on it and I want to apply Aktiv font only to those Thai letters.
I can manually do it but I'm looking for a way to automatically apply a specific font to a specific language.
It would require the library to automatically knnow the language? Make a text wrapper that you pass in a specific key to maybe?
<TextL la='en'></TextL
<TextL la='thai'></TextL
or better yet you would only ahve to use that when you dont want to use default font you have set.
A component that automatically knows the language and applies a different font style, and supporting multiple fonts on a page Idk how you would do that
@Jboncz A component that automatically knows the language and applies a different font style, and supporting multiple fonts on a page Idk how you would do that
Chum salmonOP
idk either. I was hoping there is a way 😂
I mean there is a way… but it’s not worth the overhead it would take.
It would be crazy overhead to do something like that.
the way fonts are rendered on the web is that, say you have a font list like this
then the browser will try to use font1 for all glyphs. if a glyph is not supported by font1, the browser will then try font2 for it. and so on so forth.
so what you need to do is to ensure that the Inter you load does not support any Thai characters. Or, ensure that the Aktiv font you load does not support any Latin characters.
if that isn't already the case for your fonts, you need to manually subset the font yourself to ensure a font does not support a given glyph. there are many ways you can do this, none of them are trivial
* https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/unicode-range
* or subset the font binary using font subset scripts, look them up online
so my takeaway is: i wouldn't bother with any of this. if the main font in your application is Inter, then just
and use
* {
font-family: font1, font2, font3;
}
then the browser will try to use font1 for all glyphs. if a glyph is not supported by font1, the browser will then try font2 for it. and so on so forth.
so what you need to do is to ensure that the Inter you load does not support any Thai characters. Or, ensure that the Aktiv font you load does not support any Latin characters.
if that isn't already the case for your fonts, you need to manually subset the font yourself to ensure a font does not support a given glyph. there are many ways you can do this, none of them are trivial
* https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/unicode-range
* or subset the font binary using font subset scripts, look them up online
so my takeaway is: i wouldn't bother with any of this. if the main font in your application is Inter, then just
html {
font-family: Inter;
}
.font-thai {
font-family: Aktiv;
}
and use
font-thai
where you need it.