> ## Documentation Index
> Fetch the complete documentation index at: https://docs.matterai.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Next.js

> Next.js is a React framework that enables server-side rendering, static site generation, and other advanced features with zero configuration. It provides a powerful foundation for building production-ready React applications.

<AccordionGroup>
  <Accordion title="Next.js Anti-Patterns Overview" icon="react">
    Next.js, despite its powerful features and optimizations, has several common anti-patterns that can lead to performance issues, maintenance problems, and poor user experience. Here are the most important anti-patterns to avoid when building Next.js applications.
  </Accordion>

  <Accordion title="Not Using the Correct Data Fetching Method" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: Using client-side data fetching for static content
    function ProductPage({ productId }) {
      const [product, setProduct] = useState(null);
      const [loading, setLoading] = useState(true);
      
      useEffect(() => {
        async function fetchProduct() {
          const res = await fetch(`/api/products/${productId}`);
          const data = await res.json();
          setProduct(data);
          setLoading(false);
        }
        
        fetchProduct();
      }, [productId]);
      
      if (loading) return <div>Loading...</div>;
      
      return (
        <div>
          <h1>{product.name}</h1>
          <p>{product.description}</p>
        </div>
      );
    }

    // Better approach: Use getStaticProps for static content
    export async function getStaticProps({ params }) {
      const res = await fetch(`https://api.example.com/products/${params.id}`);
      const product = await res.json();
      
      return {
        props: {
          product,
        },
        revalidate: 60, // Optional: Regenerate page after 60 seconds
      };
    }

    export async function getStaticPaths() {
      const res = await fetch('https://api.example.com/products');
      const products = await res.json();
      
      const paths = products.map((product) => ({
        params: { id: product.id.toString() },
      }));
      
      return { paths, fallback: 'blocking' };
    }

    function ProductPage({ product }) {
      return (
        <div>
          <h1>{product.name}</h1>
          <p>{product.description}</p>
        </div>
      );
    }
    ```

    Using client-side data fetching for content that could be pre-rendered leads to poor performance and SEO. Choose the appropriate data fetching method: `getStaticProps` for static content, `getServerSideProps` for dynamic content, and client-side fetching only for user-specific or frequently changing data.
  </Accordion>

  <Accordion title="Not Using Image Optimization" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: Using regular img tags
    function ProductCard({ product }) {
      return (
        <div className="card">
          <img 
            src={product.imageUrl} 
            alt={product.name} 
            width={300} 
            height={200} 
          />
          <h3>{product.name}</h3>
        </div>
      );
    }

    // Better approach: Use Next.js Image component
    import Image from 'next/image';

    function ProductCard({ product }) {
      return (
        <div className="card">
          <Image 
            src={product.imageUrl} 
            alt={product.name} 
            width={300} 
            height={200} 
            placeholder="blur"
            blurDataURL="data:image/jpeg;base64,..."
            priority={product.featured}
          />
          <h3>{product.name}</h3>
        </div>
      );
    }
    ```

    Regular `<img>` tags don't benefit from Next.js's automatic image optimization. Use the `next/image` component to get automatic image optimization, lazy loading, and proper sizing.
  </Accordion>

  <Accordion title="Not Using Next.js Link Component" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: Using regular anchor tags
    function Navigation() {
      return (
        <nav>
          <a href="/">Home</a>
          <a href="/about">About</a>
          <a href="/products">Products</a>
        </nav>
      );
    }

    // Better approach: Use Next.js Link component
    import Link from 'next/link';

    function Navigation() {
      return (
        <nav>
          <Link href="/">
            <a>Home</a>
          </Link>
          <Link href="/about">
            <a>About</a>
          </Link>
          <Link href="/products">
            <a>Products</a>
          </Link>
        </nav>
      );
    }

    // In Next.js 13+ with the App Router
    import Link from 'next/link';

    function Navigation() {
      return (
        <nav>
          <Link href="/">Home</Link>
          <Link href="/about">About</Link>
          <Link href="/products">Products</Link>
        </nav>
      );
    }
    ```

    Regular anchor tags cause full page reloads. Use the `next/link` component for client-side navigation between pages, which is faster and preserves state.
  </Accordion>

  <Accordion title="Misusing the API Routes" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: Using API routes to fetch data for getStaticProps
    // pages/products/[id].js
    export async function getStaticProps({ params }) {
      // Don't do this - it creates an unnecessary network request
      const res = await fetch(`http://localhost:3000/api/products/${params.id}`);
      const product = await res.json();
      
      return {
        props: { product },
      };
    }

    // pages/api/products/[id].js
    export default async function handler(req, res) {
      const { id } = req.query;
      const product = await getProductFromDatabase(id);
      res.status(200).json(product);
    }

    // Better approach: Import the data fetching logic directly
    // lib/products.js
    export async function getProductById(id) {
      return await getProductFromDatabase(id);
    }

    // pages/products/[id].js
    import { getProductById } from '../../lib/products';

    export async function getStaticProps({ params }) {
      const product = await getProductById(params.id);
      
      return {
        props: { product },
      };
    }

    // pages/api/products/[id].js
    import { getProductById } from '../../../lib/products';

    export default async function handler(req, res) {
      const { id } = req.query;
      const product = await getProductById(id);
      res.status(200).json(product);
    }
    ```

    Using API routes to fetch data for `getStaticProps` or `getServerSideProps` creates unnecessary network requests. Import the data fetching logic directly in both server-side functions and API routes.
  </Accordion>

  <Accordion title="Not Using Incremental Static Regeneration" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: Using getServerSideProps for semi-static content
    export async function getServerSideProps() {
      const res = await fetch('https://api.example.com/products');
      const products = await res.json();
      
      return {
        props: { products },
      };
    }

    // Better approach: Use Incremental Static Regeneration
    export async function getStaticProps() {
      const res = await fetch('https://api.example.com/products');
      const products = await res.json();
      
      return {
        props: { products },
        revalidate: 60, // Regenerate page after 60 seconds if requested
      };
    }
    ```

    Using `getServerSideProps` for content that doesn't change frequently adds unnecessary server load. Use Incremental Static Regeneration (ISR) with `revalidate` for content that changes occasionally.
  </Accordion>

  <Accordion title="Not Optimizing for Core Web Vitals" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: Loading large JavaScript libraries upfront
    import LargeChart from 'heavy-chart-library';

    function DashboardPage() {
      return (
        <div>
          <h1>Dashboard</h1>
          <LargeChart data={someData} />
        </div>
      );
    }

    // Better approach: Use dynamic imports and suspense
    import dynamic from 'next/dynamic';
    import { Suspense } from 'react';

    const LargeChart = dynamic(() => import('heavy-chart-library'), {
      loading: () => <div>Loading chart...</div>,
      ssr: false, // Disable server-side rendering if the library isn't SSR compatible
    });

    function DashboardPage() {
      return (
        <div>
          <h1>Dashboard</h1>
          <Suspense fallback={<div>Loading chart...</div>}>
            <LargeChart data={someData} />
          </Suspense>
        </div>
      );
    }
    ```

    Loading large JavaScript libraries upfront hurts performance metrics like Largest Contentful Paint (LCP) and Time to Interactive (TTI). Use dynamic imports, code splitting, and prioritize loading critical content first.
  </Accordion>

  <Accordion title="Not Using TypeScript" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: Using plain JavaScript without type checking
    function UserProfile({ user }) {
      return (
        <div>
          <h1>{user.name}</h1>
          <p>{user.email}</p>
          <p>{user.address.street}, {user.address.city}</p>
        </div>
      );
    }

    // Better approach: Use TypeScript
    interface Address {
      street: string;
      city: string;
      zipCode: string;
      country: string;
    }

    interface User {
      id: string;
      name: string;
      email: string;
      address: Address;
    }

    interface UserProfileProps {
      user: User;
    }

    function UserProfile({ user }: UserProfileProps) {
      return (
        <div>
          <h1>{user.name}</h1>
          <p>{user.email}</p>
          <p>{user.address.street}, {user.address.city}</p>
        </div>
      );
    }
    ```

    Not using TypeScript can lead to runtime errors and makes refactoring more difficult. Use TypeScript to catch errors at compile time and improve code maintainability.
  </Accordion>

  <Accordion title="Not Using Layout Components" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: Duplicating layout code in every page
    function HomePage() {
      return (
        <div>
          <header>
            <nav>{/* Navigation items */}</nav>
          </header>
          <main>
            <h1>Welcome to our site</h1>
            {/* Page content */}
          </main>
          <footer>
            {/* Footer content */}
          </footer>
        </div>
      );
    }

    function AboutPage() {
      return (
        <div>
          <header>
            <nav>{/* Navigation items */}</nav>
          </header>
          <main>
            <h1>About Us</h1>
            {/* Page content */}
          </main>
          <footer>
            {/* Footer content */}
          </footer>
        </div>
      );
    }

    // Better approach: Use layout components
    function MainLayout({ children }) {
      return (
        <div>
          <header>
            <nav>{/* Navigation items */}</nav>
          </header>
          <main>{children}</main>
          <footer>
            {/* Footer content */}
          </footer>
        </div>
      );
    }

    function HomePage() {
      return (
        <MainLayout>
          <h1>Welcome to our site</h1>
          {/* Page content */}
        </MainLayout>
      );
    }

    function AboutPage() {
      return (
        <MainLayout>
          <h1>About Us</h1>
          {/* Page content */}
        </MainLayout>
      );
    }

    // In Next.js 13+ with App Router
    // app/layout.js
    export default function RootLayout({ children }) {
      return (
        <html lang="en">
          <body>
            <header>
              <nav>{/* Navigation items */}</nav>
            </header>
            <main>{children}</main>
            <footer>
              {/* Footer content */}
            </footer>
          </body>
        </html>
      );
    }
    ```

    Duplicating layout code across pages leads to maintenance issues. Use layout components or the App Router's layout system to share common UI elements across pages.
  </Accordion>

  <Accordion title="Not Using Next.js Config Properly" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: Not configuring Next.js properly
    // next.config.js
    module.exports = {
      // No configuration
    };

    // Better approach: Configure Next.js properly
    // next.config.js
    module.exports = {
      images: {
        domains: ['images.example.com'], // Allow images from this domain
        formats: ['image/avif', 'image/webp'], // Specify image formats
      },
      i18n: {
        locales: ['en', 'fr', 'es'],
        defaultLocale: 'en',
      },
      async redirects() {
        return [
          {
            source: '/old-blog/:slug',
            destination: '/blog/:slug',
            permanent: true,
          },
        ];
      },
      async headers() {
        return [
          {
            source: '/:path*',
            headers: [
              {
                key: 'X-Content-Type-Options',
                value: 'nosniff',
              },
              {
                key: 'X-Frame-Options',
                value: 'DENY',
              },
            ],
          },
        ];
      },
    };
    ```

    Not configuring Next.js properly means missing out on important optimizations and features. Use the Next.js config file to configure image domains, internationalization, redirects, headers, and other important settings.
  </Accordion>

  <Accordion title="Not Using Error Boundaries" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: No error handling
    function ProductPage({ product }) {
      return (
        <div>
          <Header />
          <ProductDetails product={product} /> {/* If this crashes, the whole page crashes */}
          <RelatedProducts ids={product.relatedIds} />
          <Footer />
        </div>
      );
    }

    // Better approach: Use error boundaries
    import { ErrorBoundary } from 'react-error-boundary';

    function ErrorFallback({ error, resetErrorBoundary }) {
      return (
        <div role="alert">
          <p>Something went wrong:</p>
          <pre>{error.message}</pre>
          <button onClick={resetErrorBoundary}>Try again</button>
        </div>
      );
    }

    function ProductPage({ product }) {
      return (
        <div>
          <Header />
          <ErrorBoundary 
            FallbackComponent={ErrorFallback}
            onReset={() => {
              // Reset the state of your app here
            }}
          >
            <ProductDetails product={product} />
          </ErrorBoundary>
          <RelatedProducts ids={product.relatedIds} />
          <Footer />
        </div>
      );
    }
    ```

    Without error boundaries, a runtime error in a component can break the entire page. Use error boundaries to gracefully handle errors and display fallback UIs.
  </Accordion>

  <Accordion title="Not Using Server Components Properly" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: Using client components for everything in Next.js 13+
    'use client';

    import { useState } from 'react';

    async function getData() {
      const res = await fetch('https://api.example.com/data');
      return res.json();
    }

    export default function Page() {
      const [count, setCount] = useState(0);
      const data = await getData(); // This will error in client components
      
      return (
        <div>
          <h1>Data: {data.title}</h1>
          <p>Count: {count}</p>
          <button onClick={() => setCount(count + 1)}>Increment</button>
        </div>
      );
    }

    // Better approach: Split into server and client components
    // Page.js (Server Component)
    import { Counter } from './Counter';

    async function getData() {
      const res = await fetch('https://api.example.com/data');
      return res.json();
    }

    export default async function Page() {
      const data = await getData();
      
      return (
        <div>
          <h1>Data: {data.title}</h1>
          <Counter />
        </div>
      );
    }

    // Counter.js (Client Component)
    'use client';

    import { useState } from 'react';

    export function Counter() {
      const [count, setCount] = useState(0);
      
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={() => setCount(count + 1)}>Increment</button>
        </div>
      );
    }
    ```

    Using client components for everything in Next.js 13+ misses the benefits of server components. Use server components for data fetching and rendering static content, and client components only for interactive parts of your UI.
  </Accordion>

  <Accordion title="Not Using Proper Caching Strategies" icon="warning">
    ```jsx theme={null}
    // Anti-pattern: Not implementing proper caching
    // pages/products/[id].js
    export async function getServerSideProps({ params }) {
      const res = await fetch(`https://api.example.com/products/${params.id}`);
      const product = await res.json();
      
      return {
        props: { product },
      };
    }

    // Better approach: Implement proper caching
    // pages/products/[id].js
    export async function getStaticProps({ params }) {
      const res = await fetch(`https://api.example.com/products/${params.id}`, {
        headers: {
          'Cache-Control': 'public, s-maxage=10, stale-while-revalidate=59',
        },
      });
      const product = await res.json();
      
      return {
        props: { product },
        revalidate: 60,
      };
    }

    // In Next.js 13+ App Router
    // app/products/[id]/page.js
    export const revalidate = 60; // Revalidate at most every 60 seconds

    async function getProduct(id) {
      const res = await fetch(`https://api.example.com/products/${id}`, {
        next: { revalidate: 60 },
      });
      return res.json();
    }

    export default async function ProductPage({ params }) {
      const product = await getProduct(params.id);
      
      return (
        <div>
          <h1>{product.name}</h1>
          <p>{product.description}</p>
        </div>
      );
    }
    ```

    Not implementing proper caching strategies can lead to unnecessary API calls and slower performance. Use appropriate caching headers and Next.js's built-in caching mechanisms like ISR and the fetch API's cache options.
  </Accordion>
</AccordionGroup>
