বাংলা

আমাদের ফাইল-ভিত্তিক রাউটিং এর গভীর গাইডের মাধ্যমে Next.js অ্যাপ রাউটারের শক্তি উন্মোচন করুন। অ্যাপ্লিকেশন গঠন, ডাইনামিক রুট তৈরি, লেআউট পরিচালনা এবং আরও অনেক কিছু শিখুন।

Next.js অ্যাপ রাউটার: ফাইল-ভিত্তিক রাউটিং এর একটি বিস্তারিত গাইড

Next.js অ্যাপ রাউটার, যা Next.js 13-এ প্রবর্তিত হয়েছে এবং পরবর্তী সংস্করণগুলিতে স্ট্যান্ডার্ড হয়ে উঠেছে, এটি অ্যাপ্লিকেশনগুলির গঠন এবং নেভিগেশনের পদ্ধতিতে বৈপ্লবিক পরিবর্তন এনেছে। এটি একটি শক্তিশালী এবং স্বজ্ঞাত ফাইল-ভিত্তিক রাউটিং সিস্টেম চালু করেছে যা ডেভেলপমেন্টকে সহজ করে, পারফরম্যান্স উন্নত করে এবং সামগ্রিক ডেভেলপার অভিজ্ঞতাকে সমৃদ্ধ করে। এই বিস্তারিত গাইডটি অ্যাপ রাউটারের ফাইল-ভিত্তিক রাউটিং সম্পর্কে গভীরভাবে আলোচনা করবে, আপনাকে শক্তিশালী এবং স্কেলযোগ্য Next.js অ্যাপ্লিকেশন তৈরির জন্য প্রয়োজনীয় জ্ঞান এবং দক্ষতা প্রদান করবে।

ফাইল-ভিত্তিক রাউটিং কী?

ফাইল-ভিত্তিক রাউটিং এমন একটি রাউটিং সিস্টেম যেখানে আপনার অ্যাপ্লিকেশনের রুটের কাঠামো সরাসরি আপনার ফাইল এবং ডিরেক্টরির বিন্যাসের দ্বারা নির্ধারিত হয়। Next.js অ্যাপ রাউটারে, আপনি `app` ডিরেক্টরির মধ্যে ফাইল তৈরি করে রুট সংজ্ঞায়িত করেন। প্রতিটি ফোল্ডার একটি রুট সেগমেন্টকে প্রতিনিধিত্ব করে এবং সেই ফোল্ডারগুলির মধ্যে বিশেষ ফাইলগুলি সংজ্ঞায়িত করে যে সেই রুট সেগমেন্টটি কীভাবে পরিচালিত হবে। এই পদ্ধতিটি বেশ কিছু সুবিধা প্রদান করে:

অ্যাপ রাউটার দিয়ে শুরু করা

অ্যাপ রাউটার ব্যবহার করার জন্য, আপনাকে একটি নতুন Next.js প্রজেক্ট তৈরি করতে হবে অথবা একটি বিদ্যমান প্রজেক্ট মাইগ্রেট করতে হবে। নিশ্চিত করুন যে আপনি Next.js সংস্করণ 13 বা তার পরবর্তী সংস্করণ ব্যবহার করছেন।

নতুন প্রজেক্ট তৈরি করা:

আপনি নিম্নলিখিত কমান্ড ব্যবহার করে অ্যাপ রাউটার সহ একটি নতুন Next.js প্রজেক্ট তৈরি করতে পারেন:

npx create-next-app@latest my-app --example with-app

বিদ্যমান প্রজেক্ট মাইগ্রেট করা:

একটি বিদ্যমান প্রজেক্ট মাইগ্রেট করতে, আপনাকে আপনার পেজগুলি `pages` ডিরেক্টরি থেকে `app` ডিরেক্টরিতে সরাতে হবে। আপনাকে সেই অনুযায়ী আপনার রাউটিং লজিক সামঞ্জস্য করতে হতে পারে। Next.js এই প্রক্রিয়ায় আপনাকে সাহায্য করার জন্য একটি মাইগ্রেশন গাইড প্রদান করে।

ফাইল-ভিত্তিক রাউটিং এর মূল ধারণা

অ্যাপ রাউটার বেশ কিছু বিশেষ ফাইল এবং কনভেনশন চালু করেছে যা আপনার রুটগুলি কীভাবে পরিচালিত হবে তা নির্ধারণ করে:

১. `app` ডিরেক্টরি

`app` ডিরেক্টরি হল আপনার অ্যাপ্লিকেশনের রুটের মূল। এই ডিরেক্টরির মধ্যে থাকা সমস্ত ফাইল এবং ফোল্ডার রুট তৈরি করতে ব্যবহৃত হবে। `app` ডিরেক্টরির বাইরের কিছু (যেমন `pages` ডিরেক্টরি যদি আপনি মাইগ্রেট করছেন) অ্যাপ রাউটার দ্বারা উপেক্ষা করা হবে।

২. `page.js` ফাইল

`page.js` (অথবা `page.jsx`, `page.ts`, `page.tsx`) ফাইলটি অ্যাপ রাউটারের সবচেয়ে মৌলিক অংশ। এটি একটি নির্দিষ্ট রুট সেগমেন্টের জন্য রেন্ডার করা হবে এমন UI কম্পোনেন্টকে সংজ্ঞায়িত করে। এটি যেকোনো রুট সেগমেন্টের জন্য একটি **আবশ্যক** ফাইল যা আপনি সরাসরি অ্যাক্সেসযোগ্য করতে চান।

উদাহরণ:

যদি আপনার ফাইল কাঠামো এমন হয়:

app/
  about/
    page.js

যখন একজন ব্যবহারকারী `/about`-এ নেভিগেট করবেন, তখন `app/about/page.js` থেকে এক্সপোর্ট করা কম্পোনেন্টটি রেন্ডার করা হবে।

// app/about/page.js
import React from 'react';

export default function AboutPage() {
  return (
    <div>
      <h1>আমাদের সম্পর্কে</h1>
      <p>আমাদের কোম্পানি সম্পর্কে আরও জানুন।</p>
    </div>
  );
}

৩. `layout.js` ফাইল

`layout.js` (অথবা `layout.jsx`, `layout.ts`, `layout.tsx`) ফাইলটি একটি UI সংজ্ঞায়িত করে যা একটি রুট সেগমেন্টের মধ্যে একাধিক পেজে শেয়ার করা হয়। লেআউটগুলি সামঞ্জস্যপূর্ণ হেডার, ফুটার, সাইডবার এবং অন্যান্য উপাদান তৈরি করার জন্য দরকারী যা একাধিক পেজে উপস্থিত থাকা উচিত।

উদাহরণ:

ধরা যাক, আপনি `/about` পেজ এবং একটি কাল্পনিক `/about/team` পেজ উভয়েই একটি হেডার যোগ করতে চান। আপনি `app/about` ডিরেক্টরিতে একটি `layout.js` ফাইল তৈরি করতে পারেন:

// app/about/layout.js
import React from 'react';

export default function AboutLayout({ children }) {
  return (
    <div>
      <header>
        <h1>আমাদের কোম্পানি সম্পর্কে</h1>
      </header>
      <main>{children}</main>
    </div>
  );
}

`children` প্রপটি একই ডিরেক্টরিতে বা যেকোনো নেস্টেড ডিরেক্টরিতে `page.js` ফাইল দ্বারা রেন্ডার করা UI দ্বারা প্রতিস্থাপিত হবে।

৪. `template.js` ফাইল

`template.js` ফাইলটি `layout.js`-এর মতোই, কিন্তু এটি প্রতিটি চাইল্ড রুটের জন্য কম্পোনেন্টের একটি নতুন ইনস্ট্যান্স তৈরি করে। এটি এমন পরিস্থিতিতে কার্যকর যেখানে আপনি চাইল্ড রুটের মধ্যে নেভিগেট করার সময় কম্পোনেন্টের স্টেট বজায় রাখতে বা পুনরায় রেন্ডার হওয়া রোধ করতে চান। লেআউটের বিপরীতে, টেমপ্লেটগুলি নেভিগেশনের সময় পুনরায় রেন্ডার হবে। নেভিগেশনের সময় উপাদানগুলিকে অ্যানিমেট করার জন্য টেমপ্লেট ব্যবহার করা দুর্দান্ত।

উদাহরণ:

// app/template.js
'use client'

import { useState } from 'react'

export default function Template({ children }) {
  const [count, setCount] = useState(0)

  return (
    <main>
      <p>টেমপ্লেট: {count}</p>
      <button onClick={() => setCount(count + 1)}>টেমপ্লেট আপডেট করুন</button>
      {children}
    </main>
  )
}

৫. `loading.js` ফাইল

`loading.js` (অথবা `loading.jsx`, `loading.ts`, `loading.tsx`) ফাইলটি আপনাকে একটি লোডিং UI তৈরি করার অনুমতি দেয় যা একটি রুট সেগমেন্ট লোড হওয়ার সময় প্রদর্শিত হয়। ডেটা ফেচিং বা অন্যান্য অ্যাসিঙ্ক্রোনাস অপারেশন করার সময় এটি একটি ভালো ব্যবহারকারীর অভিজ্ঞতা প্রদানের জন্য দরকারী।

উদাহরণ:

// app/about/loading.js
import React from 'react';

export default function Loading() {
  return <p>আমাদের সম্পর্কে তথ্য লোড হচ্ছে...</p>;
}

যখন একজন ব্যবহারকারী `/about`-এ নেভিগেট করেন, তখন `page.js` কম্পোনেন্টটি সম্পূর্ণরূপে রেন্ডার না হওয়া পর্যন্ত `Loading` কম্পোনেন্টটি প্রদর্শিত হবে।

৬. `error.js` ফাইল

`error.js` (অথবা `error.jsx`, `error.ts`, `error.tsx`) ফাইলটি আপনাকে একটি কাস্টম ত্রুটি UI তৈরি করার অনুমতি দেয় যা একটি রুট সেগমেন্টের মধ্যে ত্রুটি ঘটলে প্রদর্শিত হয়। এটি একটি আরও ব্যবহারকারী-বান্ধব ত্রুটি বার্তা প্রদান এবং পুরো অ্যাপ্লিকেশনটি ক্র্যাশ হওয়া থেকে রক্ষা করার জন্য দরকারী।

উদাহরণ:

// app/about/error.js
'use client'

import React from 'react';

export default function Error({ error, reset }) {
  return (
    <div>
      <h2>একটি ত্রুটি ঘটেছে!</h2>
      <p>{error.message}</p>
      <button onClick={() => reset()}>আবার চেষ্টা করুন</button>
    </div>
  );
}

যদি `/about` পেজ রেন্ডার করার সময় কোনো ত্রুটি ঘটে, তাহলে `Error` কম্পোনেন্টটি প্রদর্শিত হবে। `error` প্রপ-এ ত্রুটি সম্পর্কে তথ্য থাকে এবং `reset` ফাংশন ব্যবহারকারীকে পেজটি পুনরায় লোড করার চেষ্টা করার সুযোগ দেয়।

৭. রুট গ্রুপ

রুট গ্রুপ `(groupName)` আপনাকে URL কাঠামোকে প্রভাবিত না করে আপনার রুটগুলিকে সংগঠিত করার অনুমতি দেয়। এগুলি একটি ফোল্ডারের নামকে বন্ধনীতে মুড়ে তৈরি করা হয়। এটি লেআউট এবং শেয়ার্ড কম্পোনেন্টগুলি সংগঠিত করার জন্য বিশেষভাবে সহায়ক।

উদাহরণ:

app/
  (marketing)/
    about/
      page.js
    contact/
      page.js
  (shop)/
    products/
      page.js

এই উদাহরণে, `about` এবং `contact` পেজগুলি `marketing` গ্রুপের অধীনে এবং `products` পেজটি `shop` গ্রুপের অধীনে গ্রুপ করা হয়েছে। URL গুলি যথাক্রমে `/about`, `/contact`, এবং `/products` থাকে।

৮. ডাইনামিক রুট

ডাইনামিক রুট আপনাকে পরিবর্তনশীল সেগমেন্ট সহ রুট তৈরি করতে দেয়। এটি একটি ডেটাবেস বা API থেকে আনা ডেটার উপর ভিত্তি করে বিষয়বস্তু প্রদর্শন করার জন্য দরকারী। ডাইনামিক রুট সেগমেন্টগুলি সেগমেন্টের নামকে বর্গাকার বন্ধনীতে (যেমন, `[id]`) মুড়ে সংজ্ঞায়িত করা হয়।

উদাহরণ:

ধরা যাক, আপনি তাদের ID-এর উপর ভিত্তি করে স্বতন্ত্র ব্লগ পোস্ট প্রদর্শনের জন্য একটি রুট তৈরি করতে চান। আপনি এমন একটি ফাইল কাঠামো তৈরি করতে পারেন:

app/
  blog/
    [id]/
      page.js

`[id]` সেগমেন্টটি একটি ডাইনামিক সেগমেন্ট। যখন একজন ব্যবহারকারী `/blog/123` বা `/blog/456`-এর মতো একটি URL-এ নেভিগেট করেন, তখন `app/blog/[id]/page.js` থেকে এক্সপোর্ট করা কম্পোনেন্টটি রেন্ডার করা হবে। `id` প্যারামিটারের মান কম্পোনেন্টের `params` প্রপ-এ উপলব্ধ থাকবে।

// app/blog/[id]/page.js
import React from 'react';

export default async function BlogPost({ params }) {
  const { id } = params;

  // প্রদত্ত ID সহ ব্লগ পোস্টের জন্য ডেটা আনুন
  const post = await fetchBlogPost(id);

  if (!post) {
    return <p>ব্লগ পোস্ট পাওয়া যায়নি।</p>;
  }

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  );
}

async function fetchBlogPost(id) {
  // একটি ডেটাবেস বা API থেকে ডেটা আনার অনুকরণ করুন
  return new Promise((resolve) => {
    setTimeout(() => {
      const posts = {
        '123': { title: 'আমার প্রথম ব্লগ পোস্ট', content: 'এটি আমার প্রথম ব্লগ পোস্টের বিষয়বস্তু।' },
        '456': { title: 'আরেকটি ব্লগ পোস্ট', content: 'এটি আরও কিছু উত্তেজনাপূর্ণ বিষয়বস্তু।' },
      };
      resolve(posts[id] || null);
    }, 500);
  });
}

আপনি একটি রুটে একাধিক ডাইনামিক সেগমেন্টও ব্যবহার করতে পারেন। উদাহরণস্বরূপ, আপনার `/blog/[category]/[id]` এর মতো একটি রুট থাকতে পারে।

৯. ক্যাচ-অল সেগমেন্ট

ক্যাচ-অল সেগমেন্ট আপনাকে এমন রুট তৈরি করতে দেয় যা যেকোনো সংখ্যক সেগমেন্টের সাথে মেলে। এটি এমন পরিস্থিতিতে দরকারী যেমন একটি CMS তৈরি করা যেখানে URL কাঠামো ব্যবহারকারী দ্বারা নির্ধারিত হয়। ক্যাচ-অল সেগমেন্টগুলি সেগমেন্টের নামের আগে তিনটি বিন্দু যোগ করে (যেমন, `[...slug]`) সংজ্ঞায়িত করা হয়।

