next.config.js — redirects, rewrites, headers, env

~20 daq · Next.js · Ilg'or mavzular

Muammodan boshlaylik

Sayt yangi dizayn va tuzilmaga o'tdi:

  • Eski /blog/123 manzillari endi /maqolalar/123 — Google da yuzlab eski havolalar 404 beradi
  • API boshqa serverda (api.dokon.uz), lekin frontend /api/... deb so'rashi kerak (CORS siz)
  • Xavfsizlik auditi: "Content-Security-Policy, X-Frame-Options header lari yo'q"
  • Mahsulot rasmlari tashqi CDN dan

Bularning hammasini har bir sahifada yoki middleware da yozish shart emas — next.config da bir joyda.


Hayotiy o'xshatma

Binoning boshqaruv pulti. Har bir xonaga borib chiroq yoki signalizatsiyani sozlash o'rniga — markaziy pultda: qaysi eshik qayerga olib boradi (redirects), qaysi xona aslida boshqa binoda (rewrites), barcha eshiklarga qanday qulf (headers).


Fayl

// next.config.ts
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  // sozlamalar
}

export default nextConfig

next.config.ts (TypeScript, Next.js 15+), next.config.mjs yoki next.config.js — biri. O'zgartirgandan keyin dev serverni qayta ishga tushiring.


redirects — yo'naltirish

