Next.js’e Hızlı Giriş Rehberi — 2
Bir önceki yazımızda Next.js üzerine kavramsal konularda giriş bilgiler aktarmıştık. Şimdi hızlı bir şekilde proje oluşturmak ve geliştirme adımlarına nasıl giriş sağlarız bunu sorgulayacağız. Ayrıca burada aktardığım bilgileri örnekleyen bir uygulamayı da yazının sonunda sizlerle paylaşmış olacağım.
İlk yazımıza aşağıdaki bağlantı ile ulaşabilirsiniz.
‘Boilerplate code’:Bilgisayar programlamasında,çok az varyasyonla veya hiç değişiklik göstermeden birden çok yerde tekrarlanan kod bölümleri. Ayrıntılı olarak kabul edilen dilleri kullanırken, programcının yalnızca küçük işlevleri yerine getirmek için çok sayıda kod yazması gerekir.Bunu azaltmak için kullanılır.
- ‘create-next-app’ “boilerplate” yapısı ile proje kurulumu.
npx create-next-app
# or
yarn create next-app
Bir paket yöneticisi kullanarak standart proje gerekliliklerini otomatik olarak yükleyebilirsiniz. ‘react’,’react-dom’ ve ’next’ yapılarını oluşturarak projenizi başlamak için hazır hale getirir. Bunları ayrıca tekil olarak da yükleyebilirizsiniz.
2. “pages” dizini altında rota indisleme ve dinamik rotalama.
Projeniz oluştuktan sonra “pages” dizini altında uygulama altında bulunacak sayfalarınızı bu yapıya uygun olarak ve Next.js tarafından yerleşik olarak sunulan “Link” etikenini uzantı belirterek yönlendirebilirsiniz. Ayrıca “[parametre]” gösterimi ile dinamik olarak rota oluşturma yeteneği kazanabilirsiniz.
3. Ön-işlemenin(pre-rendering) iki şekli: “Static Generation” ya da “Server-side Rendering”.
Static Generation: HTML yapıları inşa zamanında(build time) oluşturulur. Ve her istek yapıldığında tekrar tekrar kullanılır. Site hazır olarak beklediği için oldukça hızlıdır ve bu nedenle bu yapının kullanılması önerilir.
** getStaticProps( )
// Bu fonksiyon inşa zamanında(build time) çağrılır.
export async function getStaticProps() {
// Burada dış bir API uç noktası çağır.
const res = await fetch('https://.../podcasts')
const posts = await res.json()
// { props: { podcasts } }, ilgili bileşende inşa zamanında
// "props" olarak atanır.
return {
props: {
podcasts,
},
}
}
Burada yapılan dış API çağrısı ile birlikte inşa zamanında veriler statik olarak HTML yapılarına aktarıldı ve ihtiyaç duyulduğunda hızlı bir şekilde kullanılır hale getirildi.
**getStaticPaths( )
// İnşa zamanında bu fonksiyon çağrılır.
export async function getStaticPaths() {
// Dış kaynaktan yapılan API çağrısı ile podcasts verisi getirilir.
const res = await fetch('https://.../podcasts')
const posts = await res.json()//"Podcasts"lere bağlı olarak ön-işlemden geçirilerecek yollar(paths) oluşturulur.
const paths = podcasts.map((podcast) => `/podcasts/${podcast.id}`)
//Yalnızca bu yollar inşa zamanında ön işlemeden geçirilir.
// { fallback: false } ön işlemeden geçirilmemiş yollar için 404 hatası oluşturur.
return { paths, fallback: false }
}
Nasıl inşa zamanında statik oluşturma için verileri ön-işlemeden geçirmemiz gerekliyse yolların(paths) da ön işlemeden geçirilmesi gerekmektedir. Bu sayede hangi yolların hangi verileri barındırdığını önceden belirlemiş oluyoruz. Bu nedenle hem hızlı hem de performanslı bir yapı oluşturuyoruz.
Server-side Rendering: HTML yapıları her istek yapıldığında oluşturulur ve kullanıcıya sunulur. Bu nedenle statik yapıya göre site oluşumu daha fazla zaman alabilir.
**getServerSideProps( )
// Her çağrı yapıldığında bu fonksiyon çağırılır.
export async function getServerSideProps() {
// Dış API kaynağından verileri topla.
const res = await fetch(`https://.../data`)
const data = await res.json()
// "props" olarak bu verileri ilgili bileşene geçir.
return { props: { data } }
}
Her çağrı yapıldığında istenen veriler sunucu tarafında çağrılarak oluşturulur. Statik oluşturmadan farklı olarak inşa zamanında oluşturulmaz her çağrıda istenilen HTML yapısı oluşturulur.
Bu iki ön-işleme fonsksiyonu ile birlikte hibrid olarak “kullanıcı tarafı işleme(client-side rendering)” yöntemi de uygulanabilir.
4. “params” özelliği ile dinamik rota uzantısına ulaşma.
params
dinamik rotalar kullanan sayfalar için rota parametreleri içerir. Örneğin, sayfa ismi[id].js
olan yapılar içinparams
bu şekilde{ id: ... }
obje oluşturur. Bu sayede sunucu tarafı çağrı işlemlerinde bu parametrelere bu yolla erişim mümkün kılınır.
5. Komponent seviyesi CSS ekleme.
Next.js, “CSS Modules” yapılarını [name].module.css
şeklinde dosya isimlendirme sağlayarak kullanımını destekler.
Bu sayede farklı bileşenlerde ayrı CSS modülleri oluşturarak aynı “className” i ayrı bileşenlerde çakışma yaratmayacak biçimde kullanmayı mümkün kılar.
6. “Image” bileşeni optimizasyonu.
Next.js yerleşik olarak sağladığı “Image” bileşini ile geleneksel yapılara göre oldukça gelişmiş bir media yükleme deneyimi sunuyor.
// "Image" bileşenini dahil ediyoruz.
import Image from 'next/image'
function Home() {
return (
<>
<h1>My Homepage</h1>
<Image
src="/me.png"
alt="Picture of the author"
width={500}
height={500}
/>
<p>Welcome to my homepage!</p>
</>
)
}
export default Home
- “public” dizini altına yerleştirilen “image”lar kendi isimleri ile “src” içinde uzantılanarak kullanıma sunulurlar.
- Dış kaynaktan “image” sağlanırken veri “URL”nin kötüye kullanılmaması adına alan adları klasör içerisinde belirtilmek zorundadır.
module.exports = {
images: {
domains: ['example.com'],//Alan adı burada belirtilir.
},
}
7.Ortam değişkenleri.
Next.js , .env.local
den process.env
‘e aktarılan yerleşik ortam değişkenleri desteğine sahiptir.
.env.local klasör örneğiDB_HOST=localhost
DB_USER=myuser
DB_PASS=mypassword
Bu klasördeki ortam değişkenlerini sayfalar içinde aşağıdaki gibi kullanırız.
// pages/index.js
export async function getStaticProps() {
const db = await myDB.connect({
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASS,
})
// ...
}
8.Uygulamanın dağıtıma sunulması.
Next.js çerçevesinin üreticisi “Vercel”, dağıtım(deployment) süreçleri için işlemleri kolaylaştıracak bir kullanım sunmaktadır.
9. “Head” etiketi kullanımı.
SEO amaçlı anahtar sözcükleri barındırmak ve ayrıca başka amaçlar için Head etiketleri dilenen bileşen içine dahil edilebilir.
import Head from 'next/head'
function IndexPage() {
return (
<div>
<Head>
<title>My page title</title>
<meta property="og:title" content="My page title" key="title" />
</Head>
<Head>
<meta property="og:title" content="My new title" key="title" />
</Head>
<p>Hello world!</p>
</div>
)
}
export default IndexPage
“FRESH PODCASTS” UYGULAMASI
Yukarıda belirtilen özellikler kullanılarak Next.js ile bir podcast listeleme uygulaması oluşturuldu. Aylık 2500 istek limiti bulunan Listennotes API kullanıldı. Bu uygulama aşağıdaki özellikleri barındırır.
- Arama ve filtreleme
Podcastler anahtar kelimeler ile aranabilir ve türe göre en iyi podcastler filtrelenir.
- Yatay Kaydırma
Ufki düzlemde bileşenler kaydırılır. (“useRef()” ile DOM işlemleri bütünleşik kullanıldı.)
- Dinamik rotalama
Podcastler tekil olarak kendi “id” uzantısı ile görüntülendi.
- Statik Oluşturma-Kullanıcı tarafı işleme
Türe göre en iyi podcastler inşaa zamanında statik olarak oluşturuldu. Arama yapıldığında kullanıcı tarafında aranan “anahtar kelime” ile API çağrısı gerçekleştirildi. Yukarıda açıklanan hibrit yapıya uygun olarak bir kullanım söz konusudur.
- Sunucu tarafı işleme
Her bir podcast istek üzerine çağrı yapılarak oluşturuldu.
- “Image” yerleşik bileşeni kullanıldı.
Hem “public” klasöründe hem de dış bir kaynaktan alan adı belirtilerek imaj kullanımı örneklendirilmiştir.
- Sayfalandırma(Pagination)
Çağrılan podcastlerin bölümleri çok olduğundan iki sayfa olacak şekilde sayfalandırılmıştır.
- Ortam değişkenleri
Kullanılan API’ye yönelik bilgiler ortam değişkeni olarak kullanılmıştır.
- Bileşen seviyesi CSS modülü kullanımı
Farklı bileşenlerde aynı “className”ler kullanıldı. Bu isim çakışma kaygısını ortadan kaldırdı.
- “Head” etiketinin dahil edilmesi.
Uygulamanın ismi,logosu ve anahtar kelimeleri vb. istenilen sayfa içerisinde özelleştirilerek kullanılmıştır.
SONUÇ:
Birinci yazıda kavramsallaştırdığımız Next.js yapısını, ikinci yazıda pratik kullanım yönüyle ele almaya çalıştık. Burada amacımız Next.js’e hızlı giriş sağlamak adına bir yapı oluşturmaktı.
Next.js’in dökümanı içerisindeki detaylı bilgilerle kavrayışınızı geliştirebilirsiniz.
“Fresh Podcast” uygulaması Github kaynak kodlarına aşağıdaki bağlantı ile erişebilirsiniz.