উদাহরণ:

app/
  docs/
    [...slug]/
      page.js

`[...slug]` সেগমেন্টটি `/docs`-এর পরে যেকোনো সংখ্যক সেগমেন্টের সাথে মিলবে। উদাহরণস্বরূপ, এটি `/docs/getting-started`, `/docs/api/users`, এবং `/docs/advanced/configuration`-এর সাথে মিলবে। `slug` প্যারামিটারের মান একটি অ্যারে হবে যাতে মিলিত সেগমেন্টগুলি থাকবে।

// app/docs/[...slug]/page.js
import React from 'react';

export default function DocsPage({ params }) {
  const { slug } = params;

  return (
    <div>
      <h1>ডক্স</h1>
      <p>স্লাগ: {slug ? slug.join('/') : 'কোনো স্লাগ নেই'}</p>
    </div>
  );
}

ঐচ্ছিক ক্যাচ-অল সেগমেন্ট তৈরি করা যেতে পারে সেগমেন্টের নাম ডবল বর্গাকার বন্ধনীতে `[[...slug]]` যোগ করে। এটি রুট সেগমেন্টকে ঐচ্ছিক করে তোলে। উদাহরণ:

app/
  blog/
    [[...slug]]/
      page.js

এই সেটআপটি `/blog` এবং `/blog/any/number/of/segments` উভয় স্থানেই page.js কম্পোনেন্টটি রেন্ডার করবে।

১০. প্যারালাল রুট

প্যারালাল রুট আপনাকে একই লেআউটে এক বা একাধিক পেজ একসাথে রেন্ডার করতে দেয়। এটি ড্যাশবোর্ডের মতো জটিল লেআউটের জন্য বিশেষভাবে কার্যকর, যেখানে পেজের বিভিন্ন অংশ স্বাধীনভাবে লোড করা যায়। প্যারালাল রুট `@` চিহ্ন এবং তারপরে একটি স্লটের নাম (যেমন, `@sidebar`, `@main`) ব্যবহার করে সংজ্ঞায়িত করা হয়।

উদাহরণ:

app/
  @sidebar/
    page.js  // সাইডবারের জন্য বিষয়বস্তু
  @main/
    page.js  // মূল অংশের জন্য বিষয়বস্তু
  default.js // আবশ্যক: প্যারালাল রুটের জন্য ডিফল্ট লেআউট সংজ্ঞায়িত করে

প্যারালাল রুট ব্যবহার করার সময় `default.js` ফাইলটি আবশ্যক। এটি সংজ্ঞায়িত করে যে চূড়ান্ত লেআউট তৈরি করার জন্য বিভিন্ন স্লট কীভাবে একত্রিত হবে।

// app/default.js
export default function RootLayout({ children: { sidebar, main } }) {
  return (
    <div style={{ display: 'flex' }}>
      <aside style={{ width: '200px', backgroundColor: '#f0f0f0' }}>
        {sidebar}
      </aside>
      <main style={{ flex: 1, padding: '20px' }}>
        {main}
      </main>
    </div>
  );
}

১১. ইন্টারসেপ্টিং রুট

ইন্টারসেপ্টিং রুট আপনাকে আপনার অ্যাপ্লিকেশনের একটি ভিন্ন অংশ থেকে বর্তমান লেআউটের মধ্যে একটি রুট লোড করতে দেয়। এটি মোডাল, ইমেজ গ্যালারী এবং অন্যান্য UI উপাদান তৈরি করার জন্য দরকারী যা বিদ্যমান পেজের বিষয়বস্তুর উপরে উপস্থিত হওয়া উচিত। ইন্টারসেপ্টিং রুট `(..)` সিনট্যাক্স ব্যবহার করে সংজ্ঞায়িত করা হয়, যা নির্দেশ করে যে ইন্টারসেপ্ট করা রুটটি খুঁজে পেতে ডিরেক্টরি ট্রি-তে কত লেভেল উপরে যেতে হবে।

উদাহরণ:

app/
  (.)photos/
    [id]/
      page.js  // ইন্টারসেপ্ট করা রুট
  feed/
    page.js  // যে পেজে ছবির মোডালটি প্রদর্শিত হয়

এই উদাহরণে, যখন একজন ব্যবহারকারী `/feed` পেজে একটি ছবিতে ক্লিক করেন, তখন `app/(.)photos/[id]/page.js` রুটটি ইন্টারসেপ্ট করা হয় এবং `/feed` পেজের উপরে একটি মোডাল হিসাবে প্রদর্শিত হয়। `(.)` সিনট্যাক্স Next.js-কে `photos/[id]` রুটটি খুঁজে পেতে এক লেভেল উপরে (অর্থাৎ `app` ডিরেক্টরিতে) তাকাতে বলে।

অ্যাপ রাউটার দিয়ে ডেটা ফেচিং

