Foruma hoş geldin 👋, Ziyaretçi

Forum içeriğine ve tüm hizmetlerimize erişim sağlamak için foruma kayıt olmalı ya da giriş yapmalısınız. Foruma üye olmak tamamen ücretsizdir.

Next.js'te CSS-in-JS Kütüphaneleri (Styled-components, Emotion) ile SSR'da Nasıl Sorunsuz Stil Alırım?

devster

Üye
Katılım
14 Mart 2026
Mesajlar
30
Merhaba arkadaşlar, bugün başımı çok ağrıtan bir sorunu ve onun en temiz çözümünü paylaşacağım. Next.js ile server-side rendering (SSR) yaparken, styled-components veya Emotion gibi CSS-in-JS kütüphaneleri kullandığımızda, ilk render'da stil kayboluyor ve sayfa bir anlığına çıplak (FOUC - Flash of Unstyled Content) görünüyordu. Bu hatayı ilk gördüğümde, "Ben bunu production'a nasıl çıkaracağım?" diye kafayı yemiştim. Neyse ki, Next.js'in kendi dokümantasyonunda ve community'de bu işin püf noktaları var.

🔥 Karşılaştığım Sorun ve Nedenleri
Sorunun kökü şu: Server'da React bileşenlerini render edip HTML olarak istemciye gönderiyoruz. Ancak, styled-components'in stilleri, React bileşeni render edilirken oluşuyor. Eğer server'da oluşturulan bu stilleri HTML dokümanına eklemezsek, tarayıcı önce stil[siz] HTML'i görüyor, sonra JavaScript yüklenip çalıştığında stiller enjekte ediliyor. Bu da o çirkin "flash" efektine neden oluyor.

⚙️ Çözüm: Stilleri Server'dan Göndermek
Çözüm, server tarafında oluşturulan stilleri toplayıp, HTML çıktısının <head> kısmına yerleştirmek. Next.js'te bunun için _document.js (veya _document.tsx) dosyasını özelleştirmemiz gerekiyor. Bu dosya, sunucu tarafında ve istemci tarafında bir kez render edilen sayfa şablonumuz.

İşte benim kullandığım en temiz ve güvenilir yöntem:

JavaScript:
// pages/_document.js
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'
// Emotion için: import { extractCritical } from '@emotion/server'

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const sheet = new ServerStyleSheet()
    const originalRenderPage = ctx.renderPage

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        })

      const initialProps = await Document.getInitialProps(ctx)

      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      }
    } finally {
      sheet.seal()
    }
  }
}

Bu kod ne yapıyor? getInitialProps içinde, ServerStyleSheet oluşturuyoruz ve ctx.renderPage metodunu, uygulamamızı (<App />) bu style sheet'in içine sarmalayacak şekilde override ediyoruz. Bu sayfa render edilirken oluşan tüm stiller bu sheet'te toplanıyor. Sonrasında, dökümanın ilk props'larına, bu sheet'ten gelen style elementlerini ekliyoruz. Next.js bunu otomatik olarak <head> içine yerleştiriyor.

💡 Emotion Kullanıyorsanız
Eğer Emotion kullanıyorsanız, yaklaşım çok benzer. Sadece import ve metod isimleri değişiyor. Aşağıdaki gibi bir yapı kurabilirsiniz:

JavaScript:
// pages/_document.js (Emotion örneği)
import Document from 'next/document'
import { extractCritical } from '@emotion/server'

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    const { css, ids } = extractCritical(initialProps.html)
    return {
      ...initialProps,
      styles: (
        <>
          {initialProps.styles}
          <style
            data-emotion-css={ids.join(' ')}
            dangerouslySetInnerHTML={{ __html: css }}
          />
        </>
      ),
    }
  }
}

✅ Sonuç ve Performans
Bu yöntemi uyguladıktan sonra, sayfalarım artık sunucudan stil[siz] gelmiyor. İlk HTML yüklendiği anda, tüm CSS kuralları da <style> tag'leri içinde hazır oluyor. Bu, kullanıcı deneyimi için çok kritik bir iyileştirme. Ayrıca, Lighthouse skorlarında "First Contentful Paint" gibi metriklerde de olumlu etkisini görebilirsiniz.

Peki ya siz? Next.js ile CSS-in-JS kullanırken bu tarz bir sorunla karşılaştınız mı? styled-components mi yoksa Emotion mu tercih ediyorsunuz? Ya da bu işi halletmek için farklı, daha sade bir yönteminiz var mı? Yorumlarda buluşalım!
 

Tema özelleştirme sistemi

Bu menüden forum temasının bazı alanlarını kendinize özel olarak düzenleye bilirsiniz.

Zevkine göre renk kombinasyonunu belirle

Tam ekran yada dar ekran

Temanızın gövde büyüklüğünü sevkiniz, ihtiyacınıza göre dar yada geniş olarak kulana bilirsiniz.

Geri