DEV Community

MATKARIM MATKARIMOV
MATKARIM MATKARIMOV

Posted on

Next.js App Router - Functions API To'liq Qo'llanma

Next.js 15+ da barcha funksiyalar - cookies, headers, redirect, notFound, useRouter, generateMetadata, generateStaticParams, fetch, cacheLife va boshqalar

Next.js App Router - Functions API

Next.js App Router da 30 dan ortiq maxsus funksiyalar mavjud. Bu maqolada ularni kategoriyalar bo'yicha misollar bilan tushuntiraman.


Funksiyalar xaritasi

┌─────────────────────────────────────────────────────────┐
│                  NEXT.JS FUNCTIONS                       │
├──────────────────┬──────────────────┬───────────────────┤
│  SERVER          │  NAVIGATION      │  CLIENT HOOKS     │
│  (Server only)   │  (Server/Client) │  ('use client')   │
├──────────────────┼──────────────────┼───────────────────┤
│  cookies()       │  redirect()      │  useRouter()      │
│  headers()       │  permanentRedirect│ usePathname()    │
│  fetch()         │  notFound()      │  useSearchParams()│
│  connection()    │  forbidden()     │  useParams()      │
│                  │  unauthorized()  │  useLinkStatus()  │
├──────────────────┼──────────────────┼───────────────────┤
│  CACHING         │  GENERATION      │  SEGMENT HOOK     │
├──────────────────┼──────────────────┼───────────────────┤
│  cacheLife()     │  generateMetadata│  useSelectedLayout│
│  cacheTag()      │  generateStatic  │    Segment()      │
│  revalidateTag() │    Params        │  useSelectedLayout│
│  updateTag()     │  generateViewport│    Segments()     │
│  revalidatePath()│  generateSitemaps│                   │
│  after()         │  ImageResponse   │                   │
└──────────────────┴──────────────────┴───────────────────┘
Enter fullscreen mode Exit fullscreen mode

1. cookies() - Cookie bilan ishlash

Import: next/headers | Ishlaydi: Server Component, Route Handler, Server Action

import { cookies } from 'next/headers';
Enter fullscreen mode Exit fullscreen mode

Cookie o'qish (Server Component)

export default async function Page() {
  const cookieStore = await cookies(); // await kerak!

  // Bitta cookie olish
  const theme = cookieStore.get('theme');
  // { name: 'theme', value: 'dark' }

  // Cookie borligini tekshirish
  const hasToken = cookieStore.has('token'); // true/false

  // Barcha cookie lar
  const all = cookieStore.getAll();
  // [{ name: 'theme', value: 'dark' }, ...]

  return <p>Mavzu: {theme?.value}</p>;
}
Enter fullscreen mode Exit fullscreen mode

Cookie yozish (Server Action / Route Handler)

// app/actions.ts
'use server';

import { cookies } from 'next/headers';

export async function setTheme(theme: string) {
  const cookieStore = await cookies();

  // Oddiy set
  cookieStore.set('theme', theme);

  // Options bilan
  cookieStore.set('theme', theme, {
    httpOnly: true,      // JS dan o'qib bo'lmaydi
    secure: true,        // Faqat HTTPS
    sameSite: 'lax',     // CSRF himoya
    maxAge: 60 * 60 * 24 * 7, // 7 kun
    path: '/',
  });
}
Enter fullscreen mode Exit fullscreen mode

Cookie o'chirish

'use server';

import { cookies } from 'next/headers';

export async function logout() {
  const cookieStore = await cookies();

  // Usul 1: delete()
  cookieStore.delete('session');

  // Usul 2: bo'sh qiymat
  cookieStore.set('session', '');

  // Usul 3: maxAge = 0
  cookieStore.set('session', '', { maxAge: 0 });
}
Enter fullscreen mode Exit fullscreen mode

Cookie options to'liq ro'yxati

