Next.js Projesine Layout Desteği Ekleme

Ozan Bolel
Kodcular
Published in
3 min readFeb 8, 2020

Layout kelimesi genellikle sayfa yerleşimiyle alakalı olsa da kendisini bu yazıda ele almamın sebebi biraz farklı. Uygulama menüsünü sayfanın -örneğin- soluna sabitliyor olmanız, kullanıcı uygulama içerisindeki bir başka sayfaya yönlendirildiğinde menünün bundan etkilenmeyeceği, ve unmount olmayacağı anlamına gelmez. Kaldı ki, SPA (Single Page Application) uygulamalarda menünün sabit kalması ve tekrar tekrar mount-unmount olmaması beklenen deneyimdir. CRA (Create React App) üzerinde bunu sağlamak kolayken, Gatsby ve Next.js üzerinde sayfa yönlendirmesi code splitting nedeniyle farklı olduğundan Layout sürekliliğini sağlamak zor olabiliyor. Bu yazıda, Next.js ile oluşturulmuş bir projede hiçbir library kullanmadan Layout’un içerisindeki komponentlerin sayfa geçişlerinde sürekliliğini sağlayacak ve tekrar tekrar mount-unmount olmalarını önyeceğiz.

Öncelikle, eğer projede yoksa, bir “_app.js” dosyasını ”/pages” altına eklememiz gerekmekte. Bu sayede uygulamanın initialize sürecine müdahale edebilecek, ve mevcut sayfayı oluşturacağımız Layout içerisine alabileceğiz. Bir “_app.js” dosyası en basit haliyle şu şekilde gözükmekte:

export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}

Uygulamaya Layout desteğini ekleyeceğimiz yer de tam olarak burası. “/pages” altında oluşturduğumuz bu “_app.js” dosyasını şu şekilde değiştirelim:

import React from "react";export default function MyApp({ Component, pageProps }) {
const Layout = Component.Layout ?
Component.Layout : React.Fragment;
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}

Buradaki Component, bulunduğunuz URL path için dönen komponenttir. Örneğin; eğer anasayfadaysak “/pages/index.js” dosyasından default olarak export edilmiş komponent burada dönecektir. Dolayısıyla oluşturacağımız Layout komponentini de doğrudan sayfalara ekleyeceğiz. Buna birazdan döneriz. Şimdi bir Layout oluşturalım. Ekleyeceğimiz dosyayı projeyi derli toplu tutmak adına “/layouts/MyLayout.js” altında oluşturabiliriz:

import React, { useState } from "react";export default function MyLayout({ children }) {
const [counter, setCounter] = useState(0);

return (
<>
<p>
<button onClick={() => setCounter(counter + 1)}>
{counter} Defa Tıklandı
</button>
</p>
{children}
</>
)
}

Eğer “pages/_app.js” içerisinde yaptığımız kara büyüyle Layout sürekliliğini sağlayabildiysek, üzerinde sayaç bulunan butonun gösterdiği sayı, sayfa geçişlerinde sıfırlanmamalı. Öyleyse “pages” klasörü altında iki örnek sayfa oluşturalım. İlk olarak “/pages/profile.js”:

import Link from "next/link";export default function Profile() {
return (
<div>
<p>Bu yol profil sayfasına çıkar.</p>
<p>
<Link href="/account">
<a>Git: Account</a>
</Link>
</p>
</div>
);
}

Peki az önce oluşturduğumuz Layout’u bu sayfaya nasıl ekleyeceğiz? Önceden de bahsettiğim gibi; doğrudan…

import Link from "next/link";
import MyLayout from "../layouts/MyLayout";
export default function Profile() {
return (
<div>
<p>Bu yol profil sayfasına çıkar.</p>
<p>
<Link href="/account">
<a>Git: Account</a>
</Link>
</p>
</div>
);
}
Profile.Layout = MyLayout;

Yeterince karmaşık olmadığının farkındayım. İkinci örnek sayfayı da “/pages/account.js” altına ekleyerek devam edelim:

import MyLayout from "../layouts/MyLayout";export default function Account() {
return (
<div>
<p>Bu yol hesap ayarları sayfasına çıkar.</p>
<p>
<Link href="/profile">
<a>Git: Profile</a>
</Link>
</p>
</div>
);
}
Account.Layout = MyLayout;

Tüm hazırlıklar tamamlandı. Şimdi tarayıcıda Profile sayfasını açıyorum ve oluşturduğumuz Layout’ta bulunan sayaçlı butona 4 defa tıklıyorum. Ardından Account sayfasına gidiyorum, ve sonuç:

Görüldüğü gibi bu iki sayfa aynı Layout’u paylaştığından sayaç sıfırlanmadı. Eğer bambaşka bir sayfaya gidersem MyLayout unmount olacak ve sayaç sıfırlanacaktır.

Böylelikle, Layout’ları Tab Bar vb. navigasyon elementlerini sayfalar arasında sürekli kılmak için kullanabilirsiniz. Ya da mutfağa gidip çilekli pasta da yapabilirsiniz, bilmiyorum, ben yazının sonuna geldim. Umarım faydalı olmuştur, beni şuradan takip edebilirsiniz:

twitter.com/oznbll

--

--

Ozan Bolel
Kodcular
Writer for

Self-taught frontend developer. Music lover.