├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── 1-react-essentials └── Readme.md ├── 2-routing ├── 1-defining-routes │ └── Readme.md ├── 10-route-handlers │ └── Readme.md ├── 11-middleware │ └── Readme.md ├── 12-project-organization │ └── Readme.md ├── 13-internationalization │ └── Readme.md ├── 2-pages-and-layouts │ └── Readme.md ├── 3-linking-and-navigating │ └── Readme.md ├── 4-route-groups │ └── Readme.md ├── 5-dynamic-routes │ └── Readme.md ├── 6-loading-UI-and-treaming │ └── Readme.md ├── 7-error-handling │ └── Readme.md ├── 8-paralel-routes │ └── Readme.md ├── 9-intercepting-routes │ └── Readme.md └── Readme.md ├── 3-rendering ├── 1-static-and-dynamic-rendering │ └── Readme.md ├── 2-edge-and-nodejs-runtimes │ └── Readme.md └── Readme.md ├── 4-data-fetching ├── 1-fetching │ └── Readme.md ├── 2-caching │ └── Readme.md ├── 3-revalidating │ └── Readme.md ├── 4-server-actions │ └── Readme.md └── Readme.md ├── 5-styling ├── 1-css-modules │ └── Readme.md ├── 2-tailwind-css │ └── Readme.md ├── 3-css-in-js │ └── Readme.md ├── 4-sass │ └── Readme.md └── Readme.md ├── 6-optimizing ├── 1-images │ └── Readme.md ├── 2-fonts │ └── readme.md ├── 3-scripts │ └── Readme.md ├── 4-metadata │ └── Readme.md ├── 5-static-assets │ └── Readme.md ├── 6-lazy-loading │ └── Readme.md ├── 7-analytics │ └── Readme.md ├── 8-open-telemetery │ └── Readme.md ├── 9-instrumentation │ └── Readme.md └── Readme.md ├── 7-configuring ├── 1-typescript │ └── Readme.md ├── 2-eslint │ └── Readme.md ├── 3-enviroment-variables │ └── Readme.md ├── 4-absolute-imports-and-module-path-aliases │ └── Readme.md ├── 5-MDX │ └── Readme.md ├── 6-src-directory │ └── Readme.md ├── 7-draft-mode │ └── Readme.md └── Readme.md ├── 8-deploying ├── 1-static-exports │ └── Readme.md └── Readme.md ├── 9-upgrading ├── 1-codemods │ └── Readme.md ├── 2-app-router-migration │ └── readme.md └── Readme.md ├── CONTRIBUTIONS.md └── README.md /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /2-routing/1-defining-routes/Readme.md: -------------------------------------------------------------------------------- 1 | # Rotaların Tanımlanması 2 | 3 | ## Rotalar Oluşturma 4 | 5 | Next.js, rotaları tanımlamak için **klasörlerin** kullanıldığı dosya sistemi tabanlı bir yönlendirici kullanır. 6 | 7 | Her klasör, bir **URL** segmentiyle eşleşen bir rota segmentini temsil eder. İç içe bir rota oluşturmak için, klasörleri birbirinin içine yerleştirebilirsiniz. 8 | 9 | rotalar oluşturma
10 | 11 | Rota segmentlerini genel erişime açmak için özel bir `page.js` dosyası kullanılır. 12 | 13 | rotalar oluşturma-2
14 | 15 | Bu örnekte, `/dashboard/analytics` URL yolu, karşılık gelen bir `page.js` dosyasına sahip olmadığı için _genel erişime_ açık değildir. Bu klasör bileşenleri, stil sayfalarını, görüntüleri veya diğer ortak dosyaları depolamak için kullanılabilir. 16 | 17 | ## Kullanıcı Arayüzü Oluşturma 18 | 19 | Her bir rota segmenti için kullanıcı arayüzü oluşturmak üzere özel dosya kuralları kullanılır. En yaygın olanları, bir rotaya özgü kullanıcı arayüzünü gösteren sayfalar ve birden fazla rotada paylaşılan kullanıcı arayüzünü gösteren düzenlerdir. 20 | 21 | Örneğin, ilk sayfanızı oluşturmak için `app` dizininin içine bir `page.js` dosyası ekleyin ve bir React bileşenini dışa aktarın: 22 | 23 | ```tsx 24 | export default function Page() { 25 | return

Hello, Next.js!