const nextConfig: NextConfig = {
  async redirects() {
    return [
      { source: '/blog/:id', destination: '/maqolalar/:id', permanent: true },
      { source: '/eski-katalog/:yol*', destination: '/katalog/:yol*', permanent: true },
      { source: '/aksiya', destination: '/katalog?chegirma=1', permanent: false },
      {
        source: '/admin/:yol*',
        missing: [{ type: 'cookie', key: 'authjs.session-token' }],
        destination: '/login',
        permanent: false,
      },
    ]
  },
}
Maydon Ma'nosi
source Kiruvchi yo'l; :id — parametr, :yol* — qolgan hammasi
destination Yangi manzil (tashqi URL ham bo'lishi mumkin)
permanent true — 308 (doimiy, SEO "kuch"ini o'tkazadi), false — 307
has / missing Shart: header, cookie, query, host

[!TIP] Redirect lar sahifa kodidan oldin ishlaydi — eng tezi. Minglab redirect bo'lsa (eski saytdan ko'chish), ularni middleware da Map yoki baza orqali boshqarish yaxshiroq: redirects() ro'yxati juda katta bo'lsa build va routing sekinlashadi.


rewrites — URL o'zgarmasdan

async rewrites() {
  return [
    // API proxy — brauzer uchun bir xil origin, CORS kerak emas
    { source: '/api/v2/:yol*', destination: 'https://api.dokon.uz/v2/:yol*' },

    // chiroyli URL
    { source: '/@:username', destination: '/profil/:username' },
  ]
}

Foydalanuvchi /@lola ni ko'radi, Next.js esa /profil/lola sahifasini ko'rsatadi.

Bosqichlar

async rewrites() {
  return {
    beforeFiles: [],    // sahifalardan oldin tekshiriladi
    afterFiles: [],     // sahifa topilmasa (standart)
    fallback: [
      // hech narsa topilmasa — eski saytga (bosqichma-bosqich ko'chish)
      { source: '/:yol*', destination: 'https://eski.dokon.uz/:yol*' },
    ],
  }
}

fallback — eski sayt va yangi Next.js birga ishlaydi: yangi sahifalar Next.js da, qolganlari — eski serverda. Sahifama-sahifa ko'chish.


headers — xavfsizlik va kesh

async headers() {
  return [
    {
      source: '/:yol*',
      headers: [
        { key: 'X-Frame-Options', value: 'DENY' },
        { key: 'X-Content-Type-Options', value: 'nosniff' },
        { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
        { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
        { key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
      ],
    },
    {
      source: '/fonts/:fayl*',
      headers: [{ key: 'Cache-Control', value: 'public, max-age=31536000, immutable' }],
    },
  ]
}
Header Himoya
X-Frame-Options: DENY Saytni <iframe> ga joylab aldash (clickjacking)
X-Content-Type-Options Fayl turini taxmin qilish hujumlari
Strict-Transport-Security Faqat HTTPS — keyingi tashriflarda
Permissions-Policy Kamera, mikrofon va h.k. ga kirishni cheklash

Content-Security-Policy

CSP — qaysi manbalardan skript, stil, rasm yuklash mumkinligi. XSS ga qarshi eng kuchli himoya, lekin Next.js inline skriptlari tufayli nonce talab qiladi — u har so'rovda yangi bo'lishi kerak, shuning uchun middleware da yaratiladi:

// middleware.ts (qisqartirilgan)
export function middleware(request: NextRequest) {
  const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
  const csp = `default-src 'self'; script-src 'self' 'nonce-${nonce}' 'strict-dynamic'; style-src 'self' 'unsafe-inline'; img-src 'self' blob: data: https://cdn.dokon.uz; object-src 'none'; base-uri 'self'; frame-ancestors 'none';`

  const headers = new Headers(request.headers)
  headers.set('x-nonce', nonce)

  const javob = NextResponse.next({ request: { headers } })
  javob.headers.set('Content-Security-Policy', csp)
  return javob
}

[!WARNING] CSP dagi nonce bilan sahifalar dinamik render qilinadi (har so'rovda yangi nonce). CSP ni avval Content-Security-Policy-Report-Only rejimida sinang — u bloklamaydi, faqat xabar beradi — aks holda analitika, chat yoki shriftlar jim ishlamay qolishi mumkin.


Boshqa foydali sozlamalar

const nextConfig: NextConfig = {
  images: {
    remotePatterns: [{ protocol: 'https', hostname: 'cdn.dokon.uz' }],   // 57-dars
  },
  output: 'standalone',                      // Docker (67-dars)
  poweredByHeader: false,                    // "X-Powered-By: Next.js" ni olib tashlash
  reactStrictMode: true,
  trailingSlash: false,
  basePath: '/dokon',                        // sayt subpapkada: example.com/dokon
  serverExternalPackages: ['sharp'],         // bundle qilinmasin, Node dan yuklansin
  typescript: { ignoreBuildErrors: false },
  eslint: { ignoreDuringBuilds: false },
}

env

env: {
  BUILD_VAQTI: new Date().toISOString(),
}

env dagi qiymatlar build paytida kodga yoziladi va client ga ham ketadi. Ko'pincha .env fayllari va NEXT_PUBLIC_ (65-dars) yetarli va aniqroq — env maydonini faqat build vaqtida hisoblanadigan qiymatlar uchun ishlating, maxfiy narsalar uchun hech qachon.

[!INFO] typescript.ignoreBuildErrors: true yoki eslint.ignoreDuringBuilds: true — build ni "tez tuzatish" uchun ko'p tavsiya qilinadi, lekin ular xatolarni production ga o'tkazib yuboradi. Faqat vaqtinchalik va sababini bilgan holda.


Tez-tez uchraydigan xatolar

1. O'zgartirib, serverni qayta ishga tushirmaslik

next.config faqat ishga tushishda o'qiladi.

2. Redirect sikli

/a → /b va /b → /a — brauzer "Too many redirects".

3. Rewrite bilan tashqi API ga maxfiy header kutish

Rewrite brauzer so'rovini shunday uzatadi — server tomonda maxfiy kalit qo'shish kerak bo'lsa, Route Handler (proxy) yozing.


Xulosa

next.config.ts — markaziy sozlama; o'zgarishdan keyin qayta ishga tushirish
redirects — 308/307, :param, :yol*, has/missing shartlari
rewrites — URL o'zgarmasdan; API proxy; fallback — eski saytdan bosqichma-bosqich ko'chish
headers — xavfsizlik (X-Frame-Options, HSTS, Permissions-Policy), kesh
CSP — middleware da nonce bilan; avval Report-Only
images, output, poweredByHeader, basePath, serverExternalPackages
env — build da kodga yoziladi, client ga ham; maxfiy emas

Keyingi dars

72-dars: Turbopack — nima, webpack dan farqi, sozlash

Next.js ning yangi, Rust da yozilgan bundler i.