हिन्दी

हमारे फ़ाइल-आधारित रूटिंग के गहन गाइड के साथ 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 इस प्रक्रिया में आपकी मदद करने के लिए एक माइग्रेशन गाइड प्रदान करता है।

फ़ाइल-आधारित रूटिंग की मुख्य अवधारणाएँ

ऐप राउटर कई विशेष फ़ाइलों और परंपराओं को पेश करता है जो यह परिभाषित करती हैं कि आपके रूट्स को कैसे संभाला जाता है:

1. `app` डायरेक्टरी

`app` डायरेक्टरी आपके एप्लिकेशन के रूट्स की जड़ है। इस डायरेक्टरी के भीतर सभी फ़ाइलें और फ़ोल्डर रूट्स उत्पन्न करने के लिए उपयोग किए जाएंगे। `app` डायरेक्टरी के बाहर कुछ भी (जैसे `pages` डायरेक्टरी यदि आप माइग्रेट कर रहे हैं) ऐप राउटर द्वारा अनदेखा कर दिया जाएगा।

2. `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>
  );
}

3. `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 से बदल दिया जाएगा।

4. `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>
  )
}

5. `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>About जानकारी लोड हो रही है...</p>;
}

जब कोई उपयोगकर्ता `/about` पर नेविगेट करता है, तो `Loading` कंपोनेंट तब तक प्रदर्शित होगा जब तक कि `page.js` कंपोनेंट पूरी तरह से रेंडर नहीं हो जाता।

6. `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` फ़ंक्शन उपयोगकर्ता को पेज को फिर से लोड करने का प्रयास करने की अनुमति देता है।

7. रूट ग्रुप्स

रूट ग्रुप्स `(groupName)` आपको URL संरचना को प्रभावित किए बिना अपने रूट्स को व्यवस्थित करने की अनुमति देते हैं। वे फ़ोल्डर के नाम को कोष्ठक में लपेटकर बनाए जाते हैं। यह लेआउट और साझा कंपोनेंट्स को व्यवस्थित करने के लिए विशेष रूप से सहायक है।

उदाहरण:

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

इस उदाहरण में, `about` और `contact` पेज `marketing` ग्रुप के अंतर्गत हैं, और `products` पेज `shop` ग्रुप के अंतर्गत है। URL क्रमशः `/about`, `/contact`, और `/products` ही रहते हैं।

8. डायनामिक रूट्स

डायनामिक रूट्स आपको वेरिएबल सेगमेंट के साथ रूट्स बनाने की अनुमति देते हैं। यह डेटाबेस या 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]` जैसा रूट हो सकता है।

9. कैच-ऑल सेगमेंट्स

कैच-ऑल सेगमेंट्स आपको ऐसे रूट्स बनाने की अनुमति देते हैं जो किसी भी संख्या में सेगमेंट से मेल खाते हैं। यह उन परिदृश्यों के लिए उपयोगी है जैसे कि एक सीएमएस बनाना जहां 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 कंपोनेंट को रेंडर करेगा।

10. पैरेलल रूट्स

पैरेलल रूट्स आपको एक ही लेआउट में एक साथ एक या अधिक पेजों को रेंडर करने की अनुमति देते हैं। यह जटिल लेआउट, जैसे डैशबोर्ड, के लिए विशेष रूप से उपयोगी है, जहां पेज के विभिन्न अनुभागों को स्वतंत्र रूप से लोड किया जा सकता है। पैरेलल रूट्स को `@` प्रतीक के बाद एक स्लॉट नाम (जैसे, `@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>
  );
}

11. इंटरसेप्टिंग रूट्स

इंटरसेप्टिंग रूट्स आपको अपने एप्लिकेशन के एक अलग हिस्से से वर्तमान लेआउट के भीतर एक रूट लोड करने की अनुमति देते हैं। यह मोडल, इमेज गैलरी और अन्य 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: 'उत्पाद A' },
        { id: 2, name: 'उत्पाद B' },
        { id: 3, name: 'उत्पाद C' },
      ];
      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 को बताता है कि इस कंपोनेंट को क्लाइंट पर रेंडर करें।