অ্যাপ রাউটার সার্ভার কম্পোনেন্ট এবং ক্লায়েন্ট কম্পোনেন্ট ব্যবহার করে ডেটা ফেচিং এর জন্য বিল্ট-ইন সমর্থন প্রদান করে। সার্ভার কম্পোনেন্টগুলি সার্ভারে রেন্ডার করা হয়, যখন ক্লায়েন্ট কম্পোনেন্টগুলি ক্লায়েন্টে রেন্ডার করা হয়। এটি আপনাকে প্রতিটি কম্পোনেন্টের প্রয়োজনীয়তার উপর ভিত্তি করে সেরা পদ্ধতি বেছে নিতে দেয়।

সার্ভার কম্পোনেন্ট

সার্ভার কম্পোনেন্টগুলি অ্যাপ রাউটারে ডিফল্ট। এগুলি আপনাকে আলাদা API রুটের প্রয়োজন ছাড়াই সরাসরি আপনার কম্পোনেন্টগুলিতে ডেটা আনতে দেয়। এটি পারফরম্যান্স উন্নত করতে এবং আপনার কোডকে সহজ করতে পারে।

উদাহরণ:

// app/products/page.js
import React from 'react';

export default async function ProductsPage() {
  const products = await fetchProducts();

  return (
    <div>
      <h1>পণ্যসমূহ</h1>
      <ul>
        {products.map((product) => (
          <li key={product.id}>{product.name}</li>
        ))}
      </ul>
    </div>
  );
}

async function fetchProducts() {
  // একটি ডেটাবেস বা API থেকে ডেটা আনার অনুকরণ করুন
  return new Promise((resolve) => {
    setTimeout(() => {
      const products = [
        { id: 1, name: 'পণ্য ক' },
        { id: 2, name: 'পণ্য খ' },
        { id: 3, name: 'পণ্য গ' },
      ];
      resolve(products);
    }, 500);
  });
}

এই উদাহরণে, `fetchProducts` ফাংশনটি সরাসরি `ProductsPage` কম্পোনেন্টের মধ্যে কল করা হয়। কম্পোনেন্টটি সার্ভারে রেন্ডার করা হয়, এবং ডেটা ক্লায়েন্টের কাছে HTML পাঠানোর আগে আনা হয়।

ক্লায়েন্ট কম্পোনেন্ট

ক্লায়েন্ট কম্পোনেন্টগুলি ক্লায়েন্টে রেন্ডার করা হয় এবং আপনাকে ইভেন্ট লিসেনার, স্টেট এবং ব্রাউজার API-এর মতো ক্লায়েন্ট-সাইড বৈশিষ্ট্যগুলি ব্যবহার করতে দেয়। একটি ক্লায়েন্ট কম্পোনেন্ট ব্যবহার করতে, আপনাকে ফাইলের শীর্ষে `'use client'` নির্দেশিকা যোগ করতে হবে।

উদাহরণ:

// app/counter/page.js
'use client'

import React, { useState } from 'react';

export default function CounterPage() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>কাউন্টার</h1>
      <p>গণনা: {count}</p>
      <button onClick={() => setCount(count + 1)}>বৃদ্ধি করুন</button>
    </div>
  );
}

এই উদাহরণে, `CounterPage` কম্পোনেন্টটি একটি ক্লায়েন্ট কম্পোনেন্ট কারণ এটি `useState` হুক ব্যবহার করে। `'use client'` নির্দেশিকা Next.js-কে এই কম্পোনেন্টটি ক্লায়েন্টে রেন্ডার করতে বলে।

অ্যাডভান্সড রাউটিং কৌশল

অ্যাপ রাউটার বেশ কিছু অ্যাডভান্সড রাউটিং কৌশল সরবরাহ করে যা জটিল এবং পরিশীলিত অ্যাপ্লিকেশন তৈরি করতে ব্যবহার করা যেতে পারে।

১. রুট হ্যান্ডলার

রুট হ্যান্ডলার আপনাকে আপনার `app` ডিরেক্টরির মধ্যে API এন্ডপয়েন্ট তৈরি করতে দেয়। এটি একটি পৃথক `pages/api` ডিরেক্টরির প্রয়োজনীয়তা দূর করে। রুট হ্যান্ডলারগুলি `route.js` (বা `route.ts`) নামক ফাইলে সংজ্ঞায়িত করা হয় এবং বিভিন্ন HTTP পদ্ধতি (যেমন, `GET`, `POST`, `PUT`, `DELETE`) হ্যান্ডেল করে এমন ফাংশন এক্সপোর্ট করে।

উদাহরণ:

// app/api/users/route.js
import { NextResponse } from 'next/server'

export async function GET(request) {
  // একটি ডেটাবেস থেকে ব্যবহারকারীদের আনার অনুকরণ করুন
  const users = [
    { id: 1, name: 'জন ডো' },
    { id: 2, name: 'জেন ডো' },
  ];

  return NextResponse.json(users);
}

export async function POST(request) {
  const body = await request.json()
  console.log('প্রাপ্ত ডেটা:', body)
  return NextResponse.json({ message: 'ব্যবহারকারী তৈরি হয়েছে' }, { status: 201 })
}

