</>
  • Bosh sahifa
  • Men haqimda
  • Ko'nikmalar
  • Tajriba
  • Case Studies
  • Maqolalar
  • Loyihalar
madrimov.uz

Keling, jiddiy
tizim quramiz

madrimov5014@gmail.com→
</>© 2026 Madrimov Xudoshukur
GitHubTelegramKanalEmail
← Maqolalar
17-iyul, 2026

Notion'ni headless CMS sifatida: dependency'siz, pullik xizmatlarsiz

BackendArxitekturaNext.js

Blog uchun CMS tanlash — kichik sayt egasining eng ko'p vaqt yeydigan qarorlaridan biri. Strapi o'rnatasanmi — server boqish kerak. Contentful olasanmi — pullik tarif kutib turibdi. Markdown fayllar bilan ketasanmi — har post uchun commit + deploy.

Men uchinchi yo'lni tanladim: Notion'ning o'zi CMS, sayt esa uni API orqali o'qiydi. Bir yildan beri madrimov.uz shu sxemada ishlaydi — nol server, nol qo'shimcha xarajat, maqola chiqarish esa "Published" checkbox'ini belgilashdan iborat.

Nega aynan Notion?

  • Yozish tajribasi tayyor — editor, mobil ilova, versiyalar tarixi bor.
  • Database ustunlari meta uchun ideal: slug, teglar, til, sana — hammasi property.
  • API bepul va barqaror; shaxsiy blog hajmida limitlarga urilmaysan.

Muhimi: bu yechim uchun birorta npm paket kerak emas. @notionhq/client SDK'si qulay, lekin oddiy fetch ham xuddi shu ishni qiladi.

Yadro: 60 qatorlik mijoz

Notion database'ini o'qish — bitta POST so'rov. Pagination'ni unutmaslik kerak, xolos:

const NOTION_API = "https://api.notion.com/v1";

async function queryAll(dbId: string) {
	const pages = [];
	let cursor: string | undefined;
	do {
		const res = await fetch(`${NOTION_API}/databases/${dbId}/query`, {
			method: "POST",
			headers: {
				Authorization: `Bearer ${process.env.NOTION_TOKEN}`,
				"Notion-Version": "2022-06-28",
				"Content-Type": "application/json",
			},
			body: JSON.stringify({
				filter: { property: "Published", checkbox: { equals: true } },
				...(cursor ? { start_cursor: cursor } : {}),
			}),
			next: { revalidate: 300 },
		});
		if (!res.ok) break;
		const data = await res.json();
		pages.push(...data.results);
		cursor = data.has_more ? data.next_cursor : undefined;
	} while (cursor);
	return pages;
}

E'tibor ber: next: { revalidate: 300 } — bu Next.js'ning ISR mexanizmi. Sayt Notion'ga har so'rovda emas, 5 daqiqada bir marta murojaat qiladi. Notion yiqilsa ham sayt eski keshdan xizmat qilaveradi.

Bloklarni render qilish

Notion sahifa tarkibini "blok"lar daraxti sifatida qaytaradi: paragraph, heading, kod, ro'yxat. Ularni React elementlarga aylantirish — oddiy switch:

function renderBlock(block: any) {
	switch (block.type) {
		case "paragraph":
			return <p>{richText(block.paragraph.rich_text)}</p>;
		case "heading_2":
			return <h2>{richText(block.heading_2.rich_text)}</h2>;
		case "code":
			return (
				<pre>
					<code>{plain(block.code.rich_text)}</code>
				</pre>
			);
		default:
			return null;
	}
}

Hammasini qo'llab-quvvatlash shart emas — o'zing ishlatadigan 8-10 blok turi yetadi. Qolganlari null qaytarsa, sayt yiqilmaydi.

Uch qoida, bir yildan keyin

  1. Property nomlarini kod bilan qat'iy moslashtir. Notion'da ustunni qayta nomlasang, sayt jimgina bo'sh qaytadi. Bu eng ko'p uchraydigan "bug".
  2. Har doim `try/catch` + bo'sh massiv fallback. Notion API sekinlashsa yoki 500 bersa, blog sahifasi 200 bilan bo'sh ro'yxat ko'rsatgani — 500 xatodan yaxshi.
  3. Rasmlar uchun signed URL muddatini unutma. Notion fayllari ~1 soatlik imzolangan havola bilan keladi — ISR intervaling undan qisqa bo'lsa, muammo o'z-o'zidan hal.

Xulosa

Notion + fetch + ISR — shaxsiy blog uchun yetarli va ortiqchasiz CMS. Server yo'q, obuna yo'q, deploy'siz kontent. Keyingi bosqichda shu sxema ustiga avtomatik tarqatish (Telegram, LinkedIn) ham quriladi — lekin bu boshqa maqola mavzusi.

Bu kabi maqolalar har hafta

Yangi maqolalar, amaliy muhandislik tajribasi va loyihalar — Telegram kanalda.

Kanalga qo'shilish →

O'xshash maqolalar

  • Multi-core Node.js'da in-process event va cron nega buziladi — va to'g'ri yechim18-iyun, 2026
  • NestJS + Prisma'dan Bun + Hono + Drizzle'ga: nima uchun o'tdim16-iyun, 2026
  • Bun + Hono: production'da bir yil14-iyun, 2026