簡體   English   中英

NextJS:從數據庫加載字體

[英]NextJS: Loading Font from Database

我正在使用 NextJS 和 Tailwind CSS。

在我的應用程序中,用戶可以 select 包含不同配色方案的主題以及 fonts 的預選列表。他們可以為應用程序選擇他們喜歡的字體。

這些只是谷歌 Fonts。

我不確定根據從數據庫收到的字體名稱加載字體的最佳方法是什么。 我可以從serverSideProps中的database加載數據,但是如何在渲染之前加載字體,這樣就不會出現屏幕閃爍。 你能幫忙嗎?

更新

截至目前,我已經完成了以下工作:

  1. tailwind.config.js中,我用可用的不同 fonts 擴展了主題。

    主題:{ fontFamily: { inter: ['Inter', 'sans-serif'], cal: ["Cal Sans", "Inter", "sans-serif"], arima:['Arima Madurai','cursive' ], opensans:['Open Sans', 'sans-serif'], } }

  2. 我為每種字體創建了一個樣式表,它存儲在這個位置的公共文件夾中:

    /字體/opensans/stylesheet.css

    /字體/cal/stylesheet.css

    /字體/inter/stylesheet.css

    /fonts/arima/stylesheet.css

這些樣式表包含字體。 下面是一個例子:

@font-face {
  font-family: "Cal Sans";
  src: url("CalSans-SemiBold.woff2") format("woff2"),
    url("CalSans-SemiBold.woff") format("woff");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
  1. 在頁面上(比如pages/index.js ),我使用serverSideProps加載用戶的首選項並將其傳遞給Layout組件。 這個布局組件的head是通過next/head創建的。 讓我們將從服務器接收到的字體屬性稱為themeFont

假設用戶的偏好是Cal Sans ,並且用戶的偏好作為值cal存儲在數據庫中。 因此, themeFont值將為cal

在頭部,我按如下方式加載相關樣式表:

<Head>
  <link rel="stylesheet" href={`/fonts/${themeFont}/stylesheet.css`}></link>
</Head>
  1. 這將加載/fonts/cal/stylesheet.css和所需的字體。 沒有加載其他字體。 然后我可以在帶有font-cal的組件中使用它,因為它已在tailwind.config.css中定義

它工作正常。 我仍然看到閃爍,可能是因為font-display:swap ,也可能是其他原因。 但我仍然覺得這不是最佳解決方案,可以用更好的方式完成。

在這方面尋求幫助。

解決方案 1

您的方向是正確的,您應該使用getServerSideProps<link>標記中設置所需的字體。 但是你應該先添加rel="preload"屬性來加載 fonts 然后你可以為你的 css 放置鏈接。

<link rel="preload" href="/fonts/theme-font.woff2" as="font" type="font/woff2" ></link>

元素的 rel 屬性的預加載值允許您在 HTML 中聲明獲取請求,指定您的頁面將很快需要的資源,您希望在頁面生命周期的早期開始加載,在瀏覽器的主要渲染機制啟動之前。

然后為避免閃爍使用font-display屬性的fallback值,它將隱藏文本約 100 毫秒,如果字體尚未下載,將使用回退文本。

@font-face {
  font-family: "Cal Sans";
  font-display: fallback;
  src: url("CalSans-SemiBold.woff2") format("woff2"),
}

您可以將以下值用於不同策略的font-display

  • auto (默認):允許瀏覽器使用其默認加載方法,這通常類似於塊值。
  • block :指示瀏覽器暫時隱藏文本,直到字體完全下載。 更准確地說,瀏覽器使用不可見的占位符繪制文本,然后在加載后立即將其與自定義字體交換。 這也稱為“不可見文本的閃光”或 FOIT。
  • swap :指示瀏覽器使用后備字體顯示文本,直到自定義字體完全下載。 這也稱為“無樣式文本的閃現”或 FOUT。
  • fallback :作為 auto 和 swap 值之間的折衷。 瀏覽器將隱藏文本約 100 毫秒,如果尚未下載字體,將使用后備文本。 它會在下載后切換到新字體,但只會在很短的切換時間內(大概 3 秒)。
  • optional :與回退一樣,此值告訴瀏覽器最初隱藏文本,然后轉換為回退字體,直到可以使用自定義字體。 但是,此值還允許瀏覽器確定自定義字體是否被使用,使用用戶的連接速度作為決定因素,較慢的連接不太可能接收自定義字體。

方案二

作為替代解決方案,您可以將 fonts 嵌入到 css styles 中:

@font-face {
  font-family: "Cal Sans";
  font-display: fallback;
  src: url(PASTE-BASE64-HERE) format('woff2')
}

檢查此演示作為參考,您可以在那里將 woff2 文件轉換為 base64。

兩個想法:

  1. Fontsources 維護着 Google Fonts 作為 NPM 包的完整存儲庫。 只要安裝了相應的 NPM package 就應該可以動態導入你需要的字體。

https://fontsource.org/docs/getting-started

那么只要知道字體是什么,就應該可以動態導入對應的字體了。 我不知道字體會不會在這里閃爍。

await import `@fontsource/${fontName}`;

這假設您知道fontName將是一個有效的 Google 字體名稱,或者您需要try / catch它。


  1. 另一種方法是在服務器上獲取字體信息(如果您使用的是 Next.js,則可以使用getServerSideProps執行此操作,然后使用自定義<Head>元素指向 fonts.googleapis.com 上相應的fonts.googleapis.com文件並將其加載為在其他內容呈現之前<Head>的一部分(或者至少在呈現過程中)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM