Türkçe

Dosya tabanlı yönlendirmeye yönelik bu derinlemesine rehberimizle Next.js App Router'ın gücünü keşfedin. Uygulamanızı nasıl yapılandıracağınızı, dinamik rotalar oluşturacağınızı, layout'ları nasıl yöneteceğinizi ve daha fazlasını öğrenin.

Next.js App Router: Dosya Tabanlı Yönlendirme İçin Kapsamlı Bir Rehber

Next.js 13 ile tanıtılan ve sonraki sürümlerde standart hale gelen Next.js App Router, uygulamaları nasıl yapılandırdığımızı ve yönlendirdiğimizi kökten değiştiriyor. Geliştirmeyi basitleştiren, performansı artıran ve genel geliştirici deneyimini iyileştiren güçlü ve sezgisel bir dosya tabanlı yönlendirme sistemi sunar. Bu kapsamlı rehber, App Router'ın dosya tabanlı yönlendirmesine derinlemesine dalarak, size sağlam ve ölçeklenebilir Next.js uygulamaları oluşturmak için gereken bilgi ve becerileri sağlayacaktır.

Dosya Tabanlı Yönlendirme Nedir?

Dosya tabanlı yönlendirme, uygulamanızın rotalarının yapısının doğrudan dosyalarınızın ve dizinlerinizin organizasyonu tarafından belirlendiği bir yönlendirme sistemidir. Next.js App Router'da, rotaları `app` dizini içinde dosyalar oluşturarak tanımlarsınız. Her klasör bir rota segmentini temsil eder ve bu klasörler içindeki özel dosyalar, o rota segmentinin nasıl ele alınacağını tanımlar. Bu yaklaşım birkaç avantaj sunar:

App Router'a Başlarken

App Router'ı kullanmak için yeni bir Next.js projesi oluşturmanız veya mevcut bir projeyi taşımanız gerekir. Next.js'in 13. veya daha yeni bir sürümünü kullandığınızdan emin olun.

Yeni Bir Proje Oluşturma:

Aşağıdaki komutu kullanarak App Router ile yeni bir Next.js projesi oluşturabilirsiniz:

npx create-next-app@latest my-app --example with-app

Mevcut Bir Projeyi Taşıma:

Mevcut bir projeyi taşımak için, sayfalarınızı `pages` dizininden `app` dizinine taşımanız gerekir. Yönlendirme mantığınızı buna göre ayarlamanız gerekebilir. Next.js, bu süreçte size yardımcı olmak için bir taşıma rehberi sunmaktadır.

Dosya Tabanlı Yönlendirmenin Temel Kavramları

App Router, rotalarınızın nasıl işlendiğini tanımlayan birkaç özel dosya ve kural sunar:

1. `app` Dizini

Uygulamanızın rotalarının kökü `app` dizinidir. Bu dizin içindeki tüm dosyalar ve klasörler rotaları oluşturmak için kullanılacaktır. `app` dizini dışındaki her şey (eğer taşıma yapıyorsanız `pages` dizini gibi) App Router tarafından göz ardı edilecektir.

2. `page.js` Dosyası

`page.js` (veya `page.jsx`, `page.ts`, `page.tsx`) dosyası, App Router'ın en temel parçasıdır. Belirli bir rota segmenti için render edilecek UI bileşenini tanımlar. Doğrudan erişilebilir olmasını istediğiniz herhangi bir rota segmenti için gerekli bir dosyadır.

Örnek:

Eğer şöyle bir dosya yapınız varsa:

app/
  about/
    page.js

Bir kullanıcı `/about` adresine gittiğinde `app/about/page.js` dosyasından dışa aktarılan bileşen render edilecektir.

// app/about/page.js
import React from 'react';

export default function AboutPage() {
  return (
    <div>
      <h1>Hakkımızda</h1>
      <p>Şirketimiz hakkında daha fazla bilgi edinin.</p>
    </div>
  );
}

3. `layout.js` Dosyası

`layout.js` (veya `layout.jsx`, `layout.ts`, `layout.tsx`) dosyası, bir rota segmenti içindeki birden çok sayfada paylaşılan bir UI tanımlar. Layout'lar, birden çok sayfada bulunması gereken tutarlı başlıklar, altbilgiler, kenar çubukları ve diğer öğeleri oluşturmak için kullanışlıdır.

Örnek:

Diyelim ki hem `/about` sayfasına hem de varsayımsal bir `/about/team` sayfasına bir başlık eklemek istiyorsunuz. `app/about` dizininde bir `layout.js` dosyası oluşturabilirsiniz:

// app/about/layout.js
import React from 'react';

export default function AboutLayout({ children }) {
  return (
    <div>
      <header>
        <h1>Şirketimiz Hakkında</h1>
      </header>
      <main>{children}</main>
    </div>
  );
}

`children` prop'u, aynı dizindeki veya herhangi bir iç içe geçmiş dizindeki `page.js` dosyası tarafından render edilen UI ile değiştirilecektir.

4. `template.js` Dosyası

`template.js` dosyası `layout.js`'ye benzer, ancak her alt rota için bileşenin yeni bir örneğini oluşturur. Bu, alt rotalar arasında gezinirken bileşen durumunu korumak veya yeniden render'ları önlemek istediğiniz senaryolar için kullanışlıdır. Layout'ların aksine, template'ler gezinme sırasında yeniden render olur. Template'leri kullanmak, gezinme sırasında elemanları canlandırmak için harikadır.

Örnek:

// app/template.js
'use client'

import { useState } from 'react'

export default function Template({ children }) {
  const [count, setCount] = useState(0)

  return (
    <main>
      <p>Template: {count}</p>
      <button onClick={() => setCount(count + 1)}>Template'i Güncelle</button>
      {children}
    </main>
  )
}

5. `loading.js` Dosyası

`loading.js` (veya `loading.jsx`, `loading.ts`, `loading.tsx`) dosyası, bir rota segmenti yüklenirken görüntülenen bir yükleme arayüzü (UI) oluşturmanıza olanak tanır. Bu, veri çekerken veya diğer eşzamansız işlemleri gerçekleştirirken daha iyi bir kullanıcı deneyimi sağlamak için kullanışlıdır.

Örnek:

// app/about/loading.js
import React from 'react';

export default function Loading() {
  return <p>Hakkında bilgileri yükleniyor...</p>;
}

Bir kullanıcı `/about` adresine gittiğinde, `page.js` bileşeni tamamen render edilene kadar `Loading` bileşeni görüntülenecektir.

6. `error.js` Dosyası

`error.js` (veya `error.jsx`, `error.ts`, `error.tsx`) dosyası, bir rota segmenti içinde bir hata oluştuğunda görüntülenen özel bir hata arayüzü oluşturmanıza olanak tanır. Bu, daha kullanıcı dostu bir hata mesajı sağlamak ve tüm uygulamanın çökmesini önlemek için kullanışlıdır.

Örnek:

// app/about/error.js
'use client'

import React from 'react';

export default function Error({ error, reset }) {
  return (
    <div>
      <h2>Bir hata oluştu!</h2>
      <p>{error.message}</p>
      <button onClick={() => reset()}>Tekrar dene</button>
    </div>
  );
}

Eğer `/about` sayfasını render ederken bir hata oluşursa, `Error` bileşeni görüntülenecektir. `error` prop'u hata hakkında bilgi içerir ve `reset` fonksiyonu kullanıcının sayfayı yeniden yüklemeyi denemesine olanak tanır.

7. Rota Grupları

Rota Grupları `(grupAdı)`, rotalarınızı URL yapısını etkilemeden düzenlemenize olanak tanır. Bir klasör adını parantez içine alarak oluşturulurlar. Bu, özellikle layout'ları ve paylaşılan bileşenleri düzenlemek için yardımcı olur.

Örnek:

app/
  (marketing)/
    about/
      page.js
    contact/
      page.js
  (shop)/
    products/
      page.js

Bu örnekte, `about` ve `contact` sayfaları `marketing` grubu altında, `products` sayfası ise `shop` grubu altında gruplandırılmıştır. URL'ler sırasıyla `/about`, `/contact` ve `/products` olarak kalır.

8. Dinamik Rotalar

Dinamik rotalar, değişken segmentlere sahip rotalar oluşturmanıza olanak tanır. Bu, bir veritabanından veya API'den çekilen verilere dayalı olarak içerik görüntülemek için kullanışlıdır. Dinamik rota segmentleri, segment adını köşeli parantez içine alarak tanımlanır (örneğin, `[id]`).

Örnek:

Diyelim ki bireysel blog gönderilerini kimliklerine göre görüntülemek için bir rota oluşturmak istiyorsunuz. Şöyle bir dosya yapısı oluşturabilirsiniz:

app/
  blog/
    [id]/
      page.js

`[id]` segmenti dinamik bir segmenttir. `app/blog/[id]/page.js` dosyasından dışa aktarılan bileşen, bir kullanıcı `/blog/123` veya `/blog/456` gibi bir URL'ye gittiğinde render edilecektir. `id` parametresinin değeri, bileşenin `params` prop'unda mevcut olacaktır.

// app/blog/[id]/page.js
import React from 'react';

export default async function BlogPost({ params }) {
  const { id } = params;

  // Verilen ID'ye sahip blog gönderisi için veri çek
  const post = await fetchBlogPost(id);

  if (!post) {
    return <p>Blog gönderisi bulunamadı.</p>;
  }

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
}

async function fetchBlogPost(id) {
  // Bir veritabanından veya API'den veri çekmeyi simüle et
  return new Promise((resolve) => {
    setTimeout(() => {
      const posts = {
        '123': { title: 'İlk Blog Yazım', content: 'Bu benim ilk blog yazımın içeriğidir.' },
        '456': { title: 'Başka Bir Blog Yazısı', content: 'Bu biraz daha heyecan verici bir içerik.' },
      };
      resolve(posts[id] || null);
    }, 500);
  });
}

Bir rotada birden fazla dinamik segment de kullanabilirsiniz. Örneğin, `/blog/[category]/[id]` gibi bir rotanız olabilir.

9. Kapsayıcı Segmentler (Catch-all)

Kapsayıcı segmentler, herhangi bir sayıda segmentle eşleşen rotalar oluşturmanıza olanak tanır. Bu, URL yapısının kullanıcı tarafından belirlendiği bir CMS oluşturmak gibi senaryolar için kullanışlıdır. Kapsayıcı segmentler, segment adının önüne üç nokta ekleyerek tanımlanır (örneğin, `[...slug]`).

Örnek:

app/
  docs/
    [...slug]/
      page.js

`[...slug]` segmenti, `/docs`'tan sonraki herhangi bir sayıda segmentle eşleşecektir. Örneğin, `/docs/getting-started`, `/docs/api/users` ve `/docs/advanced/configuration` ile eşleşecektir. `slug` parametresinin değeri, eşleşen segmentleri içeren bir dizi olacaktır.

// app/docs/[...slug]/page.js
import React from 'react';

export default function DocsPage({ params }) {
  const { slug } = params;

  return (
    <div>
      <h1>Dökümanlar</h1>
      <p>Slug: {slug ? slug.join('/') : 'Slug yok'}</p>
    </div>
  );
}

İsteğe bağlı kapsayıcı segmentler, segment adını çift köşeli parantez `[[...slug]]` içine alarak oluşturulabilir. Bu, rota segmentini isteğe bağlı hale getirir. Örnek:

app/
  blog/
    [[...slug]]/
      page.js

Bu kurulum, page.js bileşenini hem `/blog` adresinde hem de `/blog/herhangi/bir/sayida/segment` adresinde render edecektir.

10. Paralel Rotalar

Paralel Rotalar, aynı layout içinde aynı anda bir veya daha fazla sayfayı render etmenize olanak tanır. Bu, sayfanın farklı bölümlerinin bağımsız olarak yüklenebildiği kontrol panelleri gibi karmaşık layout'lar için özellikle kullanışlıdır. Paralel Rotalar, `@` simgesi ve ardından bir slot adı (örneğin, `@sidebar`, `@main`) kullanılarak tanımlanır.

