Metadata — title, description, Open Graph, Twitter Card

~15 daq · Next.js · Kirish va Asoslar

Muammodan boshlaylik

Siz do'stingizga sayt havolasini Telegramda yubordingiz. Havola ko'rinishi:

https://mening-saytim.uz/blog/post-1

Shunchaki URL. Hech qanday rasm, sarlavha, tavsif yo'q. Do'stingiz bosadimi? Ehtimol yo'q.

Endi boshqa saytning havolasini yuboring — chiroyli karta ko'rinadi: rasm, sarlavha, qisqa tavsif. Bu — Open Graph metadata.

Ikkinchi muammo — Google da qidirganda sahifangiz qanday ko'rinadi? Sarlavha va tavsif to'g'ri bo'lmasa — odamlar bosmasligi mumkin.


Metadata nima

Metadata — sahifa haqidagi ma'lumot. Foydalanuvchi ko'rmaydi, lekin brauzer, Google, Telegram, Twitter uchun muhim.

<!-- Brauzer tab da ko'rinadi -->
<title>Mening saytim</title>

<!-- Google qidiruv natijasida ko'rinadi -->
<meta name="description" content="Sayt haqida qisqa tavsif" />

<!-- Telegram, WhatsApp da havola yuborilganda -->
<meta property="og:title" content="Sarlavha" />
<meta property="og:image" content="https://..." />

React da bularni <head> ga qo'lda yozish kerak edi. Next.js da buning uchun metadata ob'ekti bor.


Statik metadata

Sahifaning sarlavhasi va tavsifi o'zgarmasa — metadata ob'ektini eksport qilasiz:

// app/about/page.tsx
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: 'Biz haqimizda',
  description: 'Kompaniyamiz tarixi va jamoamiz haqida',
}

export default function AboutPage() {
  return <h1>Biz haqimizda</h1>
}

Next.js bu ma'lumotlarni avtomatik <head> ga qo'yadi. Siz <head> ga qo'lda hech narsa yozmasangiz ham ishlaydi.


layout.tsx da default metadata

Har bir sahifada alohida yozmaslik uchun root layout.tsx da default metadata belgilanadi. Sahifada o'z metadatasi bo'lsa — u default ni ustidan yozadi:

// app/layout.tsx
import { Metadata } from 'next'

export const metadata: Metadata = {
  title: {
    default: 'DevDocs',           // sahifada title yo'q bo'lsa
    template: '%s | DevDocs',     // sahifada title bo'lsa: "Biz haqimizda | DevDocs"
  },
  description: "O'zbek tilida dasturlash qo'llanmalari",
}

template: '%s | DevDocs' — %s o'rniga sahifaning o'z title si qo'yiladi. Natija: Biz haqimizda | DevDocs.

Sahifada faqat title: 'Biz haqimizda' yozsangiz — avtomatik Biz haqimizda | DevDocs bo'ladi.


Dinamik metadata

Sahifa sarlavhasi URL ga qarab o'zgarsa — generateMetadata funksiyasi ishlatiladi:

// app/blog/[slug]/page.tsx
import { Metadata } from 'next'

export async function generateMetadata({
  params,
}: {
  params: { slug: string }
}): Promise<Metadata> {
  const { slug } = await params
  const post = await fetch(`https://api.example.com/posts/${slug}`)
    .then(r => r.json())

  return {
    title: post.title,
    description: post.excerpt,
  }
}

export default async function BlogPost({ params }) {
  // ...
}

/blog/nextjs-kirish ga kirganda — o'sha postning sarlavhasi va tavsifi <head> ga qo'yiladi. Google har bir blog post uchun to'g'ri ma'lumot ko'radi.


Open Graph — ijtimoiy tarmoqlar uchun

Telegram, WhatsApp, Facebook da havola yuborilganda chiroyli karta ko'rsatish uchun Open Graph metadata kerak:

