Adapting Fonts for Internationalization

📢 This article was translated by gemini-3-flash-preview

Introduction

After going international, I didn’t pay much attention to posts in other languages. That is, until I saw some nice Japanese fonts while browsing. I had to snag them, only to realize the fonts for my other languages were… well, pretty rough.

Importing Fonts

Google Fonts

Using a service like Google Fonts is usually the fastest and easiest way.

For example, I’m using Comic Neue, Noto Sans JP, Noto Sans SC, Noto Sans TC, and Yomogi. After selecting them, Google Fonts generates an HTML tag to drop into your <head>.

1
<link href="https://fonts.googleapis.com/css2?family=Comic+Neue:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&family=Noto+Sans+JP:[email protected]&family=Noto+Sans+SC:[email protected]&family=Noto+Sans+TC:[email protected]&family=Yomogi&display=swap" rel="stylesheet">

Custom Imports

You can also host your own .ttf, .woff, or .woff2 files. I recommend .woff2 or .woff for smaller file sizes. (Advanced optimization involves font subsetting/splitting, which is how Google Fonts handles it).

I’m using the Yozai Font . The original .ttf is massive, so I compressed it using a tool like Transfonter before importing.

First, place the font files in a directory, then define the font family in your SCSS.
Here’s my setup. Usually, .woff2 and .woff are enough. I kept .ttf for legacy browser support (honestly, I just uploaded it before I knew better and had to optimize later).
Set font-display: swap; so the browser uses a fallback font while downloading. This prevents blank text and improves the user experience.

1
2
3
4
5
6
7
8
9
@font-face {
  font-family: 'yozai';
  src: url('/fonts/Yozai-Regular.woff2') format('woff2'),
      //  url('/fonts/Yozai-Regular.woff') format('woff'),
       url('/fonts/Yozai-Regular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

Where to Put It

For Google Fonts, my theme has a custom.html for code that needs to go into the <head>.

For self-hosted files, the theme provides a custom.scss.

Font configurations are handled in variables.scss in my theme, so I modified that directly.

Configuring Fonts

Set specific fonts based on the language.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
/**
*   Global font family
*/
:root {
    // --sys-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Droid Sans", "Helvetica Neue";
    --sys-font-family: system-ui, -apple-system, "Segoe UI", "Helvetica Neue", Arial, sans-serif;

    --zh-font-family: "yozai", "Noto Sans SC", var(--sys-font-family);
    --zh-TW-font-family: "yozai", "Noto Sans TC", var(--sys-font-family);
    --ja-font-family: "Yomogi", "Noto Sans JP", var(--sys-font-family);
    --en-font-family: "Comic Sans MS", "Comic Neue", var(--sys-font-family);

    --base-font-family: var(--sys-font-family), sans-serif;
    --code-font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}

I added font variables for other languages following the existing naming convention. Then, I used the :lang selector to dynamically swap fonts based on the lang attribute of the <html> tag.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
/* For Chinese (Simplified) */
:lang(zh), :lang(zh-CN) {
    font-family: var(--zh-font-family);
}

/* For Chinese (Traditional) */
:lang(zh-TW) {
    font-family: var(--zh-TW-font-family);
}

/* For English */
:lang(en) {
    font-family: var(--en-font-family);
}

/* For Japanese */
:lang(ja) {
    font-family: var(--ja-font-family);
}
This post is licensed under CC BY-NC-SA 4.0 by the author.
Last updated on 2025-09-23 04:21 +0900