Örnek:

app/
  @sidebar/
    page.js  // Kenar çubuğu için içerik
  @main/
    page.js  // Ana bölüm için içerik
  default.js // Gerekli: Paralel rotalar için varsayılan layout'u tanımlar

`default.js` dosyası, paralel rotalar kullanılırken gereklidir. Farklı slotların son layout'u oluşturmak için nasıl birleştirileceğini tanımlar.

// app/default.js
export default function RootLayout({ children: { sidebar, main } }) {
  return (
    <div style={{ display: 'flex' }}>
      <aside style={{ width: '200px', backgroundColor: '#f0f0f0' }}>
        {sidebar}
      </aside>
      <main style={{ flex: 1, padding: '20px' }}>
        {main}
      </main>
    </div>
  );
}

11. Yakalayıcı Rotalar (Intercepting Routes)

Yakalayıcı Rotalar, mevcut layout içinde uygulamanızın farklı bir bölümünden bir rotayı yüklemenize olanak tanır. Bu, modallar, resim galerileri ve mevcut sayfa içeriğinin üzerinde görünmesi gereken diğer UI elemanlarını oluşturmak için kullanışlıdır. Yakalayıcı Rotalar, yakalanan rotayı bulmak için dizin ağacında ne kadar yukarı gidileceğini belirten `(..)` sözdizimi kullanılarak tanımlanır.

Örnek:

app/
  (.)photos/
    [id]/
      page.js  // Yakalanan rota
  feed/
    page.js  // Fotoğraf modalının görüntülendiği sayfa

Bu örnekte, bir kullanıcı `/feed` sayfasındaki bir fotoğrafa tıkladığında, `app/(.)photos/[id]/page.js` rotası yakalanır ve `/feed` sayfasının üzerinde bir modal olarak görüntülenir. `(.)` sözdizimi, Next.js'e `photos/[id]` rotasını bulmak için bir seviye yukarıya (`app` dizinine) bakmasını söyler.

App Router ile Veri Çekme

App Router, Sunucu Bileşenleri ve İstemci Bileşenleri kullanarak veri çekme için dahili destek sağlar. Sunucu Bileşenleri sunucuda render edilirken, İstemci Bileşenleri istemcide render edilir. Bu, her bileşen için gereksinimlerine göre en iyi yaklaşımı seçmenize olanak tanır.

Sunucu Bileşenleri

Sunucu Bileşenleri, App Router'da varsayılandır. Ayrı API rotalarına ihtiyaç duymadan doğrudan bileşenlerinizde veri çekmenize olanak tanır. Bu, performansı artırabilir ve kodunuzu basitleştirebilir.

Örnek:

// app/products/page.js
import React from 'react';

export default async function ProductsPage() {
  const products = await fetchProducts();

  return (
    <div>
      <h1>Ürünler</h1>
      <ul>
        {products.map((product) => (
          <li key={product.id}>{product.name}</li>
        ))}
      </ul>
    </div>
  );
}

async function fetchProducts() {
  // Bir veritabanından veya API'den veri çekmeyi simüle et
  return new Promise((resolve) => {
    setTimeout(() => {
      const products = [
        { id: 1, name: 'Ürün A' },
        { id: 2, name: 'Ürün B' },
        { id: 3, name: 'Ürün C' },
      ];
      resolve(products);
    }, 500);
  });
}

Bu örnekte, `fetchProducts` fonksiyonu doğrudan `ProductsPage` bileşeni içinde çağrılır. Bileşen sunucuda render edilir ve HTML istemciye gönderilmeden önce veriler çekilir.

İstemci Bileşenleri

İstemci Bileşenleri istemcide render edilir ve olay dinleyicileri, durum (state) ve tarayıcı API'leri gibi istemci tarafı özelliklerini kullanmanıza olanak tanır. Bir İstemci Bileşeni kullanmak için, dosyanın en üstüne `'use client'` yönergesini eklemeniz gerekir.

Örnek:

// app/counter/page.js
'use client'

import React, { useState } from 'react';