; 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /2-routing/12-project-organization/Readme.md: -------------------------------------------------------------------------------- 1 | # Proje Organizasyonu ve Dosya Kolokasyonu (Project Organization and File Colocation) 2 | 3 | Yönlendirme klasörü ve dosya kurallarının yanı sıra Next.js, proje dosyalarınızı nasıl düzenlediğiniz ve konumlandırdığınız konusunda görüş bildirmez. 4 | 5 | ## Varsayılan olarak güvenli ortak yerleşim (Safe colocation by default) 6 | 7 | `app` dizininde, iç içe klasör hiyerarşisi rota yapısını tanımlar. 8 | 9 | Her klasör, URL yolunda karşılık gelen bir segmentle eşlenen bir rota segmentini temsil eder. 10 | 11 | Ancak, rota yapısı klasörler aracılığıyla tanımlansa da, bir rota segmentine bir `page.js` veya `route.js` dosyası eklenene kadar bir rota genel olarak erişilebilir değildir. 12 | 13 | proje-organizasyonu
14 | 15 | Ve bir rota genel erişime açık hale getirildiğinde bile, istemciye yalnızca `page.js` veya `route.js` tarafından döndürülen içerik gönderilir. 16 | 17 | proje-organizasyonu-2
18 | 19 | Bu, proje dosyalarının yanlışlıkla yönlendirilebilir olmadan `app` dizinindeki rota segmentlerinin içine güvenli bir şekilde yerleştirilebileceği anlamına gelir. 20 | 21 | proje-organizasyonu-3
22 | 23 | Bilmekte fayda var: 24 | 25 | - Bu, sayfalardaki herhangi bir dosyanın bir rota olarak kabul edildiği `pages` dizininden farklıdır. 26 | - Proje dosyalarınızı `app` dizinine yerleştirebilirsiniz ancak bunu yapmak zorunda değilsiniz. Tercih ederseniz, bunları `app` dizininin dışında tutabilirsiniz. 27 | 28 | ## Proje organizasyon özellikleri (Project organization features) 29 | 30 | Next.js, projenizi düzenlemenize yardımcı olacak çeşitli özellikler sunar. 31 | 32 | ### Özel Klasörler 33 | 34 | Özel klasörler, bir klasörün önüne alt çizgi getirilerek oluşturulabilir: `_folderName` 35 | 36 | Bu, klasörün özel bir uygulama ayrıntısı olduğunu ve yönlendirme sistemi tarafından dikkate alınmaması gerektiğini gösterir, böylece klasör ve tüm alt klasörleri yönlendirme dışında bırakılır. 37 | 38 | proje-organizasyonu-4
39 | 40 | `app` dizinindeki dosyalar varsayılan olarak güvenli bir şekilde ortak konumlandırılabildiğinden, özel klasörler ortak konumlandırma için gerekli değildir. Ancak, şunlar için yararlı olabilirler: 41 | 42 | - UI mantığını yönlendirme mantığından ayırma. 43 | - Dahili dosyaları bir proje ve Next.js ekosistemi genelinde tutarlı bir şekilde düzenleme. 44 | - Kod düzenleyicilerde dosyaları sıralama ve gruplama. 45 | - Gelecekteki Next.js dosya kurallarıyla olası adlandırma çakışmalarını önleme. 46 | 47 | Bilmekte fayda var: 48 | 49 | - Bir çatı kuralı olmamakla birlikte, özel klasörlerin dışındaki dosyaları da aynı alt çizgi kalıbını kullanarak "private" olarak işaretlemeyi düşünebilirsiniz. 50 | - Klasör adının önüne `%5F` (alt çizginin URL ile kodlanmış biçimi) ekleyerek alt çizgi ile başlayan URL segmentleri oluşturabilirsiniz: `%5FfolderName`. 51 | - Özel klasörler kullanmıyorsanız, beklenmedik adlandırma çakışmalarını önlemek için Next.js özel dosya kurallarını bilmek yararlı olacaktır. 52 | 53 | ## Rota Grupları (Route Groups) 54 | 55 | Rota grupları bir klasör parantez içine alınarak oluşturulabilir: `(folderName)` 56 | 57 | Bu, klasörün organizasyonel amaçlar için olduğunu ve rotanın URL yoluna dahil edilmemesi gerektiğini gösterir. 58 | 59 | proje-organizasyonu-5
60 | 61 | Rota grupları şunlar için kullanışlıdır: 62 | 63 | - Rotaları gruplar halinde düzenleme, örneğin site bölümüne, amaca veya ekibe göre. 64 | - Aynı rota segmenti düzeyinde iç içe düzenleri etkinleştirme: 65 | - Birden fazla kök düzen dahil olmak üzere aynı segmentte birden fazla iç içe düzen oluşturma 66 | - Ortak bir segmentteki rotaların alt kümesine bir düzen ekleme 67 | 68 | ## `src` Dizini 69 | 70 | Next.js, uygulama kodunun (`app` dahil) isteğe bağlı bir `src` dizini içinde saklanmasını destekler. Bu, uygulama kodunu çoğunlukla bir projenin kök dizininde bulunan proje yapılandırma dosyalarından ayırır. 71 | 72 | proje-organizasyonu-6
73 | 74 | ## Modül Yolu Takma Adları (Module Path Aliases) 75 | 76 | Next.js, derinlemesine iç içe geçmiş proje dosyalarında içe aktarmaları okumayı ve sürdürmeyi kolaylaştıran Modül Yolu Takma Adlarını destekler. 77 | 78 | ```ts 79 | // önce 80 | import { Button } from "../../../components/button"; 81 | 82 | // sonra 83 | import { Button } from "@/components/button"; 84 | ``` 85 | 86 | ## Proje organizasyon stratejileri (Project organization strategies) 87 | 88 | Bir Next.js projesinde kendi dosyalarınızı ve klasörlerinizi düzenlemek söz konusu olduğunda "doğru" veya "yanlış" bir yol yoktur. 89 | 90 | Aşağıdaki bölüm, yaygın stratejilerin çok üst düzey bir özetini listelemektedir. En basit çıkarım, sizin ve ekibiniz için işe yarayan bir strateji seçmek ve proje genelinde tutarlı olmaktır. 91 | 92 | Bilmekte fayda var: Aşağıdaki örneklerimizde, `components` ve `lib` klasörlerini genelleştirilmiş yer tutucular olarak kullanıyoruz, bunların adlandırılmasının özel bir çerçeve önemi yoktur ve projeleriniz `ui`, `utils`, `hooks`, `styles` vb. gibi başka klasörler kullanabilir. 93 | 94 | ### Proje dosyalarını `app` dışında saklama 95 | 96 | Bu strateji, tüm uygulama kodunu projenizin kök dizinindeki paylaşılan klasörlerde saklar ve `app` dizinini yalnızca yönlendirme amacıyla tutar. 97 | 98 | proje-organizasyonu-7
99 | 100 | ### Proje dosyalarını `app` içindeki üst düzey klasörlerde saklayın 101 | 102 | Bu strateji, tüm uygulama kodunu `app` dizininin kök dizinindeki paylaşılan klasörlerde saklar. 103 | 104 | proje-organizasyonu-8
105 | 106 | ### Proje dosyalarını özellik veya rotaya göre bölme 107 | 108 | Bu strateji, genel olarak paylaşılan uygulama kodunu kök `app` dizininde depolar ve daha spesifik uygulama kodunu bunları kullanan rota segmentlerine böler. 109 | 110 | proje-organizasyonu-9
111 | -------------------------------------------------------------------------------- /2-routing/13-internationalization/Readme.md: -------------------------------------------------------------------------------- 1 | # Uluslararasılaştırma (Internationalization) 2 | 3 | Next.js, birden fazla dili desteklemek için içeriğin yönlendirilmesini ve oluşturulmasını yapılandırmanıza olanak tanır. Sitenizi farklı yerel ayarlara uyumlu hale getirmek, çevrilmiş içerik (yerelleştirme) ve uluslararasılaştırılmış rotaları içerir. 4 | 5 | ## Terminoloji 6 | 7 | - Yerel ayar: Bir dizi dil ve biçimlendirme tercihi için bir tanımlayıcı. Bu genellikle kullanıcının tercih ettiği dili ve muhtemelen coğrafi bölgesini içerir. 8 | - `en-US`: Amerika Birleşik Devletleri'nde konuşulan İngilizce 9 | - `nl-NL`: Hollanda'da konuşulduğu şekliyle Hollandaca 10 | - `nl`: Hollandaca, belirli bir bölge yok 11 | 12 | ## Yönlendirmeye Genel Bakış (Routing Overview) 13 | 14 | Hangi yerel ayarın kullanılacağını seçmek için kullanıcının tarayıcıdaki dil tercihlerini kullanmanız önerilir. Tercih ettiğiniz dili değiştirmek, uygulamanıza gelen `Accept-Language` başlığını değiştirecektir. 15 | 16 | Örneğin, aşağıdaki kütüphaneleri kullanarak, Üstbilgilere, desteklemeyi planladığınız yerel ayarlara ve varsayılan yerel ayara göre hangi yerel ayarı seçeceğinizi belirlemek için gelen bir İsteğe bakabilirsiniz. 17 | 18 | ```ts 19 | import { match } from "@formatjs/intl-localematcher"; 20 | import Negotiator from "negotiator"; 21 | 22 | let headers = { "accept-language": "en-US,en;q=0.5" }; 23 | let languages = new Negotiator({ headers }).languages(); 24 | let locales = ["en-US", "nl-NL", "nl"]; 25 | let defaultLocale = "en-US"; 26 | 27 | match(languages, locales, defaultLocale); // -> 'en-US' 28 | ``` 29 | 30 | Yönlendirme, alt yol (`/fr/products`) veya etki alanı (`my-site.fr/products`) ile uluslararasılaştırılabilir. Bu bilgilerle artık kullanıcıyı Middleware içindeki yerel ayara göre yönlendirebilirsiniz. 31 | 32 | ```ts 33 | import { NextResponse } from 'next/server' 34 | 35 | let locales = ['en-US', 'nl-NL', 'nl'] 36 | 37 | // Yukarıdakine benzer şekilde veya bir kütüphane kullanarak tercih edilen yerel ayarı alın 38 | function getLocale(request) { ... } 39 | 40 | export function middleware(request) { 41 | // Yol adında desteklenen herhangi bir yerel ayar olup olmadığını kontrol edin 42 | const pathname = request.nextUrl.pathname 43 | const pathnameIsMissingLocale = locales.every( 44 | (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}` 45 | ) 46 | 47 | // Yerel ayar yoksa yönlendirme 48 | if (pathnameIsMissingLocale) { 49 | const locale = getLocale(request) 50 | 51 | // örneğin gelen istek /products 52 | // Yeni URL artık /en-US/products şeklindedir 53 | return NextResponse.redirect( 54 | new URL(`/${locale}/${pathname}`, request.url) 55 | ) 56 | } 57 | } 58 | 59 | export const config = { 60 | matcher: [ 61 | // Tüm dahili yolları atla (_next) 62 | '/((?!_next).*)', 63 | // İsteğe bağlı: yalnızca kök (/) URL'de çalıştır 64 | // '/' 65 | ], 66 | } 67 | ``` 68 | 69 | Son olarak, `app/` içindeki tüm özel dosyaların `app/[lang]` altında yuvalandığından emin olun. Bu, Next.js yönlendiricisinin rotadaki farklı yerel ayarları dinamik olarak işlemesini ve `lang` parametresini her düzene ve sayfaya iletmesini sağlar. Örneğin: 70 | 71 | ```ts 72 | // Artık geçerli yerel ayara erişiminiz var 73 | // örneğin /en-US/products -> `lang` "en-US "dir 74 | export default async function Page({ params: { lang } }) { 75 | return ... 76 | } 77 | ``` 78 | 79 | Kök düzen de yeni klasörün içine yerleştirilebilir (örn. `app/[lang]/layout.js`). 80 | 81 | ## Yerelleştirme (Localization) 82 | 83 | Görüntülenen içeriğin kullanıcının tercih ettiği yerel ayara veya yerelleştirmeye göre değiştirilmesi Next.js'ye özgü bir şey değildir. Aşağıda açıklanan modeller herhangi bir web uygulamasında aynı şekilde çalışacaktır. 84 | 85 | Uygulamamız içinde hem İngilizce hem de Hollandaca içeriği desteklemek istediğimizi varsayalım. Bize bazı anahtarlardan yerelleştirilmiş bir dizeye eşleme sağlayan nesneler olan iki farklı "sözlük" tutabiliriz. Örneğin: 86 | 87 | ```ts 88 | { 89 | "products": { 90 | "cart": "Add to Cart" 91 | } 92 | } 93 | ``` 94 | 95 | ```ts 96 | { 97 | "products": { 98 | "cart": "Voeg toe aan winkelwagen" 99 | } 100 | } 101 | ``` 102 | 103 | Ardından, istenen yerel ayar için çevirileri yüklemek üzere bir `getDictionary` işlevi oluşturabiliriz: 104 | 105 | ```ts 106 | import "server-only"; 107 | 108 | const dictionaries = { 109 | en: () => import("./dictionaries/en.json").then((module) => module.default), 110 | nl: () => import("./dictionaries/nl.json").then((module) => module.default), 111 | }; 112 | 113 | export const getDictionary = async (locale) => dictionaries[locale](); 114 | ``` 115 | 116 | O anda seçili olan dil göz önüne alındığında, bir düzen veya sayfanın içindeki sözlüğü getirebiliriz. 117 | 118 | ```ts 119 | import { getDictionary } from "./dictionaries"; 120 | 121 | export default async function Page({ params: { lang } }) { 122 | const dict = await getDictionary(lang); // en 123 | return ; // Add to Cart 124 | } 125 | ``` 126 | 127 | `app/` dizinindeki tüm düzenler ve sayfalar varsayılan olarak Sunucu Bileşenleri olduğundan, çeviri dosyalarının boyutunun istemci tarafı JavaScript paket boyutumuzu etkilemesi konusunda endişelenmemize gerek yoktur. Bu kod yalnızca sunucuda çalışacak ve tarayıcıya yalnızca ortaya çıkan HTML gönderilecektir. 128 | 129 | ## Statik Üretim (Static Generation) 130 | 131 | Belirli bir yerel ayar kümesi için statik rotalar oluşturmak üzere `generateStaticParams`'ı herhangi bir sayfa veya düzenle birlikte kullanabiliriz. Bu, örneğin kök düzeninde global olabilir: 132 | 133 | ```ts 134 | export async function generateStaticParams() { 135 | return [{ lang: "en-US" }, { lang: "de" }]; 136 | } 137 | 138 | export default function Root({ children, params }) { 139 | return ( 140 | 141 | {children} 142 | 143 | ); 144 | } 145 | ``` 146 | -------------------------------------------------------------------------------- /2-routing/2-pages-and-layouts/Readme.md: -------------------------------------------------------------------------------- 1 | # Sayfalar ve Düzenler 2 | 3 | ## Sayfalar 4 | 5 | Sayfa, bir rotaya **özgü** kullanıcı arayüzüdür. Bir `page.js` dosyasından bir bileşeni dışa aktararak sayfaları tanımlayabilirsiniz. Bir rota tanımlamak için iç içe klasörler ve rotayı genel erişime açmak için bir `page.js` dosyası kullanın. 6 | 7 | `app` dizini içine bir `page.js` dosyası ekleyerek ilk sayfanızı oluşturun: 8 | 9 | sayfalar
10 | 11 | ```tsx 12 | // `app/page.tsx` is the UI for the `/` URL 13 | export default function Page() { 14 | return

Hello, Home page!

; 15 | } 16 | ``` 17 | 18 | ```tsx 19 | // `app/dashboard/page.tsx` is the UI for the `/dashboard` URL 20 | export default function Page() { 21 | return

Hello, Dashboard Page!

; 22 | } 23 | ``` 24 | 25 | ## Düzenler 26 | 27 | Düzen, birden fazla sayfa arasında **paylaşılan** kullanıcı arayüzüdür. Gezinme sırasında düzenler durumu korur, etkileşimli kalır ve yeniden oluşturulmaz. Düzenler iç içe de yerleştirilebilir. 28 | 29 | Bir `layout.js` dosyasından bir React bileşenini dışa aktararak `default` olarak bir düzen tanımlayabilirsiniz. Bileşen, render sırasında bir alt düzen (varsa) veya bir alt sayfa ile doldurulacak bir `children` prop kabul etmelidir. 30 | 31 | düzenler
32 | 33 | ```tsx 34 | export default function DashboardLayout({ 35 | children, // will be a page or nested layout 36 | }: { 37 | children: React.ReactNode; 38 | }) { 39 | return ( 40 |
41 | {/* Include shared UI here e.g. a header or sidebar */} 42 | 43 | 44 | {children} 45 |
46 | ); 47 | } 48 | ``` 49 | 50 | Bilmekte fayda var: 51 | 52 | - En üstteki düzen Kök Düzen olarak adlandırılır. Bu **gerekli** düzen, bir uygulamadaki tüm sayfalarda paylaşılır. Kök düzenler `html` ve `body` etiketlerini içermelidir. 53 | - Herhangi bir rota segmenti isteğe bağlı olarak kendi Düzenini tanımlayabilir. Bu düzenler o segmentteki tüm sayfalarda paylaşılır. 54 | - Bir rotadaki düzenler varsayılan olarak **iç içedir**. Her üst düzen, React `children` prop kullanarak altındaki alt düzenleri sarar. 55 | - Paylaşılan düzenlere belirli rota segmentlerini dahil etmek ve hariç tutmak için Rota Gruplarını kullanabilirsiniz. 56 | - Düzenler varsayılan olarak Sunucu Bileşenleridir ancak İstemci Bileşeni olarak ayarlanabilir. 57 | - Düzenler veri getirebilir. 58 | - Bir üst düzen ile onun alt düzenleri arasında veri aktarımı mümkün değildir. Bununla birlikte, aynı verileri bir rotada birden fazla kez getirebilirsiniz ve React, performansı etkilemeden istekleri otomatik olarak çıkaracaktır. 59 | - Düzenlerin geçerli rota segmentlerine erişimi yoktur. Rota segmentlerine erişmek için, bir İstemci - Bileşeninde `useSelectedLayoutSegment` veya `useSelectedLayoutSegments` kullanabilirsiniz. 60 | - Düzenler için `.js`, `.jsx` veya `.tsx` dosya uzantıları kullanılabilir. 61 | - Bir `layout.js` ve `page.js` dosyası aynı klasörde tanımlanabilir. Düzen, sayfayı saracaktır. 62 | 63 | ## Kök Düzeni (Gerekli) 64 | 65 | Kök düzen, `app` dizininin en üst düzeyinde tanımlanır ve tüm rotalar için geçerlidir. Bu düzen, sunucudan döndürülen ilk HTML'yi değiştirmenize olanak tanır. 66 | 67 | ```tsx 68 | export default function RootLayout({ 69 | children, 70 | }: { 71 | children: React.ReactNode; 72 | }) { 73 | return ( 74 | 75 | {children} 76 | 77 | ); 78 | } 79 | ``` 80 | 81 | Bilmekte fayda var: 82 | 83 | - `app` dizini **mutlaka** bir kök düzen içermelidir. 84 | - Next.js `` ve `` etiketlerini otomatik olarak oluşturmadığı için mutlaka kök düzen tanımlamalıdır. 85 | - `` HTML öğelerini yönetmek için yerleşik SEO desteğini kullanabilirsiniz, örneğin, `` öğesi. 86 | - Birden fazla kök düzen oluşturmak için rota gruplarınıkullanabilirsiniz. 87 | - Kök düzen varsayılan olarak bir Sunucu Bileşenidir ve İstemci Bileşeni olarak ayarlanamaz. 88 | 89 | ## İç içe Düzenler 90 | 91 | Bir klasör içinde tanımlanan düzenler (örn. `app/dashboard/layout.js`) belirli rota segmentlerine (örn. `acme.com/dashboard`) uygulanır ve bu segmentler etkin olduğunda oluşturulur. Varsayılan olarak, dosya hiyerarşisindeki mizanpajlar **iç içe geçmiştir**, bu da children düzenlerini `children` prop'ları aracılığıyla sardıkları anlamına gelir. 92 | 93 | <img alt="düzenler" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fnested-layout.png&w=3840&q=75&dpl=dpl_C2pSAYXZnY6DPcYmVfUv54azW3BJ" /><br/> 94 | 95 | ```tsx 96 | export default function DashboardLayout({ 97 | children, 98 | }: { 99 | children: React.ReactNode; 100 | }) { 101 | return <section>{children}</section>; 102 | } 103 | ``` 104 | 105 | Yukarıdaki iki düzeni birleştirecek olursanız, kök düzen (`app/layout.js`) gösterge tablosu düzenini (`app/dashboard/layout.js`) saracak ve bu da `app/dashboard/*` içindeki rota segmentlerini saracaktır. 106 | 107 | İki düzen bu şekilde iç içe geçecektir: 108 | 109 | <img alt="düzenler" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fnested-layouts-ui.png&w=3840&q=75&dpl=dpl_C2pSAYXZnY6DPcYmVfUv54azW3BJ" /><br/> 110 | 111 | Rota Gruplarını, belirli rota segmentlerini paylaşılan düzenlere dahil etmek ve bu düzenlerden çıkarmak için kullanabilirsiniz. 112 | 113 | ## Şablonlar 114 | 115 | Şablonlar, her bir alt düzeni veya sayfayı sarması bakımından düzenlere benzer. Rotalar arasında kalıcı olan ve durumu koruyan düzenlerin aksine, şablonlar gezinme sırasında alt öğelerinin her biri için yeni bir örnek oluşturur. Bu, bir kullanıcı bir şablonu paylaşan rotalar arasında gezindiğinde, bileşenin yeni bir örneğinin monte edildiği, DOM öğelerinin yeniden oluşturulduğu, durumun korunmadığı ve efektlerin yeniden senkronize edildiği anlamına gelir. 116 | 117 | Bu belirli davranışlara ihtiyaç duyduğunuz durumlar olabilir ve şablonlar düzenlerden daha uygun bir seçenek olabilir. Örneğin: 118 | 119 | - CSS veya animasyon kütüphaneleri kullanarak giriş/çıkış animasyonları. 120 | - `useEffect` (örneğin sayfa görüntülemelerini kaydetme) ve `useState` (örneğin sayfa başına geri bildirim formu) kullanan özellikler. 121 | - Varsayılan framework davranışını değiştirmek için. Örneğin, düzenlerin içindeki Askıya Alma Sınırları, geri dönüşü yalnızca Düzen ilk kez yüklendiğinde gösterir ve sayfalar arasında geçiş yaparken göstermez. Şablonlar için, geri dönüş her gezinmede gösterilir. 122 | 123 | Öneri: Şablon kullanmak için özel bir neden yoksa Düzenleri kullanmanız önerilir. 124 | 125 | Bir `template.js` dosyasından varsayılan bir React bileşeni dışa aktarılarak bir şablon tanımlanabilir. Bileşen, iç içe segmentler olacak bir `children` prop kabul etmelidir. 126 | 127 | <img alt="şablonlar" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Ftemplate-special-file.png&w=3840&q=75&dpl=dpl_C2pSAYXZnY6DPcYmVfUv54azW3BJ" /><br/> 128 | 129 | ```tsx 130 | export default function Template({ children }: { children: React.ReactNode }) { 131 | return <div>{children}</div>; 132 | } 133 | ``` 134 | 135 | Bir düzen ve şablona sahip bir rota segmentinin işlenmiş çıktısı bu şekilde olacaktır: 136 | 137 | ```tsx 138 | <Layout> 139 | {/* Note that the template is given a unique key. */} 140 | <Template key={routeParam}>{children}</Template> 141 | </Layout> 142 | ``` 143 | 144 | ## `<head>`'in değiştirilmesi 145 | 146 | `app` dizininde, yerleşik SEO desteğini kullanarak `başlık` ve `meta` gibi `<head>` HTML öğelerini değiştirebilirsiniz. 147 | 148 | Meta veriler, bir `layout.js` veya `page.js` dosyasında bir meta veri nesnesi veya `generateMetadata` işlevi dışa aktarılarak tanımlanabilir. 149 | 150 | ```tsx 151 | import { Metadata } from "next"; 152 | 153 | export const metadata: Metadata = { 154 | title: "Next.js", 155 | }; 156 | 157 | export default function Page() { 158 | return "..."; 159 | } 160 | ``` 161 | 162 | Bilmekte fayda var: Kök düzenlere `<title>` ve `<meta>` gibi `<head>` etiketlerini manuel olarak **eklememelisiniz**. Bunun yerine, `<head>` öğelerini akışa alma ve çoğaltma gibi gelişmiş gereksinimleri otomatik olarak ele alan Metadata API'sini kullanmalısınız. 163 | -------------------------------------------------------------------------------- /2-routing/3-linking-and-navigating/Readme.md: -------------------------------------------------------------------------------- 1 | # Bağlama ve Gezinme (Linking and Navigating) 2 | 3 | Next.js yönlendiricisi, istemci tarafında gezinme ile sunucu merkezli yönlendirme kullanır. Anlık yükleme durumlarını ve eş zamanlı görüntülemeyi destekler. 4 | 5 | Rotalar arasında gezinmenin iki yolu vardır: 6 | 7 | - `<Link>` Bileşeni 8 | - `useRouter` Kancası 9 | 10 | ## `<Link>` Bileşeni 11 | 12 | `<Link>`, rotalar arasında ön getirme ve istemci tarafında gezinme sağlamak için HTML `<a>` öğesini genişleten bir React bileşenidir. Next.js'de rotalar arasında gezinmenin birincil yoludur. 13 | 14 | `<Link>`'i kullanmak için next/link'ten içe aktarın ve bileşene bir href prop iletin: 15 | 16 | ```tsx 17 | import Link from "next/link"; 18 | 19 | export default function Page() { 20 | return <Link href="/dashboard">Dashboard</Link>; 21 | } 22 | ``` 23 | 24 | ## Örnekler 25 | 26 | ### Dinamik Segmentlere Bağlantı 27 | 28 | Dinamik segmentlere bağlantı verirken, bir bağlantı listesi oluşturmak için [şablon değişmezlerini ve enterpolasyonu](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) kullanabilirsiniz. Örneğin, blog gönderilerinin bir listesini oluşturmak için: 29 | 30 | ```tsx 31 | import Link from "next/link"; 32 | 33 | export default function PostList({ posts }) { 34 | return ( 35 | <ul> 36 | {posts.map((post) => ( 37 | <li key={post.id}> 38 | <Link href={`/blog/${post.slug}`}>{post.title}</Link> 39 | </li> 40 | ))} 41 | </ul> 42 | ); 43 | } 44 | ``` 45 | 46 | ### Aktif Bağlantıları Kontrol Etme 47 | 48 | Bir bağlantının etkin olup olmadığını belirlemek için `usePathname()` işlevini kullanabilirsiniz. Örneğin, etkin bağlantıya bir sınıf eklemek için, geçerli yol adının bağlantının `href`'iyle eşleşip eşleşmediğini kontrol edebilirsiniz: 49 | 50 | ```tsx 51 | "use client"; 52 | 53 | import { usePathname } from "next/navigation"; 54 | import { Link } from "next/link"; 55 | 56 | export function Navigation({ navLinks }) { 57 | const pathname = usePathname(); 58 | 59 | return ( 60 | <> 61 | {navLinks.map((link) => { 62 | const isActive = pathname.startsWith(link.href); 63 | 64 | return ( 65 | <Link 66 | className={isActive ? "text-blue" : "text-black"} 67 | href={link.href} 68 | key={link.name} 69 | > 70 | {link.name} 71 | </Link> 72 | ); 73 | })} 74 | </> 75 | ); 76 | } 77 | ``` 78 | 79 | ### Bir kimliğe kaydırma (Scrolling to an `id`) 80 | 81 | `<Link>`'in varsayılan davranışı, değişen rota segmentinin en üstüne kaydırmaktır. `href` içinde tanımlanmış bir `id` olduğunda, normal bir `<a>` etiketine benzer şekilde belirli id'ye kaydırılır. 82 | 83 | Rota segmentinin en üstüne kaydırmayı önlemek için `scroll={false}` olarak ayarlayın ve `href` öğesine karma bir `id` ekleyin: 84 | 85 | ```tsx 86 | <Link href="/#hashid" scroll={false}> 87 | Scroll to specific id. 88 | </Link> 89 | ``` 90 | 91 | ## `useRouter()` Hook 92 | 93 | `useRouter` kancası, İstemci Bileşenleri içindeki rotaları programlı olarak değiştirmenize olanak tanır. 94 | 95 | `useRouter`'ı kullanmak için `next/navigation`'dan içe aktarın ve İstemci Bileşeninizin içindeki kancayı çağırın: 96 | 97 | ```tsx 98 | "use client"; 99 | 100 | import { useRouter } from "next/navigation"; 101 | 102 | export default function Page() { 103 | const router = useRouter(); 104 | 105 | return ( 106 | <button type="button" onClick={() => router.push("/dashboard")}> 107 | Dashboard 108 | </button> 109 | ); 110 | } 111 | ``` 112 | 113 | Öneri: `useRouter` kullanmak için özel bir gereksiniminiz olmadığı sürece rotalar arasında gezinmek için `<Link>` bileşenini kullanın. 114 | 115 | ## Navigasyon Nasıl Çalışır? 116 | 117 | - `<Link>`kullanılarak veya `router.push()` çağrısı yapılarak bir rota geçişi başlatılır. 118 | - Yönlendirici, tarayıcının adres çubuğundaki URL'yi günceller. 119 | - Yönlendirici, istemci tarafı önbelleğindeki değişmeyen bölümleri (ör. paylaşılan düzenler) yeniden kullanarak gereksiz çalışmayı önler. Bu aynı zamanda kısmi işleme olarak da adlandırılır. 120 | - Yumuşak gezinme koşulları karşılanırsa, yönlendirici yeni segmenti sunucu yerine önbellekten alır. Değilse, yönlendirici sert bir gezinme gerçekleştirir ve Sunucu Bileşeni yükünü sunucudan alır. 121 | - Oluşturulursa, yük getirilirken sunucudan yükleme kullanıcı arayüzü gösterilir. 122 | - Yönlendirici, yeni segmentleri istemcide işlemek için önbelleğe alınan veya yeni yükü kullanır. 123 | 124 | ### Oluşturulan Sunucu Bileşenlerinin İstemci Tarafında Önbelleğe Alınması 125 | 126 | Yeni yönlendirici, Sunucu Bileşenlerinin (yük) işlenmiş sonucunu depolayan bir bellek içi istemci tarafı önbelleğine sahiptir. Önbellek, herhangi bir düzeyde geçersiz kılmaya izin veren ve eşzamanlı render işlemlerinde tutarlılık sağlayan rota segmentlerine bölünmüştür. 127 | 128 | Kullanıcılar uygulamada gezinirken, yönlendirici daha önce getirilen segmentlerin ve önceden getirilen segmentlerin yükünü önbellekte depolayacaktır. 129 | 130 | Bu, belirli durumlarda yönlendiricinin sunucuya yeni bir istekte bulunmak yerine önbelleği yeniden kullanabileceği anlamına gelir. Bu, verilerin yeniden alınmasını ve bileşenlerin gereksiz yere yeniden oluşturulmasını önleyerek performansı artırır. 131 | 132 | ### Önbelleğin Geçersiz Kılınması 133 | 134 | Sunucu Eylemleri, verileri yola (`revalidatePath`) veya önbellek etiketine (`revalidateTag`) göre isteğe bağlı olarak yeniden doğrulamak için kullanılabilir. 135 | 136 | ### Prefetching 137 | 138 | Prefetching, bir rotayı ziyaret edilmeden önce arka planda önceden yüklemenin bir yoludur. Önceden yüklenen rotaların işlenmiş sonucu yönlendiricinin istemci tarafı önbelleğine eklenir. Bu, önceden yüklenmiş bir rotaya gitmeyi neredeyse anlık hale getirir. 139 | 140 | Varsayılan olarak, bileşeni kullanırken görünüm alanında görünür hale geldiklerinde rotalar önceden taranır. Bu, sayfa ilk yüklendiğinde veya kaydırma yoluyla gerçekleşebilir. Rotalar, `useRouter()` kancasının prefetch yöntemi kullanılarak programlı olarak da önceden alınabilir. 141 | 142 | #### Statik ve Dinamik Rotalar: 143 | 144 | - Rota statikse, rota segmentleri için tüm Sunucu Bileşeni yükleri önceden taranacaktır. 145 | - Rota dinamikse, ilk paylaşılan düzenden ilk `loading.js` dosyasına kadar olan yük önceden taranır. Bu, tüm rotayı dinamik olarak önceden getirmenin maliyetini azaltır ve dinamik rotalar için anlık yükleme durumlarına izin verir. 146 | 147 | ### Yumuşak Navigasyon (Soft Navigation) 148 | 149 | Gezinme sırasında, değiştirilen segmentler için önbellek yeniden kullanılır (varsa) ve veri için sunucuya yeni bir istek yapılmaz. 150 | 151 | #### Yumuşak Navigasyon için Koşullar 152 | 153 | Navigasyonda Next.js, navigasyon yaptığınız rota önceden taranmışsa ve dinamik segmentler içermiyorsa ya da mevcut rota ile aynı dinamik parametrelere sahipse yumuşak navigasyon kullanacaktır. 154 | 155 | Örneğin, dinamik bir `[team]` segmenti içeren aşağıdaki rotayı düşünün: `/dashboard/[team]/*`. `dashboard/[team]/*` altındaki önbelleğe alınmış segmentler yalnızca `[team]` parametresi değiştiğinde geçersiz kılınacaktır. 156 | 157 | - `/dashboard/team-red/*` adresinden `/dashboard/team-red/*` adresine gitmek yumuşak bir navigasyon olacaktır. 158 | - `/dashboard/team-red/*` adresinden `/dashboard/team-blue/*` adresine gitmek zor bir navigasyon olacaktır. 159 | 160 | ### Sert Navigasyon (Hard Navigation) 161 | 162 | Gezinme sırasında önbellek geçersiz kılınır ve sunucu verileri yeniden alır ve değiştirilen segmentleri yeniden işler. 163 | 164 | ### Geri/İleri Navigasyon 165 | 166 | Geri ve ileri gezinme (popstate olayı) yumuşak bir gezinme davranışına sahiptir. Bu, istemci tarafı önbelleğinin yeniden kullanıldığı ve gezinmenin neredeyse anlık olduğu anlamına gelir. 167 | 168 | ### Odaklanma ve Kaydırma Yönetimi 169 | 170 | Varsayılan olarak, Next.js odağı ayarlar ve gezinme sırasında değiştirilen segmenti görünüme kaydırır. -------------------------------------------------------------------------------- /2-routing/4-route-groups/Readme.md: -------------------------------------------------------------------------------- 1 | # Rota Grupları (Route Groups) 2 | 3 | `app` dizininde, iç içe klasörler normalde URL yollarıyla eşlenir. Ancak, klasörün rotanın URL yoluna dahil edilmesini önlemek için bir klasörü Rota Grubu olarak işaretleyebilirsiniz. 4 | 5 | Bu özellik, URL yolu yapısını etkilemeden rota segmentlerinizi ve proje dosyalarınızı mantıksal gruplar halinde düzenlemenizi sağlar. Bu, kodunuzun okunabilirliğini ve bakımını kolaylaştırır. 6 | 7 | Rota grupları, aşağıdaki durumlar için özellikle kullanışlıdır: 8 | 9 | - Rotaları gruplar halinde düzenleme: Bu, site bölümüne, amaca veya ekibe göre rotaları gruplamayı kolaylaştırır. 10 | - Aynı rota segmenti düzeyinde iç içe düzenleri etkinleştirme: Bu, aynı segmentte birden fazla iç içe düzen oluşturmayı ve ortak bir segmentteki rotaların alt kümesine bir düzen eklemeyi mümkün kılar. 11 | 12 | Bir klasörün adı parantez içine alınarak bir rota grubu oluşturulabilir: `(folderName)` 13 | 14 | ## Örnekler 15 | 16 | ### URL yolunu etkilemeden rotaları düzenleme 17 | 18 | URL'yi etkilemeden rotaları düzenlemek için, ilgili rotaları bir arada tutmak üzere bir grup oluşturun. Parantez içindeki klasörler URL'den çıkarılacaktır (örneğin `(marketing)` veya `(shop)`). 19 | 20 | <img alt="rota grupları" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Froute-group-organisation.png&w=3840&q=75&dpl=dpl_4MG439i8vBzxyfi2msZH7XDinQ5W" /><br/> 21 | 22 | `(marketing)` ve `(shop)` içindeki rotalar aynı URL hiyerarşisini paylaşsa da, klasörlerinin içine bir `layout.js` dosyası ekleyerek her grup için farklı bir düzen oluşturabilirsiniz. 23 | 24 | <img alt="rota grupları" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Froute-group-multiple-layouts.png&w=3840&q=75&dpl=dpl_4MG439i8vBzxyfi2msZH7XDinQ5W" /><br/> 25 | 26 | ### Belirli segmentleri bir düzene dahil etme 27 | 28 | Belirli rotaları bir düzene dahil etmek için yeni bir rota grubu oluşturun (örn. `(shop)`) ve aynı düzeni paylaşan rotaları gruba taşıyın (örn. `account` ve `cart`). Grubun dışındaki rotalar düzeni paylaşmayacaktır (örn. `checkout`). 29 | 30 | <img alt="rota grupları" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Froute-group-opt-in-layouts.png&w=3840&q=75&dpl=dpl_4MG439i8vBzxyfi2msZH7XDinQ5W" /><br/> 31 | 32 | ### Çoklu kök düzenleri oluşturma 33 | 34 | Birden fazla kök düzen oluşturmak için üst düzey `layout.js` dosyasını kaldırın ve her rota grubunun içine bir `layout.js` dosyası ekleyin. Bu, bir uygulamayı tamamen farklı bir kullanıcı arayüzüne veya deneyime sahip bölümlere ayırmak için kullanışlıdır. `<html>` ve `<body>` etiketlerinin her bir kök düzene eklenmesi gerekir. 35 | 36 | <img alt="rota grupları" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Froute-group-multiple-root-layouts.png&w=3840&q=75&dpl=dpl_4MG439i8vBzxyfi2msZH7XDinQ5W" /><br/> 37 | 38 | Bilmekte fayda var: 39 | 40 | - Rota gruplarının adlandırılması, organizasyon dışında özel bir öneme sahip değildir ve URL yolu üzerinde hiçbir etkisi yoktur. 41 | - Bir rota grubu içeren rotalar, diğer rotalarla aynı URL yoluna çözümlenmemelidir. Yani, `(marketing)/about/page.js` ve `(shop)/about/page.js` rotaları her ikisi de `/about` olarak çözümlenir ve bu bir hataya neden olur. 42 | - Eğer birden fazla kök düzeniniz varsa ve üst düzey bir `layout.js` dosyanız yoksa, ana `page.js` dosyanız rota gruplarından birinde tanımlanmalıdır. Örneğin: `app/(marketing)/page.js.` 43 | - Birden fazla kök düzen arasında gezinmek tam sayfa yüklemesine neden olacaktır. Yani, `app/(shop)/layout.js` kullanan `/cart` sayfasından `app/(marketing)/layout.js` kullanan `/blog` sayfasına gitmek tam sayfa yüklemeye neden olur. Bu durum, yalnızca birden fazla kök düzen için geçerlidir ve istemci tarafı gezinmenin aksine çalışır. 44 | -------------------------------------------------------------------------------- /2-routing/5-dynamic-routes/Readme.md: -------------------------------------------------------------------------------- 1 | # Dinamik Rotalar (Dynamic Routes) 2 | 3 | Segment adlarını önceden tam olarak bilmediğinizde ve dinamik verilerden rotalar oluşturmak istediğinizde, istek zamanında doldurulan veya derleme zamanında önceden oluşturulan Dinamik Segmentleri kullanabilirsiniz. 4 | 5 | Bir Dinamik Segment, bir klasörün adını köşeli parantezler içine alarak oluşturulabilir: `[folderName]`. Örneğin, `[id]` veya `[slug]`. 6 | 7 | Dinamik Segmentler `layout`, `page`, `route` ve `generateMetadata` fonksiyonlarına `params` prop olarak aktarılır. 8 | 9 | Örneğin, bir blog aşağıdaki `app/blog/[slug]/page.js` rotasını içerebilir; burada `[slug]` blog gönderileri için Dinamik Segmenttir. 10 | 11 | ```ts 12 | export default function Page({ params }: { params: { slug: string } }) { 13 | return <div>My Post: {params.slug}</div>; 14 | } 15 | ``` 16 | 17 | | Rota | Örnek URL | `Params` | 18 | | ---------------------------- | ------------- | -------------------------- | 19 | | `app/shop/[...slug]/page.js` | `/shop/a` | `{ slug: ['a'] }` | 20 | | `app/shop/[...slug]/page.js` | `/shop/a/b` | `{ slug: ['a', 'b'] }` | 21 | | `app/shop/[...slug]/page.js` | `/shop/a/b/c` | `{ slug: ['a', 'b', 'c']}` | 22 | 23 | ## İsteğe Bağlı Her Şeyi Yakalayan Segmentler (Optional Catch-all Segments) 24 | 25 | Catch-all Segmentleri, parametreyi çift köşeli parantez içine alarak isteğe bağlı hale getirilebilir: `[[...folderName]]`. 26 | 27 | Örneğin, `app/shop/[[...slug]]/page.js`, `/shop/clothes`, `/shop/clothes/tops`, `/shop/clothes/tops/t-shirts`'e ek olarak `/shop` ile de eşleşecektir. 28 | 29 | `Tümünü yakala` ve `isteğe bağlı tümünü yakala` segmentleri arasındaki fark, isteğe bağlı olduğunda parametre içermeyen rotanın da eşleştirilmesidir (yukarıdaki örnekte `/shop`). 30 | 31 | | Route | Example URL | `Params` | 32 | | ------------------------------ | ------------- | -------------------------- | 33 | | `app/shop/[[...slug]]/page.js` | `/shop` | `{}` | 34 | | `app/shop/[[...slug]]/page.js` | `/shop/a` | `{ slug: ['a'] }` | 35 | | `app/shop/[[...slug]]/page.js` | `/shop/a/b` | `{ slug: ['a', 'b'] }` | 36 | | `app/shop/[[...slug]]/page.js` | `/shop/a/b/c` | `{ slug: ['a', 'b', 'c']}` | 37 | 38 | ### TypeScript 39 | 40 | TypeScript kullanırken, yapılandırılmış rota segmentinize bağlı olarak `params` için türler ekleyebilirsiniz. 41 | 42 | ```ts 43 | export default function Page({ params }: { params: { slug: string } }) { 44 | return <h1>My Page</h1>; 45 | } 46 | ``` 47 | 48 | | Route | `Params` Type Definition | 49 | | ----------------------------------- | ---------------------------------------- | 50 | | `app/blog/[slug]/page.js` | `{ slug: string }` | 51 | | `app/shop/[...slug]/page.js` | `{ slug: string[] }` | 52 | | `app/[categoryId]/[itemId]/page.js` | `{ categoryId: string, itemId: string }` | 53 | -------------------------------------------------------------------------------- /2-routing/6-loading-UI-and-treaming/Readme.md: -------------------------------------------------------------------------------- 1 | # Kullanıcı Arayüzünü Yükleme ve Akış (Loading UI and Streaming) 2 | 3 | Özel `loading.js` dosyası, React Suspense ile anlamlı bir Yükleme Kullanıcı Arayüzü oluşturmanıza yardımcı olur. Bu kural ile, bir rota segmentinin içeriği yüklenirken sunucudan anlık bir yükleme state'i gösterebilirsiniz, render alma işlemi tamamlandığında yeni içerik otomatik olarak değiştirilir. 4 | 5 | <img alt="loading" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Floading-ui.png&w=3840&q=75&dpl=dpl_DS6dPw9iM1MterzWfxufB6ivU12S" /><br/> 6 | 7 | ## Anında Yükleme Durumları (Instant Loading States) 8 | 9 | Anında yükleme state'i, gezinmenin hemen ardından gösterilen yedek kullanıcı arayüzüdür. İskeletler ve döndürücüler gibi yükleme göstergelerini veya kapak fotoğrafı, başlık vb. gibi gelecekteki ekranların küçük ama anlamlı bir bölümünü önceden render edebilirsiniz. Bu, kullanıcıların uygulamanın yanıt verdiğini anlamasına yardımcı olur ve daha iyi bir kullanıcı deneyimi sağlar. 10 | 11 | Bir klasörün içine bir `loading.js` dosyası ekleyerek bir yükleme durumu oluşturun. 12 | 13 | <img alt="loading-2" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Floading-special-file.png&w=3840&q=75&dpl=dpl_DS6dPw9iM1MterzWfxufB6ivU12S" /><br/> 14 | 15 | ```ts 16 | export default function Loading() { 17 | // İskelet de dahil olmak üzere Loading içine herhangi bir kullanıcı arayüzü ekleyebilirsiniz. 18 | return <LoadingSkeleton />; 19 | } 20 | ``` 21 | 22 | Aynı klasörde, `loading.js` dosyası `layout.js` dosyasının içine yerleştirilecektir. Otomatik olarak `page.js` dosyasını ve altındaki tüm alt elemanları bir `<Suspense>` sınırına saracaktır. 23 | 24 | <img alt="loading-3" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Floading-overview.png&w=3840&q=75&dpl=dpl_DS6dPw9iM1MterzWfxufB6ivU12S" /><br/> 25 | 26 | Bilmekte fayda var: 27 | 28 | - Sunucu merkezli yönlendirmede bile navigasyon anında gerçekleşir. 29 | - Navigasyon kesintiye uğramaz, yani rota değiştirirken başka bir rotaya geçmeden önce rotanın içeriğinin tamamen yüklenmesini beklemek gerekmez. 30 | - Yeni rota segmentleri yüklenirken paylaşılan düzenler etkileşimli kalır. 31 | 32 | **Öneri**: Next.js bu işlevi optimize ettiğinden, rota segmentleri (düzenler ve sayfalar) için `loading.js` kuralını kullanın. 33 | 34 | ## Gerilim ile Akış (Streaming with Suspense) 35 | 36 | `loading.js`'e ek olarak, kendi UI bileşenleriniz için manuel olarak da Suspense Boundaries oluşturabilirsiniz. App Router, hem Node.js hem de Edge çalışma zamanları için [Suspense](https://react.dev/reference/react/Suspense) ile akışı destekler. 37 | 38 | ### Akış Nedir? 39 | 40 | Akış'ın React ve Next.js'de nasıl çalıştığını öğrenmek için Sunucu Tarafı Render Etme (SSR) ve sınırlamalarını anlamak faydalı olacaktır. 41 | 42 | SSR ile, bir kullanıcının bir sayfayı görebilmesi ve etkileşimde bulunabilmesi için tamamlanması gereken bir dizi adım vardır: 43 | 44 | 1. İlk olarak, belirli bir sayfa için tüm veriler sunucudan alınır. 45 | 2. Sunucu daha sonra sayfa için HTML render eder. 46 | 3. Sayfa için HTML, CSS ve JavaScript istemciye gönderilir. 47 | 4. Oluşturulan HTML ve CSS kullanılarak etkileşimli olmayan bir kullanıcı arayüzü gösterilir. 48 | 5. Son olarak, React kullanıcı arayüzünü [etkileşimli](https://react.dev/reference/react-dom/client/hydrateRoot#hydrating-server-rendered-html) hale getirir. 49 | 50 | <img alt="loading-3" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fserver-rendering-without-streaming-chart.png&w=3840&q=75&dpl=dpl_DS6dPw9iM1MterzWfxufB6ivU12S" /><br/> 51 | 52 | Bu adımlar sıralı ve engelleyicidir, yani sunucu ancak tüm veriler getirildikten sonra bir sayfanın HTML'sini render edebilir. İstemcide ise React, kullanıcı arayüzünü ancak sayfadaki tüm bileşenlerin kodu indirildikten sonra etkileşimli hale getirebilir. 53 | 54 | React ve Next.js ile SSR, kullanıcıya mümkün olan en kısa sürede etkileşimli olmayan bir sayfa göstererek algılanan yükleme performansını iyileştirmeye yardımcı olur. 55 | 56 | <img alt="loading-4" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fserver-rendering-without-streaming.png&w=3840&q=75&dpl=dpl_DS6dPw9iM1MterzWfxufB6ivU12S" /><br/> 57 | 58 | Ancak, sayfanın kullanıcıya gösterilebilmesi için sunucuda tüm veri getirme işlemlerinin tamamlanması gerektiğinden bu süreç yine de yavaş olabilir. 59 | 60 | **Akış**, sayfanın HTML'sini daha küçük parçalara ayırmanıza ve bu parçaları sunucudan istemciye aşamalı olarak göndermenize olanak tanır. 61 | 62 | <img alt="loading-5" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fserver-rendering-with-streaming.png&w=3840&q=75&dpl=dpl_DS6dPw9iM1MterzWfxufB6ivU12S" /><br/> 63 | 64 | Bu, herhangi bir kullanıcı arayüzü render edilmeden önce tüm verilerin yüklenmesini beklemeden sayfanın bazı bölümlerinin daha erken görüntülenmesini sağlar. 65 | 66 | Akış, React'in bileşen modeliyle iyi çalışır çünkü her bileşen bir yığın olarak kabul edilebilir. Daha yüksek önceliğe sahip (örn. ürün bilgileri) veya veriye bağlı olmayan bileşenler önce gönderilebilir (örn. düzen) ve React hidrasyona daha erken başlayabilir. Daha düşük önceliğe sahip bileşenler (ör. incelemeler, ilgili ürünler), verileri alındıktan sonra aynı sunucu isteğinde gönderilebilir. 67 | 68 | <img alt="loading-6" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fserver-rendering-with-streaming-chart.png&w=3840&q=75&dpl=dpl_DS6dPw9iM1MterzWfxufB6ivU12S" /><br/> 69 | 70 | Akış, [İlk Bayta Kadar Geçen Süreyi (TTFB)](https://web.dev/ttfb/) ve [İlk İçerik Boyamasını (FCP)](https://web.dev/first-contentful-paint/) azaltabileceğinden, uzun veri isteklerinin sayfanın render edilmesini engellemesini önlemek istediğinizde özellikle faydalıdır. Ayrıca, özellikle yavaş cihazlarda [Etkileşim Süresini (TTI)](https://developer.chrome.com/en/docs/lighthouse/performance/interactive/) iyileştirmeye yardımcı olur. 71 | 72 | **Örnek:** 73 | 74 | `<Suspense>`, eşzamansız bir eylem (örneğin veri getirme) gerçekleştiren bir bileşeni sararak, eylem gerçekleşirken yedek kullanıcı arayüzünü (örneğin iskelet, döndürücü) göstererek ve ardından eylem tamamlandığında bileşeninizi değiştirerek çalışır. 75 | 76 | ```ts 77 | import { Suspense } from "react"; 78 | import { PostFeed, Weather } from "./Components"; 79 | 80 | export default function Posts() { 81 | return ( 82 | <section> 83 | <Suspense fallback={<p>Loading feed...</p>}> 84 | <PostFeed /> 85 | </Suspense> 86 | <Suspense fallback={<p>Loading weather...</p>}> 87 | <Weather /> 88 | </Suspense> 89 | </section> 90 | ); 91 | } 92 | ``` 93 | 94 | Suspense kullanarak şu avantajları elde edersiniz: 95 | 96 | 1. Streaming Server Rendering - HTML'in sunucudan istemciye aşamalı olarak render edilmesi. 97 | 2. Seçici Hidrasyon - React, kullanıcı etkileşimine göre hangi bileşenlerin önce etkileşimli hale getirileceğine öncelik verir. 98 | 99 | Daha fazla Suspense örneği ve kullanım senaryosu için lütfen [React Dokümantasyonuna](https://react.dev/reference/react/Suspense) bakınız. 100 | 101 | **SEO** 102 | 103 | - Next.js, istemciye UI akışı yapmadan önce `generateMetadata` içindeki veri getirme işleminin tamamlanmasını bekler. Bu, akışlı bir yanıtın ilk bölümünün `<head>` etiketlerini içermesini garanti eder. 104 | - Akış, sunucu tarafından render edildiği için SEO'yu etkilemez. Sayfanızın Google'ın web tarayıcılarında nasıl göründüğünü görmek ve serileştirilmiş HTML'yi ([kaynak](https://web.dev/rendering-on-the-web/#seo-considerations)) görüntülemek için Google'ın [Mobil Dostu Test](https://search.google.com/test/mobile-friendly) aracını kullanabilirsiniz. 105 | -------------------------------------------------------------------------------- /2-routing/7-error-handling/Readme.md: -------------------------------------------------------------------------------- 1 | # Hata İşleme (Error Handling) 2 | 3 | `error.js` dosya kuralı, iç içe geçmiş rotalarda çalışma zamanı hatalarını zarif bir şekilde ele almanıza olanak tanır. 4 | 5 | - Bir rota segmentini ve iç içe geçmiş alt segmentlerini otomatik olarak bir [React Hata Sınırına](https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary) sarın. 6 | - Ayrıntılılığı ayarlamak için dosya sistemi hiyerarşisini kullanarak belirli segmentlere uyarlanmış hata kullanıcı arayüzü oluşturun. 7 | - Uygulamanın geri kalanını işlevsel tutarken hataları etkilenen segmentlere izole edin. 8 | - Tam sayfa yeniden yükleme olmadan bir hatadan kurtulmayı denemek için işlevsellik ekleyin. 9 | 10 | Bir rota segmentinin içine bir `error.js` dosyası ekleyerek ve bir React bileşenini dışa aktararak hata kullanıcı arayüzü oluşturun: 11 | 12 | <img alt="error" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Ferror-special-file.png&w=3840&q=75&dpl=dpl_G1mtmG8Eq9P8U8iiGPcqaT83bNbK" /><br/> 13 | 14 | ```ts 15 | "use client"; // Error components must be Client Components 16 | 17 | import { useEffect } from "react"; 18 | 19 | export default function Error({ 20 | error, 21 | reset, 22 | }: { 23 | error: Error; 24 | reset: () => void; 25 | }) { 26 | useEffect(() => { 27 | // Hatayı bir hata raporlama hizmetine kaydedin 28 | console.error(error); 29 | }, [error]); 30 | 31 | return ( 32 | <div> 33 | <h2>Something went wrong!</h2> 34 | <button 35 | onClick={ 36 | // Segmenti yeniden oluşturmayı deneyerek kurtarmaya çalışın 37 | () => reset() 38 | } 39 | > 40 | Try again 41 | </button> 42 | </div> 43 | ); 44 | } 45 | ``` 46 | 47 | ## `error.js` Nasıl Çalışır? 48 | 49 | <img alt="error-2" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Ferror-overview.png&w=3840&q=75&dpl=dpl_G1mtmG8Eq9P8U8iiGPcqaT83bNbK" /><br/> 50 | 51 | - `error.js` otomatik olarak iç içe geçmiş bir alt segmenti veya `page.js` bileşenini saran bir React Hata Sınırı oluşturur. 52 | - `error.js` dosyasından dışa aktarılan React bileşeni, yedek bileşen olarak kullanılır. 53 | - Hata sınırı içinde bir hata atılırsa, hata içerilir ve yedek bileşen render edilir. 54 | - Yedek hata bileşeni etkin olduğunda, hata sınırının üzerindeki düzenler durumlarını korur ve etkileşimli kalır ve hata bileşeni hatadan kurtulmak için işlevsellik görüntüleyebilir. 55 | 56 | ## Hatalardan Kurtarma 57 | 58 | Bir hatanın nedeni bazen geçici olabilir. Bu durumlarda, sadece tekrar denemek sorunu çözebilir. 59 | 60 | Bir hata bileşeni `reset()` fonksiyonunu kullanarak kullanıcıdan hatadan kurtulmaya çalışmasını isteyebilir. İşlev çalıştırıldığında, Hata sınırının içeriğini yeniden render etmeye çalışır. Başarılı olursa, yedek hata bileşeni yeniden render etme işleminin sonucuyla değiştirilir. 61 | 62 | ```ts 63 | "use client"; 64 | 65 | export default function Error({ 66 | error, 67 | reset, 68 | }: { 69 | error: Error; 70 | reset: () => void; 71 | }) { 72 | return ( 73 | <div> 74 | <h2>Something went wrong!</h2> 75 | <button onClick={() => reset()}>Try again</button> 76 | </div> 77 | ); 78 | } 79 | ``` 80 | 81 | ## İç İçe Rotalar (Nested Routes) 82 | 83 | Özel dosyalar aracılığıyla oluşturulan React bileşenleri, belirli bir iç içe hiyerarşi içinde oluşturulur. 84 | 85 | Örneğin, her ikisi de `layout.js` ve `error.js` dosyalarını içeren iki segmente sahip iç içe geçmiş bir rota aşağıdaki basitleştirilmiş bileşen hiyerarşisinde oluşturulur: 86 | 87 | <img alt="error-2" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fnested-error-component-hierarchy.png&w=3840&q=75&dpl=dpl_G1mtmG8Eq9P8U8iiGPcqaT83bNbK" /><br/> 88 | 89 | İç içe geçmiş bileşen hiyerarşisi, `error.js` dosyalarının iç içe geçmiş bir rota boyunca davranışı üzerinde etkilere sahiptir: 90 | 91 | - Hatalar en yakın üst hata sınırına kadar kabarır. Bu, bir `error.js` dosyasının iç içe geçmiş tüm alt segmentleri için hataları işleyeceği anlamına gelir. Daha fazla veya daha az ayrıntılı hata kullanıcı arayüzü, `error.js` dosyalarını bir rotanın iç içe geçmiş klasörlerinde farklı seviyelere yerleştirerek elde edilebilir. 92 | - Bir `error.js` sınırı, **aynı** segmentteki bir `layout.js` bileşeninde atılan hataları işlemez çünkü hata sınırı bu layout bileşeninin **içinde** yuvalanmıştır. 93 | 94 | ## Düzenlerde Hataları İşleme (Handling Errors in Layouts) 95 | 96 | `error.js` sınırları, aynı segmentteki `layout.js` veya `template.js` bileşenlerinde atılan hataları yakalamaz. Bu kasıtlı hiyerarşi, bir hata oluştuğunda kardeş rotalar arasında paylaşılan önemli kullanıcı arayüzünü (navigasyon gibi) görünür ve işlevsel tutar. 97 | 98 | Belirli bir düzen veya şablon içindeki hataları işlemek için, düzenlerin üst segmentine bir `error.js` dosyası yerleştirin. 99 | 100 | Kök düzen veya şablon içindeki hataları işlemek için,`global-error.js` adı verilen `error.js`'nin bir varyasyonunu kullanın. 101 | 102 | ## Kök Düzenlerde Hataları İşleme (Handling Errors in Root Layouts) 103 | 104 | Kök `app/error.js` sınırı, kök `app/layout.js` veya `app/template.js` bileşeninde atılan hataları yakalamaz. 105 | 106 | Bu kök bileşenlerdeki hataları özel olarak ele almak için, kök uygulama dizininde bulunan `app/global-error.js` adlı `error.js` varyasyonunu kullanın. 107 | 108 | Kök `error.js`'den farklı olarak, `global-error.js` hata sınırı tüm uygulamayı sarar ve yedek bileşeni etkin olduğunda kök düzeninin yerini alır. Bu nedenle, `global-error.js`'nin kendi `<html>` ve `<body>` etiketlerini tanımlaması gerektiğine dikkat etmek önemlidir. 109 | 110 | `global-error.js` en az ayrıntılı hata kullanıcı arayüzüdür ve tüm uygulama için "catch-all" hata işleme olarak düşünülebilir. Kök bileşenler genellikle daha az dinamik olduğundan ve diğer `error.js` sınırları çoğu hatayı yakalayacağından sık sık tetiklenmesi pek olası değildir. 111 | 112 | Bir `global-error.js` tanımlanmış olsa bile, geri dönüş bileşeni global olarak paylaşılan kullanıcı arayüzü ve markalamayı içeren kök düzen içinde oluşturulacak bir kök `error.js` tanımlanması önerilir. 113 | 114 | ```ts 115 | "use client"; 116 | 117 | export default function GlobalError({ 118 | error, 119 | reset, 120 | }: { 121 | error: Error; 122 | reset: () => void; 123 | }) { 124 | return ( 125 | <html> 126 | <body> 127 | <h2>Something went wrong!</h2> 128 | <button onClick={() => reset()}>Try again</button> 129 | </body> 130 | </html> 131 | ); 132 | } 133 | ``` 134 | 135 | ## Sunucu Hatalarını İşleme (Handling Server Errors) 136 | 137 | Veri getirme sırasında veya bir Sunucu Bileşeni içinde bir hata atılırsa, Next.js ortaya çıkan `Error` nesnesini hata prop'u olarak en yakın `error.js` dosyasına iletecektir. 138 | 139 | `Next dev` çalıştırılırken `error` serileştirilir ve Sunucu Bileşeninden istemci `error.js`'ye iletilir. Üretimde `next start` çalıştırılırken güvenliği sağlamak için, hata mesajının bir özetini içeren bir `.digest` ile birlikte hataya genel bir `error` mesajı iletilir. Bu özet, sunucu günlüklerine karşılık gelmek için kullanılabilir. 140 | -------------------------------------------------------------------------------- /2-routing/8-paralel-routes/Readme.md: -------------------------------------------------------------------------------- 1 | # Paralel Rotalar (Parallel Routes) 2 | 3 | Paralel Yönlendirme, bir veya daha fazla sayfayı aynı düzende eşzamanlı veya koşullu olarak render etmenize olanak tanır. Bir uygulamanın gösterge tabloları ve sosyal sitelerdeki beslemeler gibi son derece dinamik bölümleri için Paralel Yönlendirme, karmaşık yönlendirme modellerini uygulamak için kullanılabilir. 4 | 5 | Örneğin, ekip ve analiz sayfalarını aynı anda oluşturabilirsiniz. 6 | 7 | <img alt="paralel-rotalar" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fparallel-routes.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 8 | 9 | Paralel Yönlendirme, her bir rota için bağımsız hata ve yükleme durumları tanımlamanıza olanak tanır. 10 | 11 | <img alt="paralel-rotalar-2" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fparallel-routes-cinematic-universe.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 12 | 13 | Paralel Yönlendirme, kimlik doğrulama durumu gibi belirli koşullara bağlı olarak bir yuvayı koşullu olarak render etmenize da olanak tanır. Bu, aynı URL üzerinde tamamen ayrılmış kod sağlar. 14 | 15 | <img alt="paralel-rotalar-3" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fconditional-routes-ui.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 16 | 17 | ## Kongre (Convention) 18 | 19 | Paralel rotalar adlandırılmış **yuvalar** kullanılarak oluşturulur. Yuvalar `@folder` konvansiyonu ile tanımlanır ve aynı seviyedeki düzene prop olarak aktarılır. 20 | 21 | Yuvalar rota segmentleri değildir ve URL yapısını etkilemez. `/@team/members` dosya yoluna `/members` adresinden erişilebilir. 22 | 23 | Örneğin, aşağıdaki dosya yapısı iki açık yuva tanımlar: `@analytics` ve `@team`. 24 | 25 | <img alt="paralel-rotalar-4" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fparallel-routes-file-system.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 26 | 27 | Yukarıdaki klasör yapısı, `app/layout.js`'deki bileşenin artık `@analytics` ve `@team` slots prop'larını kabul ettiği ve bunları `alt eleman` prop ile birlikte paralel olarak render edebileceği anlamına gelir: 28 | 29 | ```ts 30 | export default function Layout(props: { 31 | children: React.ReactNode; 32 | analytics: React.ReactNode; 33 | team: React.ReactNode; 34 | }) { 35 | return ( 36 | <> 37 | {props.children} 38 | {props.team} 39 | {props.analytics} 40 | </> 41 | ); 42 | } 43 | ``` 44 | 45 | Bilmekte fayda var: `alt eleman` prop'u, bir klasörle eşleştirilmesi gerekmeyen örtük bir yuvadır. Bu, `app/page.js`'nin `app/@children/page.js` ile eşdeğer olduğu anlamına gelir. 46 | 47 | ## Eşleşmeyen Rotalar (Unmatched Routes) 48 | 49 | Varsayılan olarak, bir yuva içinde oluşturulan içerik geçerli URL ile eşleşir. 50 | 51 | Eşleşmeyen bir yuva olması durumunda, Next.js'nin işlediği içerik yönlendirme tekniğine ve klasör yapısına göre farklılık gösterir. 52 | 53 | ### `default.js` 54 | 55 | Next.js geçerli URL'ye göre bir yuvanın etkin durumunu kurtaramadığında geri dönüş olarak render edilecek bir `default.js` dosyası tanımlayabilirsiniz. 56 | 57 | Aşağıdaki klasör yapısını düşünün. `@team` yuvasının bir `settings` dizini var, ancak `@analytics`'in yok. 58 | 59 | <img alt="paralel-rotalar-5" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fparallel-routes-unmatched-routes.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 60 | 61 | Kök `/` dizininden `/settings` dizinine giderseniz, gezinme türüne ve `default.js` dosyasının kullanılabilirliğine bağlı olarak render edilen içerik farklı olur. 62 | 63 | | | `@analytics/default.js` ile | `@analytics/default.js` olmadan | 64 | | --------------- | --------------------------------------------------- | ------------------------------------------------ | 65 | | Soft Navigation | `@team/settings/page.js` ve `@analytics/page.js` | `@team/settings/page.js` ve `@analytics/page.js` | 66 | | Hard Navigation | `@team/settings/page.js` ve `@analytics/default.js` | 404 | 67 | 68 | ### Yumuşak Navigasyon (Soft Navigation) 69 | 70 | Yumuşak bir navigasyonda - Next.js, geçerli URL ile eşleşmese bile yuvanın daha önce etkin olan durumunu oluşturur. 71 | 72 | ### Sert Navigasyon (Hard Navigation) 73 | 74 | Zor bir navigasyonda (bütün sayfanın yeniden yüklenmesini gerektiren bir navigasyon) Next.js önce eşleşmeyen yuvanın default.js dosyasını render etmeye çalışır. Eğer bu dosya mevcut değilse, bir 404 görüntülenir. 75 | 76 | Eşleşmeyen rotalar için 404, paralel olarak render edilmemesi gereken bir rotayı yanlışlıkla render etmenizi sağlamaya yardımcı olur. 77 | 78 | ### `useSelectedLayoutSegment(s)` 79 | 80 | Hem `useSelectedLayoutSegment` hem de `useSelectedLayoutSegments`, o yuvadaki etkin rota segmentini okumanızı sağlayan bir `parallelRoutesKey` kabul eder. 81 | 82 | ```ts 83 | "use client"; 84 | 85 | import { useSelectedLayoutSegment } from "next/navigation"; 86 | 87 | export default async function Layout(props: { 88 | //... 89 | authModal: React.ReactNode; 90 | }) { 91 | const loginSegments = useSelectedLayoutSegment("authModal"); 92 | // ... 93 | } 94 | ``` 95 | 96 | Bir kullanıcı URL çubuğunda `@authModal/login` veya `/login` adresine gittiğinde, `loginSegments` `"login"` dizesine eşit olacaktır. 97 | 98 | ## Örnekler 99 | 100 | ### Modaller (Modals) 101 | 102 | Paralel Yönlendirme, modları render etmek için kullanılabilir. 103 | 104 | <img alt="paralel-rotalar-6" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fparallel-routes-auth-modal.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 105 | 106 | `authModal` yuvası, örneğin `/login` gibi eşleşen bir rotaya gidilerek gösterilebilen bir `<Modal>` bileşeni oluşturur. 107 | 108 | app/layout.tsx: 109 | 110 | ```ts 111 | export default async function Layout(props: { 112 | // ... 113 | authModal: React.ReactNode; 114 | }) { 115 | return ( 116 | <> 117 | {/* ... */} 118 | {props.authModal} 119 | </> 120 | ); 121 | } 122 | ``` 123 | 124 | app/@authModal/login/page.tsx: 125 | 126 | ```ts 127 | import { Modal } from "components/modal"; 128 | 129 | export default function Login() { 130 | return ( 131 | <Modal> 132 | <h1>Login</h1> 133 | {/* ... */} 134 | </Modal> 135 | ); 136 | } 137 | ``` 138 | 139 | Modal etkin olmadığında içeriğinin işlenmemesini sağlamak için `null` döndüren bir `default.js` dosyası oluşturabilirsiniz. 140 | 141 | app/@authModal/login/default.tsx: 142 | 143 | ```ts 144 | export default function Default() { 145 | return null; 146 | } 147 | ``` 148 | 149 | ### Bir modalın kapatılması (Dismissing a modal) 150 | 151 | İstemci gezintisi yoluyla, örneğin `<Link href="/login">` kullanılarak bir modal başlatılmışsa, `router.back()` öğesini çağırarak veya bir `Link` bileşeni kullanarak modalı kapatabilirsiniz. 152 | 153 | app/@authModal/login/page.tsx: 154 | 155 | ```ts 156 | "use client"; 157 | import { useRouter } from "next/navigation"; 158 | import { Modal } from "components/modal"; 159 | 160 | export default async function Login() { 161 | const router = useRouter(); 162 | return ( 163 | <Modal> 164 | <span onClick={() => router.back()}>Close modal</span> 165 | <h1>Login</h1> 166 | ... 167 | </Modal> 168 | ); 169 | } 170 | ``` 171 | 172 | Başka bir yere gitmek ve bir modalı kapatmak istiyorsanız, her şeyi kapsayan bir rota da kullanabilirsiniz. 173 | 174 | <img alt="paralel-rotalar-7" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fparallel-routes-catchall.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 175 | 176 | app/@authModal/[...catchAll]/page.tsx: 177 | 178 | ```ts 179 | export default function CatchAll() { 180 | return null; 181 | } 182 | ``` 183 | 184 | Catch-all rotaları `default.js`'ye göre önceliklidir. 185 | 186 | ## Koşullu Rotalar (Conditional Routes) 187 | 188 | Paralel Rotalar koşullu yönlendirme uygulamak için kullanılabilir. Örneğin, kimlik doğrulama durumuna bağlı olarak bir `@dashboard` veya `@login` rotası render edebilirsiniz. 189 | 190 | ```ts 191 | import { getUser } from "@/lib/auth"; 192 | 193 | export default function Layout({ params, dashboard, login }) { 194 | const isLoggedIn = getUser(); 195 | return isLoggedIn ? dashboard : login; 196 | } 197 | ``` 198 | 199 | <img alt="paralel-rotalar-8" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fconditional-routes-ui.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 200 | -------------------------------------------------------------------------------- /2-routing/9-intercepting-routes/Readme.md: -------------------------------------------------------------------------------- 1 | # Kesen Rotalar (Intercepting Routes) 2 | 3 | Rotaları kesmek, geçerli sayfanın bağlamını korurken geçerli düzen içinde bir rota yüklemenize olanak tanır. Bu yönlendirme paradigması, farklı bir rota göstermek için belirli bir rotayı "kesmek" istediğinizde yararlı olabilir. 4 | 5 | Örneğin, bir beslemenin içinden bir fotoğrafa tıklandığında, beslemeyi kaplayan bir modal fotoğrafla birlikte görünmelidir. Bu durumda Next.js, `/feed` yolunu keser ve bunun yerine `/photo/123` göstermek için bu URL'yi "maskeler". 6 | 7 | <img alt="kesen-rotalar" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fintercepting-routes-soft-navigate.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 8 | 9 | Ancak, örneğin paylaşılabilir bir URL'ye tıklayarak veya sayfayı yenileyerek doğrudan fotoğrafa gidildiğinde, modal yerine fotoğraf sayfasının tamamı render edilmelidir. Herhangi bir rota müdahalesi gerçekleşmemelidir. 10 | 11 | <img alt="kesen-rotalar-2" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fintercepting-routes-hard-navigate.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 12 | 13 | ## Convention 14 | 15 | Kesişen rotalar, göreli yol kuralı `../`'ye benzeyen ancak segmentler için olan `(..)` kuralı ile tanımlanabilir. 16 | 17 | Şu şekillerde Kullanabilirsiniz: 18 | 19 | - `(.)` aynı seviyedeki segmentleri eşleştirmek için 20 | - `(..)` bir üst seviyedeki segmentlerle eşleştirmek için 21 | - `(..)(..)` iki seviye yukarıdaki segmentlerle eşleştirmek için 22 | - `(...)` kök uygulama dizinindeki segmentleri eşleştirmek için 23 | 24 | Örneğin, bir `(..)photo` dizini oluşturarak `fotoğraf` segmentini `besleme` segmenti içinden kesebilirsiniz. 25 | 26 | <img alt="kesen-rotalar-3" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fintercepted-routes-files.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 27 | 28 | `(..)` kuralının dosya sistemini değil, yol segmentlerini temel aldığını unutmayın. 29 | 30 | ## Modaller (Modals) 31 | 32 | Yakalama Rotaları, modaller oluşturmak için Paralel Rotalar ile birlikte kullanılabilir. 33 | 34 | Bu kalıbı kullanarak modaller oluşturmak, modallerle çalışırken karşılaşılan bazı zorlukların üstesinden gelmenizi sağlar: 35 | 36 | - Modal içeriği bir URL aracılığıyla paylaşılabilir hale getirin 37 | - Sayfa yenilendiğinde, modalı kapatmak yerine bağlamı koruyun 38 | - Önceki rotaya gitmek yerine geriye doğru gezinmede modalı kapatın 39 | - İleriye doğru gezinme modalini yeniden açma 40 | 41 | <img alt="kesen-rotalar-4" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fintercepted-routes-modal-example.png&w=3840&q=75&dpl=dpl_8fzWiojXNexXAYQSWwEEmzPxZwZN" /><br/> 42 | 43 | Yukarıdaki örnekte, `@modal` bir segment değil bir slot olduğu için `photo` segmentine giden yol `(..)` eşleştiricisini kullanabilir. Bu, iki dosya sistemi seviyesi daha yüksek olmasına rağmen `photo` yolunun yalnızca bir segment seviyesi daha yüksek olduğu anlamına gelir. 44 | 45 | Diğer örnekler arasında, özel bir `/login` sayfasına sahipken üst navbarda bir oturum açma modalı açmak veya bir yan modalda bir alışveriş sepeti açmak sayılabilir. 46 | -------------------------------------------------------------------------------- /2-routing/Readme.md: -------------------------------------------------------------------------------- 1 | # Yönlendirme Temelleri (Routing Fundamentals) 2 | 3 | ## Terminoloji 4 | 5 | <img alt="yönlendirme-temelleri" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fterminology-component-tree.png&w=3840&q=75&dpl=dpl_C2pSAYXZnY6DPcYmVfUv54azW3BJ"/><br/> 6 | 7 | - **Ağaç (tree)**: Hiyerarşik bir yapıyı görselleştirmek için kullanılan bir kural. Örneğin, üst ve alt bileşenleri olan bir bileşen ağacı, bir klasör yapısı vb. 8 | - **Alt ağaç (Subtree)**: Yeni bir kökten (ilk) başlayan ve yapraklarda (son) biten bir ağacın parçası. 9 | - **Kök (Root)**: Kök düzeni gibi bir ağaç veya alt ağaçtaki ilk düğüm. 10 | - **Yaprak (Leaf)**: Bir URL yolundaki son bölüm gibi, bir alt ağaçta çocuğu olmayan düğümler. 11 | 12 | <img alt="yönlendirme-temelleri-2" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fterminology-url-anatomy.png&w=3840&q=75&dpl=dpl_C2pSAYXZnY6DPcYmVfUv54azW3BJ" /><br/> 13 | 14 | - **URL Segmenti**: URL yolunun eğik çizgilerle ayrılmış bölümü. 15 | - **URL Yolu (Path)**: URL'nin etki alanından sonra gelen kısmı (segmentlerden oluşur). 16 | 17 | ## Uygulama Yönlendiricisi (App Router) 18 | 19 | Next.js, 13. sürümde React Sunucu Bileşenleri üzerine inşa edilen ve paylaşılan düzenleri, iç içe yönlendirmeyi, yükleme durumlarını, hata işlemeyi ve daha fazlasını destekleyen yeni bir **Uygulama Yönlendiricisi** sundu. 20 | 21 | Uygulama Yönlendiricisi, `app` adlı yeni bir dizinde çalışır. `app` dizini, aşamalı uyarlamaya izin vermek için `pages` dizini ile birlikte çalışır. Bu, uygulamanızın bazı rotalarını yeni davranışa seçerken diğer rotaları önceki davranış için `pages` dizininde tutmanıza olanak tanır. 22 | 23 | Uygulama Yönlendiricisi, Sayfa Yönlendiricisine göre önceliklidir. Dizinler arasındaki yönlendirmeler aynı URL yoluna çözümlenmemelidir ve bir çakışmayı önlemek için derleme zamanı hatasına neden olur. 24 | 25 | <img alt="uygulama-yönlendiricisi" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fnext-router-directories.png&w=3840&q=75&dpl=dpl_C2pSAYXZnY6DPcYmVfUv54azW3BJ" /><br/> 26 | 27 | Varsayılan olarak, uygulama içindeki bileşenler React Sunucu Bileşenleridir. Bu bir performans optimizasyonudur ve bunları kolayca benimsemenizi sağlar ve ayrıca İstemci Bileşenlerini de kullanabilirsiniz. 28 | 29 | ## Klasörlerin ve Dosyaların Rolleri 30 | 31 | Next.js dosya sistemi tabanlı bir yönlendirici kullanır: 32 | 33 | - **Klasörler** rotaları tanımlamak için kullanılır. Rota, **kök klasörden** `page.js` dosyasını içeren son bir **yaprak klasöre** kadar dosya sistemi hiyerarşisini takip eden, iç içe geçmiş klasörlerden oluşan tek bir yoldur. 34 | 35 | - **Dosyalar**, bir rota segmenti için gösterilen kullanıcı arayüzünü oluşturmak için kullanılır. 36 | 37 | ## Rota Segmentleri 38 | 39 | Bir rotadaki her klasör bir **rota segmentini** temsil eder. Her rota segmenti, bir **URL yolunda** karşılık gelen **segmentle** eşlenir. 40 | 41 | <img alt="rota segmentleri" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Froute-segments-to-path-segments.png&w=3840&q=75&dpl=dpl_C2pSAYXZnY6DPcYmVfUv54azW3BJ" /><br/> 42 | 43 | ## İç İçe Rotalar 44 | 45 | İç içe bir rota oluşturmak için klasörleri birbirinin içine yerleştirebilirsiniz. Örneğin, uygulama dizininde iki yeni klasörü iç içe yerleştirerek yeni bir `/dashboard/settings` rotası ekleyebilirsiniz. 46 | 47 | `dashboard/settings` rotası üç segmentten oluşur: 48 | 49 | - `/` (Kök segment) 50 | - `dashboard` (Segment) 51 | - `settings` (Yaprak segmenti) 52 | 53 | ## Dosya Kuralları 54 | 55 | Next.js, iç içe rotalarda belirli davranışlara sahip kullanıcı arayüzü oluşturmak için bir dizi özel dosya sağlar: 56 | 57 | | Dosya Adı | Açıklama | 58 | | -------------- | --------------------------------------------------------------------------------------------- | 59 | | `layout` | Bir segment ve alt segmentleri için paylaşılan kullanıcı arayüzü | 60 | | `page` | Bir rotanın benzersiz kullanıcı arayüzü ve rotaların herkesin erişimine açık hale getirilmesi | 61 | | `loading` | Bir segment ve alt segmentleri için `loading` kullanıcı arayüzü | 62 | | `not-found` | Bir segment ve alt segmentleri için `not-found` kullanıcı arayüzü | 63 | | `error` | Bir segment ve alt segmentleri için `error` kullanıcı arayüzü | 64 | | `global-error` | `global-error` Kullanıcı Arayüzü | 65 | | `route` | Sunucu tarafı API uç noktası | 66 | | `template` | Özelleştirilmiş yeniden render edilen Layout Kullanıcı Arayüzü | 67 | | `default` | [Paralel Rotalar]() için Yedek Kullanıcı Arayüzü | 68 | 69 | Bilmenizde fayda var: 70 | 71 | .js, .jsx veya .tsx dosya uzantıları bu özel dosyalar için kullanılabilir. 72 | 73 | ## Bileşen Hiyerarşisi 74 | 75 | Bir rota segmentinin özel dosyalarında tanımlanan React bileşenleri belirli bir hiyerarşi içinde oluşturulur: 76 | 77 | - `layout.js` 78 | - `template.js` 79 | - `error.js` (React hata sınırı) 80 | - `loading.js` (React gerilim sınırı) 81 | - `not-found.js` (React hata sınırı) 82 | - `page.js` veya iç içe `layout.js` 83 | 84 | <img alt="bileşen hiyerarşisi" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Ffile-conventions-component-hierarchy.png&w=3840&q=75&dpl=dpl_C2pSAYXZnY6DPcYmVfUv54azW3BJ" /><br/> 85 | 86 | İç içe geçmiş bir rotada, bir segmentin bileşenleri üst segmentinin bileşenlerinin **içinde** iç içe geçecektir. 87 | 88 | <img alt="bileşen hiyerarşisi-2" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fnested-file-conventions-component-hierarchy.png&w=3840&q=75&dpl=dpl_C2pSAYXZnY6DPcYmVfUv54azW3BJ" /><br/> 89 | 90 | ## Ortak Yerleşim 91 | 92 | Özel dosyalara ek olarak, kendi dosyalarınızı (örneğin bileşenler, stiller, testler vb.) `app` dizinindeki klasörlerin içine yerleştirme seçeneğiniz vardır. 93 | 94 | Bunun nedeni, klasörler rotaları tanımlarken, yalnızca `page.js` veya `route.js` tarafından döndürülen içeriklerin genel olarak adreslenebilir olmasıdır. 95 | 96 | <img alt="ortak yerleşim" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fproject-organization-colocation.png&w=3840&q=75&dpl=dpl_C2pSAYXZnY6DPcYmVfUv54azW3BJ" /><br/> 97 | 98 | ## İstemci Tarafında Gezinme ile Sunucu Merkezli Yönlendirme 99 | 100 | İstemci tarafı yönlendirme kullanan `pages` dizininin aksine, `app router`, Sunucu Bileşenleri ve sunucuda veri getirme ile uyum sağlamak için **sunucu merkezli yönlendirme** kullanır. Sunucu merkezli yönlendirme ile istemcinin bir rota haritası indirmesi gerekmez ve Sunucu Bileşenleri için aynı istek rotaları aramak için kullanılabilir. Bu optimizasyon tüm uygulamalar için yararlıdır, ancak çok sayıda rotaya sahip uygulamalar üzerinde daha büyük bir etkiye sahiptir. 101 | 102 | Yönlendirme sunucu merkezli olmasına rağmen, yönlendirici, Tek Sayfalı Uygulama davranışına benzeyen Bağlantı Bileşeni ile **istemci tarafında gezinmeyi** kullanır. Bu, bir kullanıcı yeni bir rotaya gittiğinde tarayıcının sayfayı yeniden yüklemeyeceği anlamına gelir. Bunun yerine, URL güncellenecek ve Next.js yalnızca değişen bölümleri oluşturacaktır. 103 | 104 | Ayrıca, kullanıcılar uygulamada gezinirken, yönlendirici React Sunucu Bileşeni yükünün sonucunu **bellek içi istemci tarafı önbelleğinde** saklar. Önbellek, herhangi bir seviyede geçersiz kılmaya izin veren ve React'in eşzamanlı render'ları arasında tutarlılık sağlayan rota segmentlerine bölünmüştür. Bu, belirli durumlarda, daha önce getirilmiş bir segmentin önbelleğinin yeniden kullanılabileceği ve performansı daha da artıracağı anlamına gelir. 105 | 106 | ## Kısmi Rendering 107 | 108 | Kardeş rotalar arasında gezinirken (örneğin aşağıdaki `/dashboard/settings` ve `/dashboard/analytics`), Next.js yalnızca değişen rotalardaki düzenleri ve sayfaları getirecek ve oluşturacaktır. Alt ağaçtaki segmentlerin üzerindeki hiçbir şeyi yeniden **getirmeyecek veya yeniden oluşturmayacaktır**. Bu, bir düzeni paylaşan rotalarda, bir kullanıcı kardeş sayfalar arasında gezindiğinde düzenin korunacağı anlamına gelir. 109 | 110 | <img alt="kısmi rendering" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fpartial-rendering.png&w=3840&q=75&dpl=dpl_C2pSAYXZnY6DPcYmVfUv54azW3BJ" /><br/> 111 | 112 | Kısmi rendering olmadan, her gezinti tüm sayfanın sunucuda yeniden işlenmesine neden olur. Yalnızca güncellenen bölümün render edilmesi, aktarılan veri miktarını ve yürütme süresini azaltarak performansın artmasını sağlar. 113 | 114 | ## Gelişmiş Yönlendirme Kalıpları 115 | 116 | Uygulama Yönlendirici ayrıca daha gelişmiş yönlendirme modellerini uygulamanıza yardımcı olacak bir dizi kural sunar. Bunlar şunları içerir: 117 | 118 | - Paralel Rotalar: Aynı görünümde bağımsız olarak gezinilebilen iki veya daha fazla sayfayı aynı anda göstermenizi sağlar. Bunları, kendi alt navigasyonları olan bölünmüş görünümler için kullanabilirsiniz. Örn. gösterge tabloları. 119 | - Rotaları Kesme: Bir rotayı kesmenize ve başka bir rota bağlamında göstermenize izin verir. Geçerli sayfanın bağlamını korumak önemli olduğunda bunları kullanabilirsiniz. Örneğin, bir görevi düzenlerken tüm görevleri görmek veya bir akıştaki bir fotoğrafı genişletmek. 120 | -------------------------------------------------------------------------------- /3-rendering/1-static-and-dynamic-rendering/Readme.md: -------------------------------------------------------------------------------- 1 | # Statik ve Dinamik Render Etme (Static and Dynamic Rendering) 2 | 3 | Next.js'de bir rota statik veya dinamik olarak render edilebilir. 4 | 5 | - Statik bir rotada, bileşenler derleme zamanında sunucuda render edilir. Çalışmanın sonucu önbelleğe alınır ve sonraki isteklerde yeniden kullanılır. 6 | - Dinamik bir rotada, bileşenler istek zamanında sunucuda render edilir. 7 | 8 | ## Statik Render Etme (Varsayılan) 9 | 10 | Varsayılan olarak Next.js, performansı artırmak için rotaları statik olarak render eder. Bu, tüm işleme işinin önceden yapıldığı ve kullanıcıya coğrafi olarak daha yakın bir İçerik Dağıtım Ağı'ndan (CDN) sunulabileceği anlamına gelir. 11 | 12 | ## Statik Veri Getirme (Varsayılan) 13 | 14 | Next.js varsayılan olarak, önbelleğe alma davranışını özellikle devre dışı bırakmayan `fetch()` isteklerinin sonucunu önbelleğe alacaktır. Bu, bir `cache` seçeneği belirlemeyen fetch isteklerinin `force-cache` seçeneğini kullanacağı anlamına gelir. 15 | 16 | Rotadaki herhangi bir getirme isteği `revalidate` seçeneğini kullanırsa, rota revalidation sırasında statik olarak yeniden render edilir. 17 | 18 | ## Dinamik Render Etme 19 | 20 | Statik render etme sırasında, dinamik bir işlev veya dinamik bir `fetch()` isteği (no caching) keşfedilirse, Next.js istek anında tüm rotayı dinamik olarak render etmeye geçecektir. Önbelleğe alınan tüm veri istekleri dinamik render etme sırasında yeniden kullanılabilir. 21 | 22 | Bu tablo, dinamik işlevlerin ve önbelleğe almanın bir rotanın render etme davranışını nasıl etkilediğini özetlemektedir: 23 | 24 | | Data Fetching | Dinamik Fonksiyonlar | Render Etme | 25 | | --------------- | -------------------- | ----------- | 26 | | Statik (Cached) | Hayır | Statik | 27 | | Statik (Cached) | Evet | Dinamik | 28 | | Not Cached | Hayır | Dinamik | 29 | | Not Cached | Evet | Dinamik | 30 | 31 | Veri getirmenin önbelleğe alınıp alınmadığına bakılmaksızın, dinamik işlevlerin rotayı her zaman dinamik görüntülemeye nasıl tercih ettiğine dikkat edin. Başka bir deyişle, statik render etme yalnızca veri getirme davranışına değil, aynı zamanda rotada kullanılan dinamik işlevlere de bağlıdır. 32 | 33 | Bilmekte fayda var: Gelecekte Next.js, bir rotadaki düzenlerin ve sayfaların tüm rota yerine bağımsız olarak statik veya dinamik olarak oluşturulabileceği hibrit sunucu tarafı oluşturmayı tanıtacaktır. 34 | 35 | ## Dinamik Fonksiyonlar (Dynamic Functions) 36 | 37 | Dinamik fonksiyonlar, kullanıcının çerezleri, mevcut istek başlıkları veya URL'nin arama paramları gibi yalnızca istek sırasında bilinebilecek bilgilere dayanır. Next.js'de bu dinamik fonksiyonlar şunlardır: 38 | 39 | - Bir Sunucu Bileşeninde `cookies()` veya `headers()` kullanılması, istek anında tüm rotayı dinamik render etmeye tercih edecektir. 40 | - İstemci Bileşenlerinde `useSearchParams()` kullanılması statik render etmeyi atlar ve bunun yerine tüm İstemci Bileşenlerini istemcideki en yakın üst Suspense sınırına kadar render eder. 41 | - `useSearchParams()` kullanan İstemci Bileşenini bir `<Suspense/>` sınırına sarmanızı öneririz. Bu, üzerindeki tüm İstemci Bileşenlerinin statik olarak render edilmesini sağlayacaktır. 42 | - `searchParams` Pages prop'unu kullanmak, sayfayı istek anında dinamik render etmeye tercih edecektir. 43 | 44 | ## Dinamik Veri Getirme 45 | 46 | Dinamik veri getirme işlemleri, önbellek seçeneğini `'no-store'` veya `revalidate` değerini 0 olarak ayarlayarak önbellekleme davranışını özellikle devre dışı bırakan `fetch()` istekleridir. 47 | 48 | Bir düzen veya sayfadaki tüm `fetch` istekleri için önbelleğe alma seçenekleri segment yapılandırma nesnesi kullanılarak da ayarlanabilir. 49 | 50 | -------------------------------------------------------------------------------- /3-rendering/2-edge-and-nodejs-runtimes/Readme.md: -------------------------------------------------------------------------------- 1 | # Edge ve Node.js Çalışma Zamanları (Edge and Node.js Runtimes) 2 | 3 | Next.js bağlamında "çalışma zamanı", yürütme sırasında kodunuz tarafından kullanılabilen kütüphaneler, API'ler ve genel işlevsellik kümesini ifade eder. 4 | 5 | Next.js, uygulama kodunuzun bazı bölümlerini oluşturabileceğiniz iki sunucu çalışma zamanına sahiptir: 6 | 7 | - Node.js Çalışma Zamanı 8 | - Edge Çalışma Zamanı 9 | - Her çalışma zamanının kendi API'leri vardır. Mevcut API'lerin tam listesi için lütfen [Node.js Docs](https://nodejs.org/docs/latest/api/) ve [Edge Docs](https://nextjs.org/docs/app/api-reference/edge)'a bakın. Her iki çalışma zamanı da dağıtım altyapınıza bağlı olarak akışı destekleyebilir. 10 | 11 | Varsayılan olarak, `app` dizini Node.js çalışma zamanını kullanır. Ancak, rota bazında farklı çalışma zamanlarını (örn. Edge) seçebilirsiniz. 12 | 13 | ## Çalışma Zamanı Farklılıkları 14 | 15 | Bir çalışma zamanı seçerken dikkat edilmesi gereken birçok husus vardır. Bu tablo bir bakışta önemli farklılıkları göstermektedir. Farklılıkların daha derinlemesine bir analizini istiyorsanız, aşağıdaki bölümlere göz atın. 16 | | | Node | Serverless | Edge | 17 | |---------|----------------|------------|----------| 18 | | Cold Boot | / | ~250ms | Anında | 19 | | HTTP Streaming | Evet | Evet | Evet | 20 | | IO | Hepsi | Hepsi | `fetch` | 21 | | Scalability | / | Yüksek | En Yüksek | 22 | | Security | Normal | Yüksek | Yüksek | 23 | | Latency | Normal | Düşük | En Düşük | 24 | | npm Packages | Hepsi | Hepsi | Daha küçük bir alt küme | 25 | 26 | ## Edge Çalışma Zamanı 27 | 28 | Next.js'de hafif Edge Runtime, mevcut Node.js API'lerinin bir alt kümesidir. 29 | 30 | Küçük, basit işlevlerle düşük gecikme süresinde dinamik, kişiselleştirilmiş içerik sunmanız gerekiyorsa Edge Runtime idealdir. Edge Runtime'ın hızı minimum kaynak kullanımından gelir, ancak bu birçok senaryoda sınırlayıcı olabilir. 31 | 32 | Örneğin, Vercel'de Edge Runtime'da yürütülen kod [1 MB ile 4 MB arasını geçemez](https://vercel.com/docs/concepts/limits/overview#edge-middleware-and-edge-functions-size), bu sınır içe aktarılan paketleri, yazı tiplerini ve dosyaları içerir ve dağıtım altyapınıza bağlı olarak değişir. 33 | 34 | ##  Node.js Çalışma Zamanı 35 | 36 | Node.js çalışma zamanını kullanmak, tüm Node.js API'lerine ve bunlara dayanan tüm npm paketlerine erişmenizi sağlar. Ancak, başlatılması Edge çalışma zamanını kullanan rotalar kadar hızlı değildir. 37 | 38 | Next.js uygulamanızı bir Node.js sunucusuna dağıtmak, altyapınızı yönetmeyi, ölçeklendirmeyi ve yapılandırmayı gerektirecektir. Alternatif olarak, Next.js uygulamanızı Vercel gibi sunucusuz bir platforma dağıtmayı düşünebilirsiniz; bu platform bunu sizin için halledecektir. 39 | 40 | ## Sunucusuz Node.js 41 | 42 | Edge Runtime'dan daha karmaşık hesaplama yüklerini kaldırabilecek ölçeklenebilir bir çözüme ihtiyacınız varsa Sunucusuz idealdir. Örneğin Vercel'deki Sunucusuz İşlevler ile içe aktarılan paketler, yazı tipleri ve dosyalar dahil olmak üzere toplam kod boyutunuz [50 MB](https://vercel.com/docs/concepts/limits/overview#serverless-function-size)'tır. 43 | 44 | Edge kullanan rotalara kıyasla dezavantajı, Sunucusuz İşlevlerin istekleri işlemeye başlamadan önce önyükleme yapmasının yüzlerce milisaniye sürebilmesidir. Sitenizin aldığı trafik miktarına bağlı olarak, işlevler sık sık "ısınmadığı" için bu sık karşılaşılan bir durum olabilir. 45 | 46 | ## Örnekler 47 | 48 | ### Segment Çalışma Zamanı Seçeneği 49 | 50 | Next.js uygulamanızda tek tek rota segmentleri için bir çalışma zamanı belirleyebilirsiniz. Bunu yapmak için, runtime adında bir değişken tanımlayın ve dışa aktarın. Değişken bir dize olmalı ve `'nodejs'` ya da `'edge'` runtime değerine sahip olmalıdır. 51 | 52 | Aşağıdaki örnekte, `'edge'` değerine sahip bir çalışma zamanını dışa aktaran bir sayfa rotası segmenti gösterilmektedir: 53 | 54 | ```ts 55 | export const runtime = "edge"; // 'nodejs' (varsayılan) | 'edge' 56 | ``` 57 | 58 | Segment çalışma zamanı ayarlanmazsa, varsayılan `nodejs` çalışma zamanı kullanılacaktır. Node.js çalışma zamanından değiştirmeyi planlamıyorsanız çalışma zamanı seçeneğini kullanmanıza gerek yoktur. 59 | -------------------------------------------------------------------------------- /3-rendering/Readme.md: -------------------------------------------------------------------------------- 1 | # Render Etme (Rendering) 2 | 3 | Render etme, yazdığınız kodu kullanıcı arayüzlerine dönüştürür. 4 | 5 | React 18 ve Next.js 13, uygulamanızı render etmenin yeni yollarını tanıttı. Bu sayfa, render ortamları, stratejileri, çalışma zamanları arasındaki farkları ve bunlara nasıl dahil olacağınızı anlamanıza yardımcı olacaktır. 6 | 7 | ## Render etme Ortamları 8 | 9 | Uygulama kodunuzun işlenebileceği iki ortam vardır: istemci ve sunucu. 10 | 11 | <img alt="render" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fclient-and-server-environments.png&w=3840&q=75&dpl=dpl_Fes67gTLa5ScjbSLtJLVo9u4FfQK"/><br/> 12 | 13 | - İstemci, uygulama kodunuz için bir sunucuya istek gönderen bir kullanıcının cihazındaki tarayıcıyı ifade eder. Daha sonra sunucudan gelen yanıtı kullanıcının etkileşime girebileceği bir arayüze dönüştürür. 14 | - Sunucu, bir veri merkezinde uygulama kodunuzu depolayan, istemciden gelen istekleri alan, bazı hesaplamalar yapan ve uygun bir yanıtı geri gönderen bilgisayarı ifade eder. 15 | 16 | ## Bileşen Düzeyinde İstemci ve Sunucu Render Etme 17 | 18 | React 18'den önce, React kullanarak uygulamanızı oluşturmanın birincil yolu tamamen istemcideydi. 19 | 20 | Next.js, uygulamanızı sayfalara ayırmak ve HTML oluşturup React tarafından [hidrasyon](https://react.dev/reference/react-dom/hydrate#hydrating-server-rendered-html) edilmek üzere istemciye göndererek sunucuda önceden render etmek için daha kolay bir yol sağladı. Ancak bu, ilk HTML'yi etkileşimli hale getirmek için istemcide ek JavaScript'e ihtiyaç duyulmasına neden oldu. 21 | 22 | Şimdi, Sunucu ve İstemci Bileşenleri ile React, istemci ve sunucuda render edebilir, yani bileşen düzeyinde render etme ortamını seçebilirsiniz. 23 | 24 | Varsayılan olarak, `app` yönlendiricisi Sunucu Bileşenlerini kullanır, bu da bileşenleri sunucuda kolayca render etmenize ve istemciye gönderilen JavaScript miktarını azaltmanıza olanak tanır. 25 | 26 | ## Sunucuda Statik ve Dinamik Render Etme 27 | 28 | React bileşenleriyle istemci tarafı ve sunucu tarafı render etmeye ek olarak Next.js, Statik ve Dinamik render etme ile sunucuda render etmeyi optimize etme seçeneği sunar. 29 | 30 | ### Statik Render Etme 31 | 32 | Static Render Etme ile hem Sunucu hem de İstemci Bileşenleri derleme zamanında sunucuda önceden render edilebilir. Çalışmanın sonucu önbelleğe alınır ve sonraki isteklerde yeniden kullanılır. Önbelleğe alınan sonuç da yeniden doğrulanabilir. 33 | 34 | Bilmekte fayda var: Bu, Pages Router'daki Static Site Generation (SSG) ve Incremental Static Regeneration (ISR) ile eşdeğerdir. 35 | 36 | Statik render etme sırasında Sunucu ve İstemci Bileşenleri farklı şekilde render edilir: 37 | 38 | - İstemci Bileşenlerinin HTML ve JSON'ları önceden render edilir ve sunucuda önbelleğe alınır. Önbelleğe alınan sonuç daha sonra hidrasyon için istemciye gönderilir. 39 | - Sunucu Bileşenleri React tarafından sunucuda render edilir ve yükleri HTML oluşturmak için kullanılır. Aynı işlenmiş yük, bileşenleri istemcide hidrasyon edilmek için de kullanılır ve istemcide JavaScript gerekmez. 40 | 41 | ### Dinamik Render Etme 42 | 43 | Dinamik Render Etme ile hem Sunucu hem de İstemci Bileşenleri istek anında sunucu üzerinde render edilir. Çalışmanın sonucu önbelleğe alınmaz. 44 | 45 | Bilmekte fayda var: Bu, Pages Router'daki Sunucu Tarafı Oluşturmaya (`getServerSideProps()`) eşdeğerdir. 46 | 47 | ## Edge ve Node.js Çalışma Zamanları 48 | 49 | Sunucuda, sayfalarınızın render edilebileceği iki çalışma zamanı vardır: 50 | 51 | - Node.js Çalışma Zamanı (varsayılan) tüm Node.js API'lerine ve ekosistemdeki uyumlu paketlere erişime sahiptir. 52 | - Edge Çalışma Zamanı, Web API'lerini temel alır. 53 | 54 | Her iki çalışma zamanı da dağıtım altyapınıza bağlı olarak sunucudan akışı destekler. 55 | 56 | -------------------------------------------------------------------------------- /4-data-fetching/1-fetching/Readme.md: -------------------------------------------------------------------------------- 1 | # Veri Getirme (Data Fetching) 2 | 3 | Next.js App Router, fonksiyonu `async` olarak işaretleyerek ve [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) için `await` kullanarak verileri doğrudan React bileşenlerinizden almanıza olanak tanır. 4 | 5 | Veri getirme, [`fetch()` Web API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)'si ve React Sunucu Bileşenleri üzerine inşa edilmiştir. `fetch()` kullanıldığında, istekler varsayılan olarak otomatik olarak düşülür. 6 | 7 | Next.js, her isteğin kendi önbelleğe alma ve yeniden doğrulamasını ayarlamasına izin vermek için `fetch` options nesnesini genişletir. 8 | 9 | ## Sunucu Bileşenlerinde `async` ve `await` 10 | 11 | Sunucu Bileşenlerinde veri almak için `async` ve `await` kullanabilirsiniz. 12 | 13 | ```tsx 14 | async function getData() { 15 | const res = await fetch("https://api.example.com/..."); 16 | // Dönüş değeri *seri hale getirilmez* 17 | // Tarih, Harita, Set, vb. döndürebilirsiniz. 18 | 19 | // Öneri: hataları ele alın 20 | if (!res.ok) { 21 | // Bu, en yakın `error.js` Hata Sınırını etkinleştirecektir 22 | throw new Error("Failed to fetch data"); 23 | } 24 | 25 | return res.json(); 26 | } 27 | 28 | export default async function Page() { 29 | const data = await getData(); 30 | 31 | return <main></main>; 32 | } 33 | ``` 34 | 35 | **Bilmekte fayda var:** 36 | 37 | TypeScript ile bir `async` Sunucu Bileşeni kullanmak için TypeScript `5.1.3` veya üstünü ve `@types/react` `18.2.8` veya üstünü kullandığınızdan emin olun. 38 | 39 | ## Sunucu Bileşeni İşlevleri 40 | 41 | Next.js, Sunucu Bileşenlerinde veri getirirken ihtiyaç duyabileceğiniz yararlı sunucu işlevleri sağlar: 42 | 43 | - `cookies()` 44 | - `headers()` 45 | 46 | ## İstemci Bileşenlerinde `use` 47 | 48 | `use`, kavramsal olarak `await`'e benzer bir promise kabul eden yeni bir React fonksiyonudur. `use`, bir fonksiyon tarafından döndürülen promise'i bileşenler, hook'lar ve Suspense ile uyumlu bir şekilde işler. [React RFC](https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md#usepromise)'de `use` hakkında daha fazla bilgi edinin. 49 | 50 | `fetch` işleminin `use`'a sarılması şu anda İstemci Bileşenlerinde önerilmemektedir ve birden fazla yeniden render etmeyi tetikleyebilir. Şimdilik, bir İstemci Bileşeninde veri getirmeniz gerekiyorsa, [SWR](https://swr.vercel.app/) veya [React Query](https://tanstack.com/query/v4) gibi üçüncü taraf bir kütüphane kullanmanızı öneririz. 51 | 52 | ## Statik Veri Getirme (Static Data Fetching) 53 | 54 | Varsayılan olarak, `fetch` otomatik olarak verileri süresiz olarak getirecek ve önbelleğe alacaktır. 55 | 56 | ```tsx 57 | fetch("https://..."); // cache: 'force-cache' varsayılandır 58 | ``` 59 | 60 | ## Verileri Yeniden Doğrulama (Revalidating Data) 61 | 62 | Önbelleğe alınan verileri belirli bir zaman aralığında yeniden doğrulamak için `fetch()` işlevinde `next.revalidate` seçeneğini kullanarak bir kaynağın önbellek ömrünü (saniye cinsinden) ayarlayabilirsiniz. 63 | 64 | ```tsx 65 | fetch("https://...", { next: { revalidate: 10 } }); 66 | ``` 67 | 68 | ## Dinamik Veri Getirme (Dynamic Data Fetching) 69 | 70 | Her `fetch` isteğinde yeni veri almak için `cache: 'no-store'` seçeneğini kullanın. 71 | 72 | ```tsx 73 | fetch("https://...", { cache: "no-store" }); 74 | ``` 75 | 76 | ## Veri Getirme Kalıpları (Data Fetching Patterns) 77 | 78 | ### Paralel Veri Getirme (Parallel Data Fetching) 79 | 80 | İstemci-sunucu şelalelerini en aza indirmek için, verileri paralel olarak almak üzere bu modeli öneriyoruz: 81 | 82 | ```tsx 83 | import Albums from "./albums"; 84 | 85 | async function getArtist(username: string) { 86 | const res = await fetch(`https://api.example.com/artist/${username}`); 87 | return res.json(); 88 | } 89 | 90 | async function getArtistAlbums(username: string) { 91 | const res = await fetch(`https://api.example.com/artist/${username}/albums`); 92 | return res.json(); 93 | } 94 | 95 | export default async function Page({ 96 | params: { username }, 97 | }: { 98 | params: { username: string }; 99 | }) { 100 | // Her iki talebi de paralel olarak başlatın 101 | const artistData = getArtist(username); 102 | const albumsData = getArtistAlbums(username); 103 | 104 | // Sözlerin çözülmesini bekleyin 105 | const [artist, albums] = await Promise.all([artistData, albumsData]); 106 | 107 | return ( 108 | <> 109 | <h1>{artist.name}</h1> 110 | <Albums list={albums}></Albums> 111 | </> 112 | ); 113 | } 114 | ``` 115 | 116 | Sunucu Bileşeninde `await`'i çağırmadan önce getirme işlemini başlatarak, her istek aynı anda istekleri getirmeye başlayabilir. Bu, bileşenleri şelalelerden kaçınabileceğiniz şekilde ayarlar. 117 | 118 | Her iki isteği paralel olarak başlatarak zamandan tasarruf edebiliriz, ancak kullanıcı her iki söz de çözümlenene kadar işlenen sonucu göremez. 119 | 120 | Kullanıcı deneyimini iyileştirmek için, render çalışmasını bölmek ve sonucun bir kısmını mümkün olan en kısa sürede göstermek üzere bir askı sınırı ekleyebilirsiniz: 121 | 122 | ```tsx 123 | import { getArtist, getArtistAlbums, type Album } from "./api"; 124 | 125 | export default async function Page({ 126 | params: { username }, 127 | }: { 128 | params: { username: string }; 129 | }) { 130 | // Her iki talebi de paralel olarak başlatın 131 | const artistData = getArtist(username); 132 | const albumData = getArtistAlbums(username); 133 | 134 | // Önce sanatçının sözünün yerine gelmesini bekleyin 135 | const artist = await artistData; 136 | 137 | return ( 138 | <> 139 | <h1>{artist.name}</h1> 140 | {/* Önce sanatçı bilgilerini gönderin, 141 | ve albümleri bir gerilim sınırına sarın */} 142 | <Suspense fallback={<div>Loading...</div>}> 143 | <Albums promise={albumData} /> 144 | </Suspense> 145 | </> 146 | ); 147 | } 148 | 149 | // Album Bileşeni 150 | async function Albums({ promise }: { promise: Promise<Album[]> }) { 151 | // Albüm sözünün çözülmesini bekleyin 152 | const albums = await promise; 153 | 154 | return ( 155 | <ul> 156 | {albums.map((album) => ( 157 | <li key={album.id}>{album.name}</li> 158 | ))} 159 | </ul> 160 | ); 161 | } 162 | ``` 163 | 164 | ### Sıralı Veri Getirme (Sequential Data Fetching) 165 | 166 | Verileri sıralı olarak getirmek için, doğrudan ihtiyaç duyan bileşenin içinden getirebilir veya getirme işleminin sonucunu ihtiyaç duyan bileşenin içinde bekleyebilirsiniz: 167 | 168 | ```tsx 169 | // ... 170 | 171 | async function Playlists({ artistID }: { artistID: string }) { 172 | // Wait for the playlists 173 | const playlists = await getArtistPlaylists(artistID); 174 | 175 | return ( 176 | <ul> 177 | {playlists.map((playlist) => ( 178 | <li key={playlist.id}>{playlist.name}</li> 179 | ))} 180 | </ul> 181 | ); 182 | } 183 | 184 | export default async function Page({ 185 | params: { username }, 186 | }: { 187 | params: { username: string }; 188 | }) { 189 | // Wait for the artist 190 | const artist = await getArtist(username); 191 | 192 | return ( 193 | <> 194 | <h1>{artist.name}</h1> 195 | <Suspense fallback={<div>Loading...</div>}> 196 | <Playlists artistID={artist.id} /> 197 | </Suspense> 198 | </> 199 | ); 200 | } 201 | ``` 202 | 203 | Bileşen içinde veri getirerek, rotadaki her bir getirme isteği ve iç içe geçmiş segment, önceki istek veya segment tamamlanana kadar veri getirmeye ve oluşturmaya başlayamaz. 204 | 205 | ### Bir Rotada Oluşturmayı Engelleme (Blocking Rendering in a Route) 206 | 207 | Verileri bir layoutta getirerek, altındaki tüm rota segmentleri için işleme yalnızca veriler yüklendikten sonra başlayabilir. 208 | 209 | `pages` dizininde, sunucu oluşturma kullanan sayfalar `getServerSideProps` bitene kadar tarayıcı yükleme döndürücüsünü gösterecek, ardından o sayfa için React bileşenini oluşturacaktı. Bu, "ya hep ya hiç" veri getirme olarak tanımlanabilir. Ya sayfanız için tüm verilere sahip olurdunuz ya da hiçbirine sahip olmazdınız. 210 | 211 | `app` dizininde, keşfedebileceğiniz ek seçenekler vardır: 212 | 213 | 1. İlk olarak, veri getirme işlevinizden gelen sonucu aktarırken sunucudan anlık bir yükleme durumu göstermek için `loading.js` kullanabilirsiniz. 214 | 2. İkinci olarak, veri getirme işlemini bileşen ağacında daha aşağıya taşıyarak yalnızca sayfanın ihtiyaç duyulan bölümleri için görüntülemeyi engelleyebilirsiniz. Örneğin, veri getirmeyi kök düzende getirmek yerine belirli bir bileşene taşıyabilirsiniz. 215 | 216 | Mümkün olduğunda, verileri onu kullanan segmentte almak en iyisidir. Bu aynı zamanda sayfanın tamamı için değil, yalnızca yüklenen kısmı için bir yükleme durumu göstermenize olanak tanır. 217 | 218 | ## `fetch()` olmadan Veri Getirme (Data Fetching without `fetch()`) 219 | 220 | ORM veya veritabanı istemcisi gibi üçüncü taraf bir kütüphane kullanıyorsanız, `fetch` isteklerini doğrudan kullanma ve yapılandırma olanağına her zaman sahip olmayabilirsiniz. 221 | 222 | `fetch` özelliğini kullanamadığınız ancak yine de bir düzen veya sayfanın önbelleğe alma veya yeniden doğrulama davranışını kontrol etmek istediğiniz durumlarda, segmentin varsayılan önbelleğe alma davranışına güvenebilir veya segment önbelleği yapılandırmasını kullanabilirsiniz. 223 | 224 | ### Varsayılan Önbelleğe Alma Davranışı (Default Caching Behavior) 225 | 226 | Doğrudan `fetch` kullanmayan herhangi bir veri getirme kütüphanesi bir rotanın önbelleğe alınmasını etkilemeyecek ve rota segmentine bağlı olarak statik veya dinamik olacaktır. 227 | 228 | Segment statikse (varsayılan), isteğin çıktısı segmentin geri kalanıyla birlikte önbelleğe alınır ve yeniden doğrulanır (yapılandırılmışsa). Segment dinamikse, isteğin çıktısı önbelleğe alınmaz ve segment işlendiğinde her istekte yeniden taranır. 229 | 230 | ## Segment Önbellek Yapılandırması (Segment Cache Configuration) 231 | 232 | Geçici bir çözüm olarak, üçüncü taraf sorgularının önbelleğe alma davranışı yapılandırılana kadar, tüm segmentin önbellek davranışını özelleştirmek için segment yapılandırmasını kullanabilirsiniz. 233 | 234 | ```tsx 235 | import prisma from "./lib/prisma"; 236 | 237 | export const revalidate = 3600; // her saat yeniden doğrulama 238 | 239 | async function getPosts() { 240 | const posts = await prisma.post.findMany(); 241 | return posts; 242 | } 243 | 244 | export default async function Page() { 245 | const posts = await getPosts(); 246 | // ... 247 | } 248 | ``` 249 | -------------------------------------------------------------------------------- /4-data-fetching/2-caching/Readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emre-turan/turkce-next.js-egitimi/f9186dbe31f59c477bab786bf97094c1ff0a8480/4-data-fetching/2-caching/Readme.md -------------------------------------------------------------------------------- /4-data-fetching/3-revalidating/Readme.md: -------------------------------------------------------------------------------- 1 | # Verileri Yeniden Doğrulama (Revalidating) 2 | 3 | Next.js, sitenizin tamamını yeniden oluşturmanıza gerek kalmadan belirli statik rotaları güncellemenizi sağlar. Revalidation (Incremental Static Regeneration olarak da bilinir), milyonlarca sayfaya ölçeklenirken statik avantajlarını korumanıza olanak tanır. 4 | 5 | Next.js'de iki tür yeniden doğrulama vardır: 6 | 7 | - **Arka plan:** Verileri belirli bir zaman aralığında yeniden doğrular. 8 | - **İsteğe bağlı:** Güncelleme gibi bir olaya bağlı olarak verileri yeniden doğrular. 9 | 10 | ## Arka Plan Revalidasyonu (Background Revalidation) 11 | 12 | Önbelleğe alınan verileri belirli bir aralıkta yeniden doğrulamak için `fetch()` işlevinde `next.revalidate` seçeneğini kullanarak bir kaynağın `cache` ömrünü (saniye cinsinden) ayarlayabilirsiniz. 13 | 14 | ```ts 15 | fetch("https://...", { next: { revalidate: 60 } }); 16 | ``` 17 | 18 | `fetch` kullanmayan verileri yeniden doğrulamak istiyorsanız (yani harici bir paket veya sorgu oluşturucu kullanarak), rota segmenti yapılandırmasını kullanabilirsiniz. 19 | 20 | ```ts 21 | export const revalidate = 60; // bu sayfayı her 60 saniyede bir yeniden doğrula 22 | ``` 23 | 24 | ### Nasıl çalışır? 25 | 26 | 1. Derleme sırasında statik olarak işlenmiş olan rotaya bir istek yapıldığında, başlangıçta önbelleğe alınmış veriler gösterilir. 27 | 2. İlk istekten sonra ve 60 saniyeden önce rotaya yapılan tüm istekler de önbelleğe alınır ve anlık olarak gösterilir. 28 | 3. 60 saniyelik pencereden sonra, bir sonraki istek hala önbelleğe alınmış (eski) verileri gösterecektir. 29 | 4. Next.js arka planda verilerin yenilenmesini tetikleyecektir. 30 | 5. Rota başarıyla oluşturulduktan sonra Next.js önbelleği geçersiz kılacak ve güncellenmiş rotayı gösterecektir. Arka planda yenileme başarısız olursa, eski veriler hala değiştirilmemiş olacaktır. 31 | 32 | Oluşturulmamış bir rota segmentine bir istek yapıldığında, Next.js ilk istekte rotayı dinamik olarak oluşturacaktır. Daha sonraki istekler önbellekten statik rota segmentlerini sunacaktır. 33 | 34 | **Bilmekte fayda var:** Yukarı akış veri sağlayıcınızda önbelleğin varsayılan olarak etkin olup olmadığını kontrol edin. Devre dışı bırakmanız gerekebilir (örn. `useCdn: false`), aksi takdirde bir yeniden doğrulama ISR önbelleğini güncellemek için yeni verileri çekemez. Önbellekleme, `Cache-Control` başlığını döndürdüğünde bir CDN'de (talep edilen bir uç nokta için) gerçekleşebilir. Vercel üzerindeki [ISR önbelleği global olarak sürdürür ve geri alma işlemlerini](https://vercel.com/docs/concepts/incremental-static-regeneration/overview) gerçekleştirir. 35 | 36 | ## İsteğe Bağlı Yeniden Doğrulama (On-Demand Revalidation) 37 | 38 | `revalidate` süresini `60` olarak ayarlarsanız, tüm ziyaretçiler sitenizin oluşturulan aynı sürümünü bir dakika boyunca görür. Önbelleği geçersiz kılmanın tek yolu, bir dakika geçtikten sonra birinin sayfayı ziyaret etmesidir. 39 | 40 | Next.js Uygulama Yönlendiricisi, bir rota veya önbellek etiketine dayalı olarak içeriğin isteğe bağlı olarak yeniden doğrulanmasını destekler. Bu, belirli getirmeler için Next.js önbelleğini manuel olarak temizlemenize olanak tanıyarak sitenizi ne zaman güncelleyeceğinizi kolaylaştırır: 41 | 42 | - Başlıksız CMS'nizden içerik oluşturulur veya güncellenir. 43 | - E-ticaret meta verileri değişir (fiyat, açıklama, kategori, yorumlar vb.). 44 | 45 | ## İsteğe Bağlı Yeniden Doğrulama Kullanımı (Using On-Demand Revalidation) 46 | 47 | Veriler isteğe bağlı olarak yola (`revalidatePath`) veya önbellek etiketine (`revalidateTag`) göre yeniden doğrulanabilir. 48 | 49 | Örneğin, aşağıdaki `fetch` işlemi önbellek etiket `koleksiyonunu` ekler: 50 | 51 | ```ts 52 | export default async function Page() { 53 | const res = await fetch("https://...", { next: { tags: ["collection"] } }); 54 | const data = await res.json(); 55 | // ... 56 | } 57 | ``` 58 | 59 | Önbelleğe alınan bu veriler daha sonra bir Rota İşleyicide `revalidateTag` çağrısı yapılarak talep üzerine yeniden doğrulanabilir. 60 | 61 | ```ts 62 | import { NextRequest, NextResponse } from "next/server"; 63 | import { revalidateTag } from "next/cache"; 64 | 65 | export async function GET(request: NextRequest) { 66 | const tag = request.nextUrl.searchParams.get("tag"); 67 | revalidateTag(tag); 68 | return NextResponse.json({ revalidated: true, now: Date.now() }); 69 | } 70 | ``` 71 | 72 | ## Hata İşleme ve Yeniden Doğrulama 73 | 74 | Verileri yeniden doğrulamaya çalışırken bir hata atılırsa, başarıyla oluşturulan son veriler önbellekten sunulmaya devam eder. Sonraki bir sonraki istekte, Next.js verileri yeniden doğrulamayı yeniden deneyecektir. 75 | -------------------------------------------------------------------------------- /4-data-fetching/Readme.md: -------------------------------------------------------------------------------- 1 | # Veri Getirme (Data Fetching) 2 | 3 | Next.js App Router, React ve Web platformu üzerine inşa edilmiş yeni, basitleştirilmiş bir veri getirme sistemi sunar. 4 | 5 | ## `fetch()` API 6 | 7 | Yeni veri getirme sistemi, yerel [fetch() Web API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)'sinin üzerine inşa edilmiştir ve Sunucu Bileşenlerinde `async` ve `await`'i kullanır. 8 | 9 | - React, otomatik istek tekilleştirme sağlamak için `fetch`'i genişletir. 10 | - Next.js, her isteğin kendi önbelleğe alma ve yeniden doğrulama kurallarını belirlemesine izin vermek için `fetch` options nesnesini genişletir. 11 | 12 | ### Sunucudan Veri Getirme (Fetching Data on the Server) 13 | 14 | Mümkün oldukça, Sunucu Bileşenlerinde veri getirmenizi öneririz. Sunucu Bileşenleri **her zaman sunucudan veri getirir**. Bu size şunları sağlar: 15 | 16 | - Arka uç veri kaynaklarına (ör. veritabanları) doğrudan erişime sahip olun. 17 | - Erişim belirteçleri ve API anahtarları gibi hassas bilgilerin istemciye ifşa edilmesini önleyerek uygulamanızı daha güvenli tutun. 18 | - Verileri alın ve aynı ortamda işleyin. Bu, hem istemci ve sunucu arasındaki ileri geri iletişimi hem de istemcideki ana iş parçacığı üzerindeki çalışmayı azaltır. 19 | - İstemcide birden fazla ayrı istek yerine tek bir gidiş-dönüş ile birden fazla veri getirme işlemi gerçekleştirin. 20 | - İstemci-sunucu şelalelerini azaltın. 21 | - Bulunduğunuz bölgeye bağlı olarak, veri getirme işlemi veri kaynağınıza daha yakın bir yerde de gerçekleşebilir, böylece gecikme süresi azalır ve performans artar. 22 | 23 | **Bilmekte fayda var:** İstemci tarafında veri almak hala mümkündür. İstemci Bileşenleri ile [SWR](https://swr.vercel.app/) veya [React Query](https://tanstack.com/query/v4/) gibi üçüncü taraf bir kütüphane kullanmanızı öneririz. Gelecekte, React `use()` hook kullanarak İstemci Bileşenlerinde veri almak da mümkün olacak. 24 | 25 | ### Bileşen Düzeyinde Veri Getirme (Fetching Data at the Component Level) 26 | 27 | App Router'da düzenlerin, sayfaların ve bileşenlerin içinden veri getirebilirsiniz. Veri getirme, Akış ve Askıya Alma ile de uyumludur. 28 | 29 | **Bilmekte fayda var:** Düzenlerde, bir üst düzen ile onun alt bileşenleri arasında veri aktarmak mümkün değildir. Bir rotada aynı verileri birden çok kez talep ediyor olsanız bile, verileri doğrudan ihtiyaç duyan düzenin içinden almanızı öneririz. Sahne arkasında React ve Next.js, aynı verilerin birden fazla kez getirilmesini önlemek için istekleri önbelleğe alır ve tekilleştirir. 30 | 31 | ### Paralel ve Sıralı Veri Getirme (Parallel and Sequential Data Fetching) 32 | 33 | Bileşenler içinde veri getirirken, iki veri getirme modelinin farkında olmanız gerekir: Paralel ve Sıralı. 34 | 35 | <img alt="fetch" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fsequential-parallel-data-fetching.png&w=3840&q=75&dpl=dpl_BuM5KktxiCNXDgUUvBbDZYCUJ7hK"/> 36 | <br> 37 | 38 | - Paralel veri getirme ile, bir rotadaki istekler istekli olarak başlatılır ve aynı anda veri yüklenir. Bu, istemci-sunucu şelalelerini ve veri yüklemek için gereken toplam süreyi azaltır. 39 | - Sıralı veri getirme ile, bir rotadaki istekler birbirine bağımlıdır ve şelaleler oluşturur. Bu modeli istediğiniz durumlar olabilir çünkü bir getirme işlemi diğerinin sonucuna bağlıdır veya kaynakları korumak için bir sonraki getirme işleminden önce bir koşulun yerine getirilmesini istersiniz. Ancak bu davranış kasıtsız da olabilir ve daha uzun yükleme sürelerine yol açabilir. 40 | 41 | ### Otomatik `fetch()` İsteği Tekilleştirme (Automatic fetch() Request Deduping) 42 | 43 | Bir ağaçtaki birden fazla bileşende aynı verileri (örneğin mevcut kullanıcı) getirmeniz gerekiyorsa, Next.js aynı girdiye sahip `fetch` isteklerini `(GET)` otomatik olarak geçici bir önbellekte önbelleğe alacaktır. Bu optimizasyon, bir render etme geçişi sırasında aynı verilerin birden fazla kez getirilmesini önler. 44 | 45 | <img alt="fetch-2" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fdeduplicated-fetch-requests.png&w=3840&q=75&dpl=dpl_BuM5KktxiCNXDgUUvBbDZYCUJ7hK"/> 46 | <br> 47 | 48 | - Sunucuda önbellek, render etme işlemi tamamlanana kadar bir sunucu isteğinin ömrü boyunca sürer. 49 | - Bu optimizasyon Düzenlerde, Sayfalarda, Sunucu Bileşenlerinde, `generateMetadata` ve `generateStaticParams`'da yapılan `fetch` istekleri için geçerlidir. 50 | - Bu optimizasyon statik oluşturma (static generation) sırasında da geçerlidir. 51 | - İstemcide, önbellek, tam sayfa yeniden yüklenmeden önce bir oturum süresince (birden fazla istemci tarafı yeniden render etme içerebilir) sürer. 52 | 53 | **Bilmekte fayda var:** 54 | 55 | - `POST` istekleri otomatik olarak tekilleştirilmez. 56 | - `Fetch`'i kullanamıyorsanız, React, istek süresince verileri manuel olarak önbelleğe almanıza olanak tanıyan bir `cache` işlevi sağlar. 57 | 58 | ### Statik ve Dinamik Veri Getirme (Static and Dynamic Data Fetching) 59 | 60 | İki tür veri vardır: Statik ve Dinamik. 61 | 62 | - Statik Veriler sık sık değişmeyen verilerdir. Örneğin, bir blog yazısı. 63 | - Dinamik Veriler, sık sık değişen veya kullanıcılara özel olabilen verilerdir. Örneğin, bir alışveriş sepeti listesi. 64 | 65 | <img alt="fetch-3" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fdynamic-and-static-data-fetching.png&w=3840&q=75&dpl=dpl_BuM5KktxiCNXDgUUvBbDZYCUJ7hK"/> 66 | <br> 67 | 68 | Next.js varsayılan olarak otomatik olarak statik getirmeler yapar. Bu, verilerin derleme zamanında getirileceği, önbelleğe alınacağı ve her istekte yeniden kullanılacağı anlamına gelir. Bir geliştirici olarak, statik verilerin nasıl önbelleğe alınacağı ve yeniden doğrulanacağı üzerinde kontrole sahipsiniz. 69 | 70 | Statik veri kullanmanın iki faydası vardır: 71 | 72 | 1. Yapılan istek sayısını en aza indirerek veritabanınız üzerindeki yükü azaltır. 73 | 2. Daha iyi yükleme performansı için veriler otomatik olarak önbelleğe alınır. 74 | 75 | Bununla birlikte, verileriniz kullanıcıya göre kişiselleştirilmişse veya her zaman en son verileri getirmek istiyorsanız, istekleri dinamik olarak işaretleyebilir ve önbelleğe almadan her istekte veri getirebilirsiniz. 76 | 77 | ## Veri Önbelleğe Alma (Caching Data) 78 | 79 | Önbelleğe alma, verilerin bir konumda (örneğin [İçerik Dağıtım Ağı](https://vercel.com/docs/concepts/edge-network/overview)) depolanması işlemidir, böylece her istekte orijinal kaynaktan yeniden taranması gerekmez. 80 | 81 | <img alt="cache" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fstatic-site-generation.png&w=3840&q=75&dpl=dpl_BuM5KktxiCNXDgUUvBbDZYCUJ7hK"/> 82 | <br> 83 | 84 | **Next.js Cache**, küresel olarak dağıtılabilen kalıcı bir [HTTP önbelleğidir](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching). Bu, önbelleğin otomatik olarak ölçeklenebileceği ve platformunuza bağlı olarak birden fazla bölgede paylaşılabileceği anlamına gelir (örn. Vercel). 85 | 86 | Next.js, `fetch()` işlevinin [options nesnesini](https://developer.mozilla.org/en-US/docs/Web/API/fetch#:~:text=preflight%20requests.-,cache,-A%20string%20indicating), sunucudaki her isteğin kendi kalıcı önbellekleme davranışını ayarlamasına izin verecek şekilde genişletir. Bileşen düzeyinde veri getirme ile birlikte bu, uygulama kodunuzda önbelleğe almayı doğrudan verilerin kullanıldığı yerde yapılandırmanıza olanak tanır. 87 | 88 | Sunucu render etme sırasında, Next.js bir getirme işlemiyle karşılaştığında, verilerin zaten mevcut olup olmadığını görmek için önbelleği kontrol edecektir. Eğer mevcutsa, önbelleğe alınan verileri döndürür. Değilse, gelecekteki istekler için verileri getirecek ve depolayacaktır. 89 | 90 | **Bilmekte fayda var:** Eğer `fetch` kullanamıyorsanız, React istek süresince verileri manuel olarak önbelleğe almanızı sağlayan bir `cache` fonksiyonu sunar. 91 | 92 | ### Verileri Yeniden Doğrulama (Revalidating Data) 93 | 94 | Yeniden doğrulama, önbelleğin temizlenmesi ve en son verilerin yeniden alınması işlemidir. Bu, verileriniz değiştiğinde ve tüm uygulamanızı yeniden oluşturmak zorunda kalmadan uygulamanızın en son sürümü gösterdiğinden emin olmak istediğinizde kullanışlıdır. 95 | 96 | - Arka plan: Verileri belirli bir zaman aralığında yeniden doğrular. 97 | - İsteğe bağlı: Bir güncelleme olduğunda verileri yeniden doğrular. 98 | 99 | ### Akış ve Gerilim (Streaming and Suspense) 100 | 101 | Streaming ve Suspense, kullanıcı arayüzünün render edilmiş birimlerini aşamalı olarak render etmenize ve istemciye aşamalı olarak aktarmanıza olanak tanıyan yeni React özellikleridir. 102 | 103 | Sunucu Bileşenleri ve iç içe düzenlerle, sayfanın özellikle veri gerektirmeyen kısımlarını anında render edebilir ve sayfanın veri getiren kısımları için bir yükleme durumu gösterebilirsiniz. Bu, kullanıcının sayfayla etkileşime geçmeden önce tüm sayfanın yüklenmesini beklemek zorunda olmadığı anlamına gelir. 104 | 105 | <img alt="cache-2" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fserver-rendering-with-streaming.png&w=3840&q=75&dpl=dpl_BuM5KktxiCNXDgUUvBbDZYCUJ7hK"/> 106 | <br> 107 | 108 | ## Eski Yöntemler 109 | 110 | `getServerSideProps`, `getStaticProps` ve `getInitialProps` gibi önceki Next.js veri getirme yöntemleri yeni Uygulama Yönlendiricisinde desteklenmemektedir. Ancak, bunları Pages Router'da kullanmaya devam edebilirsiniz. 111 | -------------------------------------------------------------------------------- /5-styling/1-css-modules/Readme.md: -------------------------------------------------------------------------------- 1 | # CSS Modülleri (CSS Modules) 2 | 3 | Next.js, `.module.css` uzantısını kullanan CSS Modülleri için yerleşik desteğe sahiptir. 4 | 5 | CSS Modülleri, otomatik olarak benzersiz bir sınıf adı oluşturarak CSS'yi yerel olarak kapsar. Bu, çakışma endişesi olmadan farklı dosyalarda aynı sınıf adını kullanmanıza olanak tanır. Bu davranış CSS Modüllerini bileşen düzeyinde CSS eklemek için ideal bir yol haline getirir. 6 | 7 | ## Örnek 8 | 9 | CSS Modülleri, `app` dizini içindeki herhangi bir dosyaya aktarılabilir: 10 | 11 | ```js 12 | import styles from "./styles.module.css"; 13 | 14 | export default function DashboardLayout({ 15 | children, 16 | }: { 17 | children: React.ReactNode, 18 | }) { 19 | return <section className={styles.dashboard}>{children}</section>; 20 | } 21 | ``` 22 | 23 | ```css 24 | .dashboard { 25 | padding: 24px; 26 | } 27 | ``` 28 | 29 | CSS Modülleri isteğe bağlı bir özelliktir ve yalnızca `.module.css` uzantılı dosyalar için etkinleştirilir. Normal `<link>` stil sayfaları ve global CSS dosyaları hala desteklenmektedir. 30 | 31 | Üretimde, tüm CSS Modülü dosyaları otomatik olarak birçok küçültülmüş ve kod bölünmüş `.css` dosyasına birleştirilecektir. Bu `.css` dosyaları uygulamanızdaki sıcak yürütme yollarını temsil eder ve uygulamanızın boyaması için minimum miktarda CSS yüklenmesini sağlar. 32 | 33 | ## Küresel Stiller (Global Styles) 34 | 35 | Global stiller, `app` dizini içindeki herhangi bir düzene, sayfaya veya bileşene aktarılabilir. 36 | 37 | **Bilmekte fayda var:** Bu, yalnızca `_app.js` dosyasının içindeki global stilleri içe aktarabileceğiniz `pages` dizininden farklıdır. 38 | 39 | Örneğin, `app/global.css` adında bir stil sayfası düşünün: 40 | 41 | ```css 42 | body { 43 | padding: 20px 20px 60px; 44 | max-width: 680px; 45 | margin: 0 auto; 46 | } 47 | ``` 48 | 49 | Kök düzen `(app/layout.js)` içinde, stilleri uygulamanızdaki her rotaya uygulamak için `global.css` stil sayfasını içe aktarın: 50 | 51 | ```js 52 | // Bu stiller uygulamadaki her rota için geçerlidir 53 | import "./global.css"; 54 | 55 | export default function RootLayout({ 56 | children, 57 | }: { 58 | children: React.ReactNode, 59 | }) { 60 | return ( 61 | <html lang="en"> 62 | <body>{children}</body> 63 | </html> 64 | ); 65 | } 66 | ``` 67 | 68 | ## Harici Stil Sayfaları (External Stylesheets) 69 | 70 | Harici paketler tarafından yayınlanan stil sayfaları, ortak konumlandırılmış bileşenler de dahil olmak üzere `app` dizininin herhangi bir yerine içe aktarılabilir: 71 | 72 | ```js 73 | import "bootstrap/dist/css/bootstrap.css"; 74 | 75 | export default function RootLayout({ 76 | children, 77 | }: { 78 | children: React.ReactNode, 79 | }) { 80 | return ( 81 | <html lang="en"> 82 | <body className="container">{children}</body> 83 | </html> 84 | ); 85 | } 86 | ``` 87 | 88 | **Bilmekte fayda var:** Harici stil sayfaları doğrudan bir npm paketinden içe aktarılmalı veya indirilmeli ve kod tabanınızla birlikte yerleştirilmelidir. `<link rel="stylesheet" />` kullanamazsınız. 89 | 90 | ## Ek Özellikler 91 | 92 | Next.js, stil ekleme yazma deneyimini iyileştirmek için ek özellikler içerir: 93 | 94 | - `Next Dev` ile yerel olarak çalıştırılırken, yerel stil sayfaları (genel veya CSS modülleri), düzenlemeler kaydedildikçe değişiklikleri anında yansıtmak için Hızlı Yenileme özelliğinden yararlanacaktır. 95 | - `Next build` ile üretim için oluştururken, stilleri almak için gereken ağ isteklerinin sayısını azaltmak için CSS dosyaları daha az sayıda küçültülmüş `.css` dosyasında bir araya getirilecektir. 96 | - JavaScript'i devre dışı bırakırsanız stiller üretim derlemesinde (`next start`) yüklenmeye devam eder. Ancak, Hızlı Yenileme'yi etkinleştirmek için JavaScript'te `next dev` hala gereklidir. 97 | -------------------------------------------------------------------------------- /5-styling/2-tailwind-css/Readme.md: -------------------------------------------------------------------------------- 1 | # Tailwind CSS 2 | 3 | [Tailwind CSS](https://tailwindcss.com/), Next.js ile son derece iyi çalışan bir yardımcı program öncelikli CSS çerçevesidir. 4 | 5 | ## Tailwind'i Yükleme 6 | 7 | Tailwind CSS paketlerini yükleyin ve hem `tailwind.config.js` hem de `postcss.config.js` dosyalarını oluşturmak için `init` komutunu çalıştırın: 8 | 9 | ```terminal 10 | npm install -D tailwindcss postcss autoprefixer 11 | npx tailwindcss init -p 12 | ``` 13 | 14 | ## Tailwind'i Yapılandırma 15 | 16 | `tailwind.config.js` dosyasının içine Tailwind CSS sınıf adlarını kullanacak dosyaların yollarını ekleyin: 17 | 18 | ```js 19 | /** @type {import('tailwindcss').Config} */ 20 | module.exports = { 21 | content: [ 22 | "./app/**/*.{js,ts,jsx,tsx,mdx}", // App` dizininin eklendiğine dikkat edin. 23 | "./pages/**/*.{js,ts,jsx,tsx,mdx}", 24 | "./components/**/*.{js,ts,jsx,tsx,mdx}", 25 | 26 | // Veya `src` dizini kullanılıyorsa: 27 | "./src/**/*.{js,ts,jsx,tsx,mdx}", 28 | ], 29 | theme: { 30 | extend: {}, 31 | }, 32 | plugins: [], 33 | }; 34 | ``` 35 | 36 | `postcss.config.js` dosyasını değiştirmenize gerek yoktur. 37 | 38 | ## Stilleri İçe Aktarma 39 | 40 | Tailwind'in oluşturduğu stilleri uygulamanızdaki bir Global Stil Sayfasına enjekte etmek için kullanacağı [Tailwind CSS yönergelerini](https://tailwindcss.com/docs/functions-and-directives#directives) ekleyin: 41 | 42 | ```css 43 | @tailwind base; 44 | @tailwind components; 45 | @tailwind utilities; 46 | ``` 47 | 48 | Kök düzen `(app/layout.tsx`) içinde, stilleri uygulamanızdaki her rotaya uygulamak için `globals.css` stil sayfasını içe aktarın. 49 | 50 | ```js 51 | import type { Metadata } from "next"; 52 | 53 | // These styles apply to every route in the application 54 | import "./globals.css"; 55 | 56 | export const metadata: Metadata = { 57 | title: "Create Next App", 58 | description: "Generated by create next app", 59 | }; 60 | 61 | export default function RootLayout({ 62 | children, 63 | }: { 64 | children: React.ReactNode, 65 | }) { 66 | return ( 67 | <html lang="en"> 68 | <body>{children}</body> 69 | </html> 70 | ); 71 | } 72 | ``` 73 | 74 | ## Sınıfları Kullanma 75 | 76 | Tailwind CSS'yi yükledikten ve global stilleri ekledikten sonra, uygulamanızda Tailwind'in yardımcı sınıflarını kullanabilirsiniz. 77 | 78 | ```tsx 79 | app / page.tsx; 80 | 81 | export default function Page() { 82 | return <h1 className="text-3xl font-bold underline">Merhaba, Next.js!</h1>; 83 | } 84 | ``` 85 | 86 | ## Turbopack ile kullanım 87 | 88 | Next.js 13.1'den itibaren Tailwind CSS ve PostCSS, [Turbopack](https://turbo.build/pack/docs/features/css#tailwind-css) ile desteklenmektedir. 89 | -------------------------------------------------------------------------------- /5-styling/3-css-in-js/Readme.md: -------------------------------------------------------------------------------- 1 | # CSS-in-JS 2 | 3 | **Uyarı:** Çalışma zamanı JavaScript gerektiren CSS-in-JS kütüphaneleri şu anda Sunucu Bileşenleri'nde desteklenmemektedir. CSS-in-JS'yi Sunucu Bileşenleri ve Akış gibi daha yeni React özellikleriyle kullanmak, kütüphane yazarlarının [eşzamanlı render etme](https://react.dev/blog/2022/03/29/react-v18#what-is-concurrent-react) dahil olmak üzere React'in en son sürümünü desteklemesini gerektirir. 4 | 5 | React Sunucu Bileşenleri ve akış mimarisi desteğiyle CSS ve JavaScript varlıklarını işlemek için yukarı akış API'leri üzerinde React ekibiyle birlikte çalışıyoruz. 6 | 7 | Aşağıdaki kütüphaneler `app` dizinindeki İstemci Bileşenlerinde desteklenmektedir (alfabetik olarak): 8 | 9 | - [`kuma-ui`](https://kuma-ui.com/) 10 | - [`@mui/material`](https://mui.com/material-ui/guides/next-js-app-router/) 11 | - [`pandacss`](https://panda-css.com/) 12 | - [`styled-jsx`](https://nextjs.org/docs/app/building-your-application/styling/css-in-js#styled-jsx) 13 | - [`styled-components`](https://nextjs.org/docs/app/building-your-application/styling/css-in-js#styled-components) 14 | - [`style9`](https://github.com/johanholmerin/style9) 15 | - [`tamagui`](https://tamagui.dev/docs/guides/next-js#server-components) 16 | - [`vanilya-extract`](https://github.com/vercel/next.js/tree/canary/examples/with-vanilla-extract) 17 | 18 | Aşağıdakiler şu anda destek üzerinde çalışmaktadır: 19 | 20 | - [`emotion`](https://github.com/emotion-js/emotion/issues/2928) 21 | 22 | **Bilmekte fayda var:** Farklı CSS-in-JS kütüphanelerini test ediyoruz ve React 18 özelliklerini ve/veya `app` dizinini destekleyen kütüphaneler için daha fazla örnek ekleyeceğiz. 23 | 24 | ## Uygulamada CSS-in-JS'yi yapılandırma (Configuring CSS-in-JS in `app`) 25 | 26 | CSS-in-JS'nin yapılandırılması üç adımlı bir katılım sürecidir: 27 | 28 | - Bir render etme'deki tüm CSS kurallarını toplamak için bir stil kayıt defteri. 29 | - Kuralları, onları kullanabilecek herhangi bir içerikten önce enjekte etmek için yeni `useServerInsertedHTML` kancası. 30 | - İlk sunucu tarafı oluşturma sırasında uygulamanızı stil kayıt defteri ile saran bir İstemci Bileşeni. 31 | 32 | ### styled-jsx 33 | 34 | İstemci Bileşenlerinde `styled-jsx` kullanmak için `v5.1.0` kullanılması gerekir. İlk olarak, yeni bir kayıt defteri oluşturun: 35 | 36 | ```js 37 | app / registry.tsx; 38 | 39 | ("use client"); 40 | 41 | import React, { useState } from "react"; 42 | import { useServerInsertedHTML } from "next/navigation"; 43 | import { StyleRegistry, createStyleRegistry } from "styled-jsx"; 44 | 45 | export default function StyledJsxRegistry({ 46 | children, 47 | }: { 48 | children: React.ReactNode, 49 | }) { 50 | // Only create stylesheet once with lazy initial state 51 | // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state 52 | const [jsxStyleRegistry] = useState(() => createStyleRegistry()); 53 | 54 | useServerInsertedHTML(() => { 55 | const styles = jsxStyleRegistry.styles(); 56 | jsxStyleRegistry.flush(); 57 | return <>{styles}</>; 58 | }); 59 | 60 | return <StyleRegistry registry={jsxStyleRegistry}>{children}</StyleRegistry>; 61 | } 62 | ``` 63 | 64 | Ardından, kök düzeninizi kayıt defteri ile sarın: 65 | 66 | ```js 67 | app / layout.tsx; 68 | 69 | import StyledJsxRegistry from "./registry"; 70 | 71 | export default function RootLayout({ 72 | children, 73 | }: { 74 | children: React.ReactNode, 75 | }) { 76 | return ( 77 | <html> 78 | <body> 79 | <StyledJsxRegistry>{children}</StyledJsxRegistry> 80 | </body> 81 | </html> 82 | ); 83 | } 84 | ``` 85 | 86 | ### Styled Components 87 | 88 | Aşağıda `styled-components@v6.0.0-rc.1` veya daha büyük bir adresin nasıl yapılandırılacağına dair bir örnek verilmiştir: 89 | 90 | İlk olarak, `styled-components` API'sini kullanarak render etme sırasında oluşturulan tüm CSS stil kurallarını toplayacak global bir kayıt bileşeni ve bu kuralları döndürecek bir fonksiyon oluşturun. Ardından, kayıt defterinde toplanan stilleri kök mizanpajdaki `<head>` HTML etiketine enjekte etmek için `useServerInsertedHTML` kancasını kullanın. 91 | 92 | ```js 93 | lib / registry.tsx; 94 | 95 | ("use client"); 96 | 97 | import React, { useState } from "react"; 98 | import { useServerInsertedHTML } from "next/navigation"; 99 | import { ServerStyleSheet, StyleSheetManager } from "styled-components"; 100 | 101 | export default function StyledComponentsRegistry({ 102 | children, 103 | }: { 104 | children: React.ReactNode, 105 | }) { 106 | // Only create stylesheet once with lazy initial state 107 | // x-ref: https://reactjs.org/docs/hooks-reference.html#lazy-initial-state 108 | const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet()); 109 | 110 | useServerInsertedHTML(() => { 111 | const styles = styledComponentsStyleSheet.getStyleElement(); 112 | styledComponentsStyleSheet.instance.clearTag(); 113 | return <>{styles}</>; 114 | }); 115 | 116 | if (typeof window !== "undefined") return <>{children}</>; 117 | 118 | return ( 119 | <StyleSheetManager sheet={styledComponentsStyleSheet.instance}> 120 | {children} 121 | </StyleSheetManager> 122 | ); 123 | } 124 | ``` 125 | 126 | Kök düzenin `children` öğelerini stil kayıt defteri bileşeniyle sarın: 127 | 128 | ```js 129 | app / layout.tsx; 130 | 131 | import StyledComponentsRegistry from "./lib/registry"; 132 | 133 | export default function RootLayout({ 134 | children, 135 | }: { 136 | children: React.ReactNode, 137 | }) { 138 | return ( 139 | <html> 140 | <body> 141 | <StyledComponentsRegistry>{children}</StyledComponentsRegistry> 142 | </body> 143 | </html> 144 | ); 145 | } 146 | ``` 147 | 148 | **Bilmekte fayda var:** 149 | 150 | - Sunucu render etme sırasında, stiller global bir kayıt defterine çıkarılır ve HTML'nizin `<head>` bölümüne aktarılır. Bu, stil kurallarının onları kullanabilecek tüm içeriklerden önce yerleştirilmesini sağlar. Gelecekte, stilleri nereye enjekte edeceğimizi belirlemek için yakında çıkacak bir React özelliğini kullanabiliriz. 151 | - Akış sırasında, her bir yığından gelen stiller toplanacak ve mevcut stillere eklenecektir. İstemci tarafı hidrasyon tamamlandıktan sonra, `styled-components` her zamanki gibi devralacak ve başka dinamik stiller enjekte edecektir. 152 | - Stil kaydı için özellikle ağacın en üst seviyesinde bir İstemci Bileşeni kullanıyoruz çünkü CSS kurallarını bu şekilde çıkarmak daha verimli. Bu, sonraki sunucu render etme'lerinde stillerin yeniden oluşturulmasını ve Sunucu Bileşeni yükünde gönderilmesini önler. 153 | -------------------------------------------------------------------------------- /5-styling/4-sass/Readme.md: -------------------------------------------------------------------------------- 1 | # Sass 2 | 3 | Next.js, hem `.scss` hem de `.sass` uzantılarını kullanarak Sass için yerleşik desteğe sahiptir. `module.scss` veya `.module.sass` uzantısı aracılığıyla bileşen düzeyinde Sass kullanabilirsiniz. 4 | 5 | İlk olarak, [`sass`](https://github.com/sass/sass) yükleyin: 6 | 7 | ```terminal 8 | npm install --save-dev sass 9 | ``` 10 | 11 | **Bilmekte fayda var:** 12 | 13 | Sass, her biri kendi uzantısına sahip [iki farklı sözdizimini](https://sass-lang.com/documentation/syntax) destekler. `.scss` uzantısı [SCSS sözdizimini](https://sass-lang.com/documentation/syntax#scss) kullanmanızı gerektirirken, `.sass` uzantısı [Girintili Sözdizimini ("Sass")](https://sass-lang.com/documentation/syntax#the-indented-syntax) kullanmanızı gerektirir. 14 | 15 | Hangisini seçeceğinizden emin değilseniz, CSS'nin bir üst kümesi olan ve Girintili Sözdizimini ("Sass") öğrenmenizi gerektirmeyen `.scss` uzantısı ile başlayın. 16 | 17 | ## Sass Seçeneklerini Özelleştirme 18 | 19 | Sass derleyicisini yapılandırmak istiyorsanız `next.config.js` dosyasında `sassOptions` seçeneğini kullanın. 20 | 21 | ```js 22 | next.config.js; 23 | 24 | const path = require("path"); 25 | 26 | module.exports = { 27 | sassOptions: { 28 | includePaths: [path.join(__dirname, "styles")], 29 | }, 30 | }; 31 | ``` 32 | 33 | ## Sass Değişkenleri 34 | 35 | Next.js, CSS Modülü dosyalarından dışa aktarılan Sass değişkenlerini destekler. 36 | 37 | Örneğin, dışa aktarılan `primaryColor` Sass değişkenini kullanarak: 38 | 39 | ```scss 40 | 41 | app/variables.module.scss 42 | 43 | $primary-color: #64ff00; 44 | 45 | :export { 46 | primaryColor: $primary-color; 47 | } 48 | ``` 49 | 50 | ```js 51 | app / page.js; 52 | 53 | // maps to root `/` URL 54 | 55 | import variables from "./variables.module.scss"; 56 | 57 | export default function Page() { 58 | return <h1 style={{ color: variables.primaryColor }}>Hello, Next.js!</h1>; 59 | } 60 | ``` 61 | -------------------------------------------------------------------------------- /5-styling/Readme.md: -------------------------------------------------------------------------------- 1 | # Şekillendirme (Styling) 2 | 3 | Next.js, uygulamanızı şekillendirmenin farklı yollarını destekler: 4 | 5 | - **Global CSS:** Geleneksel CSS konusunda deneyimli olanlar için kullanımı basit ve tanıdıktır, ancak uygulama büyüdükçe daha büyük CSS paketlerine ve stilleri yönetmede zorluklara yol açabilir. 6 | - **CSS Modülleri:** Adlandırma çakışmalarını önlemek ve sürdürülebilirliği artırmak için yerel olarak kapsamlandırılmış CSS sınıfları oluşturun. 7 | - **Tailwind CSS:** Yardımcı sınıflar oluşturarak hızlı özel tasarımlara olanak tanıyan yardımcı program öncelikli bir CSS çerçevesi. 8 | - **Sass:** CSS'yi değişkenler, iç içe kurallar ve mixinler gibi özelliklerle genişleten popüler bir CSS ön işlemcisi. 9 | - **CSS-in-JS:** CSS'yi doğrudan JavaScript bileşenlerinize yerleştirerek dinamik ve kapsamı belirlenmiş stil oluşturma olanağı sağlar. 10 | -------------------------------------------------------------------------------- /6-optimizing/2-fonts/readme.md: -------------------------------------------------------------------------------- 1 | # Yazı Tipi Optimizasyonu (Font Optimization) 2 | 3 | `next/font` yazı tiplerinizi (özel yazı tipleri dahil) otomatik olarak optimize edecek ve gelişmiş gizlilik ve performans için harici ağ isteklerini kaldıracaktır. 4 | 5 | 🎥 **İzleyin:** next/font'un nasıl kullanılacağı hakkında daha fazla bilgi edinin → [YouTube (6 dakika)](https://www.youtube.com/watch?v=L8_98i_bMMA). 6 | 7 | `next/font`, herhangi bir yazı tipi dosyası için yerleşik otomatik kendi kendine barındırma içerir. Bu, kullanılan temel CSS `size-adjust` özelliği sayesinde web fontlarını sıfır düzen kayması ile en iyi şekilde yükleyebileceğiniz anlamına gelir. 8 | 9 | Bu yeni yazı tipi sistemi, performans ve gizliliği göz önünde bulundurarak tüm Google Yazı Tiplerini rahatça kullanmanıza da olanak tanır. CSS ve yazı tipi dosyaları derleme sırasında indirilir ve statik varlıklarınızın geri kalanıyla birlikte kendi kendine barındırılır. Tarayıcı tarafından Google'a hiçbir istek gönderilmez. 10 | 11 | ## Google Yazı Tipleri (Google Fonts) 12 | 13 | Herhangi bir Google Yazı Tipini otomatik olarak kendi kendine barındırın. Yazı tipleri dağıtıma dahil edilir ve dağıtımınızla aynı etki alanından sunulur. Tarayıcı tarafından Google'a hiçbir istek gönderilmez. 14 | 15 | Kullanmak istediğiniz yazı tipini next/font/google'dan bir işlev olarak içe aktararak başlayın. En iyi performans ve esneklik için [değişken yazı tipleri](https://fonts.google.com/variablefonts) kullanmanızı öneririz. 16 | 17 | ```js 18 | // app/layout.tsx 19 | 20 | import { Inter } from "next/font/google"; 21 | 22 | // Değişken bir yazı tipi yükleniyorsa, yazı tipi ağırlığını belirtmeniz gerekmez 23 | const inter = Inter({ 24 | subsets: ["latin"], 25 | display: "swap", 26 | }); 27 | 28 | export default function RootLayout({ 29 | children, 30 | }: { 31 | children: React.ReactNode, 32 | }) { 33 | return ( 34 | <html lang="en" className={inter.className}> 35 | <body>{children}</body> 36 | </html> 37 | ); 38 | } 39 | ``` 40 | 41 | Değişken bir yazı tipi kullanamıyorsanız, bir ağırlık belirtmeniz gerekecektir: 42 | 43 | ```js 44 | // app/layout.tsx 45 | 46 | import { Roboto } from "next/font/google"; 47 | 48 | const roboto = Roboto({ 49 | weight: "400", 50 | subsets: ["latin"], 51 | display: "swap", 52 | }); 53 | 54 | export default function RootLayout({ 55 | children, 56 | }: { 57 | children: React.ReactNode, 58 | }) { 59 | return ( 60 | <html lang="en" className={roboto.className}> 61 | <body>{children}</body> 62 | </html> 63 | ); 64 | } 65 | ``` 66 | 67 | Bir dizi kullanarak birden fazla ağırlık ve/veya stil belirtebilirsiniz: 68 | 69 | ```js 70 | // app/layout.tsx 71 | 72 | const roboto = Roboto({ 73 | weight: ["400", "700"], 74 | style: ["normal", "italic"], 75 | subsets: ["latin"], 76 | display: "swap", 77 | }); 78 | ``` 79 | 80 | **Bilmekte fayda var:** Birden fazla kelime içeren font adları için alt çizgi (\_) kullanın. Örneğin `Roboto Mono`, `Roboto_Mono` olarak içe aktarılmalıdır. 81 | 82 | ### Bir alt küme belirtme (Specifying a subset) 83 | 84 | Google Yazı Tipleri otomatik olarak [alt kümelendirilir](https://fonts.google.com/knowledge/glossary/subsetting). Bu, yazı tipi dosyasının boyutunu azaltır ve performansı artırır. Bu alt kümelerden hangilerini önceden yüklemek istediğinizi tanımlamanız gerekir. `preload` doğruyken herhangi bir alt küme belirtilmemesi bir uyarı ile sonuçlanacaktır. 85 | 86 | Bu, fonksiyon çağrısına eklenerek yapılabilir: 87 | 88 | ```js 89 | const inter = Inter({ subsets: ["latin"] }); // latin alt kümesi 90 | ``` 91 | 92 | ### Birden Fazla Yazı Tipi Kullanma (Using Multiple Fonts) 93 | 94 | Uygulamanızda birden fazla yazı tipini içe aktarabilir ve kullanabilirsiniz. Kullanabileceğiniz iki yaklaşım vardır. 95 | 96 | İlk yaklaşım, bir yazı tipini dışa aktaran, içe aktaran ve gerektiğinde `className`'ini uygulayan bir yardımcı program işlevi oluşturmaktır. Bu, yazı tipinin yalnızca işlendiğinde önceden yüklenmesini sağlar: 97 | 98 | ```js 99 | // app/fonts.ts 100 | import { Inter, Roboto_Mono } from "next/font/google"; 101 | 102 | export const inter = Inter({ 103 | subsets: ["latin"], 104 | display: "swap", 105 | }); 106 | 107 | export const roboto_mono = Roboto_Mono({ 108 | subsets: ["latin"], 109 | display: "swap", 110 | }); 111 | ``` 112 | 113 | ```js 114 | // app/layout.tsx 115 | 116 | import { inter } from "./fonts"; 117 | 118 | export default function Layout({ children }: { children: React.ReactNode }) { 119 | return ( 120 | <html lang="en" className={inter.className}> 121 | <body> 122 | <div>{children}</div> 123 | </body> 124 | </html> 125 | ); 126 | } 127 | ``` 128 | 129 | ```js 130 | // app/page.tsx 131 | 132 | import { roboto_mono } from "./fonts"; 133 | 134 | export default function Page() { 135 | return ( 136 | <> 137 | <h1 className={roboto_mono.className}>My page</h1> 138 | </> 139 | ); 140 | } 141 | ``` 142 | 143 | Yukarıdaki örnekte, `Inter` global olarak uygulanacak ve `Roboto Mono` gerektiğinde içe aktarılıp uygulanabilecektir. 144 | 145 | Alternatif olarak, bir CSS değişkeni oluşturabilir ve bunu tercih ettiğiniz CSS çözümüyle kullanabilirsiniz: 146 | 147 | ```js 148 | // app/layout.tsx 149 | 150 | import { Inter, Roboto_Mono } from "next/font/google"; 151 | import styles from "./global.css"; 152 | 153 | const inter = Inter({ 154 | subsets: ["latin"], 155 | variable: "--font-inter", 156 | display: "swap", 157 | }); 158 | 159 | const roboto_mono = Roboto_Mono({ 160 | subsets: ["latin"], 161 | variable: "--font-roboto-mono", 162 | display: "swap", 163 | }); 164 | 165 | export default function RootLayout({ 166 | children, 167 | }: { 168 | children: React.ReactNode, 169 | }) { 170 | return ( 171 | <html lang="en" className={`${inter.variable} ${roboto_mono.variable}`}> 172 | <body> 173 | <h1>My App</h1> 174 | <div>{children}</div> 175 | </body> 176 | </html> 177 | ); 178 | } 179 | ``` 180 | 181 | ```css 182 | /* app/global.css */ 183 | html { 184 | font-family: var(--font-inter); 185 | } 186 | 187 | h1 { 188 | font-family: var(--font-roboto-mono); 189 | } 190 | ``` 191 | 192 | Yukarıdaki örnekte, `Inter` global olarak uygulanacak ve tüm `<h1>` etiketleri `Roboto Mono` ile şekillendirilecektir. 193 | 194 | **Öneri:** Her yeni yazı tipi kullanıcının indirmesi gereken ek bi kaynak olduğundan, birden fazla yazı tipini ihtiyatlı bir şekilde kullanın. 195 | 196 | ## Yerel Yazı Tipleri (Local Fonts) 197 | 198 | `next/font/local` öğesini içe aktarın ve yerel yazı tipi dosyanızın `src`'sini belirtin. En iyi performans ve esneklik için [değişken fontlar](https://fonts.google.com/variablefonts) kullanmanızı öneririz. 199 | 200 | ```js 201 | import localFont from "next/font/local"; 202 | 203 | // Yazı tipi dosyaları `app` içine yerleştirilebilir 204 | const myFont = localFont({ 205 | src: "./my-font.woff2", 206 | display: "swap", 207 | }); 208 | 209 | export default function RootLayout({ 210 | children, 211 | }: { 212 | children: React.ReactNode, 213 | }) { 214 | return ( 215 | <html lang="en" className={myFont.className}> 216 | <body>{children}</body> 217 | </html> 218 | ); 219 | } 220 | ``` 221 | 222 | Tek bir font ailesi için birden fazla dosya kullanmak istiyorsanız, `src` bir dizi olabilir: 223 | 224 | ```js 225 | const roboto = localFont({ 226 | src: [ 227 | { 228 | path: "./Roboto-Regular.woff2", 229 | weight: "400", 230 | style: "normal", 231 | }, 232 | { 233 | path: "./Roboto-Italic.woff2", 234 | weight: "400", 235 | style: "italic", 236 | }, 237 | { 238 | path: "./Roboto-Bold.woff2", 239 | weight: "700", 240 | style: "normal", 241 | }, 242 | { 243 | path: "./Roboto-BoldItalic.woff2", 244 | weight: "700", 245 | style: "italic", 246 | }, 247 | ], 248 | }); 249 | ``` 250 | 251 | ## Tailwind CSS ile 252 | 253 | `next/font`, bir CSS değişkeni aracılığıyla Tailwind CSS ile kullanılabilir. 254 | 255 | Aşağıdaki örnekte, `next/font/google`'dan Inter yazı tipini kullanıyoruz (Google veya Yerel Yazı Tiplerinden herhangi bir yazı tipini kullanabilirsiniz). CSS değişken adınızı tanımlamak için fontunuzu `variable` seçeneği ile yükleyin ve `inter`'e atayın. Ardından, CSS değişkenini HTML belgenize eklemek için `inter.variable` kullanın. 256 | 257 | ```js 258 | // app/layout.tsx 259 | 260 | import { Inter, Roboto_Mono } from "next/font/google"; 261 | 262 | const inter = Inter({ 263 | subsets: ["latin"], 264 | display: "swap", 265 | variable: "--font-inter", 266 | }); 267 | 268 | const roboto_mono = Roboto_Mono({ 269 | subsets: ["latin"], 270 | display: "swap", 271 | variable: "--font-roboto-mono", 272 | }); 273 | 274 | export default function RootLayout({ 275 | children, 276 | }: { 277 | children: React.ReactNode, 278 | }) { 279 | return ( 280 | <html lang="en" className={`${inter.variable} ${roboto_mono.variable}`}> 281 | <body>{children}</body> 282 | </html> 283 | ); 284 | } 285 | ``` 286 | 287 | Son olarak, CSS değişkenini Tailwind CSS yapılandırmanıza ekleyin: 288 | 289 | ```js 290 | // tailwind.config.js 291 | 292 | /** @type {import('tailwindcss').Config} */ 293 | module.exports = { 294 | content: [ 295 | "./pages/**/*.{js,ts,jsx,tsx}", 296 | "./components/**/*.{js,ts,jsx,tsx}", 297 | "./app/**/*.{js,ts,jsx,tsx}", 298 | ], 299 | theme: { 300 | extend: { 301 | fontFamily: { 302 | sans: ["var(--font-inter)"], 303 | mono: ["var(--font-roboto-mono)"], 304 | }, 305 | }, 306 | }, 307 | plugins: [], 308 | }; 309 | ``` 310 | 311 | Artık fontu öğelerinize uygulamak için `font-sans` ve `font-mono` yardımcı sınıflarını kullanabilirsiniz. 312 | 313 | ## Ön Yükleme 314 | 315 | Sitenizin bir sayfasında bir yazı tipi işlevi çağrıldığında, bu işlev genel olarak kullanılamaz ve tüm rotalara önceden yüklenmez. Bunun yerine, yazı tipi yalnızca kullanıldığı dosya türüne bağlı olarak ilgili rotalara önceden yüklenir: 316 | 317 | - Benzersiz bir sayfaysa, o sayfanın benzersiz rotasına önceden yüklenir. 318 | - Bir düzen ise, düzen tarafından sarılan tüm rotalara önceden yüklenir. 319 | - Kök düzen ise, tüm rotalara önceden yüklenir. 320 | 321 | ## Yazı tiplerini yeniden kullanma 322 | 323 | `localFont` veya Google font işlevini her çağırdığınızda, bu font uygulamanızda bir örnek olarak barındırılır. Bu nedenle, aynı font işlevini birden fazla dosyaya yüklerseniz, aynı fontun birden fazla örneği barındırılır. Bu durumda aşağıdakileri yapmanız önerilir: 324 | 325 | - Yazı tipi yükleyici işlevini tek bir paylaşılan dosyada çağırın 326 | - Sabit olarak dışa aktarın 327 | - Bu yazı tipini kullanmak istediğiniz her dosyadaki sabiti içe aktarın 328 | -------------------------------------------------------------------------------- /6-optimizing/3-scripts/Readme.md: -------------------------------------------------------------------------------- 1 | # Komut Dosyası Optimizasyonu (Script Optimization) 2 | 3 | ## Düzen Komut Dosyaları (Layout Scripts) 4 | 5 | Birden fazla rota için üçüncü taraf bir komut dosyası yüklemek için `next/script` dosyasını içe aktarın ve komut dosyasını doğrudan düzen bileşeninize ekleyin: 6 | 7 | ```js 8 | // app/dashboard/layout.tsx 9 | 10 | import Script from "next/script"; 11 | 12 | export default function DashboardLayout({ 13 | children, 14 | }: { 15 | children: React.ReactNode, 16 | }) { 17 | return ( 18 | <> 19 | <section>{children}</section> 20 | <Script src="https://example.com/script.js" /> 21 | </> 22 | ); 23 | } 24 | ``` 25 | 26 | Üçüncü taraf komut dosyası, kullanıcı tarafından klasör rotasına (örn. `dashboard/page.js`) veya iç içe geçmiş herhangi bir rotaya (örn. `dashboard/settings/page.js`) erişildiğinde getirilir. Next.js, kullanıcı aynı düzende birden fazla rota arasında gezinse bile komut dosyasının yalnızca bir kez yüklenmesini sağlar. 27 | 28 | ## Uygulama Komut Dosyaları (Application Scripts) 29 | 30 | Tüm rotalar için üçüncü taraf bir komut dosyası yüklemek için `next/script` dosyasını içe aktarın ve komut dosyasını doğrudan kök düzeninize ekleyin: 31 | 32 | ```js 33 | // app/layout.tsx 34 | import Script from "next/script"; 35 | 36 | export default function RootLayout({ 37 | children, 38 | }: { 39 | children: React.ReactNode, 40 | }) { 41 | return ( 42 | <html lang="en"> 43 | <body>{children}</body> 44 | <Script src="https://example.com/script.js" /> 45 | </html> 46 | ); 47 | } 48 | ``` 49 | 50 | Bu komut dosyası, uygulamanızdaki herhangi bir rotaya erişildiğinde yüklenir ve yürütülür. Next.js, kullanıcı birden fazla sayfa arasında gezinse bile betiğin yalnızca bir kez yüklenmesini sağlayacaktır. 51 | 52 | **Öneri:** Performans üzerindeki gereksiz etkiyi en aza indirmek için üçüncü taraf komut dosyalarını yalnızca belirli sayfalara veya düzenlere eklemenizi öneririz. 53 | 54 | ## Strateji (Strategy) 55 | 56 | `next/script`'in varsayılan davranışı herhangi bir sayfa veya düzende üçüncü taraf komut dosyalarını yüklemenize izin verse de, `strategy` özelliğini kullanarak yükleme davranışına ince ayar yapabilirsiniz: 57 | 58 | - `beforeInteractive`: Kodu herhangi bir Next.js kodundan önce ve herhangi bir sayfa hidrasyonu gerçekleşmeden önce yükleyin. 59 | - `afterInteractive`: (varsayılan) Kodu erken ancak sayfada bir miktar hidrasyon gerçekleştikten sonra yükleyin. 60 | - `lazyOnload`: Tarayıcı boşta kaldığında kodu daha sonra yükleyin. 61 | - `worker`: (deneysel) Komut dosyasını bir web çalışanına yükleyin. 62 | 63 | ## Komut Dosyalarını Bir Web İşçisine Boşaltma (Deneysel) (Offloading Scripts to a Web Worker (Experimental)) 64 | 65 | **Uyarı:** `worker` stratejisi henüz kararlı değildir ve henüz `app` dizini ile çalışmaz. Dikkatli kullanın. 66 | 67 | `worker` stratejisini kullanan komut dosyaları [Partytown](https://partytown.builder.io/) ile bir web çalışanına yüklenir ve yürütülür. Bu, ana iş parçacığını uygulama kodunuzun geri kalanına ayırarak sitenizin performansını artırabilir. 68 | 69 | Bu strateji hala deneyseldir ve yalnızca `next.config.js` dosyasında `nextScriptWorkers` bayrağı etkinleştirilirse kullanılabilir: 70 | 71 | ```js 72 | // next.config.js 73 | 74 | module.exports = { 75 | experimental: { 76 | nextScriptWorkers: true, 77 | }, 78 | }; 79 | ``` 80 | 81 | Ardından, `next`'i çalıştırın (normalde `npm run dev` veya `yarn dev`) ve Next.js kurulumu tamamlamak için gerekli paketlerin kurulumunda size rehberlik edecektir: 82 | 83 | ```bash 84 | npm run dev # or yarn dev 85 | ``` 86 | 87 | Bunun gibi talimatlar göreceksiniz: Lütfen `npm install @builder.io/partytown` komutunu çalıştırarak Partytown'ı yükleyin 88 | 89 | Kurulum tamamlandığında, `strategy="worker"` tanımlaması uygulamanızda Partytown'ı otomatik olarak başlatacak ve komut dosyasını bir web worker'a yükleyecektir. 90 | 91 | ```js 92 | // pages/home.tsx 93 | 94 | import Script from "next/script"; 95 | 96 | export default function Home() { 97 | return ( 98 | <> 99 | <Script src="https://example.com/script.js" strategy="worker" /> 100 | </> 101 | ); 102 | } 103 | ``` 104 | 105 | Bir web çalışanına üçüncü taraf bir komut dosyası yüklerken dikkate alınması gereken bir dizi ödünleşme vardır. Daha fazla bilgi için lütfen Partytown'ın [tradeoffs](https://partytown.builder.io/trade-offs) belgelerine bakın. 106 | 107 | ## Satır İçi Komut Dosyaları (Inline Scripts) 108 | 109 | Satır içi komut dosyaları veya harici bir dosyadan yüklenmeyen komut dosyaları da Komut Dosyası bileşeni tarafından desteklenir. JavaScript'i küme parantezleri içine yerleştirerek yazılabilirler: 110 | 111 | ```js 112 | <Script id="show-banner"> 113 | {`document.getElementById('banner').classList.remove('hidden')`} 114 | </Script> 115 | ``` 116 | 117 | Ya da `dangerouslySetInnerHTML` özelliğini kullanarak: 118 | 119 | ```js 120 | <Script 121 | id="show-banner" 122 | dangerouslySetInnerHTML={{ 123 | __html: `document.getElementById('banner').classList.remove('hidden')`, 124 | }} 125 | /> 126 | ``` 127 | 128 | **Uyarı:** Next.js'nin komut dosyasını izlemesi ve optimize etmesi için satır içi komut dosyaları için bir `id` özelliği atanmalıdır. 129 | 130 | ## Ek Kodun Yürütülmesi (Executing Additional Code) 131 | 132 | Olay işleyicileri, belirli bir olay gerçekleştikten sonra ek kod çalıştırmak için Script bileşeniyle birlikte kullanılabilir: 133 | 134 | - `onLoad`: Kodun yüklenmesi tamamlandıktan sonra kodu çalıştırın. 135 | - `onReady`: Kodun yüklenmesi bittikten sonra ve bileşen her takıldığında kodu çalıştırın. 136 | - `onError`: Kod yüklenemezse kodu çalıştırın. 137 | 138 | Bu işleyiciler yalnızca `next/script` içe aktarıldığında ve kodun ilk satırı olarak `"use client"` tanımlanan bir İstemci Bileşeni içinde kullanıldığında çalışır: 139 | 140 | ```js 141 | // app/page.tsx; 142 | 143 | ("use client"); 144 | 145 | import Script from "next/script"; 146 | 147 | export default function Page() { 148 | return ( 149 | <> 150 | <Script 151 | src="https://example.com/script.js" 152 | onLoad={() => { 153 | console.log("Script has loaded"); 154 | }} 155 | /> 156 | </> 157 | ); 158 | } 159 | ``` 160 | 161 | ## Ek Özellikler 162 | 163 | Bir `<script>` öğesine atanabilecek, Kod bileşeni tarafından kullanılmayan, [nonce](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce) veya [özel veri nitelikleri](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*) gibi birçok DOM niteliği vardır. Herhangi bir ek niteliğin eklenmesi, HTML'ye dahil edilen son, optimize edilmiş `<script>` öğesine otomatik olarak iletecektir. 164 | 165 | ```js 166 | // app/page.tsx; 167 | 168 | import Script from "next/script"; 169 | 170 | export default function Page() { 171 | return ( 172 | <> 173 | <Script 174 | src="https://example.com/script.js" 175 | id="example-script" 176 | nonce="XUENAJFW" 177 | data-test="script" 178 | /> 179 | </> 180 | ); 181 | } 182 | ``` 183 | -------------------------------------------------------------------------------- /6-optimizing/5-static-assets/Readme.md: -------------------------------------------------------------------------------- 1 | # Statik Varlıklar (Static Assets) 2 | 3 | Next.js, görüntüler gibi statik dosyaları kök dizinde `public` adlı bir klasör altında sunabilir. `public` içindeki dosyalara daha sonra kodunuz tarafından temel URL'den (`/`) başlayarak başvurulabilir. 4 | 5 | Örneğin, `public` içine `me.png` eklerseniz, aşağıdaki kod görüntüye erişecektir: 6 | 7 | ```js 8 | // Avatar.js 9 | 10 | import Image from "next/image"; 11 | 12 | export function Avatar() { 13 | return <Image src="/me.png" alt="me" width="64" height="64" />; 14 | } 15 | ``` 16 | 17 | `Robots.txt`, `favicon.ico` gibi statik meta veri dosyaları için `app` klasörünün içinde özel meta veri dosyaları kullanmalısınız. 18 | 19 | **Bilmekte fayda var:** 20 | 21 | - Dizin `public` olarak adlandırılmalıdır. Bu ad değiştirilemez ve statik varlıkları sunmak için kullanılan tek dizindir. 22 | - Yalnızca derleme sırasında `public` dizininde bulunan varlıklar Next.js tarafından sunulacaktır. Çalışma zamanında eklenen dosyalar kullanılamayacaktır. Kalıcı dosya depolama için [AWS S3](https://aws.amazon.com/s3/) gibi üçüncü taraf bir hizmet kullanmanızı öneririz. 23 | -------------------------------------------------------------------------------- /6-optimizing/6-lazy-loading/Readme.md: -------------------------------------------------------------------------------- 1 | # Tembel Yükleme (Lazy Loading) 2 | 3 | Next.js'deki [tembel yükleme](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading), bir rotayı oluşturmak için gereken JavaScript miktarını azaltarak bir uygulamanın ilk yükleme performansını artırmaya yardımcı olur. 4 | 5 | İstemci Bileşenlerinin ve içe aktarılan kitaplıkların yüklenmesini ertelemenize ve bunları yalnızca gerektiğinde istemci paketine dahil etmenize olanak tanır. Örneğin, bir kullanıcı açmak için tıklayana kadar bir modalin yüklenmesini ertelemek isteyebilirsiniz. 6 | 7 | Next.js'de tembel yüklemeyi uygulayabileceğiniz iki yol vardır: 8 | 9 | 1. `next/dynamic` ile Dinamik İçe Aktarımları Kullanma 10 | 2. [Suspense](https://react.dev/reference/react/Suspense) ile [`React.lazy()`](https://react.dev/reference/react/lazy) Kullanımı 11 | 12 | Varsayılan olarak, Sunucu Bileşenleri otomatik olarak [code split](https://developer.mozilla.org/en-US/docs/Glossary/Code_splitting) edebilir ve kullanıcı arayüzü parçalarını sunucudan istemciye aşamalı olarak göndermek için akışı kullanabilirsiniz. Tembel yükleme İstemci Bileşenleri için geçerlidir. 13 | 14 | ## `next/dynamic` 15 | 16 | `next/dynamic`, [`React.lazy()`](https://react.dev/reference/react/lazy) ve [Suspense](https://react.dev/reference/react/Suspense)'in bir bileşimidir. Artımlı geçişe izin vermek için `app` ve `pages` dizinlerinde aynı şekilde davranır. 17 | 18 | ## Örnekler 19 | 20 | ### İstemci Bileşenlerini İçe Aktarma (Importing Client Components) 21 | 22 | ```js 23 | // app/page.js 24 | 25 | "use client"; 26 | 27 | import { useState } from "react"; 28 | import dynamic from "next/dynamic"; 29 | 30 | // Client Components: 31 | const ComponentA = dynamic(() => import("../components/A")); 32 | const ComponentB = dynamic(() => import("../components/B")); 33 | const ComponentC = dynamic(() => import("../components/C"), { ssr: false }); 34 | 35 | export default function ClientComponentExample() { 36 | const [showMore, setShowMore] = useState(false); 37 | 38 | return ( 39 | <div> 40 | {/* Hemen yükleyin, ancak ayrı bir istemci paketinde */} 41 | <ComponentA /> 42 | 43 | {/* Talep üzerine yükleyin, yalnızca koşul karşılandığında/karşılanırsa */} 44 | {showMore && <ComponentB />} 45 | <button onClick={() => setShowMore(!showMore)}>Toggle</button> 46 | 47 | {/* Yalnızca istemci tarafına yükleyin */} 48 | <ComponentC /> 49 | </div> 50 | ); 51 | } 52 | ``` 53 | 54 | ### SSR'yi Atlama (Skipping SSR) 55 | 56 | `React.lazy()` ve [Suspense](https://react.dev/reference/react/Suspense) kullanıldığında, İstemci Bileşenleri varsayılan olarak önceden render edilecektir (SSR). 57 | 58 | Bir İstemci Bileşeni için ön render etmeyi devre dışı bırakmak istiyorsanız, ssr seçeneğini false olarak ayarlayabilirsiniz: 59 | 60 | ```js 61 | const ComponentC = dynamic(() => import("../components/C"), { ssr: false }); 62 | ``` 63 | 64 | ### Sunucu Bileşenlerini İçe Aktarma (Importing Server Components) 65 | 66 | Bir Sunucu Bileşenini dinamik olarak içe aktarırsanız, Sunucu Bileşeninin kendisi değil, yalnızca Sunucu Bileşeninin alt bileşenleri olan İstemci Bileşenleri lazy-load edilecektir. 67 | 68 | ```js 69 | // app/page.js 70 | 71 | import dynamic from "next/dynamic"; 72 | 73 | // Server Component: 74 | const ServerComponent = dynamic(() => import("../components/ServerComponent")); 75 | 76 | export default function ServerComponentExample() { 77 | return ( 78 | <div> 79 | <ServerComponent /> 80 | </div> 81 | ); 82 | } 83 | ``` 84 | 85 | ### Harici Kütüphaneleri Yükleme 86 | 87 | Harici kütüphaneler [`import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) fonksiyonu kullanılarak isteğe bağlı olarak yüklenebilir. Bu örnekte bulanık arama için `fuse.js` harici kütüphanesi kullanılmaktadır. Modül, yalnızca kullanıcı arama girdisini yazdıktan sonra istemciye yüklenir. 88 | 89 | ```js 90 | // app/page.js 91 | 92 | "use client"; 93 | 94 | import { useState } from "react"; 95 | 96 | const names = ["Tim", "Joe", "Bel", "Lee"]; 97 | 98 | export default function Page() { 99 | const [results, setResults] = useState(); 100 | 101 | return ( 102 | <div> 103 | <input 104 | type="text" 105 | placeholder="Search" 106 | onChange={async (e) => { 107 | const { value } = e.currentTarget; 108 | // Dynamically load fuse.js 109 | const Fuse = (await import("fuse.js")).default; 110 | const fuse = new Fuse(names); 111 | 112 | setResults(fuse.search(value)); 113 | }} 114 | /> 115 | <pre>Results: {JSON.stringify(results, null, 2)}</pre> 116 | </div> 117 | ); 118 | } 119 | ``` 120 | 121 | ### Özel bir yükleme bileşeni ekleme (Adding a custom loading component) 122 | 123 | ```js 124 | // app/page.js 125 | 126 | import dynamic from "next/dynamic"; 127 | 128 | const WithCustomLoading = dynamic( 129 | () => import("../components/WithCustomLoading"), 130 | { 131 | loading: () => <p>Loading...</p>, 132 | } 133 | ); 134 | 135 | export default function Page() { 136 | return ( 137 | <div> 138 | {/* <WithCustomLoading/> yüklenirken yükleme bileşeni oluşturulacaktır */} 139 | <WithCustomLoading /> 140 | </div> 141 | ); 142 | } 143 | ``` 144 | 145 | ### Adlandırılmış Dışa Aktarmaları İçe Aktarma (Importing Named Exports) 146 | 147 | Adlandırılmış bir dışa aktarımı dinamik olarak içe aktarmak için, [`import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) işlevi tarafından döndürülen Promise'den geri döndürebilirsiniz: 148 | 149 | ```js 150 | // components/hello.js 151 | 152 | "use client"; 153 | 154 | export function Hello() { 155 | return <p>Hello!</p>; 156 | } 157 | ``` 158 | 159 | ```js 160 | // app/page.js 161 | 162 | import dynamic from "next/dynamic"; 163 | 164 | const ClientComponent = dynamic(() => 165 | import("../components/hello").then((mod) => mod.Hello) 166 | ); 167 | ``` 168 | -------------------------------------------------------------------------------- /6-optimizing/7-analytics/Readme.md: -------------------------------------------------------------------------------- 1 | # Analitik (Analytics) 2 | 3 | [Next.js Speed Insights](https://nextjs.org/analytics), farklı metrikler kullanarak sayfaların performansını analiz etmenize ve ölçmenize olanak tanır. 4 | 5 | [Vercel dağıtımlarında](https://vercel.com/docs/concepts/speed-insights?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) sıfır yapılandırma ile [Gerçek Deneyim Puanınızı](https://vercel.com/docs/concepts/speed-insights#core-web-vitals-explained?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) toplamaya başlayabilirsiniz. 6 | 7 | Bu belgenin geri kalanında Next.js Speed Insights'ın kullandığı yerleşik aktarıcı açıklanmaktadır. 8 | 9 | ## Web Vitals 10 | 11 | [Web Vitals](https://web.dev/vitals/), bir web sayfasının kullanıcı deneyimini yakalamayı amaçlayan bir dizi yararlı metriktir. Aşağıdaki web hayati değerlerinin tümü dahildir: 12 | 13 | - [Time to First Byte](https://developer.mozilla.org/en-US/docs/Glossary/Time_to_first_byte) (TTFB) 14 | - [First Contentful Paint](https://developer.mozilla.org/en-US/docs/Glossary/First_contentful_paint) (FCP) 15 | - [Largest Contentful Paint](https://web.dev/lcp/) (LCP) 16 | - [First Input Delay](https://web.dev/fid/) (FID) 17 | - [Cumulative Layout Shift](https://web.dev/cls/) (CLS) 18 | - [Interaction to Next Paint](https://web.dev/inp/) (INP) (experimental) 19 | -------------------------------------------------------------------------------- /6-optimizing/9-instrumentation/Readme.md: -------------------------------------------------------------------------------- 1 | # Enstrümantasyon 2 | 3 | Projenizin kök dizinindeki (veya kullanıyorsanız `src` klasörünün içindeki) `instrumentation.ts` (veya `.js`) dosyasından `register` adlı bir işlevi dışa aktarırsanız, yeni bir Next.js sunucu örneği önyüklendiğinde bu işlevi çağırırız. 4 | 5 | **Bilmekte fayda var:** 6 | 7 | - Bu özellik deneyseldir. Kullanmak için, `next.config.js` dosyanızda `experimental.instrumentationHook = true;` tanımlayarak açıkça tercih etmelisiniz. 8 | - `instrumentation` dosyası, `app` veya `pages` dizini içinde değil, projenizin kök dizininde olmalıdır. Eğer `src` klasörünü kullanıyorsanız, dosyayı `pages` ve `app` ile birlikte `src`'nin içine yerleştirin. 9 | - Bir son ek eklemek için `pageExtensions` yapılandırma seçeneğini kullanırsanız, `instrumentation` dosya adını da eşleşecek şekilde güncellemeniz gerekecektir. 10 | - Kullanabileceğiniz temel bir [with-opentelemetry](https://github.com/vercel/next.js/tree/canary/examples/with-opentelemetry) örneği oluşturduk. 11 | 12 | `register` işleviniz deploy edildiğinde, her soğuk önyüklemede çağrılacaktır (ancak her ortamda tam olarak bir kez). 13 | 14 | Bazen, neden olacağı yan etkiler nedeniyle kodunuzda bir dosyayı içe aktarmak yararlı olabilir. Örneğin, bir dizi global değişkeni tanımlayan bir dosyayı içe aktarabilir, ancak içe aktarılan dosyayı kodunuzda asla açıkça kullanmayabilirsiniz. Yine de paketin bildirdiği global değişkenlere erişiminiz olacaktır. 15 | 16 | Aşağıdaki örnekte gösterildiği gibi, `register` işlevinizde kullanmak isteyebileceğiniz `instrumentation.ts` dosyasında yan etkileri olan dosyaları içe aktarabilirsiniz: 17 | 18 | ```ts 19 | // your-project/instrumentation.ts; 20 | 21 | import { init } from "package-init"; 22 | 23 | export function register() { 24 | init(); 25 | } 26 | ``` 27 | 28 | Ancak, yan etkileri olan dosyaları içe aktarmak için bunun yerine `register` işlevinizin içinden `import` etmeyi kullanmanızı öneririz. Aşağıdaki örnek, bir `register` fonksiyonunda `import`'un temel bir kullanımını göstermektedir: 29 | 30 | ```ts 31 | // your-project/instrumentation.ts 32 | export async function register() { 33 | await import("package-with-side-effect"); 34 | } 35 | ``` 36 | 37 | Bunu yaparak, tüm yan etkilerinizi kodunuzda tek bir yerde toplayabilir ve dosyaların içe aktarılmasından kaynaklanan istenmeyen sonuçlardan kaçınabilirsiniz. 38 | 39 | Tüm ortamlarda `register` diyoruz, bu nedenle hem `edge` hem de `nodejs`'i desteklemeyen herhangi bir kodu koşullu olarak içe aktarmak gerekir. Geçerli ortamı almak için `NEXT_RUNTIME` ortam değişkenini kullanabilirsiniz. Ortama özgü bir kodu içe aktarmak şu şekilde görünecektir: 40 | 41 | ```ts 42 | // your-project/instrumentation.ts 43 | 44 | export async function register() { 45 | if (process.env.NEXT_RUNTIME === "nodejs") { 46 | await import("./instrumentation-node"); 47 | } 48 | 49 | if (process.env.NEXT_RUNTIME === "edge") { 50 | await import("./instrumentation-edge"); 51 | } 52 | } 53 | ``` 54 | -------------------------------------------------------------------------------- /6-optimizing/Readme.md: -------------------------------------------------------------------------------- 1 | # Optimizasyonlar (Optimizations) 2 | 3 | Next.js, uygulamanızın hızını ve [Core Web Vitals](https://web.dev/vitals/)'ı iyileştirmek için tasarlanmış çeşitli yerleşik optimizasyonlarla birlikte gelir. Bu kılavuz, kullanıcı deneyiminizi geliştirmek için yararlanabileceğiniz optimizasyonları kapsayacaktır. 4 | 5 | ## Yerleşik Bileşenler 6 | 7 | Yerleşik bileşenler, yaygın UI optimizasyonlarını uygulamanın karmaşıklığını ortadan kaldırır. Bu bileşenler şunlardır: 8 | 9 | - **Görüntüler:** Yerel `<img>` öğesi üzerine inşa edilmiştir. Görüntü Bileşeni, tembel yükleme ve görüntüleri cihaz boyutuna göre otomatik olarak yeniden boyutlandırma yoluyla görüntüleri performans için optimize eder. 10 | - **Bağlantı:** Yerel `<a>` etiketleri üzerine inşa edilmiştir. Bağlantı Bileşeni, daha hızlı ve daha yumuşak sayfa geçişleri için sayfaları arka planda önceden hazırlar. 11 | - **Komut Dosyaları:** Yerel `<script>` etiketleri üzerine inşa edilmiştir. Komut Dosyası Bileşeni, üçüncü taraf komut dosyalarının yüklenmesi ve yürütülmesi üzerinde kontrol sahibi olmanızı sağlar. 12 | 13 | ## Metadata 14 | 15 | Meta veriler, arama motorlarının içeriğinizi daha iyi anlamasına yardımcı olur (bu da daha iyi SEO ile sonuçlanabilir) ve içeriğinizin sosyal medyada nasıl sunulduğunu özelleştirmenize olanak tanıyarak çeşitli platformlarda daha ilgi çekici ve tutarlı bir kullanıcı deneyimi oluşturmanıza yardımcı olur. 16 | 17 | Next.js'deki Metadata API, bir sayfanın `<head>` öğesini değiştirmenize olanak tanır. Meta verileri iki şekilde yapılandırabilirsiniz: 18 | 19 | - **Yapılandırma Tabanlı Meta Veriler:** Statik bir meta veri nesnesini veya dinamik bir generateMetadata işlevini bir `layout.js` veya `page.js` dosyasına aktarın. 20 | - **Dosya Tabanlı Meta Veriler:** Rota segmentlerine statik veya dinamik olarak oluşturulan özel dosyalar ekleyin. 21 | 22 | Ayrıca, imageResponse yapıcısı ile JSX ve CSS kullanarak dinamik Open Graph Görüntüleri oluşturabilirsiniz. 23 | 24 | ## Statik Varlıklar 25 | 26 | Next.js `/public` klasörü resimler, yazı tipleri ve diğer dosyalar gibi statik varlıkları sunmak için kullanılabilir. `/public` içindeki dosyalar da CDN sağlayıcıları tarafından önbelleğe alınabilir, böylece verimli bir şekilde teslim edilirler. 27 | 28 | ## Analitik ve İzleme 29 | 30 | Büyük uygulamalar için Next.js, uygulamanızın nasıl performans gösterdiğini anlamanıza yardımcı olmak için popüler analiz ve izleme araçlarıyla entegre olur. 31 | -------------------------------------------------------------------------------- /7-configuring/1-typescript/Readme.md: -------------------------------------------------------------------------------- 1 | # TypeScript 2 | 3 | Next.js, React uygulamanızı oluşturmak için TypeScript öncelikli bir geliştirme deneyimi sunar. 4 | 5 | Gerekli paketleri otomatik olarak yüklemek ve uygun ayarları yapılandırmak için yerleşik TypeScript desteği ile birlikte gelir. 6 | 7 | Editörünüz için bir [TypeScript Eklentisinin](https://nextjs.org/docs/app/building-your-application/configuring/typescript#typescript-plugin) yanı sıra. 8 | 9 | 🎥 İzleyin: Yerleşik TypeScript eklentisi hakkında bilgi edinin → [YouTube (3 dakika)](https://www.youtube.com/watch?v=pqMqn9fKEf8) 10 | 11 | ## Yeni Projeler 12 | 13 | `create-next-app` artık varsayılan olarak TypeScript ile birlikte geliyor. 14 | 15 | ```bash 16 | // Terminal 17 | npx create-next-app@latest 18 | ``` 19 | 20 | ## Mevcut Projeler 21 | 22 | Bir dosyayı `.ts` / `.tsx` olarak yeniden adlandırarak projenize TypeScript ekleyin. Gerekli bağımlılıkları otomatik olarak yüklemek ve önerilen yapılandırma seçeneklerini içeren bir `tsconfig.json` dosyası eklemek için `next dev` ve `next build`'i çalıştırın. 23 | 24 | Zaten bir `jsconfig.json` dosyanız varsa, eski `jsconfig.json` dosyasındaki paths derleyici seçeneğini yeni `tsconfig.json` dosyasına kopyalayın ve eski `jsconfig.json` dosyasını silin. 25 | 26 | ## TypeScript Eklentisi 27 | 28 | Next.js, VSCode ve diğer kod düzenleyicilerin gelişmiş tür denetimi ve otomatik tamamlama için kullanabileceği özel bir TypeScript eklentisi ve tür denetleyicisi içerir. 29 | 30 | Eklentiyi VS Code'da şu şekilde etkinleştirebilirsiniz: 31 | 32 | 1. Komut paletini açma (`Ctrl/⌘ + Shift + P`) 33 | 2. "TypeScript: TypeScript Sürümünü Seçin" 34 | 3. "Çalışma Alanı Sürümünü Kullan" seçiliyor 35 | 36 | <img alt="typescript" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Ftypescript-command-palette.png&w=1920&q=75&dpl=dpl_6Yq4y5XKQAGCqykadPGURhWiWZCpJ"/><br/> 37 | 38 | Şimdi, dosyaları düzenlerken, özel eklenti etkinleştirilecektir. Bir sonraki `next build` çalıştırıldığında, özel tür denetleyicisi kullanılacaktır. 39 | 40 | ### Eklenti Özellikleri 41 | 42 | TypeScript eklentisi şu konularda yardımcı olabilir: 43 | 44 | - [Segment yapılandırma seçenekleri](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config) için geçersiz değerler geçilirse uyarı gösterme. 45 | - Mevcut seçenekleri ve bağlam içi belgeleri gösterme. 46 | - "use client" yönergesinin doğru kullanıldığından emin olmak. 47 | - İstemci kancalarının (`useState` gibi) yalnızca İstemci Bileşenlerinde kullanılmasını sağlama. 48 | 49 | **Bilmekte fayda var:** Gelecekte daha fazla özellik eklenecektir. 50 | 51 | ## Minimum TypeScript Sürümü 52 | 53 | [İçe aktarma adlarında tür değiştiriciler](https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#type-on-import-names) ve [performans iyileştirmeleri](https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#real-path-sync-native) gibi sözdizimi özelliklerini elde etmek için TypeScript'in en az `v4.5.2` sürümünde olmanız şiddetle tavsiye edilir. 54 | 55 | ## Statik Olarak Yazılan Bağlantılar (Statically Typed Links) 56 | 57 | Next.js, `next/link` kullanırken yazım hatalarını ve diğer hataları önlemek için bağlantıları statik olarak yazabilir ve sayfalar arasında gezinirken yazım güvenliğini artırır. 58 | 59 | Bu özelliğe dahil olmak için `experimental.typedRoutes` özelliğinin etkinleştirilmesi ve projenin TypeScript kullanıyor olması gerekir. 60 | 61 | ```js 62 | // next.config.js 63 | 64 | /** @type {import('next').NextConfig} */ 65 | const nextConfig = { 66 | experimental: { 67 | typedRoutes: true, 68 | }, 69 | }; 70 | 71 | module.exports = nextConfig; 72 | ``` 73 | 74 | Next.js, `.next/types` içinde uygulamanızdaki mevcut tüm rotalar hakkında bilgi içeren bir bağlantı tanımı oluşturacak ve TypeScript bu bağlantıyı geçersiz bağlantılar hakkında düzenleyicinize geri bildirim sağlamak için kullanabilecektir. 75 | 76 | Şu anda, deneysel destek dinamik segmentler de dahil olmak üzere herhangi bir string literalini içermektedir. Literal olmayan dizeler için, şu anda `href`'i `as Route` ile manuel olarak atmanız gerekir: 77 | 78 | ```ts 79 | import type { Route } from 'next'; 80 | import Link from 'next/link' 81 | 82 | // href geçerli bir rota ise TypeScript hatası yok 83 | <Link href="/about" /> 84 | <Link href="/blog/nextjs" /> 85 | <Link href={`/blog/${slug}`} /> 86 | <Link href={('/blog' + slug) as Route} /> 87 | 88 | // href geçerli bir rota değilse TypeScript hata verir 89 | <Link href="/aboot" />s 90 | ``` 91 | 92 | `next/link`'i saran özel bir bileşende `href` kabul etmek için bir generic kullanın: 93 | 94 | ```ts 95 | import type { Route } from "next"; 96 | import Link from "next/link"; 97 | 98 | function Card<T extends string>({ href }: { href: Route<T> | URL }) { 99 | return ( 100 | <Link href={href}> 101 | <div>My Card</div> 102 | </Link> 103 | ); 104 | } 105 | ``` 106 | 107 | **Nasıl çalışıyor?** 108 | 109 | Next.js, `next dev` veya `next build`'i çalıştırırken `.next` içinde uygulamanızdaki mevcut tüm rotalar hakkında bilgi içeren gizli bir `.d.ts` dosyası oluşturur (`href` türü Bağlantı olan tüm geçerli rotalar). Bu `.d.ts` dosyası `tsconfig.json` dosyasına dahil edilir ve TypeScript derleyicisi bu `.d.ts` dosyasını kontrol eder ve editörünüzde geçersiz bağlantılar hakkında geri bildirim sağlar. 110 | 111 | ## Uçtan Uca Tip Güvenlik (End-to-End Type Safety) 112 | 113 | Next.js 13 gelişmiş tip güvenliğine sahiptir. Buna şunlar dahildir: 114 | 115 | 1. **Fetch etme fonksiyonu ve sayfa arasında verileri serileştirme yoktur:** Sunucudaki bileşenlerde, düzenlerde ve sayfalarda doğrudan veri `fetch` edebilirsiniz. Bu verilerin React'te tüketilmek üzere istemci tarafına aktarılması için serileştirilmesi (bir dizeye dönüştürülmesi) gerekmez. Bunun yerine, `app` varsayılan olarak Sunucu Bileşenlerini kullandığından, `Date`, `Map`, `Set` ve daha fazlası gibi değerleri herhangi bir ekstra adım olmadan kullanabiliriz. Önceden, Next.js'ye özgü türlerle sunucu ve istemci arasındaki sınırı manuel olarak yazmanız gerekiyordu. 116 | 2. **Bileşenler arasındaki veri akışı kolaylaştırıldı:** Kök düzenler lehine `_app`'nin kaldırılmasıyla, bileşenler ve sayfalar arasındaki veri akışını görselleştirmek artık daha kolay. Önceden, tek tek `pages` ve `_app` arasında akan verilerin yazılması zordu ve kafa karıştırıcı hatalara yol açabiliyordu. Next.js 13'teki ortak konumlu fetch etme ile bu artık bir sorun olmaktan çıktı. 117 | 118 | Next.js'de veri fetch etme artık veritabanınız veya içerik sağlayıcı seçiminiz hakkında kuralcı olmadan mümkün olduğunca uçtan uca tip güvenliği sağlıyor. 119 | 120 | Yanıt verilerini normal TypeScript ile beklediğiniz gibi yazabiliyoruz. Örneğin: 121 | 122 | ```ts 123 | // app/page.tsx 124 | 125 | async function getData() { 126 | const res = await fetch("https://api.example.com/..."); 127 | // Dönüş değeri *seri hale getirilmez* 128 | // Tarih, Harita, Set vb. döndürebilirsiniz. 129 | return res.json(); 130 | } 131 | 132 | export default async function Page() { 133 | const name = await getData(); 134 | 135 | return "..."; 136 | } 137 | ``` 138 | 139 | Uçtan uca tam tip güvenliği için, bu aynı zamanda veritabanınızın veya içerik sağlayıcınızın TypeScript'i desteklemesini gerektirir. Bu, bir [ORM](https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping) veya tip güvenli sorgu oluşturucu kullanarak olabilir. 140 | 141 | ## Async Sunucu Bileşeni TypeScript Hatası 142 | 143 | TypeScript ile bir `async` Sunucu Bileşeni kullanmak için TypeScript `5.1.3` veya üstünü ve `@types/react` `18.2.8` veya üstünü kullandığınızdan emin olun. 144 | 145 | TypeScript'in eski bir sürümünü kullanıyorsanız, `'Promise<Element>' geçerli bir JSX öğesi türü değil` hatası görebilirsiniz. TypeScript ve `@types/react`'in en son sürümüne güncelleme yapmak bu sorunu çözmelidir. 146 | 147 | ## Sunucu ve İstemci Bileşenleri Arasında Veri Geçişi 148 | 149 | Bir Sunucu ve İstemci Bileşeni arasında prop'lar aracılığıyla veri aktarırken, veriler tarayıcıda kullanılmak üzere hala serileştirilir (bir dizeye dönüştürülür). Ancak, özel bir türe ihtiyaç duymaz. Bileşenler arasında diğer prop'ları geçirmekle aynı şekilde yazılır. 150 | 151 | Ayrıca, render edilmemiş veriler sunucu ve istemci arasında geçiş yapmadığından (sunucuda kalır) serileştirilmesi gereken daha az kod vardır. Bu artık sadece Sunucu Bileşenleri desteği ile mümkündür. 152 | 153 | ## Yol takma adları ve baseUrl (Path aliases and baseUrl) 154 | 155 | Next.js otomatik olarak `tsconfig.json` `"paths"` ve `"baseUrl"` seçeneklerini destekler. 156 | 157 | Bu özellik hakkında daha fazla bilgiyi [Modül Yolu takma adları belgesinde](https://nextjs.org/docs/app/building-your-application/configuring/absolute-imports-and-module-aliases) bulabilirsiniz. 158 | 159 | ## `next.config.js` dosyasında tür denetimi 160 | 161 | `next.config.js` dosyası Babel veya TypeScript tarafından ayrıştırılmadığı için bir JavaScript dosyası olmalıdır, ancak aşağıdaki gibi JSDoc kullanarak IDE'nize bazı tür denetimi ekleyebilirsiniz: 162 | 163 | ```js 164 | // @ts-check 165 | 166 | /** 167 | * @type {import('next').NextConfig} 168 | **/ 169 | const nextConfig = { 170 | /* yapılandırma seçenekleri burada */ 171 | }; 172 | 173 | module.exports = nextConfig; 174 | ``` 175 | 176 | ## Artımlı tip denetimi (Incremental type checking) 177 | 178 | `v10.2.1` sürümünden beri Next.js, `tsconfig.json` dosyanızda etkinleştirildiğinde [artımlı tür denetimini](https://www.typescriptlang.org/tsconfig#incremental) desteklediğinden, bu, daha büyük uygulamalarda tür denetimini hızlandırmaya yardımcı olabilir. 179 | 180 | ## TypeScript Hatalarını Yok Sayma 181 | 182 | Next.js, projenizde TypeScript hataları olduğunda üretim derlemenizde (`next build`) başarısız olur. 183 | 184 | Next.js'nin uygulamanızda hatalar olsa bile tehlikeli bir şekilde üretim kodu üretmesini istiyorsanız, yerleşik tür denetimi adımını devre dışı bırakabilirsiniz. 185 | 186 | Devre dışı bırakılmışsa, derleme veya dağıtım işleminizin bir parçası olarak tür denetimlerini çalıştırdığınızdan emin olun, aksi takdirde bu çok tehlikeli olabilir. 187 | 188 | `next.config.js` dosyasını açın ve `typescript` yapılandırmasında `ignoreBuildErrors` seçeneğini etkinleştirin: 189 | 190 | ```js 191 | // next.config.js 192 | 193 | module.exports = { 194 | typescript: { 195 | !! UYARI !!! 196 | // Tehlikeli bir şekilde üretim derlemelerinin başarıyla tamamlanmasına izin ver 197 | // projenizde tip hataları var. 198 | // !! UYARI!! 199 | ignoreBuildErrors: true, 200 | }, 201 | }; 202 | ``` 203 | -------------------------------------------------------------------------------- /7-configuring/3-enviroment-variables/Readme.md: -------------------------------------------------------------------------------- 1 | # Ortam Değişkenleri (Environment Variables) 2 | 3 | Next.js, aşağıdakileri yapmanıza olanak tanıyan ortam değişkenleri için yerleşik destekle birlikte gelir: 4 | 5 | - Ortam değişkenlerini yüklemek için `.env.local` kullanın 6 | - `NEXT_PUBLIC_` ile önekleyerek tarayıcı için ortam değişkenlerini paketleyin 7 | 8 | ## Ortam Değişkenlerini Yükleme 9 | 10 | Next.js, ortam değişkenlerini `.env.local`'den `process.env`'ye yüklemek için yerleşik desteğe sahiptir. 11 | 12 | ```bash 13 | // .env.local 14 | 15 | 16 | DB_HOST=localhost 17 | DB_USER=myuser 18 | DB_PASS=mypassword 19 | ``` 20 | 21 | Bu, `process.env.DB_HOST`, `process.env.DB_USER` ve `process.env.DB_PASS` dosyalarını otomatik olarak Node.js ortamına yükler ve bunları Rota İşleyicilerinde kullanmanıza olanak tanır. 22 | 23 | Örneğin: 24 | 25 | ```js 26 | // app/api/route.js 27 | 28 | export async function GET() { 29 | const db = await myDB.connect({ 30 | host: process.env.DB_HOST, 31 | username: process.env.DB_USER, 32 | password: process.env.DB_PASS, 33 | }); 34 | // ... 35 | } 36 | ``` 37 | 38 | ### Diğer Değişkenlere Referans Verme 39 | 40 | Next.js, `.env*` dosyalarınızın içindeki `$VARIABLE` gibi diğer değişkenlere referans vermek için `$` kullanan değişkenleri otomatik olarak genişletecektir. Bu, diğer gizliliklere referans vermenizi sağlar. Örneğin: 41 | 42 | ```bash 43 | // .env 44 | TWITTER_USER=nextjs 45 | TWITTER_URL=https://twitter.com/$TWITTER_USER 46 | ``` 47 | 48 | Yukarıdaki örnekte, `process.env.TWITTER_URL` `https://twitter.com/nextjs` olarak ayarlanacaktır. 49 | 50 | **Bilmekte fayda var:** Gerçek değerinde `$` olan bir değişken kullanmanız gerekiyorsa, bunun öncelenmesi gerekir, örneğin `\$`. 51 | 52 | ## Tarayıcı için Ortam Değişkenlerinin Paketlenmesi 53 | 54 | Non-`NEXT_PUBLIC_` ortam değişkenleri yalnızca Node.js ortamında kullanılabilir, yani tarayıcı tarafından erişilemezler (istemci farklı bir ortamda çalışır). 55 | 56 | Bir ortam değişkeninin değerini tarayıcıda erişilebilir kılmak için Next.js, derleme sırasında istemciye teslim edilen js paketine bir değer "satır içi" ekleyebilir ve `process.env.[variable]`'a yapılan tüm referansları sabit kodlanmış bir değerle değiştirebilir. Bunu yapmasını söylemek için değişkenin önüne `NEXT_PUBLIC_` eklemeniz yeterlidir. Örneğin: 57 | 58 | ```terminal 59 | NEXT_PUBLIC_ANALYTICS_ID=abcdefghijk 60 | ``` 61 | 62 | Bu, Next.js'ye Node.js ortamındaki `process.env.NEXT_PUBLIC_ANALYTICS_ID`'ye yapılan tüm referansları `next build`'i çalıştırdığınız ortamdaki değerle değiştirmesini söyleyecek ve kodunuzun herhangi bir yerinde kullanmanıza izin verecektir. Tarayıcıya gönderilen tüm JavaScript'lerde satır içi olarak yer alacaktır. 63 | 64 | **Not:** Oluşturulduktan sonra, uygulamanız artık bu ortam değişkenlerindeki değişikliklere yanıt vermeyecektir. Örneğin, bir ortamda oluşturulan slug'ları başka bir ortama tanıtmak için bir Heroku pipeline kullanıyorsanız veya tek bir Docker görüntüsü oluşturup birden fazla ortama dağıtıyorsanız, tüm `NEXT_PUBLIC_` değişkenleri derleme zamanında değerlendirilen değerle dondurulacaktır, bu nedenle proje oluşturulduğunda bu değerlerin uygun şekilde ayarlanması gerekir. Çalışma zamanı ortam değerlerine erişmeniz gerekiyorsa, bunları istemciye sağlamak için kendi API'nizi kurmanız gerekir (talep üzerine veya başlatma sırasında). 65 | 66 | ```js 67 | import setupAnalyticsService from "../lib/my-analytics-service"; 68 | 69 | // 'NEXT_PUBLIC_ANALYTICS_ID', 'NEXT_PUBLIC_' ile ön ekli olduğu için burada kullanılabilir. 70 | // Derleme sırasında `setupAnalyticsService('abcdefghijk')` olarak dönüştürülecektir. 71 | 72 | setupAnalyticsService(process.env.NEXT_PUBLIC_ANALYTICS_ID); 73 | 74 | function HomePage() { 75 | return <h1>Hello World</h1>; 76 | } 77 | 78 | export default HomePage; 79 | ``` 80 | 81 | Aşağıdaki gibi dinamik aramaların satır içi yapılmayacağını unutmayın: 82 | 83 | ```js 84 | // Bu bir değişken kullandığı için satır içi yapılmayacaktır 85 | const varName = "NEXT_PUBLIC_ANALYTICS_ID"; 86 | setupAnalyticsService(process.env[varName]); 87 | 88 | // Bu bir değişken kullandığı için satır içi yapılmayacaktır 89 | const env = process.env; 90 | setupAnalyticsService(env.NEXT_PUBLIC_ANALYTICS_ID); 91 | ``` 92 | 93 | ## Varsayılan Ortam Değişkenleri 94 | 95 | Genel olarak yalnızca bir `.env.local` dosyası gereklidir. Ancak, bazen geliştirme (`next dev`) veya production (`next start`) ortamı için bazı varsayılanlar eklemek isteyebilirsiniz. 96 | 97 | Next.js, `.env` (tüm ortamlar), `.env.development` (geliştirme ortamı) ve `.env.production` (production ortamı) içinde varsayılanları ayarlamanıza olanak tanır. 98 | 99 | `.env.local` her zaman ayarlanan varsayılanları geçersiz kılar. 100 | 101 | **Bilmenizde fayda var:** `.env`, `.env.development` ve `.env.production` dosyaları varsayılanları tanımladıkları için deponuza dahil edilmelidir. `.env*.local` dosyaları `.gitignore`'a eklenmelidir, çünkü bu dosyaların göz ardı edilmesi amaçlanmıştır. `.env.local` gizli dosyaların saklanabileceği yerdir. 102 | 103 | ## Vercel'de Ortam Değişkenleri 104 | 105 | Next.js uygulamanızı [Vercel](https://vercel.com/)'e deploy ederken, Ortam Değişkenleri [Proje Ayarları](https://vercel.com/docs/concepts/projects/environment-variables?utm_source=next-site&utm_medium=docs&utm_campaign=next-website)'nda yapılandırılabilir. 106 | 107 | Her tür Ortam Değişkeni burada yapılandırılmalıdır. Geliştirmede kullanılan Ortam Değişkenleri bile - ki bunlar daha sonra [yerel cihazınıza indirilebilir](https://vercel.com/docs/concepts/projects/environment-variables#development-environment-variables?utm_source=next-site&utm_medium=docs&utm_campaign=next-website). 108 | 109 | [Geliştirme Ortam Değişkenlerini yapılandırdıysanız](https://vercel.com/docs/concepts/projects/environment-variables#development-environment-variables?utm_source=next-site&utm_medium=docs&utm_campaign=next-website), aşağıdaki komutu kullanarak bunları yerel makinenizde kullanmak üzere bir `.env.local` içine çekebilirsiniz: 110 | 111 | ```Terminal 112 | vercel env pull .env.local 113 | ``` 114 | 115 | ## Test Ortamı Değişkenleri 116 | 117 | `development` ve `production` ortamlarının yanı sıra 3. bir seçenek daha mevcuttur: `test`. Geliştirme veya production ortamları için varsayılanları ayarlayabileceğiniz gibi, aynı şeyi test ortamı için bir `.env.test` dosyası ile de yapabilirsiniz (ancak bu önceki ikisi kadar yaygın değildir). Next.js, `testing` ortamında `.env.development` veya `.env.production` dosyalarındaki ortam değişkenlerini yüklemeyecektir. 118 | 119 | Bu, yalnızca test amacıyla belirli ortam değişkenlerini ayarlamanız gereken `jest` veya `cypress` gibi araçlarla testler çalıştırırken kullanışlıdır. `NODE_ENV` `test` olarak ayarlanırsa test varsayılan değerleri yüklenecektir, ancak test araçları bunu sizin için ele alacağından genellikle bunu manuel olarak yapmanız gerekmez. 120 | 121 | `test` ortamı ile hem `development` hem de `production` arasında aklınızda bulundurmanız gereken küçük bir fark vardır: Testlerin herkes için aynı sonuçları üretmesini beklediğiniz için `.env.local` yüklenmeyecektir. Bu şekilde her test yürütmesi, `.env.local` (varsayılan seti geçersiz kılmak için tasarlanmıştır) dosyanızı yok sayarak farklı yürütmelerde aynı env varsayılanlarını kullanacaktır. 122 | 123 | **Bilmenizde fayda var:** Varsayılan Ortam Değişkenlerine benzer şekilde, `.env.test` dosyası deponuza dahil edilmelidir, ancak `.env.test.local` dosyası dahil edilmemelidir, çünkü `.env*.local` dosyasının `.gitignore` aracılığıyla göz ardı edilmesi amaçlanmıştır. 124 | 125 | Birim testlerini çalıştırırken, `@next/env` paketindeki `loadEnvConfig` işlevinden yararlanarak ortam değişkenlerinizi Next.js'nin yaptığı gibi yüklediğinizden emin olabilirsiniz. 126 | 127 | ```js 128 | // // Aşağıdakiler, test kurulumunuz için bir Jest global kurulum dosyasında veya benzerinde kullanılabilir 129 | import { loadEnvConfig } from "@next/env"; 130 | 131 | export default async () => { 132 | const projectDir = process.cwd(); 133 | loadEnvConfig(projectDir); 134 | }; 135 | ``` 136 | 137 | ## Ortam Değişkeni Yük Sırası 138 | 139 | Ortam değişkenleri sırasıyla aşağıdaki yerlerde aranır ve değişken bulunduğunda durdurulur. 140 | 141 | 1. `process.env` 142 | 2. `.env.$(NODE_ENV).local` 143 | 3. `.env.local` (`NODE_ENV` `test` olduğunda kontrol edilmez.) 144 | 4. `.env.$(NODE_ENV)` 145 | 5. `.env` 146 | 147 | Örneğin, `NODE_ENV` `development` ise ve hem `.env.development.local` hem de `.env`'de bir değişken tanımlarsanız, `.env.development.local`'deki değer kullanılır. 148 | 149 | **Bilmekte fayda var:** `NODE_ENV` için izin verilen değerler `development`, `production` ve `test`tir. 150 | 151 | ## Bilmekte fayda var 152 | 153 | - Eğer bir `/src` dizini kullanıyorsanız, `.env.*` dosyaları projenizin kök dizininde kalmalıdır. 154 | - `NODE_ENV` ortam değişkeni atanmamışsa Next.js, `next dev` komutunu çalıştırırken otomatik olarak `development` veya diğer tüm komutlar için `production` ataması yapar. 155 | -------------------------------------------------------------------------------- /7-configuring/4-absolute-imports-and-module-path-aliases/Readme.md: -------------------------------------------------------------------------------- 1 | # Mutlak İçe Aktarmalar ve Modül Yolu Takma Adları (Absolute Imports and Module Path Aliases) 2 | 3 | Next.js, `tsconfig.json` ve `jsconfig.json` dosyalarının `"paths"` ve `"baseUrl"` seçenekleri için yerleşik destek sunar. 4 | 5 | Bu seçenekler, proje dizinlerini mutlak yollara takma ad olarak eklemenize olanak tanıyarak modülleri içe aktarmayı kolaylaştırır. Örneğin: 6 | 7 | ```ts 8 | // önce 9 | import { Button } from "../../../components/button"; 10 | 11 | // sonra 12 | import { Button } from "@/components/button"; 13 | ``` 14 | 15 | **bilmekte fayda var:** `create-next-app`, bu seçenekleri sizin için yapılandırmayı önerir. 16 | 17 | ## Mutlak İçe Aktarmalar (Absolute Imports) 18 | 19 | `baseUrl` yapılandırma seçeneği, projenin kökünden doğrudan içe aktarmanıza olanak tanır. 20 | 21 | Bu yapılandırmanın bir örneği: 22 | 23 | ```json 24 | // tsconfig.json veya jsconfig.json 25 | 26 | { 27 | "compilerOptions": { 28 | "baseUrl": "." 29 | } 30 | } 31 | ``` 32 | 33 | ```typescript 34 | // components/button.tsx; 35 | 36 | export default function Button() { 37 | return <button>Click me</button>; 38 | } 39 | ``` 40 | 41 | ```js 42 | // app / page.tsx; 43 | 44 | import Button from "components/button"; 45 | 46 | export default function HomePage() { 47 | return ( 48 | <> 49 | <h1>Hello World</h1> 50 | <Button /> 51 | </> 52 | ); 53 | } 54 | ``` 55 | 56 | ### Modül Takma Adları (Module Aliases) 57 | 58 | `baseUrl` yolu yapılandırmasına ek olarak, `"paths"` seçeneğini kullanarak modül yollarını "alias" olarak kullanabilirsiniz. 59 | 60 | Örneğin, aşağıdaki yapılandırma, `@/components/*`'ı `components/*`'a eşler: 61 | 62 | ```json 63 | // tsconfig.json veya jsconfig.json 64 | 65 | { 66 | "compilerOptions": { 67 | "baseUrl": ".", 68 | "paths": { 69 | "@/components/_": ["components/_"] 70 | } 71 | } 72 | } 73 | ``` 74 | 75 | ```ts 76 | // components/button.tsx 77 | 78 | export default function Button() { 79 | return <button>Click me</button>; 80 | } 81 | ``` 82 | 83 | ```ts 84 | /// app/page.tsx 85 | 86 | import Button from "@/components/button"; 87 | 88 | export default function HomePage() { 89 | return ( 90 | <> 91 | <h1>Hello World</h1> 92 | <Button /> 93 | </> 94 | ); 95 | } 96 | ``` 97 | 98 | `"paths"` her biri `baseUrl` konumuna görelidir. Örneğin: 99 | 100 | ```json 101 | // tsconfig.json veya jsconfig.json 102 | 103 | { 104 | "compilerOptions": { 105 | "baseUrl": "src/", 106 | "paths": { 107 | "@/styles/_": ["styles/_"], 108 | "@/components/_": ["components/_"] 109 | } 110 | } 111 | } 112 | ``` 113 | 114 | ```js 115 | // pages/index.js 116 | 117 | import Button from "@/components/button"; 118 | import "@/styles/styles.css"; 119 | import Helper from "utils/helper"; 120 | 121 | export default function HomePage() { 122 | return ( 123 | <Helper> 124 | <h1>Hello World</h1> 125 | <Button /> 126 | </Helper> 127 | ); 128 | } 129 | ``` 130 | -------------------------------------------------------------------------------- /7-configuring/5-MDX/Readme.md: -------------------------------------------------------------------------------- 1 | # MDX 2 | 3 | [Markdown](https://daringfireball.net/projects/markdown/syntax), metni biçimlendirmek için kullanılan hafif bir biçimlendirme dilidir. Düz metin sözdizimi kullanarak yazmanıza ve yapısal olarak geçerli HTML'ye dönüştürmenize olanak tanır. Genellikle web sitelerinde ve bloglarda içerik yazmak için kullanılır. 4 | 5 | Siz aşağıdakini yazdığınızda... 6 | 7 | ```md 8 | I **love** using [Next.js](https://nextjs.org/) 9 | ``` 10 | 11 | Çıktı: 12 | 13 | ```md 14 | <p> <a href="https://nextjs.org/">Next.js</a></p> kullanmayı <strong>seviyorum</strong> 15 | ``` 16 | 17 | [MDX](https://mdxjs.com/), [JSX](https://react.dev/learn/writing-markup-with-jsx)'i doğrudan markdown dosyalarınıza yazmanıza olanak tanıyan bir markdown üst kümesidir. Dinamik etkileşim eklemenin ve içeriğinize React bileşenleri yerleştirmenin güçlü bir yoludur. 18 | 19 | Next.js, hem uygulamanızın içindeki yerel MDX içeriğini hem de sunucudan dinamik olarak getirilen uzak MDX dosyalarını destekleyebilir. Next.js eklentisi, Sunucu Bileşenlerinde (`app`'de varsayılan) kullanım desteği de dahil olmak üzere Markdown ve React bileşenlerini HTML'ye dönüştürmeyi yönetir. 20 | 21 | ## `@next/mdx` 22 | 23 | `@next/mdx` paketi, projelerinizin kök dizinindeki `next.config.js` dosyasında yapılandırılır. Yerel dosyalardan veri alır ve doğrudan `/pages` veya `/app` dizininizde `.mdx` uzantılı sayfalar oluşturmanıza olanak tanır. 24 | 25 | ## Başlarken 26 | 27 | `@next/mdx` paketini yükleyin: 28 | 29 | ```bash 30 | npm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdx 31 | ``` 32 | 33 | Uygulamanızın kök dizininde (`app/` veya `src/` klasörünün üst dizini) `mdx-components.tsx` dosyasını oluşturun: 34 | 35 | ```tsx 36 | ///mdx-components.tsx 37 | 38 | import type { MDXComponents } from "mdx/types"; 39 | 40 | // Bu dosya, MDX dosyalarında kullanılmak üzere 41 | // özel React bileşenleri sağlamanıza olanak tanır. 42 | // Diğer kütüphanelerdeki bileşenler de dahil olmak üzere 43 | // istediğiniz herhangi bir react bileşenini 44 | // içe aktarabilir ve kullanabilirsiniz. 45 | 46 | // Bu dosya MDX'i `app` dizininde kullanmak için gereklidir. 47 | export function useMDXComponents(components: MDXComponents): MDXComponents { 48 | return { 49 | // Yerleşik bileşenlerin özelleştirilmesine, örneğin stil eklenmesine izin verir. 50 | // h1: ({ children }) => <h1 style={{ fontSize: "100px" }}>{children}</h1>, 51 | ...components, 52 | }; 53 | } 54 | ``` 55 | 56 | `next.config.js` dosyasını `mdxRs` kullanacak şekilde güncelleyin: 57 | 58 | ```js 59 | ///next.config.js 60 | 61 | /** @type {import('next').NextConfig} */ 62 | const nextConfig = { 63 | experimental: { 64 | mdxRs: true, 65 | }, 66 | }; 67 | 68 | const withMDX = require("@next/mdx")(); 69 | module.exports = withMDX(nextConfig); 70 | ``` 71 | 72 | `app` dizininize MDX içerikli yeni bir dosya ekleyin: 73 | 74 | ```mdx 75 | // app/hello.mdx 76 | 77 | Merhaba, Next.js! 78 | 79 | MDX dosyalarındaki React bileşenlerini içe aktarabilir ve kullanabilirsiniz. 80 | ``` 81 | 82 | İçeriği görüntülemek için `MDX` dosyasını bir `pages` içine aktarın: 83 | 84 | ```tsx 85 | // app/page.tsx 86 | 87 | import HelloWorld from "./hello.mdx"; 88 | 89 | export default function Page() { 90 | return <HelloWorld />; 91 | } 92 | ``` 93 | 94 | ## Uzaktan MDX (Remote MDX) 95 | 96 | Markdown veya MDX dosyalarınız uygulamanızın içinde yaşamıyorsa, bunları sunucudan dinamik olarak getirebilirsiniz. Bu, bir CMS'den veya başka bir veri kaynağından içerik almak için kullanışlıdır. 97 | 98 | MDX içeriğini almak için iki popüler topluluk paketi vardır: [`next-mdx-remote`](https://github.com/hashicorp/next-mdx-remote#react-server-components-rsc--nextjs-app-directory-support) ve [`contentlayer`](https://www.contentlayer.dev/). Örneğin, aşağıdaki örnek `next-mdx-remote` kullanmaktadır: 99 | 100 | **Bilmekte fayda var:** Lütfen dikkatli olun. MDX, JavaScript olarak derlenir ve sunucuda yürütülür. MDX içeriğini yalnızca güvenilir bir kaynaktan almalısınız, aksi takdirde bu durum uzaktan kod yürütülmesine (RCE) yol açabilir. 101 | 102 | ```ts 103 | // app/page.tsx 104 | 105 | import { MDXRemote } from "next-mdx-remote/rsc"; 106 | 107 | export default async function Home() { 108 | const res = await fetch("https://..."); 109 | const markdown = await res.text(); 110 | return <MDXRemote source={markdown} />; 111 | } 112 | ``` 113 | 114 | ## Düzenlemeler (Layouts) 115 | 116 | MDX içeriği etrafında bir düzen paylaşmak için Uygulama Yönlendiricisi ile [yerleşik düzen desteği](https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts#layouts)ni kullanabilirsiniz. 117 | 118 | ## Remark ve Rehype Eklentileri 119 | 120 | MDX içeriğini dönüştürmek için isteğe bağlı olarak `remark` ve `rehype` eklentileri sağlayabilirsiniz. Örneğin, GitHub Flavored Markdown'ı desteklemek için `remark-gfm` kullanabilirsiniz. 121 | 122 | `remark` ve `rehype` ekosistemi yalnızca ESM olduğundan, yapılandırma dosyası olarak `next.config.mjs` dosyasını kullanmanız gerekir. 123 | 124 | ```js 125 | //next.config.mjs 126 | 127 | import remarkGfm from "remark-gfm"; 128 | import createMDX from "@next/mdx"; 129 | 130 | /** @type {import('next').NextConfig} */ 131 | const nextConfig = {}; 132 | 133 | const withMDX = createMDX({ 134 | options: { 135 | extension: /\.mdx?$/, 136 | remarkPlugins: [remarkGfm], 137 | rehypePlugins: [], 138 | // Eğer `MDXProvider` kullanıyorsanız, aşağıdaki satırı kaldırın. 139 | // providerImportSource: "@mdx-js/react", 140 | }, 141 | }); 142 | export default withMDX(nextConfig); 143 | ``` 144 | 145 | ## Frontmatter 146 | 147 | Frontmatter, bir sayfa hakkındaki verileri depolamak için kullanılabilen YAML benzeri bir anahtar/değer eşleştirmesidir. Öntanımlı olarak `@next/mdx` frontmatter'ı desteklemez, ancak MDX içeriğinize frontmatter eklemek için [gray-matter](https://github.com/jonschlinkert/gray-matter) gibi birçok çözüm vardır. 148 | 149 | Sayfa meta verilerine `@next/mdx` ile erişmek için `.mdx` dosyası içinden bir meta nesnesini dışa aktarabilirsiniz: 150 | 151 | ```mdx 152 | export const meta = { 153 | author: 'Rich Haines', 154 | } 155 | 156 | # My MDX pag 157 | 158 | e 159 | ``` 160 | 161 | ## Özel Unsurlar 162 | 163 | Markdown kullanmanın hoş yönlerinden biri, yerel `HTML` öğeleriyle eşleşerek yazmayı hızlı ve sezgisel hale getirmesidir: 164 | 165 | ```md 166 | Bu markdown'da bir listedir: 167 | 168 | - Bir 169 | - İki 170 | - Üç 171 | ``` 172 | 173 | Yukarıdaki işlem aşağıdaki `HTML`'yi oluşturur: 174 | 175 | ```html 176 | <p>Bu markdown'da bir listedir:</p> 177 | 178 | <ul> 179 | <li>Bir</li> 180 | <li>İki</li> 181 | <li>Üç</li> 182 | </ul> 183 | ``` 184 | 185 | Web sitenize veya uygulamanıza özel bir his vermek için kendi öğelerinizi şekillendirmek istediğinizde, kısa kodları aktarabilirsiniz. Bunlar, `HTML` öğelerine eşlenen kendi özel bileşenlerinizdir. Bunu yapmak için `MDXProvider`'ı kullanır ve bir components nesnesini prop olarak geçirirsiniz. Components nesnesindeki her nesne anahtarı bir `HTML` öğesi adıyla eşleşir. 186 | 187 | Etkinleştirmek için `next.config.js` içinde `providerImportSource: "@mdx-js/react"` belirtmeniz gerekir: 188 | 189 | ```js 190 | //next.config.js 191 | 192 | const withMDX = require("@next/mdx")({ 193 | // ... 194 | options: { 195 | providerImportSource: "@mdx-js/react", 196 | }, 197 | }); 198 | ``` 199 | 200 | Ardından sağlayıcıyı sayfanızda ayarlayın 201 | 202 | ```js 203 | //pages/index.js 204 | 205 | import { MDXProvider } from "@mdx-js/react"; 206 | import Image from "next/image"; 207 | import { Heading, InlineCode, Pre, Table, Text } from "my-components"; 208 | 209 | const ResponsiveImage = (props) => ( 210 | <Görüntü 211 | alt={props.alt} 212 | sizes="100vw" 213 | style={{ width: "100%", height: "auto" }} 214 | {...props} 215 | /> 216 | ); 217 | 218 | const bileşenler = { 219 | img: ResponsiveImage, 220 | h1: Heading.H1, 221 | h2: Heading.H2, 222 | p: Metin, 223 | Öncesi: Öncesi, 224 | kod: InlineCode, 225 | }; 226 | 227 | export default function Post(props) { 228 | dönüş( 229 | <MDXProvider components={components}> 230 | <main {...props} /> 231 | </MDXProvider> 232 | ); 233 | } 234 | ``` 235 | 236 | Site genelinde kullanıyorsanız, sağlayıcıyı `_app.js`'ye eklemek isteyebilirsiniz, böylece tüm MDX sayfaları özel öğe yapılandırmasını alır. 237 | 238 | ## Derin Anlatım: Markdown'ı HTML'e nasıl dönüştürürsünüz? 239 | 240 | React, Markdown'ı yerel olarak anlamaz. Markdown düz metninin önce HTML'ye dönüştürülmesi gerekir. Bu, `remark` ve `rehype` ile gerçekleştirilebilir. 241 | 242 | `remark`, markdown etrafında bir araç ekosistemidir. `rehype` da aynıdır, ancak HTML içindir. Örneğin, aşağıdaki kod parçacığı markdown'u HTML'ye dönüştürür: 243 | 244 | ```js 245 | import { unified } from "unified"; 246 | import remarkParse from "remark-parse"; 247 | import remarkRehype from "remark-rehype"; 248 | import rehypeSanitize from "rehype-sanitize"; 249 | import rehypeStringify from "rehype-stringify"; 250 | 251 | main(); 252 | 253 | async function main() { 254 | const file = await unified() 255 | .use(remarkParse) // Markdown AST'ye dönüştürme 256 | .use(remarkRehype) // HTML AST'ye Dönüştürme 257 | .use(rehypeSanitize) // HTML girdisini sterilize edin 258 | .use(rehypeStringify) // AST'yi serileştirilmiş HTML'ye dönüştürme 259 | .process("Hello, Next.js!"); 260 | 261 | console.log(String(file)); // <p>Hello, Next.js!</p> 262 | } 263 | ``` 264 | 265 | `remark` ve `rehype` ekosistemi, [sözdizimi vurgulama](https://github.com/atomiks/rehype-pretty-code), [başlıkları bağlama](https://github.com/rehypejs/rehype-autolink-headings), [içindekiler tablosu oluşturma](https://github.com/remarkjs/remark-toc) ve daha fazlası için eklentiler içerir. 266 | 267 | Aşağıda gösterildiği gibi `@next/mdx` kullanırken, sizin için halledildiğinden doğrudan `remark` ve `rehype` kullanmanıza gerek yoktur. 268 | 269 | ## Rust tabanlı MDX derleyicisini kullanma (Deneysel) 270 | 271 | Next.js, Rust dilinde yazılmış yeni bir MDX derleyicisini desteklemektedir. Bu derleyici hala deneyseldir ve üretim kullanımı için önerilmez. Yeni derleyiciyi kullanmak için `next.config.js` dosyasını `withMDX`'e aktarırken yapılandırmanız gerekir: 272 | 273 | ```js 274 | // next.config.js 275 | module.exports = withMDX({ 276 | experimental: { 277 | mdxRs: true, 278 | }, 279 | }); 280 | ``` 281 | 282 | ## Yararlı Bağlantılar 283 | 284 | - [MDX](https://mdxjs.com/) 285 | - [`@next/mdx`](https://www.npmjs.com/package/@next/mdx) 286 | - [remark](https://github.com/remarkjs/remark) 287 | - [rehype](https://github.com/rehypejs/rehype) 288 | 289 | -------------------------------------------------------------------------------- /7-configuring/6-src-directory/Readme.md: -------------------------------------------------------------------------------- 1 | # src Dizini 2 | 3 | Projenizin kök dizininde özel Next.js `app` veya `pages` dizinlerine sahip olmaya alternatif olarak Next.js, uygulama kodunu `src` dizininin altına yerleştirmenin yaygın modelini de destekler. 4 | 5 | Bu, uygulama kodunu, bazı bireyler ve ekipler tarafından tercih edilen, çoğunlukla bir projenin kök dizininde bulunan proje yapılandırma dosyalarından ayırır. 6 | 7 | `src` dizinini kullanmak için, `app` Router klasörünü veya `pages` Router klasörünü sırasıyla `src/app` veya `src/pages` dizinine taşıyın. 8 | 9 | <img alt="src-dizini" src="https://nextjs.org/_next/image?url=%2Fdocs%2Fdark%2Fproject-organization-src-directory.png&w=1920&q=75&dpl=dpl_FgqPZgpvfTdBpYwq43qhnaRUcyXh"/> 10 | <br> 11 | 12 | **Bilmekte Fayda Var:** 13 | 14 | - `/public` dizini projenizin kök dizininde kalmalıdır. 15 | - `package.json`, `next.config.js` ve `tsconfig.json` gibi yapılandırma dosyaları projenizin kök dizininde kalmalıdır. 16 | - `.env.*` dosyaları projenizin kök dizininde kalmalıdır. 17 | - Kök dizinde `app` veya `pages` varsa `src/app` veya `src/pages` göz ardı edilecektir. 18 | - Eğer `src` kullanıyorsanız, muhtemelen `/components` veya `/lib` gibi diğer uygulama klasörlerini de taşıyacaksınız. 19 | - Tailwind CSS kullanıyorsanız, [içerik bölümündeki](https://tailwindcss.com/docs/content-configuration) `tailwind.config.js` dosyasına `/src` önekini eklemeniz gerekir. 20 | -------------------------------------------------------------------------------- /7-configuring/7-draft-mode/Readme.md: -------------------------------------------------------------------------------- 1 | # Taslak Modu (Draft Mode) 2 | 3 | Statik oluşturma, sayfalarınız headless bir CMS'den veri aldığında kullanışlıdır. Ancak, headless CMS'nizde bir taslak yazarken ve taslağı hemen sayfanızda görüntülemek istediğinizde ideal değildir. Next.js'nin bu sayfaları derleme zamanı yerine istek zamanında oluşturmasını ve yayınlanan içerik yerine taslak içeriği getirmesini istersiniz. Next.js'in yalnızca bu özel durum için dinamik oluşturmaya geçmesini istersiniz. 4 | 5 | Next.js, bu sorunu çözen Taslak Modu adlı bir özelliğe sahiptir. İşte nasıl kullanılacağına dair talimatlar. 6 | 7 | ## Adım 1: Rota İşleyiciyi oluşturun ve erişin (Create and access the route handler) 8 | 9 | İlk olarak, bir Rota İşleyicisi oluşturun. Herhangi bir isme sahip olabilir - örneğin `app/api/draft/route.ts` 10 | 11 | Ardından, `next/headers` öğesinden `draftMode` öğesini içe aktarın ve `enable()` yöntemini çağırın. 12 | 13 | ```ts 14 | //app/api/draft/route.ts 15 | 16 | // taslak modunu etkinleştiren rota işleyicisi 17 | import { draftMode } from "next/headers"; 18 | 19 | export async function GET(request: Request) { 20 | draftMode().enable(); 21 | return new Response("Draft mode is enabled"); 22 | } 23 | ``` 24 | 25 | Bu, taslak modunu etkinleştirmek için bir çerez ayarlayacaktır. Bu çerezi içeren sonraki istekler, statik olarak oluşturulan sayfaların davranışını değiştirerek Taslak Modunu tetikleyecektir (bu konuda daha sonra daha fazla bilgi verilecektir). 26 | 27 | Bunu `/api/draft` adresini ziyaret ederek ve tarayıcınızın geliştirici araçlarına bakarak manuel olarak test edebilirsiniz. `Set-Cookie` yanıt başlığının `__prerender_bypass` adlı bir çerez içerdiğine dikkat edin. 28 | 29 | ### Headless CMS'nizden güvenli bir şekilde erişme 30 | 31 | Pratikte, bu Rota İşleyiciyi headless CMS'nizden güvenli bir şekilde çağırmak istersiniz. Belirli adımlar hangi headless CMS'yi kullandığınıza bağlı olarak değişecektir, ancak burada atabileceğiniz bazı genel adımlar vardır. 32 | 33 | Bu adımlar, kullandığınız headless CMS'nin özel taslak URL'leri ayarlamayı desteklediğini varsaymaktadır. Desteklemiyorsa, taslak URL'lerinizi güvence altına almak için bu yöntemi yine de kullanabilirsiniz, ancak taslak URL'yi manuel olarak oluşturmanız ve erişmeniz gerekir. 34 | 35 | **İlk olarak**, seçtiğiniz bir token oluşturucuyu kullanarak gizli bir token dizesi oluşturmalısınız. Bu sır yalnızca Next.js uygulamanız ve headless CMS'niz tarafından bilinecektir. Bu sır, CMS'nize erişimi olmayan kişilerin taslak URL'lere erişmesini engeller. 36 | 37 | **İkinci olarak**, headless CMS'niz özel taslak URL'lerin ayarlanmasını destekliyorsa, taslak URL olarak aşağıdakileri belirtin. Bu, Rota İşleyicinizin `app/api/draft/route.ts` adresinde bulunduğunu varsayar 38 | 39 | ```Terminal 40 | 41 | https://<siteniz>/api/draft?secret=<token>&slug=<path> 42 | ``` 43 | 44 | - `<siteniz>` dağıtım alanınız olmalıdır. 45 | - `<token>`, oluşturduğunuz gizli belirteç ile değiştirilmelidir. 46 | - `<path>` görüntülemek istediğiniz sayfanın yolu olmalıdır. Eğer `/posts/foo` sayfasını görüntülemek istiyorsanız, `&slug=/posts/foo` kullanmalısınız. 47 | 48 | Headless CMS'niz taslak URL'ye bir değişken eklemenize izin verebilir, böylece `<path>` CMS'nin verilerine göre dinamik olarak şu şekilde ayarlanabilir: `&slug=/posts/{entry.fields.slug}` 49 | 50 | `Son olarak,` Rota İşleyicide: 51 | 52 | - Gizli bilginin eşleşip eşleşmediğini ve `slug` parametresinin var olup olmadığını kontrol edin (yoksa istek başarısız olmalıdır). 53 | - Çerezi ayarlamak için `draftMode.enable()` işlevini çağırın. 54 | - Ardından tarayıcıyı `slug` tarafından belirtilen yola yönlendirin. 55 | 56 | ```ts 57 | //app/api/draft/route.ts 58 | 59 | // secret ve slug ile rota işleyicisi 60 | import { draftMode } from 'next/headers' 61 | import { redirect } from 'next/navigation' 62 | 63 | export async function GET(request: İstek) { 64 | // Sorgu dizesi parametrelerini ayrıştır 65 | const { searchParams } = yeni URL(request.url) 66 | const secret = searchParams.get('secret') 67 | const slug = searchParams.get('slug') 68 | 69 | // Gizli ve sonraki parametreleri kontrol edin 70 | // Bu sır yalnızca bu rota işleyicisi ve CMS tarafından bilinmelidir 71 | if (secret !== 'MY_SECRET_TOKEN' || !slug) { 72 | return new Response('Invalid token', { status: 401 }) 73 | } 74 | 75 | // Sağlanan `slug`ın var olup olmadığını kontrol etmek için headless CMS'yi getirin 76 | // getPostBySlug, headless CMS'ye gerekli getirme mantığını uygulayacaktır 77 | const post = await getPostBySlug(slug) 78 | 79 | // Eğer slug mevcut değilse taslak modunun etkinleştirilmesini engelleyin 80 | if (!post) { 81 | return new Response('Invalid slug', { status: 401 }) 82 | } 83 | 84 | // Çerezi ayarlayarak Taslak Modunu etkinleştirin 85 | draftMode().enable() 86 | 87 | // Getirilen gönderideki yola yönlendir 88 | // Açık yönlendirme güvenlik açıklarına yol açabileceğinden searchParams.slug adresine yönlendirme yapmıyoruz 89 | redirect(post.slug) 90 | } 91 | ``` 92 | 93 | Başarılı olursa, tarayıcı taslak modu çerezi ile görüntülemek istediğiniz yola yönlendirilecektir. 94 | 95 | ## Adım 2: Sayfayı güncelleyin 96 | 97 | Bir sonraki adım, sayfanızı `draftMode().isEnabled` değerini kontrol edecek şekilde güncellemektir. 98 | 99 | Çerezin ayarlandığı bir sayfayı talep ederseniz, veriler istek zamanında (derleme zamanı yerine) getirilecektir. 100 | 101 | Ayrıca, `isEnabled` değeri `true` olacaktır. 102 | 103 | ```ts 104 | //app/page.tsx 105 | 106 | // veri getiren sayfa 107 | import { draftMode } from "next/headers"; 108 | 109 | async function getData() { 110 | const { isEnabled } = draftMode(); 111 | 112 | const url = isEnabled 113 | ? "https://draft.example.com" 114 | : "https://production.example.com"; 115 | 116 | const res = await fetch(url); 117 | 118 | return res.json(); 119 | } 120 | 121 | export default async function Page() { 122 | const { title, desc } = await getData(); 123 | 124 | return ( 125 | <main> 126 | <h1>{title}</h1> 127 | <p>{desc}</p> 128 | </main> 129 | ); 130 | } 131 | ``` 132 | 133 | İşte bu kadar! Taslak Rota İşleyicisine (`secret` ve `slug` ile) headless CMS'nizden veya manuel olarak erişirseniz, artık taslak içeriği görebilmeniz gerekir. Ve taslağınızı yayınlamadan güncellerseniz, taslağı görüntüleyebilmeniz gerekir. 134 | 135 | Bunu headless CMS'nizde taslak URL'si olarak ayarlayın veya manuel olarak erişin ve taslağı görebilmeniz gerekir. 136 | 137 | ```terminal 138 | https://<your-site>/api/draft?secret=<token>&slug=<path> 139 | ``` 140 | 141 | ## Daha Fazla Detay 142 | 143 | ### Taslak Modu çerezini temizleyin 144 | 145 | Varsayılan olarak, Taslak Modu oturumu tarayıcı kapatıldığında sona erer. 146 | 147 | Taslak Modu çerezini manuel olarak temizlemek için `draftMode().disable()` çağrısı yapan bir Rota İşleyicisi oluşturun: 148 | 149 | ```ts 150 | //app/api/disable-draft/route.ts; 151 | 152 | import { draftMode } from "next/headers"; 153 | 154 | export async function GET(request: İstek) { 155 | draftMode().disable(); 156 | return new Response("Taslak modu devre dışı"); 157 | } 158 | ``` 159 | 160 | Ardından, Rota İşleyiciyi çağırmak için `/api/disable-draft` adresine bir istek gönderin. Bu rotayı `next/link` kullanarak çağırıyorsanız, prefetch'te çerezin yanlışlıkla silinmesini önlemek için `prefetch={false}` değerini geçmelisiniz. 161 | 162 | ### `next build` için benzersiz 163 | 164 | `next build`'i her çalıştırdığınızda yeni bir bypass çerez değeri oluşturulacaktır. 165 | 166 | Bu, bypass çerezinin tahmin edilememesini sağlar. 167 | 168 | **Bilmekte fayda var:** Taslak Modunu HTTP üzerinden yerel olarak test etmek için tarayıcınızın üçüncü taraf çerezlerine ve yerel depolama erişimine izin vermesi gerekir. 169 | -------------------------------------------------------------------------------- /7-configuring/Readme.md: -------------------------------------------------------------------------------- 1 | # Yapılandırma (Configuring) 2 | 3 | Next.js, projenizi belirli gereksinimleri karşılayacak şekilde özelleştirmenize olanak tanır. Bu, TypeScript, ESlint ve daha fazlası ile entegrasyonların yanı sıra Mutlak İçe Aktarmalar ve Ortam Değişkenleri gibi dahili yapılandırma seçeneklerini de içerir. 4 | -------------------------------------------------------------------------------- /8-deploying/1-static-exports/Readme.md: -------------------------------------------------------------------------------- 1 | # Statik Dışa Aktarmalar (Static Exports) 2 | 3 | Next.js, statik bir site veya Tek Sayfalı Uygulama (SPA) olarak başlamayı ve daha sonra isteğe bağlı olarak sunucu gerektiren özellikleri kullanmak için yükseltmeyi sağlar. 4 | 5 | Next.js, `next build` çalıştırırken her rota için bir HTML dosyası oluşturur. Next.js, katı bir SPA'yı ayrı HTML dosyalarına bölerek istemci tarafında gereksiz JavaScript kodlarının yüklenmesini önleyebilir, paket boyutunu küçültebilir ve sayfanın daha hızlı yüklenmesini sağlayabilir. 6 | 7 | Next.js bu statik dışa aktarımı desteklediğinden, HTML/CSS/JS statik varlıklarını sunabilen herhangi bir web sunucusunda dağıtılabilir ve barındırılabilir. 8 | 9 | ## Konfigürasyon 10 | 11 | Statik dışa aktarmayı etkinleştirmek için `next.config.js` içindeki çıktı modunu değiştirin: 12 | 13 | ```js 14 | // next.config.js 15 | /** 16 | * @type {import('next').NextConfig} 17 | */ 18 | const nextConfig = { 19 | output: "export", 20 | 21 | // İsteğe bağlı: Bağlantıları `/me` -> `/me/` olarak değiştirin ve `/me.html` -> `/me/index.html` olarak yayın 22 | // trailingSlash: true, 23 | 24 | // İsteğe bağlı: Otomatik `/me` -> `/me/` kullanımını önleyin, bunun yerine `href`i koruyun 25 | // skipTrailingSlashRedirect: true, 26 | 27 | // İsteğe bağlı: Çıktı dizinini `out` -> `dist` olarak değiştirin 28 | // distDir: 'dist', 29 | }; 30 | 31 | module.exports = nextConfig; 32 | ``` 33 | 34 | Next.js, `next build` çalıştırdıktan sonra uygulamanız için HTML/CSS/JS varlıklarını içeren bir `out` klasörü üretecektir. 35 | 36 | ## Desteklenen Özellikler 37 | 38 | Next.js'nin çekirdeği statik dışa aktarımları desteklemek üzere tasarlanmıştır. 39 | 40 | ### Sunucu Bileşenleri 41 | 42 | Statik dışa aktarma oluşturmak için `next build` çalıştırdığınızda, `app` dizini içinde tüketilen Sunucu Bileşenleri, geleneksel statik site oluşturmaya benzer şekilde derleme sırasında çalışacaktır. 43 | 44 | Ortaya çıkan bileşen, ilk sayfa yüklemesi için statik HTML'ye ve rotalar arasında istemci gezintisi için statik bir yüke dönüştürülecektir. Dinamik sunucu işlevlerini kullanmadıkları sürece, statik dışa aktarmayı kullanırken Sunucu Bileşenleriniz için hiçbir değişiklik gerekmez. 45 | 46 | ```tsx 47 | // app/page.tsx 48 | export default async function Page() { 49 | // This fetch will run on the server during `next build` 50 | const res = await fetch("https://api.example.com/..."); 51 | const data = await res.json(); 52 | 53 | return <main>...</main>; 54 | } 55 | ``` 56 | 57 | ## İstemci Bileşenleri 58 | 59 | İstemcide veri getirme işlemi gerçekleştirmek istiyorsanız, istekleri memoize etmek için [SWR](https://github.com/vercel/swr) ile bir İstemci Bileşeni kullanabilirsiniz. 60 | 61 | ```tsx 62 | // app/other/page.tsx 63 | "use client"; 64 | 65 | import useSWR from "swr"; 66 | 67 | const fetcher = (url: string) => fetch(url).then((r) => r.json()); 68 | 69 | export default function Page() { 70 | const { data, error } = useSWR( 71 | `https://jsonplaceholder.typicode.com/posts/1`, 72 | fetcher 73 | ); 74 | if (error) return "Failed to load"; 75 | if (!data) return "Loading..."; 76 | 77 | return data.title; 78 | } 79 | ``` 80 | 81 | Rota geçişleri istemci tarafında gerçekleştiğinden, bu geleneksel bir SPA gibi davranır. Örneğin, aşağıdaki dizin rotası istemcide farklı gönderilere gitmenizi sağlar: 82 | 83 | ```tsx 84 | // app/page.tsx 85 | import Link from "next/link"; 86 | 87 | export default function Page() { 88 | return ( 89 | <> 90 | <h1>Index Page</h1> 91 | <hr /> 92 | <ul> 93 | <li> 94 | <Link href="/post/1">Post 1</Link> 95 | </li> 96 | <li> 97 | <Link href="/post/2">Post 2</Link> 98 | </li> 99 | </ul> 100 | </> 101 | ); 102 | } 103 | ``` 104 | 105 | ### Görüntü Optimizasyonu 106 | 107 | `next/image` aracılığıyla Görüntü Optimizasyonu, `next.config.js`'de özel bir görüntü yükleyici tanımlayarak statik bir dışa aktarma ile kullanılabilir. Örneğin, Cloudinary gibi bir hizmetle görüntüleri optimize edebilirsiniz: 108 | 109 | ```js 110 | // next.config.js 111 | /** @type {import('next').NextConfig} */ 112 | const nextConfig = { 113 | output: "export", 114 | images: { 115 | loader: "custom", 116 | loaderFile: "./my-loader.ts", 117 | }, 118 | }; 119 | 120 | module.exports = nextConfig; 121 | ``` 122 | 123 | Bu özel yükleyici, görüntülerin uzak bir kaynaktan nasıl alınacağını tanımlayacaktır. Örneğin, aşağıdaki yükleyici Cloudinary için URL oluşturacaktır: 124 | 125 | ```ts 126 | // my-loader.ts 127 | export default function cloudinaryLoader({ 128 | src, 129 | width, 130 | quality, 131 | }: { 132 | src: string; 133 | width: number; 134 | quality?: number; 135 | }) { 136 | const params = ["f_auto", "c_limit", `w_${width}`, `q_${quality || "auto"}`]; 137 | return `https://res.cloudinary.com/demo/image/upload/${params.join( 138 | "," 139 | )}${src}`; 140 | } 141 | ``` 142 | 143 | Daha sonra uygulamanızda `next/image` öğesini kullanarak Cloudinary'deki görüntüye göreli yollar tanımlayabilirsiniz: 144 | 145 | ```tsx 146 | // app/page.tsx 147 | import Image from "next/image"; 148 | 149 | export default function Page() { 150 | return <Image alt="turtles" src="/turtles.jpg" width={300} height={300} />; 151 | } 152 | ``` 153 | 154 | ### Rota İşleyicileri 155 | 156 | Rota İşleyicileri `next build` çalıştırırken statik bir yanıt oluşturacaktır. Yalnızca `GET` HTTP fiili desteklenir. Bu, önbelleğe alınmış veya önbelleğe alınmamış verilerden statik HTML, JSON, TXT veya diğer dosyaları oluşturmak için kullanılabilir. Örneğin: 157 | 158 | ```js 159 | // app/data.json/route.ts 160 | import { NextResponse } from "next/server"; 161 | 162 | export async function GET() { 163 | return NextResponse.json({ name: "Lee" }); 164 | } 165 | ``` 166 | 167 | Yukarıdaki `app/data.json/route.ts` dosyası `next build` sırasında statik bir dosyaya dönüştürülecek ve `{ name: 'Lee' }` içeren `data.json` dosyası oluşturulacaktır. 168 | 169 | Gelen istekten dinamik değerleri okumanız gerekiyorsa, statik bir dışa aktarma kullanamazsınız. 170 | 171 | ### Tarayıcı API'leri 172 | 173 | İstemci Bileşenleri `next build` sırasında HTML'ye önceden oluşturulur. `window`, `localStorage` ve `navigator` gibi [Web API](https://developer.mozilla.org/en-US/docs/Web/API)'leri sunucuda bulunmadığından, bu API'lere yalnızca tarayıcıda çalışırken güvenli bir şekilde erişmeniz gerekir. Örneğin: 174 | 175 | ```tsx 176 | 'use client'; 177 | 178 | import { useEffect } from 'react'; 179 | 180 | export default function ClientComponent() { 181 | useEffect(() => { 182 | // You now have access to `window` 183 | console.log(window.innerHeight); 184 | }, []) 185 | 186 | return ...; 187 | } 188 | ``` 189 | 190 | ## Desteklenmeyen Özellikler 191 | 192 | Node.js sunucusu gerektiren özellikler veya derleme işlemi sırasında hesaplanamayan dinamik mantık desteklenmez: 193 | 194 | - dynamicParams ile `dynamicParams: true` 195 | - `generateStaticParams()` olmadan Dinamik Rotalar 196 | - İstek'e dayanan Rota İşleyicileri 197 | - Çerezler 198 | - Yeniden Yazma 199 | - Yönlendirmeler 200 | - Başlıklar 201 | - Orta Yazılım 202 | - Artımlı Statik Rejenerasyon 203 | - Varsayılan `loader` ile Görüntü Optimizasyonu 204 | - Taslak Modu 205 | 206 | Bu özelliklerden herhangi birinin `next dev` ile kullanılmaya çalışılması, kök düzende `dynamic` seçeneğinin `error` olarak ayarlanmasına benzer şekilde bir hatayla sonuçlanacaktır. 207 | 208 | ```js 209 | export const dynamic = "error"; 210 | ``` 211 | 212 | ## Dağıtım (Deploying) 213 | 214 | Statik bir dışa aktarma ile Next.js, HTML/CSS/JS statik varlıkları sunabilen herhangi bir web sunucusunda dağıtılabilir ve barındırılabilir. 215 | 216 | Next.js, `next build` çalıştırırken statik dışa aktarımı `out` klasörüne oluşturur. Artık `next export` kullanmaya gerek yoktur. Örneğin, aşağıdaki rotalara sahip olduğunuzu varsayalım: 217 | 218 | - `/` 219 | - `/blog/[id]` 220 | 221 | Next.js, `next build` çalıştırdıktan sonra aşağıdaki dosyaları oluşturacaktır: 222 | 223 | - `/out/index.html` 224 | - `/out/404.html` 225 | - `/out/blog/post-1.html` 226 | - `/out/blog/post-2.html` 227 | 228 | Nginx gibi statik bir ana bilgisayar kullanıyorsanız, gelen isteklerden doğru dosyalara yeniden yazmaları yapılandırabilirsiniz: 229 | 230 | ```nginx 231 | # nginx.conf 232 | server { 233 | listen 80; 234 | server_name acme.com; 235 | 236 | root /var/www/out; 237 | 238 | location / { 239 | try_files $uri $uri.html $uri/ =404; 240 | } 241 | 242 | # This is necessary when `trailingSlash: false`. 243 | # You can omit this when `trailingSlash: true`. 244 | location /blog/ { 245 | rewrite ^/blog/(.*)$ /blog/$1.html break; 246 | } 247 | 248 | error_page 404 /404.html; 249 | location = /404.html { 250 | internal; 251 | } 252 | } 253 | ``` 254 | -------------------------------------------------------------------------------- /8-deploying/Readme.md: -------------------------------------------------------------------------------- 1 | # Dağıtım (Deploying) 2 | 3 | Tebrikler! Next.js uygulamanızı dağıtmaya hazır olduğunuz için buradasınız. Bu sayfa, Next.js Build API'sini kullanarak yönetilen veya kendi kendine barındırılan dağıtımın nasıl yapılacağını gösterecektir. 4 | 5 | ## Next.js Yapı API'si 6 | 7 | `next build`, uygulamanızın üretim için optimize edilmiş bir sürümünü oluşturur. Bu standart çıktı şunları içerir: 8 | 9 | - `getStaticProps` veya Otomatik Statik Optimizasyon kullanan sayfalar için HTML dosyaları 10 | - Genel stiller veya ayrı ayrı kapsamlandırılmış stiller için CSS dosyaları 11 | - Next.js sunucusundan dinamik içeriği önceden render etmek için JavaScript 12 | - React aracılığıyla istemci tarafında etkileşim için JavaScript 13 | 14 | Bu çıktı `.next` klasörünün içinde oluşturulur: 15 | 16 | - `.next/static/chunks/pages` - Bu klasördeki her JavaScript dosyası aynı isimli rota ile ilgilidir. Örneğin, `.next/static/chunks/pages/about.js`, uygulamanızda `/about` rotası görüntülendiğinde yüklenen JavaScript dosyası olacaktır 17 | - `.next/static/media` - `next/image` adresinden statik olarak içe aktarılan görüntüler hashlenir ve buraya kopyalanır 18 | - `.next/static/css` - Uygulamanızdaki tüm sayfalar için global CSS dosyaları 19 | - `.next/server/pages` - Sunucudan önceden işlenen HTML ve JavaScript giriş noktaları. `.nft.json` dosyaları, Çıktı Dosyası İzleme etkinleştirildiğinde oluşturulur ve belirli bir sayfaya bağlı olan tüm dosya yollarını içerir. 20 | - `.next/server/chunks` - Uygulamanızda birden fazla yerde kullanılan paylaşılan JavaScript parçaları 21 | - `.next/cache` - Next.js sunucusundan derleme önbelleği ve önbelleğe alınmış görüntüler, yanıtlar ve sayfalar için çıktı. Önbellek kullanmak, derleme sürelerini azaltmaya ve görüntü yükleme performansını artırmaya yardımcı olur 22 | 23 | `.next` içindeki tüm JavaScript kodu derlenmiş ve tarayıcı paketleri en iyi performansı elde etmeye ve tüm modern tarayıcıları desteklemeye yardımcı olmak için küçültülmüştür. 24 | 25 | ## Vercel ile Yönetilen Next.js 26 | 27 | [Vercel](https://vercel.com/?utm_source=next-site&utm_medium=docs&utm_campaign=next-website), Next.js uygulamanızı sıfır yapılandırma ile dağıtmanın en hızlı yoludur. 28 | 29 | Vercel'e dağıtım yaparken, platform [Next.js'yi otomatik olarak algılar](https://vercel.com/solutions/nextjs?utm_source=next-site&utm_medium=docs&utm_campaign=next-website), `next build` çalıştırır ve derleme çıktısını sizin için optimize eder: 30 | 31 | - Değişmemişse önbelleğe alınan varlıkların dağıtımlar arasında sürdürülmesi 32 | - Her işlem için benzersiz bir URL ile [değişmez dağıtımlar](https://vercel.com/features/previews?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) 33 | - [Sayfalar](https://nextjs.org/docs/pages/building-your-application/rendering/automatic-static-optimization) mümkünse otomatik olarak statik olarak optimize edilir 34 | - Varlıklar (JavaScript, CSS, görüntüler, yazı tipleri) sıkıştırılır ve bir [Global Edge Ağından](https://vercel.com/features/infrastructure?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) sunulur 35 | - API Rotaları otomatik olarak sonsuz ölçeklendirilebilen yalıtılmış [Sunucusuz İşlevler](https://vercel.com/features/infrastructure?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) olarak optimize edilir 36 | - Middleware, sıfır soğuk başlatma ve anında önyükleme yapan Edge İşlevleri olarak otomatik olarak optimize edilir 37 | 38 | Buna ek olarak, Vercel aşağıdaki gibi özellikler sağlar: 39 | 40 | - [Next.js Speed Insights](https://vercel.com/analytics?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) ile otomatik performans izleme 41 | - Otomatik HTTPS ve SSL sertifikaları 42 | - Otomatik CI/CD (GitHub, GitLab, Bitbucket vb. aracılığıyla) 43 | - [Ortam Değişkenleri](https://vercel.com/docs/environment-variables?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) için Destek 44 | - [Özel Domainler](https://vercel.com/docs/custom-domains?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) için Destek 45 | - `next/image` ile Görüntü Optimizasyonu Desteği 46 | - `git push` aracılığıyla anında küresel dağıtımlar 47 | 48 | Denemek için bir Next.js uygulamasını [Vercel'e ücretsiz olarak dağıtın](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/hello-world&project-name=hello-world&repository-name=hello-world&utm_source=next-site&utm_medium=docs&utm_campaign=next-website). -------------------------------------------------------------------------------- /9-upgrading/1-codemods/Readme.md: -------------------------------------------------------------------------------- 1 | #Codemods 2 | 3 | Codemod'lar kod tabanınızda programlı olarak çalışan dönüşümlerdir. Bu, her dosyayı manuel olarak gözden geçirmek zorunda kalmadan çok sayıda değişikliğin programlı olarak uygulanmasına olanak tanır. 4 | 5 | Next.js, bir API güncellendiğinde veya kullanımdan kaldırıldığında Next.js kod tabanınızı yükseltmenize yardımcı olmak için Codemod dönüşümleri sağlar. 6 | 7 | ## Kullanım 8 | 9 | Terminalinizde, projenizin klasörüne gidin (`cd`) ve ardından çalıştırın: 10 | 11 | ```bash 12 | npx @next/codemod <transform> <path> 13 | ``` 14 | 15 | `<transform>` ve `<path>` öğelerinin uygun değerlerle değiştirilmesi. 16 | 17 | - `transform` - dönüşümün adı 18 | - `path` - dönüştürülecek dosyalar veya dizin 19 | - `--dry` Kuru çalıştırma yapın, hiçbir kod düzenlenmeyecektir 20 | - `--print` Karşılaştırma için değiştirilen çıktıyı yazdırır 21 | 22 | ## Next.js Codemods 23 | 24 | ## 13.2 25 | 26 | ### Yerleşik Yazı Tipini Kullanın 27 | 28 | #### `built-in-next-font` 29 | 30 | ```bash 31 | npx @next/codemod@latest built-in-next-font . 32 | ``` 33 | 34 | Bu codemod `@next/font` paketini kaldırır ve `@next/font` içe aktarımlarını yerleşik `next/font`'a dönüştürür. 35 | 36 | Örneğin: 37 | 38 | ```bash 39 | import { Inter } from '@next/font/google' 40 | ``` 41 | 42 | Aşağıdakine dönüşür: 43 | 44 | ```bash 45 | import { Inter } from 'next/font/google' 46 | ``` 47 | 48 | ## 13.0 49 | 50 | ### Next Görüntü Aktarımlarını Yeniden Adlandır 51 | 52 | #### `next-image-to-legacy-image` 53 | 54 | ```bash 55 | npx @next/codemod@latest next-image-to-legacy-image . 56 | ``` 57 | 58 | Mevcut Next.js 10, 11 veya 12 uygulamalarındaki `next/image` içe aktarımlarını Next.js 13'te `next/legacy/image` olarak güvenli bir şekilde yeniden adlandırır. Ayrıca `next/future/image` öğesini `next/image` olarak yeniden adlandırır. 59 | 60 | Örneğin: 61 | 62 | ```js 63 | /// pages/index.js 64 | 65 | import Image1 from "next/image"; 66 | import Image2 from "next/future/image"; 67 | 68 | export default function Home() { 69 | return ( 70 | <div> 71 | <Image1 src="/test.jpg" width="200" height="300" /> 72 | <Image2 src="/test.png" width="500" height="400" /> 73 | </div> 74 | ); 75 | } 76 | ``` 77 | 78 | Aşağıdakine dönüşür: 79 | 80 | ```js 81 | /// pages/index.js 82 | 83 | // 'next/image', 'next/legacy/image' olur 84 | import Image1 from "next/legacy/image"; 85 | // 'next/future/image', 'next/image' olur 86 | import Image2 from "next/image"; 87 | 88 | export default function Home() { 89 | return ( 90 | <div> 91 | <Image1 src="/test.jpg" width="200" height="300" /> 92 | <Image2 src="/test.png" width="500" height="400" /> 93 | </div> 94 | ); 95 | } 96 | ``` 97 | 98 | ### Yeni Görüntü Bileşenine Geçiş Yapın 99 | 100 | #### `next-image-experimental` 101 | 102 | ```bash 103 | npx @next/codemod@latest next-image-experimental . 104 | ``` 105 | 106 | Dangerously, satır içi stiller ekleyerek ve kullanılmayan sahne öğelerini kaldırarak `next/legacy/image` öğesinden yeni `next/image` öğesine geçiş yapar. 107 | 108 | - `layout` prop'unu kaldırır ve `style` ekler. 109 | - `objectFit` prop'unu kaldırır ve `style` ekler. 110 | - `objectPosition` prop'unu kaldırır ve `style` ekler. 111 | - `lazyBoundary` prop'unu kaldırır. 112 | - `lazyRoot` prop'unu kaldırır. 113 | 114 | ### Link Bileşenlerinden `<a>` Etiketlerini Kaldırma 115 | 116 | #### `new-link` 117 | 118 | ```bash 119 | npx @next/codemod@latest new-link . 120 | ``` 121 | 122 | Link Bileşenleri içindeki `<a>` etiketlerini kaldırın veya otomatik olarak düzeltilemeyen Bağlantılara bir `legacyBehavior` prop ekleyin. 123 | 124 | Örneğin: 125 | 126 | ```js 127 | <Link href="/about"> 128 | <a>About</a> 129 | </Link> 130 | // buna dönüşür 131 | <Link href="/about"> 132 | About 133 | </Link> 134 | 135 | <Link href="/about"> 136 | <a onClick={() => console.log('clicked')}>About</a> 137 | </Link> 138 | // buna dönüşür 139 | <Link href="/about" onClick={() => console.log('clicked')}> 140 | About 141 | </Link> 142 | ``` 143 | 144 | Otomatik düzeltmenin uygulanamadığı durumlarda, `legacyBehavior` özelliği eklenir. Bu, uygulamanızın söz konusu bağlantı için eski davranışı kullanarak çalışmaya devam etmesini sağlar. 145 | 146 | ```js 147 | const Component = () => <a>About</a> 148 | 149 | <Link href="/about"> 150 | <Component /> 151 | </Link> 152 | // aşağıdakine dönüşür 153 | <Link href="/about" legacyBehavior> 154 | <Component /> 155 | </Link> 156 | ``` 157 | 158 | ## 11 159 | 160 | ### CRA'dan geçiş yapın 161 | 162 | #### `cra-to-next` 163 | 164 | ```bash 165 | npx @next/codemod cra-to-next 166 | ``` 167 | 168 | Bir Create React App projesini Next.js'ye geçirir; bir Pages Router ve davranışla eşleşmesi için gerekli yapılandırmayı oluşturur. SSR sırasında `window` kullanımı nedeniyle uyumluluğun bozulmasını önlemek için başlangıçta yalnızca istemci tarafı oluşturmadan yararlanılır ve Next.js'ye özgü özelliklerin kademeli olarak benimsenmesine izin vermek için sorunsuz bir şekilde etkinleştirilebilir. 169 | 170 | Lütfen bu dönüşümle ilgili geri bildirimlerinizi [bu tartışmada](https://github.com/vercel/next.js/discussions/25858) paylaşın. 171 | 172 | ## 10 173 | 174 | ### Add React imports 175 | 176 | #### `add-missing-react-import` 177 | 178 | ```bash 179 | npx @next/codemod add-missing-react-import 180 | ``` 181 | 182 | `React`'i içe aktarmayan dosyaları, yeni [React JSX dönüşümünün](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) çalışması için içe aktarmayı içerecek şekilde dönüştürür. 183 | 184 | Örneğin: 185 | 186 | ```js 187 | export default class Home extends React.Component { 188 | render() { 189 | return <div>Hello World</div>; 190 | } 191 | } 192 | ``` 193 | 194 | Aşağıdakine dönüşür: 195 | 196 | ```js 197 | import React from "react"; 198 | export default class Home extends React.Component { 199 | render() { 200 | return <div>Hello World</div>; 201 | } 202 | } 203 | ``` 204 | 205 | ## 9 206 | 207 | ### Anonim Bileşenleri Adlandırılmış Bileşenlere Dönüştürme 208 | 209 | #### `name-default-component` 210 | 211 | ```bash 212 | npx @next/codemod name-default-component 213 | ``` 214 | 215 | ### 9 ve üzeri sürümler. 216 | 217 | [Fast Refresh](https://nextjs.org/blog/next-9-4#fast-refresh) ile çalıştıklarından emin olmak için anonim bileşenleri adlandırılmış bileşenlere dönüştürür. 218 | 219 | Örneğin: 220 | 221 | ```js 222 | export default function () { 223 | return <div>Hello World</div>; 224 | } 225 | ``` 226 | 227 | Aşağıdakine dönüşür: 228 | 229 | ```js 230 | export default function MyComponent() { 231 | return <div>Hello World</div>; 232 | } 233 | ``` 234 | 235 | Bileşen, dosyanın adına göre camel-cased bir ada sahip olur ve arrow fonksiyonlarıyla da çalışır. 236 | 237 | ## 8 238 | 239 | ### AMP HOC'yi sayfa yapılandırmasına dönüştürme 240 | 241 | #### `withamp-to-config` 242 | 243 | ```bash 244 | npx @next/codemod withamp-to-config 245 | ``` 246 | 247 | `withAmp` HOC'yi Next.js 9 sayfa yapılandırmasına dönüştürür. 248 | 249 | Örneğin: 250 | 251 | ```js 252 | // Öncesi 253 | import { withAmp } from "next/amp"; 254 | 255 | function Home() { 256 | return <h1>My AMP Page</h1>; 257 | } 258 | 259 | export default withAmp(Home); 260 | ``` 261 | 262 | ```js 263 | // Sonrası 264 | export default function Home() { 265 | return <h1>My AMP Page</h1>; 266 | } 267 | 268 | export const config = { 269 | amp: true, 270 | }; 271 | ``` 272 | 273 | ## 6 274 | 275 | ### `withrouter` kullanın 276 | 277 | #### `url-to-withrouter` 278 | 279 | ```bash 280 | npx @next/codemod url-to-withrouter 281 | ``` 282 | 283 | Üst düzey sayfalarda kullanımdan kaldırılan otomatik olarak enjekte edilen `url` özelliğini `withRouter` ve enjekte ettiği `router` özelliğini kullanmaya dönüştürür. Daha fazlasını buradan okuyun: https://nextjs.org/docs/messages/url-deprecated 284 | 285 | Örneğin: 286 | 287 | ```js 288 | // Öncesi 289 | 290 | import React from "react"; 291 | export default class extends React.Component { 292 | render() { 293 | const { pathname } = this.props.url; 294 | return <div>Current pathname: {pathname}</div>; 295 | } 296 | } 297 | ``` 298 | 299 | ```js 300 | // Sonrası 301 | 302 | import React from "react"; 303 | import { withRouter } from "next/router"; 304 | export default withRouter( 305 | class extends React.Component { 306 | render() { 307 | const { pathname } = this.props.router; 308 | return <div>Current pathname: {pathname}</div>; 309 | } 310 | } 311 | ); 312 | ``` 313 | 314 | Bu bir vakadır. Dönüştürülen (ve test edilen) tüm vakalar [**testfixtures** dizininde](https://github.com/vercel/next.js/tree/canary/packages/next-codemod/transforms/__testfixtures__/url-to-withrouter) bulunabilir. 315 | -------------------------------------------------------------------------------- /9-upgrading/Readme.md: -------------------------------------------------------------------------------- 1 | # Yükseltme Kılavuzu (Upgrading Guide) 2 | 3 | Uygulamanızı Next.js'nin daha yeni sürümlerine yükseltin veya Pages Router'dan App Router'a geçiş yapın. 4 | 5 | - Codemods 6 | - App Router Migration 7 | - Migrating from Vite 8 | -------------------------------------------------------------------------------- /CONTRIBUTIONS.md: -------------------------------------------------------------------------------- 1 | # Katkıda Bulunma Rehberi 2 | 3 | Bu repoya katkıda bulunmak isteyen herkes için bazı yönergeler ve öneriler. Bu rehber, katkıda bulunma sürecini kolaylaştırmak ve daha verimli hale getirmek için hazırlanmıştır. Katkıda bulunmadan önce bu rehberi dikkatlice okumanızı tavsiye ederim. 4 | 5 | ## Katkıda Bulunmadan Önce 6 | 7 | 1. Projeyi forklayın ve kendi bilgisayarınıza klonlayın. 8 | 2. Yeni bir dal (branch) oluşturarak değişikliklerinizi bu dal üzerinde yapın. 9 | 10 | ## Katkıda Bulunma Süreci 11 | 12 | 1. Değişiklik yapmadan önce, halihazırda açılmış olan issue'ları inceleyin. 13 | 2. Eğer yeni bir issue açmayı düşünüyorsanız, benzer bir issue olup olmadığını kontrol edin. 14 | 3. Değişikliklerinizi yapın ve commit mesajlarınızı açıklayıcı bir şekilde yazın. 15 | 4. Değişikliklerinizi yaptığınız dalı (branch) kendi repoma gönderin. 16 | 5. Pull request oluşturun ve değişikliklerinizi açıklayın. 17 | 6. Pull request'iniz onaylandıktan sonra, değişiklikleriniz repoya eklenecektir. 18 | 7. Değişikliklerinizin repoya eklenmesiyle birlikte, pull request'inizi kapatabilirsiniz. 19 | 20 | ## Çeviri Katkıları 21 | 22 | 1. Çeviri yaparken, Türkçe dilbilgisi ve imla kurallarına dikkat edin. 23 | 2. Teknik terimlerin doğru çevirisi için özen gösterin. 24 | 3. Anlam kayması olmaması için orijinal metni dikkatli bir şekilde inceleyin. 25 | 26 | ## İletişim ve Sorular 27 | 28 | 1. Herhangi bir sorunuz olursa, GitHub üzerinden issue açarak ya da doğrudan bana ulaşarak sorabilirsiniz. 29 | 2. Katkılarınız için teşekkür eder, projenin daha iyi bir hale gelmesi için sizin fikirlerinizi de sabırsızlıkla beklerim. 30 | --------------------------------------------------------------------------------