export const metadata: Metadata = {
  title: 'Next.js ga kirish',
  description: 'Next.js ni noldan o\'rganish',
  openGraph: {
    title: 'Next.js ga kirish',
    description: 'Next.js ni noldan o\'rganish',
    url: 'https://devdocs.uz/blog/nextjs',
    siteName: 'DevDocs',
    images: [
      {
        url: 'https://devdocs.uz/og/nextjs.png',
        width: 1200,
        height: 630,
        alt: 'Next.js kursi',
      },
    ],
    locale: 'uz_UZ',
    type: 'article',
  },
}

images dagi rasm — havola yuborilganda ko'rinadigan rasm. Standart o'lcham: 1200×630px.


Twitter Card

Twitter (X) Open Graph ni qisman qo'llab-quvvatlaydi, lekin o'zining twitter metadatasi ham bor:

export const metadata: Metadata = {
  twitter: {
    card: 'summary_large_image',  // katta rasm bilan karta
    title: 'Next.js ga kirish',
    description: 'Next.js ni noldan o\'rganish',
    images: ['https://devdocs.uz/og/nextjs.png'],
  },
}

card turlari:

  • summary — kichik rasm, matn
  • summary_large_image — katta rasm (ko'proq e'tibor tortadi)

opengraph-image.tsx — dinamik OG rasm

Har bir sahifa uchun alohida OG rasm yaratish uchun opengraph-image.tsx fayli:

// app/blog/[slug]/opengraph-image.tsx
import { ImageResponse } from 'next/og'

export const size = { width: 1200, height: 630 }

export default async function OgImage({ params }) {
  const { slug } = await params
  const post = await fetch(`https://api.example.com/posts/${slug}`)
    .then(r => r.json())

  return new ImageResponse(
    (
      <div style={{
        background: '#0f172a',
        width: '100%',
        height: '100%',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        fontSize: 48,
        color: 'white',
      }}>
        {post.title}
      </div>
    )
  )
}

Next.js bu faylni avtomatik topib, OG rasm sifatida ishlatadi. Har bir blog post uchun o'ziga xos rasm — qo'lda rasm yaratmasdan.


Tez-tez uchraydigan xatolar

1. metadata ni Client Component da eksport qilish

// ❌ — Client Component da metadata ishlamaydi
'use client'

export const metadata = { title: 'Sahifa' }  // e'tiborga olinmaydi

metadata faqat Server Component da ishlaydi. Agar sahifada 'use client' kerak bo'lsa — metadata ni alohida Server Component da saqlang.

2. OG rasm o'lchami noto'g'ri

// ❌ — kichik rasm, ba'zi platformalarda ko'rinmaydi
images: [{ url: '...', width: 400, height: 200 }]

// ✅ — standart o'lcham
images: [{ url: '...', width: 1200, height: 630 }]

3. generateMetadata da params ni await qilmaslik (Next.js 15+)

// ❌
export async function generateMetadata({ params }) {
  const post = await fetch(`/api/${params.slug}`)  // xato!
}

// ✅
export async function generateMetadata({ params }) {
  const { slug } = await params
  const post = await fetch(`/api/${slug}`)
}

Xulosa

Metadata — Google, Telegram, Twitter uchun sahifa haqidagi ma'lumot.

metadata ob'ekti     → statik sahifalar uchun
generateMetadata()   → dinamik sahifalar uchun (blog, mahsulot)
template: '%s | ...' → barcha sahifalarda bir xil suffix
openGraph            → Telegram, Facebook, WhatsApp kartasi
twitter              → Twitter/X kartasi
opengraph-image.tsx  → dinamik OG rasm yaratish

metadata faqat Server Component da ishlaydi.


Keyingi dars

10-dars: Server Component — nima, qanday ishlaydi, qachon ishlatiladi

Birinchi bo'limni yakunladik. Ikkinchi bo'lim — Rendering Strategiyalari. Server Component ni chuqurroq ko'ramiz.