उन्नत रूटिंग तकनीकें

ऐप राउटर कई उन्नत रूटिंग तकनीकें प्रदान करता है जिनका उपयोग जटिल और परिष्कृत एप्लिकेशन बनाने के लिए किया जा सकता है।

1. रूट हैंडलर्स

रूट हैंडलर्स आपको अपनी `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: 'John Doe' },
    { id: 2, name: 'Jane Doe' },
  ];

  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` फ़ंक्शन एक नया उपयोगकर्ता बनाता है।

2. एकाधिक लेआउट के साथ रूट ग्रुप्स

आप अपने एप्लिकेशन के विभिन्न अनुभागों के लिए अलग-अलग लेआउट बनाने के लिए रूट ग्रुप्स को लेआउट के साथ जोड़ सकते हैं। यह उन परिदृश्यों के लिए उपयोगी है जहाँ आप अपनी साइट के विभिन्न हिस्सों के लिए एक अलग हेडर या साइडबार रखना चाहते हैं।

उदाहरण:

app/
  (marketing)/
    layout.js  // मार्केटिंग लेआउट
    about/
      page.js
    contact/
      page.js
  (admin)/
    layout.js  // एडमिन लेआउट
    dashboard/
      page.js

इस उदाहरण में, `about` और `contact` पेज `marketing` लेआउट का उपयोग करेंगे, जबकि `dashboard` पेज `admin` लेआउट का उपयोग करेगा।

3. मिडलवेयर

मिडलवेयर आपको आपके एप्लिकेशन द्वारा अनुरोध को संभालने से पहले कोड चलाने की अनुमति देता है। यह प्रमाणीकरण, प्राधिकरण, लॉगिंग और उपयोगकर्ताओं को उनके स्थान या डिवाइस के आधार पर पुनर्निर्देशित करने जैसे कार्यों के लिए उपयोगी है।

मिडलवेयर को आपके प्रोजेक्ट की जड़ में `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 को प्रभावी ढंग से कैसे लागू कर सकते हैं:

1. सब-पाथ रूटिंग

सब-पाथ का उपयोग करके लोकेल के आधार पर अपने रूट्स को व्यवस्थित करें। उदाहरण के लिए:

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(`लोकेल ${locale} के लिए अनुवाद लोड करने में विफल`, error);
    return dictionaries.en();
  }
};

इस सेटअप में, `[locale]` डायनामिक रूट सेगमेंट विभिन्न लोकेल (जैसे, `/en`, `/es`) को संभालता है। अनुवाद लोकेल के आधार पर गतिशील रूप से लोड होते हैं।

2. डोमेन रूटिंग

एक और उन्नत दृष्टिकोण के लिए, आप प्रत्येक लोकेल के लिए अलग-अलग डोमेन या सबडोमेन का उपयोग कर सकते हैं। इसमें अक्सर आपके होस्टिंग प्रदाता के साथ अतिरिक्त कॉन्फ़िगरेशन शामिल होता है।

3. लोकेल डिटेक्शन के लिए मिडलवेयर

उपयोगकर्ता के पसंदीदा लोकेल का स्वचालित रूप से पता लगाने और उन्हें तदनुसार पुनर्निर्देशित करने के लिए मिडलवेयर का उपयोग करें।

// 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);
      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 ऐप राउटर और वैश्विक पहुँच (Global Accessibility)

वैश्विक रूप से सुलभ वेब एप्लिकेशन बनाने के लिए पहुंच (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 एप्लिकेशन बना सकते हैं। ऐप राउटर की विभिन्न विशेषताओं के साथ प्रयोग करें और जानें कि यह आपके विकास वर्कफ़्लो को कैसे सरल बना सकता है और उपयोगकर्ता अनुभव में सुधार कर सकता है।