next.js์ google font์, tailwind๋ฅผ ์ฌ์ฉํด์
ํ๋ก์ ํธ์ ์ ์ฉํ ๋ด์ฉ์ ๊ฐ๋จํ๊ฒ ์ ๋ฆฌํด ๋ณด์์ต๋๋ค.next.js google font
https://nextjs.org/docs/basic-features/font-optimization#google-fonts
// pages/_app.js
import { Inter } from 'next/font/google' // ํด๋น ํฐํธ์ ํจ์๋ฅผ ์ฌ์ฉํฉ๋๋ค.
const inter = Inter({ subsets: ['latin'] }) // ๋ณ์๋ฅผ ์ ์ธํ๊ณ , ํจ์์ ์ธ์๋ก ์คํ์ผ์ ์ง์ ํฉ๋๋ค.
export default function MyApp({ Component, pageProps }) {
return (
<main className={inter.className}> {/* className์ ํตํด ํ์ ์ปดํฌ๋ํธ์์ ํฐํธ๋ฅผ ์ฌ์ฉํฉ๋๋ค. */}
<Component {...pageProps} />
</main>
)
}
๊ตฌ๊ธ ํฐํธ https://nextjs.org/docs/basic-features/font-optimization#google-fonts
ํจ์ ์ธ์ https://nextjs.org/docs/api-reference/next/font#font-function-arguments
๐ { ํ๋ก์ ํธ์ ๊ธฐ๋ณธ ํฐํธ๋ก
๋ ธํ ์ฐ์ค
๋ฅผ ์ฌ์ฉํ๊ณ , ์ผ๋ถ ํฐํธ์roboto
๋ฅผ ์ฐ๊ณ ์ถ์ด์. )
import { Roboto, Noto_Sans_KR } from "next/font/google"; // Roboto์ ํ๊ธ NotoSans๋ฅผ ์ฌ์ฉํฉ๋๋ค.
const notoSansKr = Noto_Sans_KR({
// preload: true, ๊ธฐ๋ณธ๊ฐ
subsets: ["latin"], // ๋๋ preload: false
weight: ["100", "400", "700", "900"], // ๊ฐ๋ณ ํฐํธ๊ฐ ์๋ ๊ฒฝ์ฐ, ์ฌ์ฉํ fontWeight ๋ฐฐ์ด
});
const roboto = Roboto({
subsets: ["latin"], // preload์ ์ฌ์ฉํ subsets์
๋๋ค.
weight: ["100", "400", "700"],
variable: "--roboto", // CSS ๋ณ์ ๋ฐฉ์์ผ๋ก ์คํ์ผ์ ์ง์ ํ ๊ฒฝ์ฐ์ ์ฌ์ฉํฉ๋๋ค.
});
Noto_Sans_KR๋ฅผ ๋ถ๋ฌ์์ ์์ฑํ๋ค ๋ณด๋ subsets: []
์์ ์์ฑํ ๊ฐ์ korean์ ์์ต๋๋ค.
ํ๊ตญ์ด๋ฅผ ์ฐ๊ณ ์ถ์๋ฐ subsets์๋ latin, greek, vietnamese ๋ฐ์ ์์ผ๋ฉด์, subsets ์ธ์๋ฅผ ์ญ์ ํ๋ฉด ์๋ฌ๊ฐ ์๊น๋๋ค.
์ด๋ป๊ฒ ํ๋ผ๋ ๊ฑธ๊น์? ๋นํฉํ์ง ์๊ณ ์๋ฌ ๋ฉ์์ง์ ๋งํฌ๋ฅผ ๋๋ฌ๋ด
๋๋ค.
https://nextjs.org/docs/messages/google-fonts-missing-subsets
next.js์ ๊ตฌ๊ธ ํฐํธ๋ ์๋์ผ๋ก ํฐํธ๋ฅผ preloadํฉ๋๋ค. ์ด๋ฅผ ์ํด ์ง์ ํ๋ ๊ฐ์ดย
subset (ํ์ ์งํฉ)ย ์ ๋๋ค.ย preload๋ฅผ ์ฌ์ฉํ์ฌ ๊ธ๊ผด ํ์ผ์ ํฌ๊ธฐ๊ฐ ์ค์ด๋ค๊ณ
์ฑ๋ฅ์ด ํฅ์๋ฉ๋๋ค.ย ๋ฏธ๋ฆฌ ๋ก๋ํ ํ์ ์งํฉ์ ์ ์ํด์ผ ํฉ๋๋ค.
ํ์ ์งํฉ์ ์ง์ ํ์ง ์์ผ๋ฉดย preload ๊ฒฝ๊ณ ๊ฐ ๋ฐ์ํฉ๋๋ค.
vercel์ ์ ์ ๋ฆฌ๋ ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํ์๋ฉด, subsets
์ preload
ํ ํ์ ์งํฉ์ ์ง์ ํฉ๋๋ค. ๊ธ๊ผด ํ์ผ์ ์ค์ด๊ณ ์ฑ๋ฅ์ด ํฅ์์ํต๋๋ค. ๊ทธ๋ฆฌ๊ณ preload์ ๊ธฐ๋ณธ๊ฐ์ true์ด๊ธฐ ๋๋ฌธ์, subsets๊ฐ ์์ผ๋ฉด preloadํ ๋์์ ์ ์ ์์ผ๋ฏ๋ก ๊ฒฝ๊ณ ๊ฐ ๋ฐ์ํฉ๋๋ค.
๊ทธ๋ฐ๋ฐ ์์ฝ์ง๋ง subsets์์ ํ๊ธ์ ์ ๊ณตํ์ง ์๋ค์.
๊ณต์๋ฌธ์ ํ๋จ์ Noto_Sans_JP ์์์ ๊ฐ์ด, preload๋ฅผ false๋ก ์ง์ ํด๋ ๋ฉ๋๋ค. ํ์ง๋ง ์๋ฌธ์๋ ๋
ธํ ์ฐ์ค ํฐํธ๋ฅผ ์ฌ์ฉํ ๊ณํ์ด ์๋ค๋ฉด preload๋ฅผ ์ํ ์ด์ ๊ฐ ์์๊น์? ๋ฐ๋๋ก presets์ ์กด์ฌํ์ง ์๋, ์๋ฅผ ๋ค์ด ์์ด๊ฐ ์๋ ๋ค๊ตญ์ด
์๋ง ํด๋น ํฐํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ผ๋ฉด preload๋ฅผ false๋ก ์ฌ์ฉํ ์ ์๊ฒ ์ต๋๋ค.
const notoSansJp = Noto_Sans_JP({
// preload: true, ๊ธฐ๋ณธ๊ฐ
preload: false,
weight: ["100", "400", "700"]
});
ํ๋ก์ ํธ์ ๋ค์๊ณผ ๊ฐ์ด ์ ์ฉํ์์ต๋๋ค.
export const cls = (...classnames: string[]) => {
return classnames.join(" ");
};
<main className={cls(notoSansKr.className, roboto.variable)}>
<DefaultLayout>
<Component {...pageProps} />
</DefaultLayout>
</main>
tailwind.config
์์ theme extend์ fontfamily
๋ฅผ ์ค์ ํฉ๋๋ค./** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {
fontFamily: { // ํฐํธํจ๋ฐ๋ฆฌ
roboto: ["var(--roboto)"], // ๋ค์๊ณผ ๊ฐ์ด ๋ฐฐ์ด ์์ string์ผ๋ก ์์ฑํฉ๋๋ค.
},
},
},
variants: {
extend: {},
},
plugins: [require("tailwind-scrollbar-hide")],
};
export default function MainComponent() {
return (
<div>
๋
ธํ ์ฐ์ค ๊ธ์จ์
๋๋ค.
<p className="font-roboto">123 $&@ roboto ROBOTO ๋ก๋ณดํ ์
๋๋ค.</p>
</div>
);
}