13.8-bob: Metadata, SEO va Optimizatsiya
13-QISM — Next.js · 8-mavzu
1. Kirish va motivatsiya
Eng zo'r sayt ham, agar uni hech kim topmasa, foydasiz. Foydalanuvchilar saytlarni ko'pincha Google qidiruvi orqali topadi (yoki ijtimoiy tarmoqda ulashilgan havola orqali). SEO (Search Engine Optimization — qidiruv tizimini optimizatsiya qilish) — saytni Google, Bing kabi qidiruv tizimlarida yuqori o'ringa chiqarish san'ati. Bu — biznes uchun hayotiy muhim (e-commerce sayt Google'da 1-sahifada bo'lsa — ko'p mijoz; 5-sahifada — deyarli hech kim ko'rmaydi). Next.js bu sohada eng kuchli frameworklardan biri: server'da render (Google darrov ko'radi — 13.1: 2.1), metadata API (sarlavha, tavsif — har sahifaga), va SEO uchun barcha vositalar (sitemap, robots, strukturali ma'lumot).
Bundan tashqari, havola ijtimoiy tarmoqda (Telegram, Facebook, Twitter) ulashilganda qanday ko'rinadi? Yaxshi sozlangan saytda — chiroyli karta (sarlavha, tavsif, rasm); sozlanmaganda — quruq havola (hech kim bosmaydi). Buni Open Graph va Twitter Card metadata boshqaradi. Va Google'ning "boy natijalari" (rich results — yulduzli reyting, narx, FAQ to'g'ridan qidiruvda) — strukturali ma'lumot (JSON-LD) bilan. Bularning hammasi — saytni ko'rinadigan, bosiladigan, ishonchli qiladi.
Bu bob: SEO asoslari (Next.js'da), Metadata API (statik metadata), generateMetadata (dinamik — har sahifaga), title/description, Open Graph (ijtimoiy ulashish), Twitter Card, favicon va ikonlar, sitemap.xml (sitemap.ts), robots.txt (robots.ts), strukturali ma'lumot (JSON-LD — boy natijalar), canonical (takror kontent), OG rasm generatsiyasi (next/og), va SEO best practices (semantik HTML, til). Bu mavzular to'liq, har kod misolida maqsad + izoh + "nima qiladi" bilan ochib beriladi.
O'xshatish: SEO va metadata — bu do'kon peshtaxtasi va manzili. Do'koningiz ichi (sayt kontenti) qanchali zo'r bo'lmasin, agar (1) peshtaxta (Open Graph — ijtimoiy ulashish kartasi) jozibasiz bo'lsa, hech kim kirmaydi; (2) do'kon xaritada (sitemap — Google'ga "menda shu sahifalar bor" deb aytish) yo'q bo'lsa, odamlar topmaydi; (3) lavha (title, description — qidiruvda ko'rinadigan sarlavha/tavsif) tushunarsiz bo'lsa, o'tib ketishadi; (4) mahsulot yorliqlari (JSON-LD — narx, reyting) bo'lmasa, mijoz noaniqlikda qoladi. SEO — do'koningizni ko'rinadigan (Google topadi), jozibali (chiroyli peshtaxta), va ishonchli (aniq yorliq) qilish. Eng yaxshi mahsulot ham, agar do'koningizni hech kim topmasa yoki peshtaxta jirkanch bo'lsa, sotilmaydi. Next.js — sizga peshtaxta, manzil, lavha, yorliqlarni tez va to'g'ri qilishga vosita beradi.
Nega muhim?
- Topilish (discoverability) — SEO'siz sayt Google'da yo'q (foydalanuvchilar topmaydi — biznes yo'q).
- Server render afzalligi — Next.js SSR/SSG (Google JavaScript'ni kutmasdan HTML ko'radi — SPA zaif — 13.1: 2.1).
- Ijtimoiy ulashish — Open Graph bilan havola chiroyli (ko'proq bosish — trafik).
- Ishonch va CTR — boy natijalar (reyting, narx) qidiruvda ajralib turadi (ko'proq bosiladi).
2. Nazariya — chuqur tushuntirish
2.1. SEO asoslari (Next.js nega kuchli)
SEO — qidiruv tizimida YUQORI o'ringa chiqish (Google saytni qanday ko'radi):
GOOGLE QANDAY ISHLAYDI (3 bosqich):
1. CRAWL (kezish) — Googlebot saytni o'qiydi (havolalar bo'yicha yuradi)
2. INDEX (indekslash) — kontentni tushunadi, bazaga qo'shadi (title, matn, struktura)
3. RANK (reyting) — qidiruvda tartiblaydi (mos kelish, tezlik, ishonch — 100+ omil)
SPA (faqat CSR — 13.1: 2.1) MUAMMOSI:
Googlebot kelsa — BO'SH HTML (<div id="root"></div>) — JavaScript kerak
Google JS'ni ba'zan ishlatadi, lekin SEKIN/ishonchsiz kontent ko'rinmasligi mumkin
NEXT.JS YECHIMI (SSR/SSG — 13.4):
Googlebot kelsa — TO'LIQ HTML (kontent, title, meta — tayyor)
Google darrov ko'radi va indekslaydi (ishonchli, tez — SEO kuchli)
SEO — Google'da topilish (crawl index rank); kontent HTML'da bo'lishi shart
Next.js SSR/SSG — to'liq HTML (Google darrov ko'radi); SPA — bo'sh HTML (zaif SEO)SEO asoslari (Next.js nega kuchli) — qidiruv tizimining ishlashi va Next.js afzalligi. SEO (Search Engine Optimization) — saytni Google kabi qidiruv tizimlarida yuqori o'ringa chiqarish. Google qanday ishlaydi (uch bosqich): (1) crawl (kezish) — Googlebot (Google roboti) saytni o'qiydi (havolalar bo'yicha yurib, sahifalarni topadi); (2) index (indekslash) — kontentni tushunadi va bazaga qo'shadi (title, matn, struktura — nima haqida); (3) rank (reyting) — qidiruvda tartiblaydi (so'rovga mos kelish, sahifa tezligi, ishonch — 100+ omil). SPA muammosi (faqat CSR — 13.1: 2.1): Googlebot kelsa — bo'sh HTML (
<div id="root"></div>— kontent JavaScript bilan keyin qo'shiladi), Google JavaScript'ni ba'zan ishlatadi, lekin sekin va ishonchsiz (kontent ko'rinmasligi yoki kech indekslanishi mumkin — SEO zaif). Next.js yechimi (SSR/SSG — 13.4): Googlebot kelsa — to'liq HTML (kontent, title, meta — server'da render bo'lgan, tayyor), Google darrov ko'radi va indekslaydi (ishonchli, tez — SEO kuchli). Ikki nuqta: (1) SEO — Google'da topilish (crawl index rank), buning uchun kontent HTML'da bo'lishi shart (JavaScript ortida yashiringan emas); (2) Next.js SSR/SSG — to'liq HTML (Google darrov ko'radi — kuchli SEO), SPA — bo'sh HTML (zaif SEO — JavaScript'ga bog'liq). Bu — Next.js'ning SEO uchun nega tanlanishining asosiy sababi (e-commerce, blog, marketing — SEO muhim bo'lgan har loyiha Next.js'ni afzal ko'radi). SEO — server render'ning eng katta amaliy foydasi.
2.2. Metadata API (statik)
METADATA API — sahifa meta ma'lumotlari (title, description — HTML <head>'ga):
// app/about/page.tsx — statik metadata (o'zgarmas sahifa):
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Biz haqimizda — MyShop",
description: "MyShop — O'zbekistondagi eng yaxshi onlayn do'kon. 2020 yildan beri...",
};
export default function AboutPage() { return <main>...</main>; }
Next.js buni HTML <head>'ga qo'yadi (server'da — Google ko'radi):
// <title>Biz haqimizda — MyShop</title>
// <meta name="description" content="MyShop — ...">
LAYOUT'DA (umumiy — barcha sahifa uchun default):
// app/layout.tsx
export const metadata: Metadata = {
title: { default: "MyShop", template: "%s — MyShop" }, // %s — sahifa title'i
description: "...",
};
metadata — export const (statik); Next.js HTML <head>'ga qo'yadi (server — SEO)
Layout'da default/template; sahifada aniq (template: "%s — MyShop" — avtomatik qo'shadi)Metadata API (statik) — sahifa meta ma'lumotlarini belgilash. Metadata API — Next.js'ning sahifa
<head>ma'lumotlarini (title, description, va boshqalar) belgilash usuli. Statik (o'zgarmas) sahifa uchunexport const metadata:export const metadata: Metadata = { title: "...", description: "..." }— Next.js buni HTML<head>ga qo'yadi (<title>,<meta name="description">), va bu server'da (Google ko'radi — SEO — 2.1). Eng muhim ikki maydon:title(sahifa sarlavhasi — qidiruvda ko'k havola, brauzer tab'ida),description(qisqa tavsif — qidiruvda havola ostidagi matn — foydalanuvchi bosishga qaror qiladi). Layout'da (umumiy — barcha sahifa uchun default):title: { default: "MyShop", template: "%s — MyShop" }—default(sarlavha berilmagan sahifalar uchun),template(%so'rniga sahifa title'i qo'yiladi — masalan blog post title'i "Mening Postim" bo'lsa, to'liq title "Mening Postim — MyShop" bo'ladi — avtomatik brend qo'shish). Ikki nuqta: (1)metadata—export const(statik); Next.js uni HTML<head>ga server'da qo'yadi (SEO — Google ko'radi); (2) layout'da default/template (umumiy), sahifada aniq (template: "%s — MyShop"— har sahifa title'iga brend avtomatik qo'shiladi — izchillik). Bu — SEO'ning asosiy qadami (har sahifaning to'g'ri title va description'i — Google va foydalanuvchi uchun). SPA'da metadata client'da (useEffect— sekin, Google ko'rmaydi — 13.7: Misol 8); Next.js'da server'da (HTML — SEO).
2.3. generateMetadata (dinamik)
generateMetadata — DINAMIK metadata (har mahsulot/post uchun o'z title — ma'lumotdan):
// app/products/[id]/page.tsx
import type { Metadata } from "next";
export async function generateMetadata({ params }): Promise<Metadata> {
const { id } = await params;
const product = await fetch(`/api/products/${id}`).then((r) => r.json());
return {
title: product.name, // har mahsulot — o'z title
description: product.description.slice(0, 160), // tavsif (160 belgi — optimal)
};
}
// /products/42 <title>iPhone 15 — MyShop</title> (mahsulot nomidan)
XUSUSIYATLARI:
- DINAMIK ([id], [slug] — har element o'z metadata'si)
- async (ma'lumot olib — DB/API'dan)
- Kesh: fetch keshlansa, metadata ham keshlanadi (Request Memoization — 13.7: Misol 8)
- page'ning fetch'i bilan BIR XIL dedup (ikki marta so'rov yo'q)
generateMetadata — dinamik sahifa metadata'si (har element o'z title/description — ma'lumotdan)
async (DB/API'dan); page bilan bir xil fetch dedup (Request Memoization — 13.5: 2.3)generateMetadata (dinamik) — har element uchun o'z metadata'si. Statik
metadata2.2-bob o'zgarmas sahifalar uchun (about, contact). Lekin dinamik sahifalar ([id],[slug]— har mahsulot, har blog post) uchun metadata ma'lumotdan kelishi kerak (har mahsulotning o'z nomi, har postning o'z sarlavhasi) — buning uchungenerateMetadata(async funksiya):export async function generateMetadata({ params }) { const product = await fetch(...); return { title: product.name, description: ... } }. Natijada/products/42<title>iPhone 15 — MyShop</title>(mahsulot nomidan — dinamik). Xususiyatlari: (1) dinamik ([id],[slug]— har element o'z metadata'si); (2) async (ma'lumot olib — DB/API'dan); (3) kesh — agarfetchkeshlansa, metadata ham keshlanadi 13.7-bob; (4) muhim —pageningfetchi bilan bir xil so'rov bo'lsa, Next.js uni dedup qiladi (Request Memoization — 13.5: 2.3) — ya'nigenerateMetadatada vapageda bir xil mahsulotnifetchqilsangiz, DB'ga bir marta boradi (ikki marta emas — isrof yo'q). Ikki nuqta: (1)generateMetadata— dinamik sahifa metadata'si (har mahsulot/post o'z title/description'i — ma'lumotdan — SEO uchun har sahifa noyob); (2) async (DB/API'dan),pagebilan bir xil fetch dedup (Request Memoization — qo'shimcha so'rov yo'q). Bu — e-commerce, blog kabi ko'p dinamik sahifali saytlar uchun majburiy (har mahsulot/post o'z noyob title/description'iga ega bo'lishi kerak — Google har birini alohida indekslaydi).descriptionni ~160 belgi qilish optimal (Google qidiruvda shuncha ko'rsatadi). Bu — dinamik SEO'ning asosi.
2.4. Open Graph (ijtimoiy ulashish)
OPEN GRAPH — havola ijtimoiy tarmoqda (Telegram, Facebook) qanday ko'rinadi:
export const metadata: Metadata = {
title: "Mahsulot nomi",
description: "...",
openGraph: { // ijtimoiy ulashish kartasi
title: "Mahsulot nomi",
description: "...",
images: [{ url: "https://saytim.com/og-image.jpg", width: 1200, height: 630 }],
type: "website", // yoki "article" (blog)
url: "https://saytim.com/products/42",
siteName: "MyShop",
},
};
HAVOLA ULASHILGANDA (Open Graph'siz vs bilan):
Open Graph yo'q quruq havola (saytim.com/products/42) — hech kim bosmaydi
Open Graph bor CHIROYLI KARTA (rasm + sarlavha + tavsif) — ko'p bosiladi
OG RASM o'lchami: 1200×630px (standart — Telegram/Facebook/Twitter mos)
Open Graph — havola ijtimoiy tarmoqda chiroyli karta (rasm+title+tavsif) — ko'proq bosish
OG rasm 1200×630px; type (website/article); barcha asosiy sahifagaOpen Graph (ijtimoiy ulashish) — havola ijtimoiy tarmoqda qanday ko'rinishi. Open Graph — Facebook ixtiro qilgan, lekin endi barcha ijtimoiy tarmoq (Telegram, Twitter, LinkedIn, WhatsApp) ishlatadigan protokol: havola ulashilganda qanday ko'rinishini belgilaydi (karta — rasm, sarlavha, tavsif). Metadata'da
openGraphobyekti:title,description,images(ulashganda ko'rinadigan rasm — eng muhim — vizual jalb qiladi),type("website"yoki"article"— blog uchun),url(canonical havola),siteName(sayt nomi). Farq: Open Graph'siz — havola ulashilganda quruq matn (saytim.com/products/42— jozibasiz, hech kim bosmaydi); Open Graph bilan — chiroyli karta (katta rasm + qalin sarlavha + tavsif — Telegram/Facebook'da ko'rinadigan professional ko'rinish — ko'p bosiladi). OG rasm o'lchami — 1200×630px (standart — barcha platformada to'g'ri ko'rinadi — boshqa o'lcham kesilishi yoki noto'g'ri ko'rinishi mumkin). Ikki nuqta: (1) Open Graph — havola ijtimoiy tarmoqda chiroyli karta (rasm + title + tavsif — quruq havola o'rniga — ko'proq bosish, ko'proq trafik); (2) OG rasm 1200×630px,type(website/article), barcha asosiy sahifaga (bosh, mahsulot, blog post — ulashilishi mumkin bo'lgan). Bu — ijtimoiy marketing uchun muhim (mahsulot/maqola Telegram kanalda ulashilsa — chiroyli karta ko'proq odamni jalb qiladi). Real saytlar Open Graph'ga katta e'tibor beradi (har ulashish — bepul reklama, lekin faqat karta chiroyli bo'lsa). Open Graph'ni tekshirish uchun: Telegram'da o'zingizga havola yuborib ko'rish (karta ko'rinadimi).
2.5. Twitter Card va boshqa metadata
TWITTER CARD — Twitter/X'da maxsus ko'rinish (Open Graph'ni to'ldiradi):
export const metadata: Metadata = {
twitter: {
card: "summary_large_image", // katta rasmli karta (yoki "summary")
title: "Mahsulot nomi",
description: "...",
images: ["https://saytim.com/og.jpg"],
creator: "@myshop", // muallif/brand
},
};
BOSHQA MUHIM METADATA:
metadataBase: new URL("https://saytim.com"), // nisbiy URL'lar uchun asos (OG rasm to'liq URL)
alternates: { canonical: "https://saytim.com/products/42" }, // canonical 2.8-bob
robots: { index: true, follow: true }, // Google indekslasinmi 2.7-bob
keywords: ["telefon", "iPhone"], // (zamonaviy Google kam ishlatadi)
authors: [{ name: "Ali Valiyev" }],
themeColor: "#000000", // brauzer UI rangi (mobil)
Twitter Card — Twitter'da maxsus karta (Open Graph bilan birga); metadataBase — URL asos
metadataBase MUHIM (nisbiy OG rasm to'liq URL'ga aylanadi — aks holda ishlamaydi)Twitter Card va boshqa metadata — qo'shimcha platforma va sozlamalar. Twitter Card — Twitter/X'da havola maxsus ko'rinishi (Open Graph'ni to'ldiradi — Twitter o'z formatini afzal ko'radi):
twitter: { card: "summary_large_image", title, description, images, creator }—card("summary_large_image"— katta rasmli karta, yoki"summary"— kichik),creator(@username— muallif/brand). Boshqa muhim metadata: (1)metadataBase—new URL("https://saytim.com")— nisbiy URL'lar uchun asos (juda muhim — OG rasmni/og.jpgdeb yozsangiz, Next.js unihttps://saytim.com/og.jpgga aylantiradi —metadataBasesiz nisbiy rasm ishlamaydi); (2)alternates.canonical— canonical URL (takror kontent — 2.8); (3)robots—{ index: true, follow: true }(Google indekslasinmi, havolalarni kuzatsinmi — 2.7); (4)keywords(zamonaviy Google kam ishlatadi — ilgari muhim edi); (5)authors,themeColor(mobil brauzer UI rangi). Ikki nuqta: (1) Twitter Card — Twitter'da maxsus karta (Open Graph bilan birga — ikkalasini bersangiz har platformada chiroyli);metadataBase— URL asos (nisbiy URL'lar uchun); (2)metadataBasemuhim — nisbiy OG rasm to'liq URL'ga aylanishi uchun (eng keng unutiladigan narsa —metadataBasesiz OG rasm ishlamaydi, ijtimoiy ulashishda rasm ko'rinmaydi). Bu metadata'lar — saytni har platformada (Twitter, Facebook, Telegram) to'g'ri ko'rsatishning to'liq to'plami.metadataBaseni root layout'da bir marta belgilash yetarli (butun sayt uchun).
2.6. Sitemap va robots
SITEMAP — Google'ga "menda shu sahifalar bor" (qidiruv robotiga xarita):
// app/sitemap.ts /sitemap.xml avtomatik generatsiya
import type { MetadataRoute } from "next";
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const products = await db.product.findMany();
// Statik sahifalar:
const staticPages = [
{ url: "https://saytim.com", lastModified: new Date(), priority: 1 },
{ url: "https://saytim.com/about", lastModified: new Date(), priority: 0.8 },
];
// Dinamik (har mahsulot):
const productPages = products.map((p) => ({
url: `https://saytim.com/products/${p.id}`,
lastModified: p.updatedAt,
priority: 0.6,
}));
return [...staticPages, ...productPages];
}
// app/robots.ts /robots.txt (qaysi sahifani kezsin/kezmasin):
export default function robots(): MetadataRoute.Robots {
return {
rules: { userAgent: "*", allow: "/", disallow: ["/admin", "/api"] },
sitemap: "https://saytim.com/sitemap.xml",
};
}
sitemap.ts /sitemap.xml (Google'ga barcha sahifa xaritasi — tez/to'liq indekslash)
robots.ts /robots.txt (qaysi sahifa kezilsin — admin/api disallow)Sitemap va robots — qidiruv robotlari bilan muloqot. Sitemap (
sitemap.ts/sitemap.xml) — Google'ga saytdagi barcha sahifalar ro'yxatini beradi (xarita — "menda shu sahifalar bor, ularni indeksla"). Bu Googlebot'ga yordam beradi (havolalar bo'yicha yurib topishni kutmasdan — to'g'ridan ro'yxat — tezroq va to'liqroq indekslash).MetadataRoute.Sitemapqaytaradi: har sahifa uchunurl,lastModified(oxirgi o'zgarish — Google qachon qayta kezishni biladi),priority(muhimlik — bosh sahifa 1, ichki 0.6). Dinamik (har mahsulot, blog post) DB'dan generatsiya qilinadi (products.map(...)— har mahsulot uchun URL). Robots (robots.ts/robots.txt) — qaysi sahifani Googlebot kezsin/kezmasin:rules: { userAgent: "*", allow: "/", disallow: ["/admin", "/api"] }(hammasini kez, lekin/adminva/apini emas — bular qidiruvda bo'lishi keraksiz/xavfli), vasitemap(sitemap manzili — Google'ga ko'rsatish). Ikki nuqta: (1)sitemap.ts/sitemap.xml(Google'ga barcha sahifa xaritasi — tez va to'liq indekslash — ayniqsa katta, ko'p sahifali sayt uchun muhim); (2)robots.ts/robots.txt(qaysi sahifa kezilsin — admin/api/private'nidisallow— qidiruvda ko'rinmasin). Bular — SEO'ning texnik asosi (Google saytni to'liq va to'g'ri indekslashi uchun). Next.js bularni kod bilan generatsiya qiladi (statik fayl emas — dinamik — har mahsulot avtomatik sitemap'ga qo'shiladi). Google Search Console'da sitemap'ni yuborish (Google'ga xabar berish) — keyingi qadam.
2.7. robots meta va indekslashni boshqarish
INDEKSLASHNI BOSHQARISH — qaysi sahifa Google'da ko'rinsin/ko'rinmasin:
// Sahifa darajasida (robots metadata):
export const metadata: Metadata = {
robots: {
index: false, // bu sahifani INDEKSLAMA (qidiruvda ko'rinmasin)
follow: true, // lekin havolalarni kuzat
},
};
QACHON noindex (qidiruvda ko'rinmasin):
Admin panel, dashboard (login ortida — qidiruvda keraksiz)
Qidiruv natija sahifalari (/search?q=... — takror kontent)
Tashakkur/to'lov sahifalari (faqat oqim ichida)
Test/qoralama sahifalar
QACHON index (qidiruvda ko'rinsin — default):
Bosh sahifa, mahsulot, blog post, kategoriya (asosiy kontent)
┌────────────────────────────────────────────────────────────┐
│ index: true (default — ko'rinsin) | false (noindex — yashir)│
│ follow: havolalarni kuzatsinmi (link orqali boshqa sahifaga)│
└────────────────────────────────────────────────────────────┘
robots metadata — sahifa indekslansinmi (admin/qidiruv natija noindex)
Asosij kontent — index (default); shaxsiy/takror noindexrobots meta va indekslashni boshqarish — qaysi sahifa qidiruvda ko'rinishi.
robots.txt2.6-bob butun saytni boshqarsa, sahifa darajasidarobotsmetadata aniq nazorat beradi:robots: { index: false, follow: true }—index: false(bu sahifani indekslama — qidiruvda ko'rinmasin),follow: true(lekin sahifadagi havolalarni kuzat — boshqa sahifalarga o'tsin). Qachonnoindex(qidiruvda ko'rinmasin): (1) admin panel, dashboard (login ortida — qidiruvda keraksiz va xavfli); (2) qidiruv natija sahifalari (/search?q=...— har so'rov uchun alohida sahifa — takror, sifatsiz kontent — Google jazolaydi); (3) tashakkur/to'lov sahifalari (faqat oqim ichida — qidiruvda mantiqsiz); (4) test/qoralama sahifalar. Qachonindex(ko'rinsin — default): bosh sahifa, mahsulot, blog post, kategoriya (asosiy, qiymatli kontent — Google ko'rsatsin). Ikki nuqta: (1)robotsmetadata — sahifa indekslansinmi (admin/dashboard/qidiruv natijanoindex— ko'rinmasin); (2) asosiy kontent —index(default — ko'rinsin), shaxsiy/takrornoindex. Bu — SEO sifatini boshqarish (Google'ga faqat yaxshi sahifalarni ko'rsatish — sifatsiz/takror sahifalar reytingga zarar yetkazadi).follow/nofollowesa havolalarni kuzatishni boshqaradi (odatdafollow— havolalar Google uchun foydali). To'g'ri indekslash strategiyasi — sayt SEO sog'ligining muhim qismi (keraklisini ko'rsat, keraksizni yashir).
2.8. Strukturali ma'lumot (JSON-LD)
JSON-LD — strukturali ma'lumot (Google "BOY natijalar" — reyting, narx, FAQ):
// Mahsulot sahifasida JSON-LD (Google mahsulotni tushunadi):
export default function ProductPage({ product }) {
const jsonLd = {
"@context": "https://schema.org",
"@type": "Product",
name: product.name,
image: product.image,
description: product.description,
offers: {
"@type": "Offer",
price: product.price,
priceCurrency: "UZS",
availability: "https://schema.org/InStock",
},
aggregateRating: { "@type": "AggregateRating", ratingValue: 4.5, reviewCount: 120 },
};
return (
<main>
{/* JSON-LD'ni script orqali (Google o'qiydi — foydalanuvchi ko'rmaydi): */}
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
<h1>{product.name}</h1>
</main>
);
}
// Google qidiruvda: 4.5 (120 sharh) · 1,200,000 so'm · Mavjud — BOY natija (ajralib turadi)
JSON-LD — strukturali ma'lumot (Product/Article/FAQ) Google boy natija (reyting, narx)
schema.org tipi; script type="application/ld+json"; boy natija ko'proq bosiladi (CTR)Strukturali ma'lumot (JSON-LD) — Google "boy natijalar" uchun. JSON-LD (JavaScript Object Notation for Linked Data) — sahifa kontentini strukturali (mashina o'qiydigan) shaklda Google'ga berish — natijada Google "boy natijalar" (rich results) ko'rsatadi (yulduzli reyting, narx, mavjudlik, FAQ — to'g'ridan qidiruvda, havola ostida). Misol: mahsulot sahifasida
jsonLdobyekti (@context: schema.org,@type: "Product",name,image,offers— narx,aggregateRating— reyting), va uni<script type="application/ld+json">ichida (Google o'qiydi, foydalanuvchi ko'rmaydi — yashirin metama'lumot). Natija: Google qidiruvda oddiy ko'k havola o'rniga boy natija ko'rsatadi —4.5 (120 sharh) · 1,200,000 so'm · Mavjud— bu havolani ajratib turadi (rangli yulduzlar, narx — ko'zga tashlanadi — ko'proq bosiladi — CTR yuqori). Tiplar (schema.org):Product(mahsulot — narx, reyting),Article(maqola — muallif, sana),FAQPage(savol-javob — to'g'ridan qidiruvda ochiladi),Recipe(retsept),Event,Organization,BreadcrumbList. Ikki nuqta: (1) JSON-LD — strukturali ma'lumot (Product/Article/FAQ— schema.org) Google boy natija (reyting, narx, FAQ — qidiruvda ko'rinadi); (2)script type="application/ld+json", schema.org tipi; boy natija havola ajralib turadi ko'proq bosiladi (CTR oshadi — bepul trafik). Bu — SEO'ning ilg'or, lekin juda ta'sirli qismi (e-commerce mahsulot reytingi, retsept sayti, FAQ — boy natija bilan qidiruvda hukmronlik qiladi). Google'ning "Rich Results Test" vositasi bilan tekshirsa bo'ladi (JSON-LD to'g'rimi). JSON-LD — qidiruvda vizual ustunlikning kaliti.
2.9. OG rasm generatsiyasi (next/og)
next/og — OG rasmni DINAMIK generatsiya (har mahsulot/post uchun avtomatik rasm):
MUAMMO: har mahsulot/post uchun qo'lda OG rasm yasash — imkonsiz (minglab)
YECHIM: next/og bilan KODDAN rasm generatsiya (sarlavha, narx — avtomatik chiziladi):
// app/products/[id]/opengraph-image.tsx
import { ImageResponse } from "next/og";
export default async function OGImage({ params }) {
const { id } = await params;
const product = await fetch(`/api/products/${id}`).then((r) => r.json());
return new ImageResponse(
(
<div style={{ display: "flex", flexDirection: "column", width: "100%", height: "100%",
background: "#fff", padding: 60, justifyContent: "center" }}>
<h1 style={{ fontSize: 60 }}>{product.name}</h1> {/* mahsulot nomi rasmda */}
<p style={{ fontSize: 40, color: "#0070f3" }}>{product.price} so'm</p>
</div>
),
{ width: 1200, height: 630 } // standart OG o'lcham 2.4-bob
);
}
// har mahsulot uchun avtomatik chizilgan OG rasm (sarlavha + narx)
next/og (ImageResponse) — OG rasmni KODDAN dinamik generatsiya (har element o'z rasmi)
JSX rasm (sarlavha, narx avtomatik); 1200×630; qo'lda minglab rasm yasash shart emasOG rasm generatsiyasi (next/og) — har element uchun avtomatik ijtimoiy rasm. Muammo: Open Graph rasmi 2.4-bob ijtimoiy ulashishda juda muhim, lekin har mahsulot/blog post uchun qo'lda rasm yasash (Photoshop'da minglab rasm) — imkonsiz. Yechim —
next/og(ImageResponse): OG rasmni koddan (JSX bilan) dinamik generatsiya qilish. Fayl:app/products/[id]/opengraph-image.tsx(maxsus fayl nomi — Next.js uni o'sha sahifaning OG rasmi sifatida ishlatadi), ichidaImageResponse— JSX (<div>sarlavha, narx bilan) rasmga aylantiriladi (server'da). Misol: har mahsulot uchun<h1>{product.name}</h1>+<p>{product.price} so'm</p>— avtomatik chizilgan rasm (mahsulot nomi va narxi bilan — 1200×630 — standart OG o'lcham). Natija: har mahsulotning o'z OG rasmi (nomi va narxi yozilgan) — qo'lda yasamasdan (minglab mahsulot uchun avtomatik). Telegram'da ulashilsa — har mahsulot o'z noyob, chiroyli kartasi bilan ko'rinadi. Ikki nuqta: (1)next/og(ImageResponse) — OG rasmni koddan dinamik generatsiya (har element o'z rasmi — qo'lda emas); (2) JSX rasm (sarlavha, narx avtomatik chiziladi), 1200×630, minglab rasm qo'lda yasash shart emas. Bu — zamonaviy saytlarning (blog, e-commerce platformalari) keng ishlatadigan texnikasi (har maqola/mahsulot o'z brendlangan OG rasmi bilan — professional, izchil).opengraph-image.tsx(statik OG rasm uchun) yokigenerateImageMetadata(bir necha rasm) ham bor. Bu — ijtimoiy ulashishni miqyosda (scale) avtomatlashtirishning usuli (qo'lda imkonsizni kod bilan).
2.10. SEO best practices va semantik HTML
SEMANTIK HTML — Google kontentni TUSHUNISHi uchun to'g'ri teglar:
NOTO'G'RI (div'lar — Google strukturani tushunmaydi):
<div class="title">Sarlavha</div>
<div class="nav">...</div>
TO'G'RI (semantik teglar — Google ma'noni biladi):
<header>, <nav>, <main>, <article>, <section>, <aside>, <footer>
<h1> (sahifada BITTA — asosiy sarlavha), <h2>, <h3> (ierarxiya)
<a href> (havola — Google kuzatadi), <button> (amal)
SEO BEST PRACTICES:
Har sahifa noyob title + description (60/160 belgi — 2.2, 2.3)
Bitta <h1> har sahifada (asosiy mavzu); ierarxik h2/h3
Open Graph + Twitter (ijtimoiy — 2.4, 2.5); metadataBase
sitemap.ts + robots.ts 2.6-bob
JSON-LD asosiy kontentga (mahsulot, maqola — 2.8)
Tez sayt (Core Web Vitals — 13.7: 2.9); rasm alt (a11y+SEO)
lang="uz" (<html>); canonical (takror kontent — 2.5)
Server render (SSR/SSG — Google ko'radi — 2.1)
Semantik HTML — Google kontent strukturasini tushunadi (div emas — header/main/article)
Best: noyob meta + h1 + OG + sitemap + JSON-LD + tez + semantik + server renderSEO best practices va semantik HTML — SEO'ning amaliy yakuni. Semantik HTML — to'g'ri ma'noli teglar ishlatish (Google kontent strukturasini tushunishi uchun):
<div>lar o'rniga<header>(sarlavha qismi),<nav>(navigatsiya),<main>(asosiy kontent),<article>(mustaqil kontent — blog post),<section>(bo'lim),<aside>(yon panel),<footer>(pastki qism);<h1>(sahifada bitta — asosiy sarlavha),<h2>/<h3>(ierarxiya — bo'limlar);<a href>(havola — Google kuzatadi),<button>(amal). Google bu teglardan kontent strukturasini tushunadi (<h1>— sahifa nima haqida,<nav>— navigatsiya,<article>— asosiy maqola). SEO best practices (butun bobni umumlashtiradi): (1) har sahifa noyobtitle(60 belgi) +160 belgi — 2.2, 2.3); (2) bittadescription(<h1>har sahifada (asosiy mavzu), ierarxik<h2>/<h3>; (3) Open Graph + Twitter (ijtimoiy — 2.4, 2.5),metadataBase; (4)sitemap.ts+robots.ts2.6-bob; (5) JSON-LD asosiy kontentga (mahsulot, maqola — 2.8); (6) tez sayt (Core Web Vitals — 13.7: 2.9), rasmalt(a11y + SEO); (7)lang="uz"(<html>— til), canonical (takror kontent — 2.5); (8) server render (SSR/SSG — Google ko'radi — 2.1). Ikki nuqta: (1) semantik HTML — Google kontent strukturasini tushunadi (<div>emas —<header>/<main>/<article>— ma'noli teglar); (2) best: noyob meta + bitta h1 + OG + sitemap + JSON-LD + tez + semantik + server render (birga — kuchli SEO). Bu — SEO'ning to'liq nazorat ro'yxati (har biri kichik, lekin birga sayt Google'da yuqori chiqadi). SEO — bir marta qilinadigan emas, doimiy ish (kontent, tezlik, struktura — uzluksiz yaxshilash). Next.js bularning texnik qismini (server render, metadata, sitemap) oson qiladi, kontent sifati esa sizning zimmangizda.
2.11. Favicon va ikonlar (fayl konvensiyasi)
IKONLAR — brauzer tab'i, xatcho'p, telefon ekrani ikonasi (fayl nomi bilan):
app/
├── favicon.ico klassik favicon (brauzer tab, xatcho'p — barcha brauzer)
├── icon.png zamonaviy ikona (yoki icon.svg — <link rel="icon">)
├── apple-icon.png iOS "Bosh ekranga qo'shish" ikonasi (180×180)
└── icon.tsx ikonani KODDAN generatsiya (ImageResponse — 2.9 kabi)
Next.js bu fayllarni AVTOMATIK topadi va HTML <head>'ga <link> qo'shadi:
// <link rel="icon" href="/favicon.ico" sizes="any">
// <link rel="icon" href="/icon.png" type="image/png">
// <link rel="apple-touch-icon" href="/apple-icon.png">
Ikona — fayl nomi konvensiyasi (favicon.ico / icon.png / apple-icon.png — app/'da)
Next.js avtomatik <link> qo'shadi (metadata'da qo'lda yozish shart emas)Favicon va ikonlar (fayl konvensiyasi) — sayt ikonalari. Favicon — brauzer tab'ida, xatcho'plarda, qidiruv natijalarida ko'rinadigan kichik ikona (brend belgisi — sayt taniladi). Next.js ikonalarni fayl nomi konvensiyasi orqali boshqaradi (
app/papkasiga maxsus nomli fayl qo'yiladi — Next.js uni avtomatik topadi va HTML<head>ga tegishli<link>qo'shadi — qo'ldametadatada yozish shart emas): (1)favicon.ico— klassik favicon (barcha brauzer, xatcho'p — eng keng qo'llab-quvvatlanadigan format); (2)icon.pngyokiicon.svg— zamonaviy ikona (<link rel="icon">); (3)apple-icon.png— iOS'da "Bosh ekranga qo'shish" bosilganda ishlatiladigan ikona (tavsiya etilgan o'lcham 180×180); (4)icon.tsx— ikonani koddan generatsiya qilish (ImageResponse— OG rasm kabi — 2.9). Ikki nuqta: (1) ikona — fayl nomi konvensiyasi (favicon.ico/icon.png/apple-icon.png—app/ildiziga); (2) Next.js avtomatik<link>qo'shadi (metadata'da qo'lda yozish shart emas — faqat to'g'ri nomli faylni joylashtirish yetarli). Favicon — SEO'ga bevosita ta'sir qilmaydi, lekin brend taniqligini oshiradi (qidiruv natijalarida, tab'da ikona — professional ko'rinish, ishonch).
2.12. Viewport va themeColor (alohida eksport)
VIEWPORT — mobil ko'rinish va tema rangi (metadata'dan ALOHIDA export):
// app/layout.tsx — viewport ALOHIDA export (metadata bilan emas)
import type { Viewport } from "next";
export const viewport: Viewport = {
width: "device-width", // mobil ekran kengligiga moslash (responsiv)
initialScale: 1, // boshlang'ich zoom (1 = normal)
themeColor: "#0070f3", // brauzer UI rangi (mobil — manzil paneli)
colorScheme: "light dark", // yorug'/qorong'i tema qo'llab-quvvatlash
};
Next.js buni HTML <head>'ga qo'yadi:
// <meta name="viewport" content="width=device-width, initial-scale=1">
// <meta name="theme-color" content="#0070f3">
viewport/themeColor — ALOHIDA export const viewport (metadata ichida EMAS — Next 14+)
width=device-width — mobil responsiv (majburiy); themeColor — mobil brauzer UI rangiViewport va themeColor (alohida eksport) — mobil ko'rinish sozlamalari. Ilgari
themeColorvaviewportmetadataobyekti ichida edi, lekin zamonaviy Next.js'da ular alohidaexport const viewportga ko'chirildi (chunki bu qiymatlar renderda boshqacha ishlanadi — ularni ajratish samaraliroq).export const viewport: Viewport: (1)width: "device-width"— sahifa mobil ekran kengligiga moslashsin (responsiv dizayn uchun majburiy — busiz mobil'da sayt kichik va noqulay ko'rinadi, bu esa Google mobil reytingiga zarar — Google mobil-first indekslaydi); (2)initialScale: 1— boshlang'ich masshtab (zoom 1 — normal); (3)themeColor— mobil brauzer UI rangi (manzil paneli, status bar — brend rangiga bo'yaladi — professional mobil ko'rinish); (4)colorScheme— yorug'/qorong'i tema qo'llab-quvvatlash.themeColorni tema (yorug'/qorong'i) bo'yicha ham berish mumkin ([{ media: "(prefers-color-scheme: dark)", color: "#000" }]). Ikki nuqta: (1)viewport/themeColor— alohidaexport const viewport(metadata ichida emas — zamonaviy Next.js talabi — eski koddagimetadata.themeColorogohlantirish beradi); (2)width=device-width— mobil responsivlik (Google mobil-first — majburiy),themeColor— mobil brauzer UI rangi. Bu — mobil UX va mobil SEO uchun muhim (Google saytni asosan mobil versiyasi bo'yicha baholaydi).
2.13. manifest.json (PWA)
MANIFEST — sayt "ilovaga o'xshab" o'rnatilishi uchun (PWA — Progressive Web App):
// app/manifest.ts /manifest.webmanifest (avtomatik)
import type { MetadataRoute } from "next";
export default function manifest(): MetadataRoute.Manifest {
return {
name: "MyShop — Onlayn do'kon", // to'liq nom
short_name: "MyShop", // qisqa nom (bosh ekran ikonasi ostida)
description: "O'zbekistondagi onlayn do'kon",
start_url: "/", // ilova ochilganda qaysi sahifa
display: "standalone", // brauzer UI'siz (ilovaga o'xshab)
background_color: "#ffffff",
theme_color: "#0070f3",
icons: [
{ src: "/icon-192.png", sizes: "192x192", type: "image/png" },
{ src: "/icon-512.png", sizes: "512x512", type: "image/png" },
],
};
}
manifest.ts /manifest.webmanifest (PWA — sayt telefon bosh ekraniga o'rnatiladi)
display: standalone (brauzer UI'siz — ilovaga o'xshaydi); icons (bosh ekran ikonasi)manifest.json (PWA) — saytni ilovaga aylantirish. PWA (Progressive Web App — progressiv veb-ilova) — veb-saytni telefon/kompyuterda ilovaga o'xshab o'rnatish imkoni (bosh ekranga ikona qo'yiladi, brauzer manzil panelisiz to'liq ekranda ochiladi — mahalliy ilova taassuroti). Buning uchun web manifest kerak:
app/manifest.ts/manifest.webmanifest(Next.js avtomatik generatsiya).MetadataRoute.Manifestqaytaradi:name(to'liq nom),short_name(bosh ekran ikonasi ostida ko'rinadigan qisqa nom),start_url(ilova ochilganda qaysi sahifa yuklansin),display: "standalone"(brauzer UI'siz — ilovaga o'xshab ochiladi — PWA'ning asosiy belgisi),theme_color/background_color(ranglar),icons(turli o'lchamdagi ikonalar — bosh ekran uchun 192×192 va 512×512). Ikki nuqta: (1)manifest.ts/manifest.webmanifest(PWA — sayt telefon bosh ekraniga o'rnatiladi, ilova kabi ochiladi); (2)display: standalone(brauzer UI'siz),icons(bosh ekran ikonasi). PWA to'liq bo'lishi uchun manifest'dan tashqari service worker (offlayn ishlash) ham kerak (bu alohida mavzu), lekin manifest — birinchi qadam (o'rnatiladigan, ilovaga o'xshash sayt). Bu — mobil foydalanuvchi tajribasini yaxshilaydi (takroriy foydalanuvchi saytni ilova kabi ochadi — ko'proq qaytish).
2.14. Core Web Vitals, metadata streaming va indekslash
PERFORMANCE SEO — Google reyting omili sifatida tezlik (Core Web Vitals):
CORE WEB VITALS (Google reyting omili — 13.7-bob):
┌──────┬────────────────────────────┬─────────┬──────────┬─────────┐
│ LCP │ eng katta element yuklandi │ ≤2.5s │ ≤4s │ >4s │
│ INP │ bosishga javob (yangi FID) │ ≤200ms │ ≤500ms │ >500ms │
│ CLS │ layout siljishi (barqaror) │ ≤0.1 │ ≤0.25 │ >0.25 │
└──────┴────────────────────────────┴──yaxshi─┴─o'rtacha─┴──yomon──┘
METADATA STREAMING (Next.js): generateMetadata sekin bo'lsa (DB kutadi),
sahifa kontenti bloklanmaydi — Next.js metadata'ni oqim (stream) bilan yuboradi
sahifa tez ko'rinadi, metadata tayyor bo'lganda <head>'ga qo'shiladi
INDEKSLASH (Google Search Console):
sitemap.xml'ni yuborish (Google'ga "menda shu sahifalar bor")
indekslash holatini kuzatish (qaysi sahifa indekslandi/xato)
"URL Inspection" — bitta URL Google qanday ko'rishini tekshirish
Core Web Vitals (LCP/INP/CLS) — Google reyting omili (tez sayt = yuqori o'rin)
Search Console — sitemap yuborish + indekslashni kuzatish (SEO'ning amaliy nazorati)Core Web Vitals, metadata streaming va indekslash — SEO'ning tezlik va nazorat tomoni. Core Web Vitals — Google'ning rasmiy tezlik ko'rsatkichlari (reyting omili — tez sayt Google'da yuqoriroq — 13.7-bobda chuqur): (1) LCP (Largest Contentful Paint — eng katta kontent elementi yuklanishi — sahifa "yuklandi" tuyg'usi; yaxshi ≤2.5s, yomon >4s); (2) INP (Interaction to Next Paint — foydalanuvchi bosishiga javob tezligi, eski FID o'rniga; yaxshi ≤200ms); (3) CLS (Cumulative Layout Shift — sahifa yuklanayotganda elementlarning siljishi — barqarorlik; yaxshi ≤0.1). Ikkalasi ham "yaxshi" bo'lsa — Google reytingda ustunlik beradi (ayniqsa yaqin natijalar orasida). Metadata streaming — Next.js'ning muhim xususiyati:
generateMetadatasekin bo'lsa (DB'dan ma'lumot kutsa), u sahifa kontentini bloklamaydi — Next.js metadata'ni oqim (stream) orqali yuboradi (sahifa tez ko'rinadi, metadata tayyor bo'lganda<head>ga qo'shiladi) — bu tezlikka (LCP) yordam beradi. Indekslash nazorati (Google Search Console — Google'ning bepul vositasi): (1)sitemap.xml'ni Google'ga yuborish (rasmiy xabar — "menda shu sahifalar bor" — 2.6); (2) indekslash holatini kuzatish (qaysi sahifa indekslandi, qaysi biri xato bilan — masalannoindexyokirobots.txtblokladimi); (3) "URL Inspection" — bitta URL Google qanday ko'rishini tekshirish (metadata, kontent to'g'ri ko'rinadimi). Ikki nuqta: (1) Core Web Vitals (LCP/INP/CLS) — Google reyting omili (tez, barqaror sayt = yuqori o'rin — 13.7 bilan bog'liq); (2) Search Console — sitemap yuborish va indekslashni kuzatish (SEO nazoratining amaliy vositasi). SEO — faqat kod emas, doimiy kuzatish ham (Search Console orqali Google saytni qanday ko'rayotganini bilib, muammolarni tuzatish).
3. Sintaksis — tez ma'lumotnoma
STATIK META 2.2-bob: export const metadata: Metadata = { title, description }
DINAMIK 2.3-bob: export async function generateMetadata({ params }): Promise<Metadata>
TEMPLATE 2.2-bob: title: { default: "X", template: "%s — X" }
OPEN GRAPH 2.4-bob: openGraph: { title, description, images: [{ url, width:1200, height:630 }] }
TWITTER 2.5-bob: twitter: { card: "summary_large_image", images }
BASE 2.5-bob: metadataBase: new URL("https://saytim.com")
SITEMAP 2.6-bob: app/sitemap.ts MetadataRoute.Sitemap
ROBOTS 2.6-bob: app/robots.ts MetadataRoute.Robots; robots: { index, follow }
JSON-LD 2.8-bob: <script type="application/ld+json"> (schema.org)
OG RASM 2.9-bob: app/.../opengraph-image.tsx ImageResponse (1200×630)
IKONA 2.11-bob: app/favicon.ico | icon.png | apple-icon.png (fayl konvensiyasi)
VIEWPORT 2.12-bob: export const viewport: Viewport = { width, initialScale, themeColor }
MANIFEST 2.13-bob: app/manifest.ts MetadataRoute.Manifest (PWA)
CANONICAL 2.5-bob: alternates: { canonical: "/path" }
HREFLANG 2.10-bob: alternates: { languages: { uz: "...", en: "..." } }4. Batafsil kod namunalari
Har misol: Maqsad + izohli kod + "Bu kod nima qiladi".
Misol 1 — Root layout metadata (umumiy SEO — 2.2, 2.5)
Maqsad: Butun sayt uchun asosiy metadata'ni belgilash — title template, default OG, metadataBase. Bu har sahifa meros oladigan SEO poydevori.
// app/layout.tsx — butun sayt uchun metadata asosi
import type { Metadata } from "next";
export const metadata: Metadata = {
metadataBase: new URL("https://myshop.uz"), // nisbiy URL'lar uchun asos (2.5)
title: {
default: "MyShop — Onlayn do'kon", // sarlavha berilmagan sahifalap
template: "%s — MyShop", // %s = sahifa title (avtomatik brend)
},
description: "O'zbekistondagi eng yaxshi onlayn do'kon. Tez yetkazib berish, sifatli mahsulotlar.",
openGraph: {
siteName: "MyShop",
locale: "uz_UZ",
type: "website",
},
twitter: { card: "summary_large_image" },
robots: { index: true, follow: true }, // default — indekslansin
};
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="uz"> {/* til (SEO + a11y — 2.10) */}
<body>{children}</body>
</html>
);
}Bu kod nima qiladi: Bu — butun saytning SEO poydevori (root layout metadata — har sahifa meros oladi). metadata obyektida: (1) metadataBase (new URL("https://myshop.uz")) — nisbiy URL'lar uchun asos (juda muhim — 2.5 — OG rasmni /og.jpg deb yozsangiz, Next.js uni https://myshop.uz/og.jpgga aylantiradi — metadataBasesiz ijtimoiy ulashishda rasm ishlamaydi); (2) title — { default, template } 2.2-bob: default (sarlavha berilmagan sahifalar uchun "MyShop — Onlayn do'kon"), template: "%s — MyShop" (har sahifa o'z title'iga brend avtomatik qo'shadi — mahsulot "iPhone 15" "iPhone 15 — MyShop" — izchillik); (3) description (umumiy tavsif); (4) openGraph (siteName, locale: "uz_UZ" — o'zbek tili, type: "website" — ijtimoiy ulashish asosi); (5) twitter (karta turi); (6) robots (default — indekslansin). Va <html lang="uz"> — sayt tili (SEO — Google o'zbek tilidagi qidiruvda ko'rsatadi; accessibility — ekran o'qiguvchi to'g'ri o'qiydi — 2.10). Bu metadata butun saytga taalluqli (har sahifa buni meros oladi va o'ziniki bilan to'ldiradi/almashtiradi — masalan har sahifa o'z titleini bersa, template orqali brend qo'shiladi). Demak root layout — SEO'ning "default sozlamalari" (har sahifa shundan boshlaydi). Bu — har Next.js loyihaning birinchi SEO qadami (root metadata — metadataBase, title template, default OG, til). Bir marta to'g'ri sozlab, butun sayt undan foydalanadi.
Misol 2 — Dinamik mahsulot metadata (2.3, 2.4)
Maqsad: Har mahsulot uchun noyob, to'liq metadata (title, description, OG rasm) — generateMetadata bilan. Bu e-commerce SEO'ning yuragi (har mahsulot Google'da alohida).
// app/products/[id]/page.tsx
import type { Metadata } from "next";
import { notFound } from "next/navigation";
export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise<Metadata> {
const { id } = await params;
const product = await fetch(`https://api.myshop.uz/products/${id}`).then((r) => r.json());
if (!product) return { title: "Mahsulot topilmadi" };
return {
title: product.name, // template orqali "...— MyShop" bo'ladi (Misol 1)
description: product.description.slice(0, 160), // 160 belgi (Google optimal)
openGraph: {
title: product.name,
description: product.description.slice(0, 160),
images: [{ url: product.image, width: 1200, height: 630 }], // mahsulot rasmi
type: "website",
},
alternates: { canonical: `/products/${id}` }, // canonical (takror oldini — 2.5)
};
}
export default async function ProductPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
const product = await fetch(`https://api.myshop.uz/products/${id}`).then((r) => r.json());
if (!product) notFound();
return <main><h1>{product.name}</h1>{/* ... */}</main>;
}Bu kod nima qiladi: Bu — e-commerce SEO'ning yuragi (har mahsulot noyob metadata — Google har birini alohida indekslaydi). generateMetadata (2.3 — async, dinamik): mahsulotni fetch qilib, undan metadata yasaydi: (1) title (product.name — mahsulot nomi; root layout template orqali "iPhone 15 — MyShop" bo'ladi — Misol 1); (2) description (product.description.slice(0, 160) — mahsulot tavsifi, 160 belgi — Google qidiruvda shuncha ko'rsatadi); (3) openGraph (ijtimoiy ulashish — mahsulot nomi, tavsif, va rasm — product.image — Telegram'da ulashilsa mahsulot rasmi bilan chiroyli karta — 2.4); (4) alternates.canonical (/products/${id} — bu mahsulotning "asosiy" URL'i — agar bir mahsulot bir necha URL bilan ochilsa — masalan ?ref=... query bilan — Google ularni takror deb hisoblamasin, asosiy URL'ni biladi — 2.5). Eng muhim: generateMetadatada va pageda bir xil fetch (mahsulotni olish) — Next.js uni dedup qiladi (Request Memoization — 13.5: 2.3 — DB'ga bir marta boradi, ikki emas — generateMetadata va page ikki marta so'rov yubormaydi). Natija: har mahsulot sahifasi o'z noyob title, description, OG rasmi bilan (Google har mahsulotni alohida, to'g'ri indekslaydi; Telegram'da har mahsulot chiroyli karta bilan ulashiladi). Bu — minglab mahsulotli e-commerce sayt uchun majburiy (har mahsulot Google'da o'z so'rovi bilan topilishi uchun — masalan "iPhone 15 narxi" qidiruvida sizning mahsulot sahifangiz chiqishi uchun). Dinamik metadata — ko'p sahifali sayt SEO'sining asosi.
Misol 3 — Sitemap (dinamik — 2.6)
Maqsad: Barcha sahifani (statik + dinamik) o'z ichiga olgan sitemap generatsiya qilish — Google to'liq indekslashi uchun. Bu katta saytda muhim (Google barcha sahifani topsin).
// app/sitemap.ts /sitemap.xml (avtomatik)
import type { MetadataRoute } from "next";
import { db } from "@/lib/db";
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
// 1. Statik sahifalar (qo'lda):
const staticRoutes: MetadataRoute.Sitemap = [
{ url: "https://myshop.uz", lastModified: new Date(), changeFrequency: "daily", priority: 1 },
{ url: "https://myshop.uz/about", lastModified: new Date(), changeFrequency: "monthly", priority: 0.5 },
{ url: "https://myshop.uz/products", lastModified: new Date(), changeFrequency: "daily", priority: 0.9 },
];
// 2. Dinamik — har mahsulot (DB'dan):
const products = await db.product.findMany({ select: { id: true, updatedAt: true } });
const productRoutes: MetadataRoute.Sitemap = products.map((p) => ({
url: `https://myshop.uz/products/${p.id}`,
lastModified: p.updatedAt, // mahsulot oxirgi yangilangan vaqt
changeFrequency: "weekly",
priority: 0.7,
}));
// 3. Dinamik — har blog post:
const posts = await db.post.findMany({ select: { slug: true, updatedAt: true } });
const postRoutes: MetadataRoute.Sitemap = posts.map((p) => ({
url: `https://myshop.uz/blog/${p.slug}`,
lastModified: p.updatedAt,
priority: 0.6,
}));
return [...staticRoutes, ...productRoutes, ...postRoutes]; // hammasi birga
}Bu kod nima qiladi: Bu — to'liq, dinamik sitemap (Google saytdagi barcha sahifani topishi uchun — 2.6). app/sitemap.ts /sitemap.xml (Next.js avtomatik XML generatsiya qiladi). Funksiya uch qismni birlashtiradi: (1) statik sahifalar (qo'lda — bosh, about, products ro'yxati) — har biri url, lastModified (oxirgi o'zgarish), changeFrequency (qancha tez o'zgaradi — Google qachon qayta kelishni biladi — bosh sahifa daily, about monthly), priority (muhimlik — bosh 1, about 0.5); (2) dinamik mahsulotlar — DB'dan barcha mahsulotni olib (db.product.findMany), har biri uchun URL generatsiya (products.map — /products/${p.id}, lastModified: p.updatedAt — mahsulot qachon yangilangan); (3) dinamik blog postlar — xuddi shunday (/blog/${p.slug}). Hammasi birlashadi ([...staticRoutes, ...productRoutes, ...postRoutes]). Natija: /sitemap.xml — saytdagi har bir sahifa (statik + minglab mahsulot + blog post) ro'yxati, Google'ga to'liq xarita beradi. Nega muhim: Googlebot havolalar bo'yicha yurib sahifalarni topadi (crawl — 2.1), lekin katta saytda ba'zi sahifalar havolasiz qolishi mumkin (masalan eski mahsulot) — sitemap kafolatlaydi (har sahifa ro'yxatda — Google topadi). Va lastModified — Google qachon qayta indekslashni biladi (o'zgargan sahifani tez qayta kezadi). Dinamik sitemap (DB'dan) — yangi mahsulot qo'shilsa avtomatik sitemap'ga tushadi (qo'lda yangilash yo'q). Bu — katta, ko'p sahifali sayt SEO'sining texnik asosi (Google'ga "menda shu sahifalar bor — hammasini indeksla"). Google Search Console'da sitemap URL'ini yuborish — Google'ga rasmiy xabar.
Misol 4 — robots.txt (2.6, 2.7)
Maqsad: Qidiruv robotlariga qaysi sahifani kezish/kezmaslikni aytish — robots.ts. Bu admin/private sahifani qidiruvdan yashiradi.
// app/robots.ts /robots.txt (avtomatik)
import type { MetadataRoute } from "next";
export default function robots(): MetadataRoute.Robots {
return {
rules: [
{
userAgent: "*", // barcha robot (Google, Bing...)
allow: "/", // hamma sahifani kez (default)
disallow: [
"/admin", // admin panel — qidiruvda YO'Q
"/api/", // API endpointlar — kezilmasin
"/dashboard", // shaxsiy dashboard
"/checkout", // to'lov oqimi (faqat oqim ichida)
"/*?*", // query'li URL'lar (takror — ixtiyoriy)
],
},
],
sitemap: "https://myshop.uz/sitemap.xml", // sitemap manzili (Google'ga ko'rsat)
host: "https://myshop.uz", // asosiy domen
};
}Bu kod nima qiladi: Bu — qidiruv robotlarini boshqarish (qaysi sahifani kezsin/kezmasin — 2.6, 2.7). app/robots.ts /robots.txt (Next.js avtomatik generatsiya — bu standart fayl, har qidiruv roboti birinchi o'qiydi). rules: (1) userAgent: "*" — barcha robotga (Google, Bing, Yandex — hammasiga); (2) allow: "/" — hamma sahifani kezishga ruxsat (default — asosiy kontent indekslansin); (3) disallow — qaysi sahifani kezmaslik: /admin (admin panel — qidiruvda bo'lishi xavfli va keraksiz), /api/ (API endpointlar — sahifa emas, kezilmasin), /dashboard (shaxsiy — login ortida), /checkout (to'lov oqimi — faqat xarid jarayonida), /*?* (query'li URL'lar — masalan filtr ?category=... — takror kontent — ixtiyoriy). Va sitemap (sitemap manzili — Google'ga "to'liq xarita shu yerda" — 2.6), host (asosiy domen). Nega muhim: (1) xavfsizlik/maxfiylik — admin/dashboard qidiruvda ko'rinsa, yomon niyatli odamlar topishi oson (robots.txt bilan yashirish — birinchi qatlam, lekin haqiqiy himoya auth — 13.9); (2) SEO sifati — API, takror query sahifalari indekslansa, Google "sifatsiz sayt" deb hisoblashi mumkin (faqat yaxshi sahifani ko'rsatish — reyting yaxshi); (3) crawl byudjeti — Google har saytga cheklangan vaqt ajratadi (crawl budget) — keraksiz sahifalarga sarflamaclik (asosiy kontentga yo'naltirish). Diqqat: robots.txt — "iltimos" (Google hurmat qiladi, lekin yomon botlar e'tibor bermacliki mumkin) — shuning uchun maxfiy ma'lumot faqat robots.txt bilan emas, auth bilan himoyalanishi shart 13.9-bob. robots.txt — SEO uchun (qidiruvda nima ko'rinsin), xavfsizlik uchun emas. Bu — sitemap (Misol 3) bilan birga SEO'ning texnik asosi.
Misol 5 — JSON-LD strukturali ma'lumot (2.8)
Maqsad: Mahsulot uchun JSON-LD qo'shish — Google boy natija (reyting, narx) ko'rsatishi uchun. Bu qidiruvda havolani ajratib turadi (CTR oshadi).
// app/products/[id]/page.tsx — JSON-LD bilan
export default async function ProductPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
const product = await fetch(`https://api.myshop.uz/products/${id}`).then((r) => r.json());
// Strukturali ma'lumot (schema.org — Google tushunadi):
const jsonLd = {
"@context": "https://schema.org",
"@type": "Product",
name: product.name,
image: product.image,
description: product.description,
sku: product.sku,
brand: { "@type": "Brand", name: product.brand },
offers: {
"@type": "Offer",
url: `https://myshop.uz/products/${id}`,
priceCurrency: "UZS",
price: product.price,
availability: product.inStock ? "https://schema.org/InStock" : "https://schema.org/OutOfStock",
},
aggregateRating: product.reviewCount > 0 ? {
"@type": "AggregateRating",
ratingValue: product.rating, // o'rtacha reyting (4.5)
reviewCount: product.reviewCount, // sharhlar soni (120)
} : undefined,
};
return (
<main>
{/* JSON-LD'ni <script>Bu kod nima qiladi: Bu — JSON-LD strukturali ma'lumot (Google boy natija — 2.8). jsonLd obyekti — mahsulot ma'lumotini schema.org standartida (Google tushunadigan "til"da) tasvirlaydi: @type: "Product" (bu mahsulot), name/image/description (asosiy), brand (ishlab chiqaruvchi), offers (sotuv — price, priceCurrency: "UZS" — so'm, availability — mavjudmi), aggregateRating (o'rtacha reyting 4.5 va sharhlar soni 120 — agar sharh bo'lsa). Bu obyekt <script type="application/ld+json"> ichida JSON sifatida joylashtiriladi (Google o'qiydi — qidiruv roboti buni tushunadi; foydalanuvchi ko'rmaydi — yashirin metama'lumot — 2.8). Natija: Google qidiruvda sizning mahsulot havolasini oddiy ko'k havola o'rniga boy natija ko'rsatadi — 4.5 (120 sharh) · 1,200,000 so'm · Mavjud — yulduzli reyting, narx, mavjudlik to'g'ridan qidiruvda. Bu havolani ajratib turadi (rangli yulduzlar, narx — boshqa quruq havolalar orasida ko'zga tashlanadi), natijada ko'proq bosiladi (CTR — Click-Through Rate — oshadi — bepul trafik). E-commerce uchun bu juda kuchli (mahsulot reytingi qidiruvda ko'rinsa — ishonch, ko'proq xarid). availability shartli (inStock ? InStock : OutOfStock — to'g'ri holat), aggregateRating shartli (sharh bo'lsa — yolg'on reyting qo'ymaclik — Google jazolaydi). Tiplar ko'p (2.8 — Article, FAQPage, Recipe, Organization) — har kontent turiga mos. JSON-LD'ni Google'ning "Rich Results Test" vositasi bilan tekshiriladi (to'g'ri formatda'mi, boy natija chiqadimi). Bu — SEO'ning ilg'or, lekin eng ta'sirli qismi (qidiruvda vizual hukmronlik).
Misol 6 — Dinamik OG rasm (next/og — 2.9)
Maqsad: Har blog post uchun avtomatik OG rasm generatsiya — next/og bilan. Bu minglab postga qo'lda rasm yasamasdan, har biri brendlangan karta bilan ulashilishi.
// app/blog/[slug]/opengraph-image.tsx — har post uchun avtomatik OG rasm
import { ImageResponse } from "next/og";
export const size = { width: 1200, height: 630 }; // standart OG o'lcham (2.4)
export const contentType = "image/png";
export default async function OGImage({ params }: { params: { slug: string } }) {
const post = await fetch(`https://api.myshop.uz/posts/${params.slug}`).then((r) => r.json());
return new ImageResponse(
(
<div
style={{
width: "100%", height: "100%", display: "flex", flexDirection: "column",
background: "linear-gradient(135deg, #0070f3, #00c6ff)", // brend gradient
padding: 80, justifyContent: "space-between", color: "white",
}}
>
<div style={{ fontSize: 32, opacity: 0.9 }}>MyShop Blog</div> {/* brend */}
<div style={{ fontSize: 64, fontWeight: 700 }}>{post.title}</div> {/* post sarlavhasi */}
<div style={{ fontSize: 28 }}>{post.author} · {post.readTime} daqiqa o'qish</div>
</div>
),
{ ...size }
);
}Bu kod nima qiladi: Bu — dinamik OG rasm generatsiyasi (har blog post uchun avtomatik — 2.9). app/blog/[slug]/opengraph-image.tsx — maxsus fayl nomi (Next.js uni o'sha blog post sahifasining OG rasmi sifatida ishlatadi — generateMetadatada qo'lda images yozish shart emas — bu fayl avtomatik OG rasm bo'ladi). ImageResponse — JSX'ni rasmga aylantiradi (server'da — next/og brauzer-darajadagi render qiladi): bu yerda gradient fon (brend rangi), "MyShop Blog" (brend nomi), post.title (post sarlavhasi — katta — asosiy), post.author va readTime (muallif va o'qish vaqti). Natija: har blog post uchun avtomatik chizilgan, brendlangan OG rasm (gradient fon, sarlavha, muallif — professional ko'rinish — 1200×630). Telegram/Facebook'da post ulashilsa — bu chiroyli karta ko'rinadi (post sarlavhasi, brend bilan — quruq havola emas). Nega muhim: minglab blog post uchun qo'lda OG rasm yasash (Photoshop) imkonsiz — next/og har post uchun avtomatik generatsiya qiladi (post sarlavhasini kodga solib — rasm chizadi). Bu ko'p zamonaviy blog va texnologiya platformalari ishlatadigan texnika (har maqola o'z brendlangan kartasi bilan — izchil, professional, miqyosda). size/contentType eksport — rasm o'lchami va formatini belgilaydi. JSX'da CSS (flexbox, gradient) ishlatiladi (lekin cheklangan — next/og Tailwind emas, inline style yoki cheklangan CSS). Demak: ijtimoiy ulashish (Open Graph — 2.4) + avtomatlashtirish (next/og) = har sahifa/post o'z chiroyli, brendlangan kartasi bilan, qo'lda mehnatsiz. Bu — zamonaviy SEO/ijtimoiy marketing texnikasi (miqyosda ulashish).
Misol 7 — Canonical va takror kontent (2.5)
Maqsad: Bir kontent bir necha URL'da bo'lganda canonical bilan "asosiy"ni ko'rsatish — Google'ni chalg'itmaclik. Bu takror kontent jazosidan saqlaydi.
// app/products/[id]/page.tsx — canonical bilan
import type { Metadata } from "next";
export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise<Metadata> {
const { id } = await params;
return {
title: "Mahsulot",
alternates: {
// ASOSIY URL (bir mahsulot bir necha URL'da bo'lca — Google shuni hisoblaydi):
canonical: `/products/${id}`,
},
};
}
// MUAMMO: bir mahsulot turli URL'da ochilishi mumkin:
// /products/42
// /products/42?ref=telegram (reklama manbasi)
// /products/42?color=red (variant)
// /category/phones/products/42 (kategoriya orqali)
// Google ularni 4 TAKROR sahifa deb hisoblab, reytingni BO'LADI (yomon)
//
// YECHIM: hammaci canonical: /products/42 ni ko'rsatadi
// Google biladi: "asosiy — /products/42, qolgani o'sha sahifa" (reyting birlashadi)Bu kod nima qiladi: Bu — canonical URL (takror kontent muammosini hal qilish — 2.5). Muammo: bir mahsulot (yoki sahifa) ko'p turli URL bilan ochilishi mumkin: /products/42 (asosiy), /products/42?ref=telegram (reklama manbasi tracking), /products/42?color=red (variant), /category/phones/products/42 (kategoriya orqali) — bir xil kontent, lekin to'rt xil URL. Google bularni to'rt alohida (takror) sahifa deb hisoblashi mumkin, va: (1) reytingni bo'ladi (bir sahifaning kuchi to'rtga bo'linadi — har biri zaif); (2) "takror kontent" deb jazolashi mumkin (Google takror kontentni yomon ko'radi). Yechim — canonical: alternates: { canonical: \/products/${id}` }— bu Google'ga "bu kontentning **asosiy** URL'i/products/42, boshqa variantlari o'sha sahifaning nusxalari" deb aytadi. Natija: Google **barcha** variantni bitta sahifa (/products/42) deb hisoblaydi — reyting **birlashadi** (bo'linmaydi — kuchli), takror jazosi yo'q. Ya'ni ?ref=telegrambilan ham,?color=redbilan ham ochilsa — Google/products/42ni indekslaydi (bitta, kuchli sahifa). **Nega muhim**: e-commerce saytlarda query parametrlar (tracking, filtr, variant) keng — canonical'siz har query alohida sahifa bo'lib, SEO zarar ko'radi. Canonical — har dinamik sahifada (mahsulot, blog post) bo'lishi kerak (asosiy URL'ni aniq ko'rsatish). Bu — SEO'ning nozik, lekin muhim qismi (takror kontent — keng, lekin ko'rinmas SEO muammosi). robots: noindex` 2.7-bob ham takror sahifani yashirishda ishlatiladi, lekin canonical yaxshiroq (reyting birlashadi, yo'qotilmaydi). Canonical — "asosiy nusxa qaysi" ni Google'ga aytishning usuli.
Misol 8 — FAQ JSON-LD (boy natija — 2.8)
Maqsad: FAQ (savol-javob) sahifasiga JSON-LD qo'shish — Google to'g'ridan qidiruvda savollarni ko'rsatishi uchun. Bu qidiruvda ko'p joy egallaydi (ko'proq e'tibor).
// app/faq/page.tsx — FAQ JSON-LD bilan
export default function FAQPage() {
const faqs = [
{ q: "Yetkazib berish qancha vaqt oladi?", a: "Toshkent ichida 1-2 kun, viloyatlarga 3-5 kun." },
{ q: "To'lovni qanday amalga oshiraman?", a: "Karta, naqd yoki onlayn to'lov tizimlari orqali." },
{ q: "Mahsulotni qaytarish mumkinmi?", a: "Ha, 14 kun ichida sababsiz qaytarish mumkin." },
];
// FAQ strukturali ma'lumot (Google to'g'ridan qidiruvda ko'rsatadi):
const jsonLd = {
"@context": "https://schema.org",
"@type": "FAQPage",
mainEntity: faqs.map((faq) => ({
"@type": "Question",
name: faq.q,
acceptedAnswer: { "@type": "Answer", text: faq.a },
})),
};
return (
<main>
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
<h1>Ko'p so'raladigan savollar</h1>
{faqs.map((faq, i) => (
<details key={i}>
<summary>{faq.q}</summary> {/* semantik — ochiladigan savol 2.10-bob */}
<p>{faq.a}</p>
</details>
))}
</main>
);
}Bu kod nima qiladi: Bu — FAQ JSON-LD (savol-javob boy natija — 2.8). faqs — savol-javoblar massivi. jsonLd — uni schema.org FAQPage formatida tasvirlaydi: @type: "FAQPage", mainEntity (har savol — Question tipi, acceptedAnswer — javob — Answer). Bu <script type="application/ld+json"> ichida (Google o'qiydi). Natija: Google qidiruvda sizning FAQ sahifangiz havolasi ostida to'g'ridan savollarni ko'rsatadi (ochiladigan akkordeon — foydalanuvchi qidiruvda savolni ko'rib, javobni to'g'ridan ochadi — sahifaga kirmacdan ham). Bu qidiruvda ko'p joy egallaydi (oddiy havola bir qator, FAQ boy natija — bir necha savol bilan — katta) — ya'ni sizning havolangiz qidiruvda ko'proq ko'rinadi (ko'zga tashlanadi, ko'proq bosiladi). Bundan tashqari, JSX'da semantik <details>/<summary> ishlatilgan 2.10-bob — bu native ochiladigan savol (JavaScript'siz ishlaydi — accessibility), va Google buni ham tushunadi. Nega muhim: FAQ — ko'p sayt uchun foydali (yetkazib berish, to'lov, qaytarish — keng savollar), va FAQ boy natija bilan qidiruvda ajralib turadi (masalan "MyShop yetkazib berish" qidiruvida sizning FAQ to'g'ridan javob bilan chiqadi). Bu Product (Misol 5) bilan birga JSON-LD'ning eng keng turlaridan biri. Schema.org ko'p tip beradi (HowTo, Recipe, Event, Course) — har kontent turiga mos boy natija. JSON-LD'ni to'g'ri yozish (Google Rich Results Test bilan tekshirib) — qidiruvda vizual ustunlik beradi. FAQ JSON-LD — kam mehnatli, lekin ta'sirli SEO texnikasi.
Misol 9 — Til va xalqaro SEO (hreflang — 2.10)
Maqsad: Ko'p tilli sayt uchun til metadata va hreflang — Google har tilni to'g'ri til qidiruvida ko'rsatishi uchun. Bu xalqaro/ko'p tilli sayt SEO'sining asosi.
// app/[locale]/products/[id]/page.tsx — ko'p tilli (uz/en/ru)
import type { Metadata } from "next";
export async function generateMetadata({ params }: { params: Promise<{ locale: string; id: string }> }): Promise<Metadata> {
const { locale, id } = await params;
const product = await fetch(`https://api.myshop.uz/${locale}/products/${id}`).then((r) => r.json());
return {
title: product.name,
description: product.description,
alternates: {
canonical: `/${locale}/products/${id}`,
// hreflang — har til versiyasi (Google to'g'ri tilni ko'rsatadi):
languages: {
"uz": `/uz/products/${id}`,
"en": `/en/products/${id}`,
"ru": `/ru/products/${id}`,
},
},
openGraph: {
locale: locale === "uz" ? "uz_UZ" : locale === "ru" ? "ru_RU" : "en_US",
},
};
}Bu kod nima qiladi: Bu — ko'p tilli sayt SEO'si (hreflang — 2.10). Ko'p tilli saytda (/uz/..., /en/..., /ru/... — 13.6: Misol 5 i18n) har til versiyasi alohida URL'da. Muammo: Google qaysi til versiyasini qaysi foydalanuvchiga ko'rsatishni qanday biladi? (o'zbek foydalanuvchiga /uz/, ingliz foydalanuvchiga /en/). Yechim — hreflang (alternates.languages): languages: { "uz": "/uz/products/42", "en": "/en/products/42", "ru": "/ru/products/42" } — bu Google'ga "bu sahifaning uch til versiyasi bor, har biri shu URL'da" deb aytadi. Natija: Google to'g'ri til versiyasini to'g'ri foydalanuvchiga ko'rsatadi (o'zbekistondagi qidiruvda /uz/, AQSh'da /en/, Rossiyada /ru/) — har foydalanuvchi o'z tilidagi sahifani ko'radi (yaxshi UX, to'g'ri SEO). Va canonical (har til o'z asosiy URL'i — /uz/products/42 — uz versiyaning canonical'i), openGraph.locale (ijtimoiy ulashishda til — uz_UZ/en_US/ru_RU). Nega muhim: hreflang'siz, Google til versiyalarini takror kontent deb hisoblashi (bir mahsulot uch tilda — uchta sahifa) yoki noto'g'ri tilni ko'rsatishi mumkin (ingliz foydalanuvchiga o'zbek sahifa). Hreflang — Google'ga til strukturasini aniq aytadi (har til — alohida, lekin bog'langan versiya). Bu — xalqaro/ko'p tilli sayt (turli mamlakat foydalanuvchilari uchun) SEO'sining asosiy elementi. <html lang="uz"> (Misol 1) — sahifa tilini aytadi, hreflang — til versiyalari orasidagi bog'lanishni. Ko'p tilli e-commerce, hujjat sayti uchun majburiy (har til Google'da o'z auditoryasiga to'g'ri ko'rinishi uchun).
Misol 10 — To'liq SEO sahifa (hammasi birga)
Maqsad: Barcha SEO elementini bir sahifada birlashtirish — metadata, OG, JSON-LD, semantik HTML, canonical. Bu butun bobning amaliy yakuni (professional SEO sahifa).
// app/blog/[slug]/page.tsx — to'liq SEO bilan blog post
import type { Metadata } from "next";
import { notFound } from "next/navigation";
export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {
const { slug } = await params;
const post = await fetch(`https://api.myshop.uz/posts/${slug}`).then((r) => r.json());
if (!post) return { title: "Topilmadi" };
return {
title: post.title,
description: post.excerpt,
authors: [{ name: post.author }],
openGraph: {
title: post.title, description: post.excerpt, type: "article",
publishedTime: post.publishedAt, authors: [post.author],
// OG rasm — opengraph-image.tsx avtomatik (Misol 6)
},
alternates: { canonical: `/blog/${slug}` },
};
}
export default async function BlogPostPage({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const post = await fetch(`https://api.myshop.uz/posts/${slug}`).then((r) => r.json());
if (!post) notFound();
const jsonLd = {
"@context": "https://schema.org", "@type": "Article",
headline: post.title, author: { "@type": "Person", name: post.author },
datePublished: post.publishedAt, image: post.coverImage,
};
return (
<article> {/* semantik — maqola 2.10-bob */}
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} />
);
}Bu kod nima qiladi: Bu — butun bobning amaliy yakuni (barcha SEO elementi bir professional sahifada). Blog post sahifasi, to'liq SEO bilan: (1) generateMetadata 2.3-bob — dinamik metadata: title, description (post.excerpt), authors (muallif — Article uchun), openGraph (type: "article" — blog post ekanini, publishedTime — chop etilgan sana, muallif — ijtimoiy ulashish va Google uchun), canonical (/blog/${slug} — asosiy URL — 2.7); (2) OG rasm — opengraph-image.tsx (Misol 6 — avtomatik dinamik rasm — bu yerda qo'lda yozish shart emas, alohida fayl); (3) JSON-LD 2.8-bob — Article tipi (headline, author — Person, datePublished, image) — Google maqolani tushunadi (qidiruvda muallif, sana — boy natija); (4) semantik HTML 2.10-bob — <article> (mustaqil kontent — maqola), <header> (sarlavha qismi), bitta <h1> (post sarlavhasi — asosiy — sahifada faqat bitta), <section> (kontent); (5) notFound() (topilmasa 404 — 13.2). Bu sahifa SEO jihatdan to'liq: Google darrov ko'radi (server render — 2.1), noyob metadata (title/description — qidiruvda), Article JSON-LD (boy natija — muallif/sana), OG rasm (ijtimoiy ulashish — chiroyli karta), canonical (takror oldini), semantik HTML (struktura tushunarli). Demak professional SEO sahifa — bir element emas, barcha elementning birikmasi: metadata (qidiruv ko'rinishi) + OG (ijtimoiy) + JSON-LD (boy natija) + semantik (struktura) + canonical (takror) + server render (Google ko'radi) + tez (13.7 — Core Web Vitals). Har biri kichik, lekin birga sayt Google'da yuqori, ijtimoiy tarmoqda chiroyli, foydalanuvchiga tushunarli. Bu — Next.js'ning SEO kuchining to'liq ko'rinishi (server render + metadata API + barcha vosita). Professional blog/e-commerce sahifa shunday quriladi — har SEO elementi ongli qo'shilgan.
Misol 11 — Ikona, viewport va manifest (fayl konvensiyasi + PWA — 2.11, 2.12, 2.13)
Maqsad: Sayt ikonasi, mobil viewport/themeColor va PWA manifest'ini sozlash — professional brend ko'rinishi va o'rnatiladigan sayt. Bu metadata'ni to'liq qiladi (faqat title/OG emas).
// 1. app/icon.tsx — ikonani KODDAN generatsiya (favicon.ico ham qo'yish mumkin)
import { ImageResponse } from "next/og";
export const size = { width: 32, height: 32 };
export const contentType = "image/png";
export default function Icon() {
return new ImageResponse(
(
<div style={{ width: "100%", height: "100%", display: "flex", alignItems: "center",
justifyContent: "center", background: "#0070f3", color: "white",
fontSize: 22, fontWeight: 700, borderRadius: 6 }}>
M {/* brend harfi — kichik ikona */}
</div>
),
{ ...size }
);
}
// 2. app/layout.tsx — viewport ALOHIDA export (2.12)
import type { Viewport } from "next";
export const viewport: Viewport = {
width: "device-width", // mobil responsivlik (majburiy)
initialScale: 1,
themeColor: "#0070f3", // mobil brauzer UI rangi
};
// 3. app/manifest.ts — PWA manifest (2.13)
import type { MetadataRoute } from "next";
export default function manifest(): MetadataRoute.Manifest {
return {
name: "MyShop — Onlayn do'kon",
short_name: "MyShop",
start_url: "/",
display: "standalone", // ilovaga o'xshab ochiladi
background_color: "#ffffff",
theme_color: "#0070f3",
icons: [
{ src: "/icon-192.png", sizes: "192x192", type: "image/png" },
{ src: "/icon-512.png", sizes: "512x512", type: "image/png" },
],
};
}Bu kod nima qiladi: Bu — metadata'ning "to'liqlovchi" elementlari (ikona, mobil sozlama, PWA — 2.11, 2.12, 2.13). Uch qism: (1) app/icon.tsx 2.11-bob — sayt ikonasini koddan generatsiya qiladi (ImageResponse — OG rasm kabi, lekin kichik 32×32 — brend harfi "M" ko'k fonda). Next.js buni avtomatik <link rel="icon"> qilib <head>ga qo'shadi (brauzer tab'ida, xatcho'pda ko'rinadi). Muqobil — oddiy favicon.ico/icon.png faylni app/ga qo'yish (u ham avtomatik topiladi — qo'lda yozish shart emas). (2) export const viewport 2.12-bob — mobil sozlama (metadata'dan alohida export — zamonaviy Next.js talabi): width: "device-width" (mobil ekranga moslashish — responsivlik uchun majburiy — Google mobil-first indekslaydi), themeColor (mobil brauzer UI rangi — manzil paneli brend rangida). (3) app/manifest.ts 2.13-bob — PWA manifest (/manifest.webmanifest): display: "standalone" (sayt telefon bosh ekraniga o'rnatilganda ilovaga o'xshab, brauzer UI'siz ochiladi), icons (bosh ekran ikonalari — 192×192, 512×512). Bu uch element — metadata'ning ko'p unutiladigan, lekin professional ko'rinish uchun muhim qismi: ikona (brend tab'da/qidiruvda taniladi), viewport (mobil'da to'g'ri ko'rinish — mobil SEO), manifest (o'rnatiladigan, ilovaga o'xshash sayt — takroriy foydalanuvchi). Demak to'liq metadata — faqat title/description/OG emas, balki ikona + mobil sozlama + PWA ham (butun brend va platforma tajribasi). Har biri Next.js'da fayl konvensiyasi yoki alohida export bilan — sodda, lekin ta'sirli.
5. To'g'ri va noto'g'ri holatlar
1) Metadata
client'da document.title (useEffect — Google ko'rmaydi — 13.7: Misol 8)
metadata/generateMetadata (server — HTML — 2.2, 2.3)2) Dinamik sahifa title
barcha mahsulot bir xil title (Google ajratmaydi)
generateMetadata (har mahsulot noyob — Misol 2)3) metadataBase
metadataBase yo'q (OG rasm nisbiy — ishlamaydi — 2.5)
metadataBase: new URL("https://...") (Misol 1)4) OG rasm o'lchami
tasodifiy o'lcham (kesiladi — 2.4)
1200×630 (standart — barcha platforma — Misol 2)5) Sarlavha teglari
ko'p h1 yoki div'lar (struktura noaniq — 2.10)
bitta h1 + ierarxik h2/h3 + semantik teglar (Misol 10)6) Takror URL
canonical yo'q (query/variant takror — reyting bo'linadi — 2.5)
canonical (asosiy URL — Misol 7)7) Viewport/themeColor joyi
themeColor/viewport metadata ichida (Next 14+ ogohlantiradi — 2.12)
alohida export const viewport: Viewport (Misol 11)8) Mobil viewport
viewport yo'q (mobil'da kichik ko'rinadi — Google mobil-first zarar — 2.12)
width: "device-width" (responsiv — mobil SEO — Misol 11)6. Keng tarqalgan xatolar va yechimlari
Xato 1 — Google sayt kontentini ko'rmayapti
Sababi: CSR (client render — Google JS kutmaydi — 2.1). Yechimi: SSR/SSG (Server Component — HTML'da kontent — 13.4).
Xato 2 — OG rasm ijtimoiy tarmoqda ko'rinmaydi
Sababi: metadataBase yo'q (nisbiy URL) yoki rasm o'lchami noto'g'ri (2.4, 2.5). Yechimi: metadataBase + 1200×630 to'liq URL (Misol 1, 2).
Xato 3 — Barcha sahifa bir xil title (Google'da)
Sababi: generateMetadata yo'q yoki statik metadata dinamik sahifada 2.3-bob. Yechimi: generateMetadata (har element — Misol 2).
Xato 4 — JSON-LD boy natija chiqmayapti
Sababi: noto'g'ri format yoki yolg'on ma'lumot (Google rad etadi — 2.8). Yechimi: Google Rich Results Test bilan tekshirish; haqiqiy ma'lumot.
Xato 5 — Admin sahifa Google'da ko'rinadi
Sababi: robots disallow yoki noindex yo'q (2.6, 2.7). Yechimi: robots.ts disallow + sahifa robots noindex (Misol 4).
Xato 6 — Takror kontent ogohlantirishi (Search Console)
Sababi: canonical yo'q (query/til variant — 2.5). Yechimi: canonical har sahifada (Misol 7).
Xato 7 — Sitemap'da yangi sahifalar yo'q
Sababi: statik sitemap (qo'lda) — dinamik element qo'shilmagan 2.6-bob. Yechimi: dinamik sitemap (DB'dan — Misol 3).
7. Integratsiya — bu mavzu stack'ning qayerida uchraydi
- Rendering 13.4-bob: SSR/SSG — Google kontentni ko'radi (SEO asosi).
- Performance 13.7-bob: Core Web Vitals — Google reyting omili; metadata server'da.
- Routing 13.2-bob: generateMetadata — har sahifa/dinamik segment.
- Data fetching 13.5-bob: generateMetadata fetch — page bilan dedup.
- i18n 13.6-bob: hreflang — ko'p tilli SEO.
- Images 13.7-bob: next/image alt — SEO + a11y; OG rasm.
- Accessibility: semantik HTML — a11y + SEO (birga).
- PWA 2.13-bob: manifest.ts — o'rnatiladigan sayt; ikona 2.11-bob.
- Search Console 2.14-bob: sitemap yuborish, indekslashni kuzatish.
- Marketing: Open Graph — ijtimoiy ulashish (trafik).
8. Eng yaxshi amaliyotlar (best practices)
- Server render (SSR/SSG) (Google ko'radi — 2.1).
- Har sahifa noyob title + description (generateMetadata — 2.3, Misol 2).
- metadataBase (OG rasm to'liq URL — 2.5, Misol 1).
- Open Graph + Twitter (1200×630 — ijtimoiy — 2.4).
- sitemap.ts + robots.ts (dinamik — 2.6, Misol 3, 4).
- JSON-LD asosiy kontentga (Product/Article/FAQ — 2.8, Misol 5, 8).
- next/og dinamik OG rasm (miqyosda — 2.9, Misol 6).
- Canonical (takror kontent — 2.5, Misol 7).
- Semantik HTML + bitta h1 (struktura — 2.10).
- Ikona konvensiyasi (favicon.ico / icon.png / apple-icon — 2.11, Misol 11).
- Viewport alohida export (width: device-width, themeColor — 2.12, Misol 11).
- manifest.ts (PWA) (o'rnatiladigan sayt — 2.13).
- Tez sayt (Core Web Vitals — LCP/INP/CLS — SEO omili — 2.14, 13.7).
- Search Console (sitemap yuborish, indekslashni kuzatish — 2.14).
9. Amaliy loyiha: "To'liq SEO-Optimizatsiyalangan Sayt"
Metadata, SEO va ijtimoiy ulashishni real saytda mustahkamlash.
Maqsad
E-commerce/blog sayt: to'liq SEO — metadata, OG, JSON-LD, sitemap, robots, canonical.
Talablar (requirements)
- Root metadata: template, metadataBase, default OG (Misol 1).
- Dinamik metadata: har mahsulot/post noyob (generateMetadata — Misol 2).
- Open Graph + Twitter: ijtimoiy karta (1200×630 — 2.4).
- Dinamik OG rasm: next/og (har element — Misol 6).
- Sitemap: statik + dinamik (DB'dan — Misol 3).
- Robots: admin/api disallow (Misol 4).
- JSON-LD: Product + FAQ + Article (Misol 5, 8).
- Canonical: takror oldini (Misol 7).
- Semantik HTML: header/main/article + bitta h1 2.10-bob.
- Ikona + viewport + manifest: favicon/icon, alohida viewport, PWA manifest (Misol 11).
- Tekshirish: Google Rich Results Test + Search Console + ijtimoiy preview (Telegram).
Maslahatlar (hint)
- Server render (Google ko'radi — Xato 1).
- metadataBase (OG rasm — Xato 2).
- generateMetadata (har element — Xato 3).
- JSON-LD'ni Rich Results Test bilan tekshirish (Xato 4).
- robots + noindex (admin — Xato 5).
- canonical (takror — Xato 6).
"Tayyor" mezonlari (acceptance criteria)
- Root + dinamik metadata.
- Open Graph + Twitter (1200×630).
- Dinamik OG rasm (next/og).
- Sitemap (dinamik) + robots.
- JSON-LD (boy natija).
- Canonical (takror yo'q).
- Semantik HTML (bitta h1).
- Ikona + viewport (device-width) + manifest (PWA).
- Rich Results Test o'tdi; Search Console'da sitemap yuborildi.
Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.
10. Xulosa va keyingi bobga ko'prik
Bu bobda Next.js'da Metadata va SEO'ni chuqur o'rgandik:
- SEO asoslari (Google — 2.1); Metadata API (statik — 2.2); generateMetadata (dinamik — 2.3); Open Graph 2.4-bob; Twitter/metadataBase 2.5-bob.
- Sitemap/robots 2.6-bob; indekslash (noindex — 2.7); JSON-LD (boy natija — 2.8); OG rasm (next/og — 2.9); semantik HTML/best practices 2.10-bob.
- Ikona konvensiyasi (favicon/icon/apple-icon — 2.11); viewport/themeColor (alohida export — 2.12); manifest.json (PWA — 2.13); Core Web Vitals/metadata streaming/Search Console 2.14-bob.
Endi siz Next.js saytni Google va ijtimoiy tarmoqlarda ko'rinadigan, bosiladigan, ishonchli qila olasiz: har sahifa noyob metadata, ijtimoiy karta, boy natijalar (JSON-LD), to'liq sitemap. Bu — saytning topilishi va o'sishining kalitidir.
Keyingi bob — 13.9-bob: Autentifikatsiya (NextAuth/Auth.js). SEO'ni bildik; endi autentifikatsiya (foydalanuvchi kim — login, ro'yxat)ni Next.js'da chuqur ko'ramiz: Auth.js (NextAuth) (sozlash, provayderlar — Google/GitHub/email), sessiya (server va client'da), himoyalangan sahifalar (middleware + server — 13.6), rollar (admin/foydalanuvchi), JWT vs database session, va xavfsizlik (CSRF, parol). Bu — har real ilovaning asosiy qismi (foydalanuvchi tizimi).
Foydalanilgan rasmiy/ishonchli manbalar
- Next.js rasmiy hujjati — Metadata API: statik
metadata,generateMetadata,title.template,alternates(canonical/languages),robots - Next.js rasmiy hujjati — fayl konvensiyalari:
sitemap.ts,robots.ts,manifest.ts,opengraph-image,icon/apple-icon/favicon - Next.js rasmiy hujjati —
viewport(alohida export),next/og(ImageResponse— dinamik OG rasm, edge runtime) - schema.org — strukturali ma'lumot tiplari (Product, Article, FAQPage, BreadcrumbList, Organization)
- Google Search Central — SEO asoslari (crawl/index/rank), rich results (JSON-LD), Google Search Console (sitemap, indekslash, URL Inspection)
- web.dev — Core Web Vitals (LCP, INP, CLS) reyting omili sifatida; mobil-first indekslash
- Open Graph protokoli (Facebook) va Twitter Card hujjati — ijtimoiy ulashish metama'lumotlari
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!