এই উদাহরণটি `/api/users`-এ একটি রুট হ্যান্ডলার সংজ্ঞায়িত করে যা `GET` এবং `POST` উভয় অনুরোধই হ্যান্ডেল করে। `GET` ফাংশনটি ব্যবহারকারীদের একটি তালিকা প্রদান করে, এবং `POST` ফাংশনটি একটি নতুন ব্যবহারকারী তৈরি করে।

২. একাধিক লেআউট সহ রুট গ্রুপ

আপনি আপনার অ্যাপ্লিকেশনের বিভিন্ন বিভাগের জন্য বিভিন্ন লেআউট তৈরি করতে রুট গ্রুপ এবং লেআউট একত্রিত করতে পারেন। এটি এমন পরিস্থিতিতে দরকারী যেখানে আপনি আপনার সাইটের বিভিন্ন অংশের জন্য একটি ভিন্ন হেডার বা সাইডবার রাখতে চান।

উদাহরণ:

app/
  (marketing)/
    layout.js  // মার্কেটিং লেআউট
    about/
      page.js
    contact/
      page.js
  (admin)/
    layout.js  // অ্যাডমিন লেআউট
    dashboard/
      page.js

এই উদাহরণে, `about` এবং `contact` পেজগুলি `marketing` লেআউট ব্যবহার করবে, যখন `dashboard` পেজটি `admin` লেআউট ব্যবহার করবে।

৩. মিডলওয়্যার

মিডলওয়্যার আপনাকে আপনার অ্যাপ্লিকেশন দ্বারা একটি অনুরোধ হ্যান্ডেল করার আগে কোড চালানোর অনুমতি দেয়। এটি প্রমাণীকরণ, অনুমোদন, লগিং এবং ব্যবহারকারীদের তাদের অবস্থান বা ডিভাইসের উপর ভিত্তি করে পুনঃনির্দেশ করার মতো কাজের জন্য দরকারী।

মিডলওয়্যার আপনার প্রজেক্টের রুটে `middleware.js` (বা `middleware.ts`) নামক একটি ফাইলে সংজ্ঞায়িত করা হয়।

উদাহরণ:

// middleware.js
import { NextResponse } from 'next/server'

