خروجی‌گیری استاتیک از اپلیکیشن Next.js – ساخت HTML مستقل، میزبانی بدون سرور، و بهینه‌سازی تصاویر

Next.js امکان خروجی‌گیری استاتیک از اپلیکیشن را فراهم می‌کند، به‌طوری‌که هر مسیر به فایل HTML مستقل تبدیل می‌شود. این مقاله نحوهٔ پیکربندی خروجی، استفاده از Server و Client Components، بهینه‌سازی تصاویر با Cloudinary، و نحوهٔ میزبانی در سرورهایی مانند Nginx را بررسی می‌کند.

Server ComponentCloudinaryNginx

~3 دقیقه مطالعه • بروزرسانی ۶ آبان ۱۴۰۴

مقدمه


Next.js به شما اجازه می‌دهد اپلیکیشن را به‌صورت SPA یا سایت استاتیک آغاز کنید و در صورت نیاز، قابلیت‌های سرور را به‌تدریج اضافه نمایید. با اجرای next build، برای هر مسیر یک فایل HTML تولید می‌شود که باعث کاهش حجم جاوااسکریپت و افزایش سرعت بارگذاری می‌شود.


پیکربندی خروجی استاتیک


در فایل next.config.js گزینه output: 'export' را فعال کنید:

const nextConfig = {
  output: 'export',
  trailingSlash: true, // اختیاری
  distDir: 'dist', // اختیاری
}
module.exports = nextConfig

پس از اجرای next build، پوشه out شامل فایل‌های HTML/CSS/JS تولید می‌شود.


پشتیبانی از Server Components


کامپوننت‌های سرور در زمان build اجرا شده و خروجی HTML تولید می‌کنند:

export default async function Page() {
  const res = await fetch('https://api.example.com/...')
  const data = await res.json()
  return <main>...</main>
}

استفاده از Client Components و SWR


برای واکشی داده در کلاینت:

'use client'
import useSWR from 'swr'

const fetcher = (url) => fetch(url).then((r) => r.json())

export default function Page() {
  const { data, error } = useSWR('/api/posts/1', fetcher)
  if (error) return 'Failed to load'
  if (!data) return 'Loading...'
  return data.title
}

ناوبری کلاینتی بین صفحات


مثال از صفحه index:

import Link from 'next/link'

export default function Page() {
  return (
    <>
      <h1>Index Page</h1>
      <ul>
        <li><Link href="/post/1">Post 1</Link></li>
        <li><Link href="/post/2">Post 2</Link></li>
      </ul>
    </>
  )
}

بهینه‌سازی تصاویر با Cloudinary


در next.config.js:

images: {
  loader: 'custom',
  loaderFile: './my-loader.ts',
}

در فایل my-loader.ts:

export default function cloudinaryLoader({ src, width, quality }) {
  const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`]
  return `https://res.cloudinary.com/demo/image/upload/${params.join(',')}${src}`
}

استفاده از next/image


import Image from 'next/image'

export default function Page() {
  return <Image alt="turtles" src="/turtles.jpg" width={300} height={300} />
}

استفاده از Route Handler برای خروجی JSON


// app/data.json/route.ts
export async function GET() {
  return Response.json({ name: 'Lee' })
}

در زمان build، فایل data.json تولید می‌شود.


دسترسی به APIهای مرورگر


در کامپوننت کلاینتی:

'use client'
import { useEffect } from 'react'

useEffect(() => {
  console.log(window.innerHeight)
}, [])

ویژگی‌های غیرقابل پشتیبانی در خروجی استاتیک


  • مسیرهای دینامیک بدون generateStaticParams()
  • کوکی‌ها، ریدایرکت‌ها، Proxy، ISR، Server Actions
  • بهینه‌سازی تصویر با loader پیش‌فرض

استقرار در سرورهای استاتیک


پس از build، فایل‌های زیر تولید می‌شوند:

/out/index.html
/out/404.html
/out/blog/post-1.html
/out/blog/post-2.html

پیکربندی Nginx:

server {
  listen 80;
  server_name acme.com;
  root /var/www/out;

  location / {
    try_files $uri $uri.html $uri/ =404;
  }

  location /blog/ {
    rewrite ^/blog/(.*)$ /blog/$1.html break;
  }

  error_page 404 /404.html;
  location = /404.html {
    internal;
  }
}

جمع‌بندی


با خروجی‌گیری استاتیک از Next.js، می‌توانید اپلیکیشن خود را بدون نیاز به سرور Node.js در هر هاست HTML/CSS/JS منتشر کنید. این روش برای SPAها، سایت‌های مستندات، و پروژه‌های سبک بسیار مناسب است.


نوشته و پژوهش شده توسط دکتر شاهین صیامی