Option Turi Tavsif
name string Cookie nomi
value string Cookie qiymati
expires Date Aniq tugash sanasi
maxAge number Umr davomiyligi (soniyalarda)
domain string Qaysi domenda mavjud
path string Qaysi yo'lda mavjud (default: /)
secure boolean Faqat HTTPS
httpOnly boolean Faqat HTTP (JS kirish yo'q)
sameSite 'lax' \ 'strict' \

2. headers() - So'rov headerlari

Import: next/headers | Ishlaydi: Server Component | Faqat o'qish

import { headers } from 'next/headers';

export default async function Page() {
  const headersList = await headers(); // await kerak!

  const userAgent = headersList.get('user-agent');
  const referer = headersList.get('referer');
  const authorization = headersList.get('authorization');
  const acceptLanguage = headersList.get('accept-language');

  return <p>Brauzer: {userAgent}</p>;
}
Enter fullscreen mode Exit fullscreen mode

Header ni boshqa so'rovga uzatish

import { headers } from 'next/headers';

export default async function Page() {
  const authorization = (await headers()).get('authorization');

  // Header ni API so'rovga uzatish
  const res = await fetch('https://api.example.com/user', {
    headers: { authorization: authorization! },
  });
  const user = await res.json();

  return <h1>{user.name}</h1>;
}
Enter fullscreen mode Exit fullscreen mode

Mavjud metodlar

Metod Qaytaradi Tavsif
get(name) `string \ null`
has(name) boolean Header borligini tekshirish
entries() Iterator Barcha key/value juftliklari
keys() Iterator Barcha header nomlari
values() Iterator Barcha header qiymatlari
forEach(fn) void Har bir header uchun funksiya

Muhim: headers() faqat o'qish uchun - header yozib bo'lmaydi. Header o'rnatish uchun Route Handler da new Response() ishlatang.


3. redirect() va permanentRedirect() - Yo'naltirish

Import: next/navigation

redirect() - Vaqtinchalik yo'naltirish (307)

import { redirect } from 'next/navigation';

export default async function Page({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const team = await fetchTeam(id);

  if (!team) {
    redirect('/login'); // return kerak EMAS
  }

  return <h1>{team.name}</h1>;
}
Enter fullscreen mode Exit fullscreen mode

permanentRedirect() - Doimiy yo'naltirish (308)

import { permanentRedirect } from 'next/navigation';

export default async function Page() {
  permanentRedirect('/new-page');
  // Brauzer va qidiruv botlari eski URL ni eslab qoladi
}
Enter fullscreen mode Exit fullscreen mode

Server Action dan redirect

// app/actions.ts
'use server';

import { redirect } from 'next/navigation';

export async function createPost(data: FormData) {
  const post = await db.posts.create({
    data: { title: data.get('title') as string },
  });

  redirect(`/blog/${post.slug}`); // 303 status
}
Enter fullscreen mode Exit fullscreen mode

Farqlari

Funksiya HTTP Status Qachon ishlatish
redirect() 307 (Server Action da 303) Login kerak, resurs ko'chdi (vaqtinchalik)
permanentRedirect() 308 URL butunlay o'zgardi (doimiy)

Muhim qoidalar

  • redirect() return yozish shart emas - u never tipini qaytaradi
  • Server Action va Route Handler da try/catch ichida ishlatmang
  • Event handler da ishlatmang - useRouter().push() ishlatang
  • Tashqi URL ga ham yo'naltirish mumkin: redirect('https://google.com')

4. notFound() - 404 sahifa

Import: next/navigation | Route ga mos not-found.tsx renderlanadi

import { notFound } from 'next/navigation';

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  const post = await getPost(slug);

  if (!post) {
    notFound(); // not-found.tsx renderlanadi, 404 status
  }

  return <h1>{post.title}</h1>;
}
Enter fullscreen mode Exit fullscreen mode

5. forbidden() va unauthorized() (Experimental)

import { forbidden, unauthorized } from 'next/navigation';

export default async function AdminPage() {
  const session = await verifySession();

  if (!session) {
    unauthorized(); // 401 + unauthorized.tsx
  }

  if (session.role !== 'ADMIN') {
    forbidden();    // 403 + forbidden.tsx
  }

  return <div>Admin Panel</div>;
}
Enter fullscreen mode Exit fullscreen mode

6. useRouter() - Client-side navigatsiya

Import: next/navigation | Ishlaydi: Client Component ('use client')

'use client';

import { useRouter } from 'next/navigation';

export default function Dashboard() {
  const router = useRouter();

  return (
    <div>
      {/* Sahifaga o'tish (tarixga qo'shiladi) */}
      <button onClick={() => router.push('/settings')}>
        Sozlamalar
      </button>

      {/* Sahifaga o'tish (tarix almashtiriladi) */}
      <button onClick={() => router.replace('/login')}>
        Login
      </button>

      {/* Joriy sahifani yangilash */}
      <button onClick={() => router.refresh()}>
        Yangilash
      </button>

      {/* Oldindan yuklash */}
      <button onMouseEnter={() => router.prefetch('/heavy-page')}>
        Og'ir sahifa (hover qilganda yuklanadi)
      </button>

      {/* Orqaga */}
      <button onClick={() => router.back()}>
        Orqaga
      </button>

      {/* Oldinga */}
      <button onClick={() => router.forward()}>
        Oldinga
      </button>
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Barcha metodlar

Metod Tavsif
push(href, { scroll }) Sahifaga o'tish, tarixga qo'shish
replace(href, { scroll }) Sahifaga o'tish, tarixni almashtirish
refresh() Joriy sahifani serverdan yangilash
prefetch(href) Sahifani oldindan yuklash
back() Brauzer tarixida orqaga
forward() Brauzer tarixida oldinga

scroll parametri

// Sahifa yuqorisiga scroll qilmaydi (default: true)
router.push('/page', { scroll: false });
Enter fullscreen mode Exit fullscreen mode

Xavfsizlik: router.push() ga foydalanuvchi kiritgan URL ni tekshirmasdan bermang - XSS xavfi bor!


7. usePathname() - Joriy URL yo'li

'use client';

import { usePathname } from 'next/navigation';

export function Breadcrumbs() {
  const pathname = usePathname();
  // /blog/my-post

  const segments = pathname.split('/').filter(Boolean);
  // ['blog', 'my-post']

  return (
    <nav>
      {segments.map((segment, i) => (
        <span key={i}> / {segment}</span>
      ))}
    </nav>
  );
}
Enter fullscreen mode Exit fullscreen mode

8. useSearchParams() - URL query parametrlari

'use client';

import { useSearchParams } from 'next/navigation';

export function SearchFilter() {
  const searchParams = useSearchParams();

  const query = searchParams.get('query');      // "hello"
  const page = searchParams.get('page');         // "2"
  const tags = searchParams.getAll('tag');        // ["react", "next"]
  const hasSort = searchParams.has('sort');       // true/false
  const allParams = searchParams.toString();      // "query=hello&page=2"

  return <p>Qidiruv: {query}, Sahifa: {page}</p>;
}
Enter fullscreen mode Exit fullscreen mode

Muhim: useSearchParams() eng yaqin <Suspense> chegarasigacha client-side rendering ga o'tkazadi.


9. useParams() - Dinamik route parametrlari

'use client';

import { useParams } from 'next/navigation';

export function PostHeader() {
  const params = useParams();
  // { slug: 'my-post' } yoki { category: 'react', slug: 'hooks' }

  return <h1>Post: {params.slug}</h1>;
}
Enter fullscreen mode Exit fullscreen mode
Route URL useParams()
app/blog/[slug]/page.tsx /blog/hello { slug: 'hello' }
app/shop/[...slug]/page.tsx /shop/a/b { slug: ['a', 'b'] }

10. useSelectedLayoutSegment() - Aktiv segment

Layout da qaysi child segment aktiv ekanligini aniqlash:

'use client';

import { useSelectedLayoutSegment } from 'next/navigation';
import Link from 'next/link';

export function NavLink({
  href,
  children,
}: {
  href: string;
  children: React.ReactNode;
}) {
  const segment = useSelectedLayoutSegment();
  // /blog da → 'blog'
  // /about da → 'about'
  // / da → null

  const isActive = href.includes(segment || '');

  return (
    <Link
      href={href}
      style={{ fontWeight: isActive ? 'bold' : 'normal' }}
    >
      {children}
    </Link>
  );
}
Enter fullscreen mode Exit fullscreen mode

11. useLinkStatus() - Link holati

Navigatsiya jarayonida vizual feedback berish:

'use client';

import { useLinkStatus } from 'next/link';

export function LoadingIndicator() {
  const { pending } = useLinkStatus();

  return pending ? <span className="spinner" /> : null;
}
Enter fullscreen mode Exit fullscreen mode

12. fetch() - Kengaytirilgan fetch

Next.js Web fetch() ni kengaytirgan - server tomonida caching va revalidation qo'shilgan:

export default async function Page() {
  // Default - statik prerendering da keshlanadi
  const data = await fetch('https://api.example.com/posts');

  // Har safar yangi ma'lumot
  const fresh = await fetch('https://api.example.com/posts', {
    cache: 'no-store',
  });

  // 1 soat kesh
  const cached = await fetch('https://api.example.com/posts', {
    next: { revalidate: 3600 },
  });

  // Tag bilan kesh (revalidateTag bilan yangilash uchun)
  const tagged = await fetch('https://api.example.com/posts', {
    next: { tags: ['posts'] },
  });

  // Majburiy kesh
  const forced = await fetch('https://api.example.com/posts', {
    cache: 'force-cache',
  });
}
Enter fullscreen mode Exit fullscreen mode

cache qiymatlari

Qiymat Tavsif
'auto' (default) Next.js o'zi aniqlaydi
'no-store' Har safar serverdan yangi oladi
'force-cache' Keshdan beradi, yo'q bo'lsa yuklab keshlaydi

next.revalidate qiymatlari

Qiymat Tavsif
false Cheksiz kesh
0 Keshlamaslik
60 60 soniyada bir yangilash

13. generateStaticParams() - Statik sahifalar generatsiyasi

Build vaqtida dinamik route lar uchun sahifalar yaratish:

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

// Build vaqtida qaysi sahifalar yaratilishini aniqlash
export async function generateStaticParams() {
  const posts = await fetch('https://api.example.com/posts')
    .then(res => res.json());

  return posts.map(post => ({
    slug: post.slug,
  }));
  // [{ slug: 'post-1' }, { slug: 'post-2' }, ...]
}

export default async function Page({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  return <h1>{slug}</h1>;
}
Enter fullscreen mode Exit fullscreen mode

Strategiyalar

// 1. Barcha sahifalarni build da yaratish
export async function generateStaticParams() {
  const posts = await fetchAllPosts();
  return posts.map(p => ({ slug: p.slug }));
}

// 2. Faqat mashhurlarini build da, qolganini runtime da
export async function generateStaticParams() {
  const posts = await fetchPopularPosts();
  return posts.slice(0, 10).map(p => ({ slug: p.slug }));
}

// 3. Hech birini build da yaratmaslik (hammasi runtime da)
export async function generateStaticParams() {
  return [];
}

// 4. Generatsiya qilinmaganlarni 404 qilish
export const dynamicParams = false;
Enter fullscreen mode Exit fullscreen mode

Ko'p darajali dinamik segmentlar

// app/products/[category]/layout.tsx
export async function generateStaticParams() {
  return [
    { category: 'electronics' },
    { category: 'clothing' },
  ];
}

// app/products/[category]/[product]/page.tsx
export async function generateStaticParams({
  params: { category },
}: {
  params: { category: string };
}) {
  // Har bir category uchun productlar
  const products = await fetchProducts(category);
  return products.map(p => ({ product: p.id }));
}
Enter fullscreen mode Exit fullscreen mode

14. generateMetadata() - SEO Metadata

Statik metadata

import type { Metadata } from 'next';

export const metadata: Metadata = {
  title: 'Blog',
  description: 'Eng yaxshi blog postlar',
};

export default function Page() {
  return <h1>Blog</h1>;
}
Enter fullscreen mode Exit fullscreen mode

Dinamik metadata

import type { Metadata } from 'next';

export async function generateMetadata({
  params,
}: {
  params: Promise<{ slug: string }>;
}): Promise<Metadata> {
  const { slug } = await params;
  const post = await getPost(slug);

  return {
    title: post.title,
    description: post.excerpt,
    openGraph: {
      title: post.title,
      description: post.excerpt,
      images: [post.coverImage],
    },
  };
}
Enter fullscreen mode Exit fullscreen mode

Title template

// app/layout.tsx - Root layout
export const metadata: Metadata = {
  title: {
    template: '%s | MySite',   // %s → child title bilan almashadi
    default: 'MySite',         // Child title bo'lmasa
  },
};

// app/about/page.tsx
export const metadata: Metadata = {
  title: 'Biz haqimizda',
};
// Natija: <title>Biz haqimizda | MySite</title>

// app/blog/page.tsx
export const metadata: Metadata = {
  title: {
    absolute: 'Blog',   // Template ni e'tiborsiz qoldiradi
  },
};
// Natija: <title>Blog</title>
Enter fullscreen mode Exit fullscreen mode

To'liq metadata misol

export const metadata: Metadata = {
  // Asosiy
  title: 'Next.js Blog',
  description: 'React framework haqida blog',
  keywords: ['Next.js', 'React', 'TypeScript'],
  authors: [{ name: 'Mehmon', url: 'https://example.com' }],

  // Base URL
  metadataBase: new URL('https://example.com'),

  // Open Graph (Telegram, Facebook)
  openGraph: {
    title: 'Next.js Blog',
    description: 'React framework haqida blog',
    url: 'https://example.com',
    siteName: 'MySite',
    locale: 'uz_UZ',
    type: 'website',
    images: [
      {
        url: '/og-image.png',
        width: 1200,
        height: 630,
        alt: 'Blog rasmi',
      },
    ],
  },

  // Twitter
  twitter: {
    card: 'summary_large_image',
    title: 'Next.js Blog',
    description: 'React framework haqida blog',
    creator: '@mehmon',
    images: ['/twitter-image.png'],
  },

  // Robots
  robots: {
    index: true,
    follow: true,
    googleBot: {
      index: true,
      follow: true,
      'max-image-preview': 'large',
    },
  },

  // Alternates (til versiyalari)
  alternates: {
    canonical: '/',
    languages: {
      'uz-UZ': '/uz',
      'en-US': '/en',
      'ru-RU': '/ru',
    },
  },

  // Verifikatsiya
  verification: {
    google: 'google-site-verification-code',
    yandex: 'yandex-verification-code',
  },

  // Ikonkalar
  icons: {
    icon: '/favicon.ico',
    apple: '/apple-icon.png',
  },

  // Manifest (PWA)
  manifest: '/manifest.json',
};
Enter fullscreen mode Exit fullscreen mode

Metadata birlashtirish qoidasi

app/layout.tsx (title: "MySite", openGraph: { title: "MySite", description: "..." })
    │
    └── app/blog/page.tsx (title: "Blog")
         │
         Natija:
         title = "Blog"                    ← almashtrildi
         openGraph.title = "MySite"        ← meros qoldi (blog da openGraph yo'q)
         openGraph.description = "..."     ← meros qoldi
Enter fullscreen mode Exit fullscreen mode

Qoida: Child segment da maydon belgilansa - almashtiriladi. Belgilanmasa - ota dan meros qoladi.


15. Caching funksiyalari

cacheLife() - Kesh muddati

import { cacheLife } from 'next/cache';

async function BlogPosts() {
  'use cache';
  cacheLife('hours'); // 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'max'

  return await fetchPosts();
}
Enter fullscreen mode Exit fullscreen mode

cacheTag() + revalidateTag() / updateTag()

import { cacheTag, revalidateTag, updateTag } from 'next/cache';

// Keshlash va tag qo'yish
async function getPosts() {
  'use cache';
  cacheTag('posts');
  return await fetchPosts();
}

// Server Action - fonda yangilash
async function createPost(data: FormData) {
  'use server';
  await db.posts.create(data);
  revalidateTag('posts'); // stale-while-revalidate
}

// Server Action - darhol yangilash
async function updateCart(itemId: string) {
  'use server';
  await db.cart.update(itemId);
  updateTag('cart'); // darhol keshni tozalash
}
Enter fullscreen mode Exit fullscreen mode

revalidatePath() - Yo'l bo'yicha yangilash

import { revalidatePath } from 'next/cache';

export async function createPost() {
  'use server';
  await db.posts.create(...);
  revalidatePath('/blog'); // /blog sahifasini yangilash
}
Enter fullscreen mode Exit fullscreen mode

after() - Javobdan keyin ishlatish

So'rov javob yuborilgandan keyin loglar yoki analytics yuborish:

import { after } from 'next/server';

export default async function Page() {
  const data = await fetchData();

  after(async () => {
    // Javob yuborilgandan KEYIN ishlaydi
    await analytics.track('page-view');
    await logger.log('Page rendered');
  });

  return <div>{data}</div>;
}
Enter fullscreen mode Exit fullscreen mode

16. connection() - So'rov vaqtiga kechirish

Komponentni so'rov vaqtida ishlashga majburlash:

import { connection } from 'next/server';

async function DynamicContent() {
  await connection(); // Prerendering dan chiqish

  const now = new Date().toISOString();
  const uuid = crypto.randomUUID();

  return <p>{now} - {uuid}</p>;
}
Enter fullscreen mode Exit fullscreen mode

17. draftMode() - Qoralama rejim

CMS bilan integratsiya - chop etilmagan kontentni ko'rish:

import { draftMode } from 'next/headers';

export default async function Page() {
  const { isEnabled } = await draftMode();

  const posts = isEnabled
    ? await fetchDraftPosts()   // Qoralama postlar
    : await fetchPublishedPosts(); // Chop etilgan postlar

  return <div>{/* ... */}</div>;
}
Enter fullscreen mode Exit fullscreen mode

Xulosa jadvali

Server funksiyalari (Server Component da ishlatiladi)

Funksiya Vazifasi Dinamik rendering ga o'tkazadimi?
cookies() Cookie o'qish/yozish Ha
headers() So'rov headerlari Ha
connection() So'rov vaqtiga kechirish Ha
draftMode() Qoralama rejim Ha
after() Javobdan keyin kod ishlatish Yo'q

Navigatsiya funksiyalari (Server va Client da)

Funksiya Vazifasi HTTP Status
redirect() Vaqtinchalik yo'naltirish 307 (SA: 303)
permanentRedirect() Doimiy yo'naltirish 308
notFound() 404 sahifa 404
forbidden() 403 sahifa 403
unauthorized() 401 sahifa 401

Client hooklar ('use client' da ishlatiladi)

Hook Vazifasi
useRouter() Programmatik navigatsiya
usePathname() Joriy URL yo'li
useSearchParams() Query parametrlari
useParams() Dinamik route parametrlari
useLinkStatus() Link navigatsiya holati
useSelectedLayoutSegment() Aktiv child segment

Generatsiya funksiyalari

Funksiya Vazifasi
generateMetadata() SEO metadata
generateStaticParams() Statik sahifalar
generateViewport() Viewport sozlamalari
generateSitemaps() Sitemap generatsiyasi

Keshlash funksiyalari

Funksiya Vazifasi
cacheLife() Kesh muddati
cacheTag() Kesh tegi
revalidateTag() Fonda yangilash
updateTag() Darhol yangilash
revalidatePath() Yo'l bo'yicha yangilash

Bu maqola Next.js 15+ rasmiy dokumentatsiyasi asosida yozilgan. Savollar yoki takliflar bo'lsa, kommentariyada yozing!
(https://matkarim.uz)

Top comments (0)