export function middleware(request) {
  // ব্যবহারকারী প্রমাণীকৃত কিনা তা পরীক্ষা করুন
  const isAuthenticated = false; // আপনার প্রমাণীকরণ লজিক দিয়ে প্রতিস্থাপন করুন

  if (!isAuthenticated && request.nextUrl.pathname.startsWith('/admin')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  return NextResponse.next();
}

// আরও জানতে "Matching Paths" দেখুন
export const config = {
  matcher: '/admin/:path*',
}

এই উদাহরণটি এমন একটি মিডলওয়্যার সংজ্ঞায়িত করে যা `/admin` এর অধীনে যেকোনো রুটে অ্যাক্সেস করার আগে ব্যবহারকারী প্রমাণীকৃত কিনা তা পরীক্ষা করে। যদি ব্যবহারকারী প্রমাণীকৃত না হন, তবে তাদের `/login` পেজে পুনঃনির্দেশ করা হয়।

ফাইল-ভিত্তিক রাউটিং এর জন্য সেরা অভ্যাস

অ্যাপ রাউটারের ফাইল-ভিত্তিক রাউটিং সিস্টেমের সর্বোচ্চ ব্যবহার করতে, নিম্নলিখিত সেরা অভ্যাসগুলি বিবেচনা করুন:

Next.js অ্যাপ রাউটার দিয়ে আন্তর্জাতিকীকরণের উদাহরণ

Next.js অ্যাপ রাউটার ফাইল-ভিত্তিক রাউটিংয়ের মাধ্যমে আন্তর্জাতিকীকরণ (i18n) সহজ করে তোলে। এখানে আপনি কীভাবে কার্যকরভাবে i18n বাস্তবায়ন করতে পারেন তা দেখানো হলো:

১. সাব-পাথ রাউটিং

সাব-পাথ ব্যবহার করে লোকেল অনুসারে আপনার রুটগুলি সংগঠিত করুন। উদাহরণস্বরূপ:

app/
  [locale]/
    page.tsx         // লোকেল-এর জন্য হোম পেজ
    about/
      page.tsx     // লোকেল-এর জন্য অ্যাবাউট পেজ
// app/[locale]/page.tsx
import { getTranslations } from './dictionaries';

export default async function HomePage({ params: { locale } }) {
  const t = await getTranslations(locale);
  return (<h1>{t.home.title}</h1>);
}

// dictionaries.js
const dictionaries = {
  en: () => import('./dictionaries/en.json').then((module) => module.default),
  es: () => import('./dictionaries/es.json').then((module) => module.default),
};

export const getTranslations = async (locale) => {
  try {
    return dictionaries[locale]() ?? dictionaries.en();
  } catch (error) {
    console.error(`Failed to load translations for locale ${locale}`, error);
    return dictionaries.en();
  }
};

এই সেটআপে, `[locale]` ডাইনামিক রুট সেগমেন্টটি বিভিন্ন লোকেল (যেমন, `/en`, `/es`) হ্যান্ডেল করে। অনুবাদগুলি লোকেল অনুসারে গতিশীলভাবে লোড হয়।

২. ডোমেইন রাউটিং

আরও উন্নত পদ্ধতির জন্য, আপনি প্রতিটি লোকেল-এর জন্য বিভিন্ন ডোমেইন বা সাবডোমেইন ব্যবহার করতে পারেন। এর জন্য প্রায়শই আপনার হোস্টিং প্রদানকারীর সাথে অতিরিক্ত কনফিগারেশন প্রয়োজন হয়।

৩. লোকেল সনাক্তকরণের জন্য মিডলওয়্যার

ব্যবহারকারীর পছন্দের লোকেল স্বয়ংক্রিয়ভাবে সনাক্ত করতে এবং তাদের সেই অনুযায়ী পুনঃনির্দেশ করতে মিডলওয়্যার ব্যবহার করুন।

// middleware.js
import { NextResponse } from 'next/server';
import { match } from '@formatjs/intl-localematcher';
import Negotiator from 'negotiator';

let locales = ['en', 'es', 'fr'];

function getLocale(request) {
  const negotiatorHeaders = {};
  request.headers.forEach((value, key) => (negotiatorHeaders[key] = value));
  let languages = new Negotiator({ headers: negotiatorHeaders }).languages();

  try {
      return match(languages, locales, 'en'); // "en" কে ডিফল্ট লোকেল হিসেবে ব্যবহার করুন
  } catch (error) {
      console.error("Error matching locale:", error);
      return 'en'; // ম্যাচিং ব্যর্থ হলে ইংরেজিতে ফলব্যাক করুন
  }
}

export function middleware(request) {
  const pathname = request.nextUrl.pathname;
  const pathnameIsMissingLocale = locales.every(
    (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
  );

  if (pathnameIsMissingLocale) {
    const locale = getLocale(request);

    return NextResponse.redirect(
      new URL(
        `/${locale}${pathname.startsWith('/') ? '' : '/'}${pathname}`,
        request.url
      )
    );
  }
}

export const config = {
  matcher: [
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
};

এই মিডলওয়্যারটি অনুরোধ করা পাথে লোকেল প্রিফিক্স আছে কিনা তা পরীক্ষা করে। যদি না থাকে, তবে এটি `Accept-Language` হেডার ব্যবহার করে ব্যবহারকারীর পছন্দের লোকেল সনাক্ত করে এবং তাদের উপযুক্ত লোকেল-নির্দিষ্ট পাথে পুনঃনির্দেশ করে। লোকেল নেগোসিয়েশন হ্যান্ডেল করার জন্য `@formatjs/intl-localematcher` এবং `negotiator`-এর মতো লাইব্রেরি ব্যবহার করা হয়।

Next.js অ্যাপ রাউটার এবং গ্লোবাল অ্যাক্সেসিবিলিটি

বিশ্বব্যাপী অ্যাক্সেসযোগ্য ওয়েব অ্যাপ্লিকেশন তৈরির জন্য অ্যাক্সেসিবিলিটি (a11y) নীতির সতর্ক বিবেচনা প্রয়োজন। Next.js অ্যাপ রাউটার অ্যাক্সেসযোগ্য অভিজ্ঞতা তৈরির জন্য একটি শক্তিশালী ভিত্তি প্রদান করে, তবে আপনার অ্যাপ্লিকেশনটি সবার জন্য ব্যবহারযোগ্য তা নিশ্চিত করার জন্য সেরা অভ্যাসগুলি বাস্তবায়ন করা অপরিহার্য, তাদের ক্ষমতা নির্বিশেষে।

মূল অ্যাক্সেসিবিলিটি বিবেচ্য বিষয়

  1. সিমেন্টিক HTML: আপনার বিষয়বস্তু গঠন করার জন্য সিমেন্টিক HTML উপাদান (যেমন, `<article>`, `<nav>`, `<aside>`, `<main>`) ব্যবহার করুন। এটি সহায়ক প্রযুক্তিকে অর্থ প্রদান করে এবং ব্যবহারকারীদের আপনার সাইট আরও সহজে নেভিগেট করতে সাহায্য করে।
  2. ARIA অ্যাট্রিবিউট: কাস্টম কম্পোনেন্ট এবং উইজেটগুলির অ্যাক্সেসিবিলিটি বাড়ানোর জন্য ARIA (Accessible Rich Internet Applications) অ্যাট্রিবিউট ব্যবহার করুন। ARIA অ্যাট্রিবিউটগুলি সহায়ক প্রযুক্তিকে উপাদানগুলির ভূমিকা, অবস্থা এবং বৈশিষ্ট্য সম্পর্কে অতিরিক্ত তথ্য প্রদান করে।
  3. কিবোর্ড নেভিগেশন: নিশ্চিত করুন যে সমস্ত ইন্টারেক্টিভ উপাদান কিবোর্ডের মাধ্যমে অ্যাক্সেসযোগ্য। ব্যবহারকারীদের `Tab` কী ব্যবহার করে আপনার অ্যাপ্লিকেশনের মাধ্যমে নেভিগেট করতে এবং `Enter` বা `Space` কী ব্যবহার করে উপাদানগুলির সাথে ইন্টারঅ্যাক্ট করতে সক্ষম হওয়া উচিত।
  4. রঙের কনট্রাস্ট: দৃষ্টি প্রতিবন্ধী ব্যবহারকারীদের জন্য পঠনযোগ্যতা নিশ্চিত করতে টেক্সট এবং ব্যাকগ্রাউন্ডের মধ্যে পর্যাপ্ত রঙের কনট্রাস্ট ব্যবহার করুন। ওয়েব কনটেন্ট অ্যাক্সেসিবিলিটি গাইডলাইনস (WCAG) সাধারণ টেক্সটের জন্য কমপক্ষে 4.5:1 এবং বড় টেক্সটের জন্য 3:1 কনট্রাস্ট অনুপাতের সুপারিশ করে।
  5. ইমেজ অল্ট টেক্সট: সমস্ত ইমেজের জন্য বর্ণনামূলক অল্ট টেক্সট প্রদান করুন। অল্ট টেক্সট ইমেজের জন্য একটি টেক্সট বিকল্প প্রদান করে যা স্ক্রিন রিডার দ্বারা পড়া যায়।
  6. ফর্ম লেবেল: `<label>` উপাদান ব্যবহার করে ফর্ম লেবেলগুলিকে তাদের সংশ্লিষ্ট ইনপুট ফিল্ডের সাথে সংযুক্ত করুন। এটি ব্যবহারকারীদের কাছে স্পষ্ট করে যে প্রতিটি ফিল্ডে কী তথ্য প্রত্যাশিত।
  7. স্ক্রিন রিডার টেস্টিং: আপনার অ্যাপ্লিকেশনটি দৃষ্টি প্রতিবন্ধী ব্যবহারকারীদের জন্য অ্যাক্সেসযোগ্য কিনা তা নিশ্চিত করতে একটি স্ক্রিন রিডার দিয়ে পরীক্ষা করুন। জনপ্রিয় স্ক্রিন রিডারগুলির মধ্যে রয়েছে NVDA, JAWS, এবং VoiceOver।

Next.js অ্যাপ রাউটারে অ্যাক্সেসিবিলিটি বাস্তবায়ন

  1. Next.js লিঙ্ক কম্পোনেন্ট ব্যবহার করুন: নেভিগেশনের জন্য `<Link>` কম্পোনেন্ট ব্যবহার করুন। এটি প্রিফেচিং এবং ফোকাস ব্যবস্থাপনার মতো বিল্ট-ইন অ্যাক্সেসিবিলিটি বৈশিষ্ট্য সরবরাহ করে।
  2. ফোকাস ব্যবস্থাপনা: পেজগুলির মধ্যে নেভিগেট করার সময় বা মোডাল খোলার সময়, নিশ্চিত করুন যে ফোকাস সঠিকভাবে পরিচালিত হয়। ফোকাস নতুন পেজ বা মোডালের সবচেয়ে যৌক্তিক উপাদানে সেট করা উচিত।
  3. অ্যাক্সেসযোগ্য কাস্টম কম্পোনেন্ট: কাস্টম কম্পোনেন্ট তৈরি করার সময়, উপরে বর্ণিত নীতিগুলি অনুসরণ করে নিশ্চিত করুন যে সেগুলি অ্যাক্সেসযোগ্য। আপনার কম্পোনেন্টগুলিকে সবার জন্য ব্যবহারযোগ্য করতে সিমেন্টিক HTML, ARIA অ্যাট্রিবিউট এবং কিবোর্ড নেভিগেশন ব্যবহার করুন।
  4. লিন্টিং এবং টেস্টিং: আপনার কোডে সম্ভাব্য অ্যাক্সেসিবিলিটি সমস্যাগুলি সনাক্ত করতে অ্যাক্সেসিবিলিটি প্লাগইন সহ ESLint-এর মতো লিন্টিং সরঞ্জাম ব্যবহার করুন। এছাড়াও, অ্যাক্সেসিবিলিটি লঙ্ঘনের জন্য আপনার অ্যাপ্লিকেশন পরীক্ষা করার জন্য স্বয়ংক্রিয় পরীক্ষার সরঞ্জাম ব্যবহার করুন।

উপসংহার

Next.js অ্যাপ রাউটারের ফাইল-ভিত্তিক রাউটিং সিস্টেম আপনার অ্যাপ্লিকেশনগুলিকে গঠন এবং নেভিগেট করার একটি শক্তিশালী এবং স্বজ্ঞাত উপায় সরবরাহ করে। এই গাইডে বর্ণিত মূল ধারণা এবং সেরা অভ্যাসগুলি বোঝার মাধ্যমে, আপনি শক্তিশালী, স্কেলযোগ্য এবং রক্ষণাবেক্ষণযোগ্য Next.js অ্যাপ্লিকেশন তৈরি করতে পারেন। অ্যাপ রাউটারের বিভিন্ন বৈশিষ্ট্য নিয়ে পরীক্ষা করুন এবং আবিষ্কার করুন কীভাবে এটি আপনার ডেভেলপমেন্ট ওয়ার্কফ্লোকে সহজ করতে এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে পারে।