İçeriğe geç
nextjs

Next.js Font Optimizasyonu: next/font ile Performans

Tarık Tunç
Next.js Font Optimizasyonu: next/font ile Performans

Next.js Font Optimizasyonu: next/font ile Performans

Web fontları, tasarımın ayrılmaz bir parçasıdır ancak yanlış yüklendiğinde layout shift (CLS) ve yavaş sayfa yüklemelerine neden olur. Next.js'in next/font modülü, fontları build zamanında optimize ederek self-host eder ve sıfır layout shift garantisi sunar. Bu rehberde Google Fonts ve özel fontların nasıl optimize edileceğini adım adım göstereceğiz.

Google Fonts ile Başlangıç

next/font/google modülü, Google Fonts'un tüm font ailesini destekler ve fontları otomatik olarak self-host eder:

// app/layout.tsx
import { Inter } from 'next/font/google';

const inter = Inter({
  subsets: ['latin'],
  display: 'swap',
});

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="tr" className={inter.className}>
      <body>{children}</body>
    </html>
  );
}

Birden Fazla Font Kullanma

// lib/fonts.ts
import { Inter, Roboto_Mono, Playfair_Display } from 'next/font/google';

export const inter = Inter({
  subsets: ['latin'],
  variable: '--font-inter',
  display: 'swap',
});

export const robotoMono = Roboto_Mono({
  subsets: ['latin'],
  variable: '--font-roboto-mono',
  display: 'swap',
});

export const playfair = Playfair_Display({
  subsets: ['latin'],
  variable: '--font-playfair',
  display: 'swap',
});

// app/layout.tsx
import { inter, robotoMono, playfair } from '@/lib/fonts';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html
      lang="tr"
      className={`${inter.variable} ${robotoMono.variable} ${playfair.variable}`}
    >
      <body className="font-sans">{children}</body>
    </html>
  );
}

CSS Variable ile Tailwind Entegrasyonu

// tailwind.config.ts
import type { Config } from 'tailwindcss';

const config: Config = {
  content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'],
  theme: {
    extend: {
      fontFamily: {
        sans: ['var(--font-inter)', 'system-ui', 'sans-serif'],
        mono: ['var(--font-roboto-mono)', 'monospace'],
        serif: ['var(--font-playfair)', 'Georgia', 'serif'],
      },
    },
  },
};

export default config;

// Kullanım
// <h1 className="font-serif text-4xl">Başlık</h1>
// <p className="font-sans">Paragraf</p>
// <code className="font-mono">Kod</code>
İpucu: CSS variable yaklaşımı, fontları Tailwind CSS ile entegre etmenin en temiz yoludur. variable prop'u ile CSS custom property tanımlayın, ardından Tailwind config'de kullanın.

Font Ağırlıkları ve Stilleri

import { Noto_Sans } from 'next/font/google';

// Belirli ağırlıklar (variable font değilse)
const notoSans = Noto_Sans({
  subsets: ['latin'],
  weight: ['400', '500', '600', '700'],
  style: ['normal', 'italic'],
  display: 'swap',
});

// Variable font — tüm ağırlıklar otomatik
import { Inter } from 'next/font/google';

const inter = Inter({
  subsets: ['latin'],
  // weight belirtmeye gerek yok — variable font
  display: 'swap',
});

Özel (Local) Font Kullanma

Kendi font dosyalarınızı next/font/local ile optimize edebilirsiniz:

// lib/fonts.ts
import localFont from 'next/font/local';

export const myFont = localFont({
  src: [
    {
      path: '../public/fonts/MyFont-Regular.woff2',
      weight: '400',
      style: 'normal',
    },
    {
      path: '../public/fonts/MyFont-Medium.woff2',
      weight: '500',
      style: 'normal',
    },
    {
      path: '../public/fonts/MyFont-Bold.woff2',
      weight: '700',
      style: 'normal',
    },
    {
      path: '../public/fonts/MyFont-Italic.woff2',
      weight: '400',
      style: 'italic',
    },
  ],
  variable: '--font-custom',
  display: 'swap',
  fallback: ['system-ui', 'sans-serif'],
});

// Variable font dosyası
export const geist = localFont({
  src: '../public/fonts/GeistVF.woff2',
  variable: '--font-geist',
  display: 'swap',
});
Uyarı: Font dosyaları WOFF2 formatında olmalıdır. WOFF2, en iyi sıkıştırma oranını sunar ve modern tüm tarayıcılar tarafından desteklenir.

Font Display Stratejileri

Değer Davranış Kullanım
swap Fallback font gösterilir, font yüklenince değişir Çoğu durumda önerilir
block Kısa süre metin görünmez, sonra font ile gösterilir Icon fontları
fallback Çok kısa bekleme, sonra fallback kalır Performans öncelikli
optional Font cache'te varsa kullanılır, yoksa fallback En az layout shift
auto Tarayıcı varsayılanı Önerilmez

Subset ve Preload

import { Noto_Sans } from 'next/font/google';

const notoSans = Noto_Sans({
  subsets: ['latin', 'latin-ext'], // Türkçe karakterler için latin-ext
  display: 'swap',
  preload: true, // Varsayılan: true
  adjustFontFallback: true, // Fallback font metriklerini ayarla
});
Bilgi: Türkçe karakterler (ç, ğ, ı, ö, ş, ü) için latin-ext subset'ini eklemeyi unutmayın. Sadece latin subset'i bu karakterleri içermeyebilir.

Sayfa Bazlı Font

// app/blog/layout.tsx
import { Merriweather } from 'next/font/google';

const merriweather = Merriweather({
  subsets: ['latin'],
  weight: ['400', '700'],
  display: 'swap',
});

export default function BlogLayout({ children }: { children: React.ReactNode }) {
  return (
    <div className={merriweather.className}>
      {children}
    </div>
  );
}

// Sadece blog sayfaları Merriweather kullanır
// Diğer sayfalar root layout'taki fontu kullanır

next/font Nasıl Çalışır?

  • Build zamanında font dosyaları indirilir ve self-host edilir
  • Google'a runtime'da istek gönderilmez (gizlilik avantajı)
  • size-adjust CSS özelliği ile CLS sıfırlanır
  • Font dosyaları _next/static altında serve edilir
  • Preload link etiketleri otomatik eklenir

Sonuç

Next.js next/font modülü, font optimizasyonunu tamamen otomatize eder. Google Fonts'u self-host ederek gizliliği korur, layout shift'i ortadan kaldırır ve performansı artırır. CSS variable entegrasyonu ile Tailwind CSS ve diğer styling çözümleriyle kusursuz çalışır. Fontlarınızı next/font ile yönetmek, Core Web Vitals'da somut iyileşmeler sağlayacaktır.

Kaynaklar

İlgili Yazılar