export default function CounterPage() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>Sayaç</h1>
      <p>Sayı: {count}</p>
      <button onClick={() => setCount(count + 1)}>Arttır</button>
    </div>
  );
}

Bu örnekte, `CounterPage` bileşeni `useState` hook'unu kullandığı için bir İstemci Bileşenidir. `'use client'` yönergesi, Next.js'e bu bileşeni istemcide render etmesini söyler.

Gelişmiş Yönlendirme Teknikleri

App Router, karmaşık ve sofistike uygulamalar oluşturmak için kullanılabilecek birkaç gelişmiş yönlendirme tekniği sunar.

1. Rota İşleyicileri (Route Handlers)

Rota İşleyicileri, `app` dizininiz içinde API uç noktaları oluşturmanıza olanak tanır. Bu, ayrı bir `pages/api` dizini ihtiyacını ortadan kaldırır. Rota İşleyicileri, `route.js` (veya `route.ts`) adlı dosyalarda tanımlanır ve farklı HTTP metotlarını (örneğin, `GET`, `POST`, `PUT`, `DELETE`) işleyen fonksiyonları dışa aktarır.

Örnek:

// app/api/users/route.js
import { NextResponse } from 'next/server'

export async function GET(request) {
  // Veritabanından kullanıcıları çekmeyi simüle et
  const users = [
    { id: 1, name: 'John Doe' },
    { id: 2, name: 'Jane Doe' },
  ];

  return NextResponse.json(users);
}

export async function POST(request) {
  const body = await request.json()
  console.log('Alınan veri:', body)
  return NextResponse.json({ message: 'Kullanıcı oluşturuldu' }, { status: 201 })
}

Bu örnek, `/api/users` adresinde hem `GET` hem de `POST` isteklerini işleyen bir rota işleyicisi tanımlar. `GET` fonksiyonu bir kullanıcı listesi döndürür ve `POST` fonksiyonu yeni bir kullanıcı oluşturur.

2. Çoklu Layout'lu Rota Grupları

Uygulamanızın farklı bölümleri için farklı layout'lar oluşturmak amacıyla rota gruplarını layout'larla birleştirebilirsiniz. Bu, sitenizin farklı bölümleri için farklı bir başlık veya kenar çubuğu olmasını istediğiniz senaryolar için kullanışlıdır.

Örnek:

app/
  (marketing)/
    layout.js  // Pazarlama layout'u
    about/
      page.js
    contact/
      page.js
  (admin)/
    layout.js  // Yönetici layout'u
    dashboard/
      page.js

Bu örnekte, `about` ve `contact` sayfaları `marketing` layout'unu kullanırken, `dashboard` sayfası `admin` layout'unu kullanacaktır.

3. Middleware (Ara Yazılım)

Middleware, bir istek uygulamanız tarafından işlenmeden önce kod çalıştırmanıza olanak tanır. Bu, kimlik doğrulama, yetkilendirme, loglama ve kullanıcıları konumlarına veya cihazlarına göre yönlendirme gibi görevler için kullanışlıdır.

Middleware, projenizin kök dizininde `middleware.js` (veya `middleware.ts`) adlı bir dosyada tanımlanır.

Örnek:

// middleware.js
import { NextResponse } from 'next/server'

export function middleware(request) {
  // Kullanıcının kimliğinin doğrulanıp doğrulanmadığını kontrol et
  const isAuthenticated = false; // Kendi kimlik doğrulama mantığınızla değiştirin

  if (!isAuthenticated && request.nextUrl.pathname.startsWith('/admin')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  return NextResponse.next();
}

// Daha fazla bilgi için aşağıdaki "Eşleşen Yollar" bölümüne bakın
export const config = {
  matcher: '/admin/:path*',
}

Bu örnek, kullanıcının `/admin` altındaki herhangi bir rotaya erişmesine izin vermeden önce kimliğinin doğrulanıp doğrulanmadığını kontrol eden bir middleware tanımlar. Eğer kullanıcı kimliği doğrulanmamışsa, `/login` sayfasına yönlendirilir.

Dosya Tabanlı Yönlendirme İçin En İyi Uygulamalar

App Router'ın dosya tabanlı yönlendirme sisteminden en iyi şekilde yararlanmak için aşağıdaki en iyi uygulamaları göz önünde bulundurun:

Next.js App Router ile Uluslararasılaştırma Örnekleri

Next.js App Router, dosya tabanlı yönlendirme aracılığıyla uluslararasılaştırmayı (i18n) basitleştirir. İşte i18n'i etkili bir şekilde nasıl uygulayabileceğiniz:

1. Alt Dizin Yönlendirmesi (Sub-path Routing)

Rotalarınızı yerel ayara göre alt dizinler kullanarak düzenleyin. Örneğin:

app/
  [locale]/
    page.tsx         // Yerel ayar için ana sayfa
    about/
      page.tsx     // Yerel ayar için hakkında sayfası
// app/[locale]/page.tsx
import { getTranslations } from './dictionaries';

export default async function HomePage({ params: { locale } }) {
  const t = await getTranslations(locale);
  return (<h1>{t.home.title}</h1>);
}

// dictionaries.js
const dictionaries = {
  en: () => import('./dictionaries/en.json').then((module) => module.default),
  tr: () => import('./dictionaries/tr.json').then((module) => module.default),
};

export const getTranslations = async (locale) => {
  try {
    return dictionaries[locale]() ?? dictionaries.en();
  } catch (error) {
    console.error(`Yerel ayar ${locale} için çeviriler yüklenemedi`, error);
    return dictionaries.en();
  }
};

Bu kurulumda, `[locale]` dinamik rota segmenti farklı yerel ayarları (örneğin, `/en`, `/tr`) yönetir. Çeviriler, yerel ayara göre dinamik olarak yüklenir.

2. Alan Adı Yönlendirmesi (Domain Routing)

Daha gelişmiş bir yaklaşım için, her yerel ayar için farklı alan adları veya alt alan adları kullanabilirsiniz. Bu genellikle hosting sağlayıcınızla ek yapılandırma gerektirir.

3. Yerel Ayar Tespiti için Middleware

Kullanıcının tercih ettiği yerel ayarı otomatik olarak tespit etmek ve onları uygun şekilde yönlendirmek için middleware kullanın.

// middleware.js
import { NextResponse } from 'next/server';
import { match } from '@formatjs/intl-localematcher';
import Negotiator from 'negotiator';

let locales = ['en', 'tr', 'de'];

function getLocale(request) {
  const negotiatorHeaders = {};
  request.headers.forEach((value, key) => (negotiatorHeaders[key] = value));
  let languages = new Negotiator({ headers: negotiatorHeaders }).languages();

  try {
      return match(languages, locales, 'tr'); // Varsayılan yerel ayar olarak "tr" kullanın
  } catch (error) {
      console.error("Yerel ayar eşleştirilirken hata:", error);
      return 'tr'; // Eşleştirme başarısız olursa Türkçe'ye geri dön
  }
}

export function middleware(request) {
  const pathname = request.nextUrl.pathname;
  const pathnameIsMissingLocale = locales.every(
    (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
  );

  if (pathnameIsMissingLocale) {
    const locale = getLocale(request);

    return NextResponse.redirect(
      new URL(
        `/${locale}${pathname.startsWith('/') ? '' : '/'}${pathname}`,
        request.url
      )
    );
  }
}

export const config = {
  matcher: [
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
};

Bu middleware, istenen yolun bir yerel ayar önekine sahip olup olmadığını kontrol eder. Değilse, `Accept-Language` başlığını kullanarak kullanıcının tercih ettiği yerel ayarı algılar ve onları uygun yerel ayara özgü yola yönlendirir. Yerel ayar pazarlığını yönetmek için `@formatjs/intl-localematcher` ve `negotiator` gibi kütüphaneler kullanılır.

Next.js App Router ve Küresel Erişilebilirlik

Küresel olarak erişilebilir web uygulamaları oluşturmak, erişilebilirlik (a11y) ilkelerinin dikkatli bir şekilde değerlendirilmesini gerektirir. Next.js App Router, erişilebilir deneyimler oluşturmak için sağlam bir temel sağlar, ancak uygulamanızın yetenekleri ne olursa olsun herkes tarafından kullanılabilir olmasını sağlamak için en iyi uygulamaları uygulamak esastır.

Temel Erişilebilirlik Hususları

  1. Semantik HTML: İçeriğinizi yapılandırmak için semantik HTML öğeleri (örneğin, `<article>`, `<nav>`, `<aside>`, `<main>`) kullanın. Bu, yardımcı teknolojilere anlam kazandırır ve kullanıcıların sitenizde daha kolay gezinmesine yardımcı olur.
  2. ARIA Nitelikleri: Özel bileşenlerin ve widget'ların erişilebilirliğini artırmak için ARIA (Accessible Rich Internet Applications) niteliklerini kullanın. ARIA nitelikleri, öğelerin rolü, durumu ve özellikleri hakkında yardımcı teknolojilere ek bilgi sağlar.
  3. Klavye Navigasyonu: Tüm etkileşimli öğelerin klavye ile erişilebilir olduğundan emin olun. Kullanıcılar, `Tab` tuşunu kullanarak uygulamanızda gezinebilmeli ve `Enter` veya `Boşluk` tuşunu kullanarak öğelerle etkileşim kurabilmelidir.
  4. Renk Kontrastı: Görme engelli kullanıcılar için okunabilirliği sağlamak amacıyla metin ve arka plan arasında yeterli renk kontrastı kullanın. Web İçeriği Erişilebilirlik Yönergeleri (WCAG), normal metin için en az 4.5:1 ve büyük metin için 3:1 kontrast oranını önerir.
  5. Resim Alt Metni: Tüm resimler için açıklayıcı alt metin sağlayın. Alt metin, ekran okuyucular tarafından okunabilen resimler için bir metin alternatifi sunar.
  6. Form Etiketleri: Form etiketlerini `<label>` öğesini kullanarak karşılık gelen giriş alanlarıyla ilişkilendirin. Bu, kullanıcıların her alanda hangi bilginin beklendiğini net bir şekilde anlamasını sağlar.
  7. Ekran Okuyucu Testi: Görme engelli kullanıcılar için erişilebilir olduğundan emin olmak amacıyla uygulamanızı bir ekran okuyucu ile test edin. Popüler ekran okuyucular arasında NVDA, JAWS ve VoiceOver bulunur.

Next.js App Router'da Erişilebilirlik Uygulaması

  1. Next.js Link Bileşenini Kullanın: Navigasyon için `<Link>` bileşenini kullanın. Önceden getirme (prefetching) ve odak yönetimi gibi yerleşik erişilebilirlik özellikleri sağlar.
  2. Odak Yönetimi: Sayfalar arasında gezinirken veya modallar açarken odağın doğru yönetildiğinden emin olun. Odak, yeni sayfada veya modalda en mantıklı öğeye ayarlanmalıdır.
  3. Erişilebilir Özel Bileşenler: Özel bileşenler oluştururken, yukarıda özetlenen ilkelere uyarak erişilebilir olduklarından emin olun. Bileşenlerinizi herkes tarafından kullanılabilir hale getirmek için semantik HTML, ARIA nitelikleri ve klavye navigasyonu kullanın.
  4. Linting ve Test: Kodunuzdaki potansiyel erişilebilirlik sorunlarını belirlemek için ESLint gibi linting araçlarını erişilebilirlik eklentileriyle kullanın. Ayrıca, uygulamanızı erişilebilirlik ihlallerine karşı test etmek için otomatik test araçları kullanın.

Sonuç

Next.js App Router'ın dosya tabanlı yönlendirme sistemi, uygulamalarınızı yapılandırmak ve yönlendirmek için güçlü ve sezgisel bir yol sunar. Bu kılavuzda özetlenen temel kavramları ve en iyi uygulamaları anlayarak, sağlam, ölçeklenebilir ve sürdürülebilir Next.js uygulamaları oluşturabilirsiniz. App Router'ın farklı özellikleriyle denemeler yapın ve geliştirme iş akışınızı nasıl basitleştirebileceğini ve kullanıcı deneyimini nasıl iyileştirebileceğini keşfedin.