DevSecOps

Erori de Build Next.js: Ghid Complet de Depanare

Nicu Constantin
--7 min lectura
#nextjs#react#typescript#build-errors#troubleshooting

Erorile de build Next.js pot fi criptice. Acest ghid acopera toate erorile frecvente de build si solutiile lor pentru Next.js 14 si 15.

Eroare: Module Not Found

Simptom:

Module not found: Can't resolve 'some-package'
Error: Cannot find module '@/components/MyComponent'

Solutia 1 - Instaleaza pachetul lipsa:

npm install some-package

Solutia 2 - Corecteaza path alias:

// tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@components/*": ["./src/components/*"]
    }
  }
}

Solutia 3 - Verifica sensibilitatea la majuscule/minuscule:

// ❌ Gresit (Windows poate functiona, Linux nu)
import MyComponent from '@/Components/MyComponent';
 
// ✅ Corect (potriveste calea reala a fisierului)
import MyComponent from '@/components/MyComponent';

Eroare: Hydration Mismatch

Simptom:

Error: Hydration failed because the initial UI does not match what was rendered on the server
Warning: Expected server HTML to contain a matching <div> in <div>
Text content does not match server-rendered HTML

Cauza 1 - Cod doar pentru browser in renderul initial:

// ❌ Cauzeaza hydration mismatch
export default function Component() {
  return <div>{window.innerWidth}</div>;  // window undefined on server
}
 
// ✅ Foloseste useEffect pentru cod doar pe browser
export default function Component() {
  const [width, setWidth] = useState(0);
 
  useEffect(() => {
    setWidth(window.innerWidth);
  }, []);
 
  return <div>{width || 'Loading...'}</div>;
}

Cauza 2 - Diferente de data/ora:

// ❌ Diferit pe server vs client
<span>{new Date().toLocaleString()}</span>
 
// ✅ Suprima avertismentul de hydration sau foloseste useEffect
<span suppressHydrationWarning>{new Date().toLocaleString()}</span>
 
// ✅ Mai bine: formateaza doar pe client
const [time, setTime] = useState<string>();
useEffect(() => {
  setTime(new Date().toLocaleString());
}, []);

Cauza 3 - Extensii/modificari ale browserului:

// Adauga suppressHydrationWarning pe body pentru extensii de browser
<body suppressHydrationWarning>
  {children}
</body>

Eroare: Dynamic Server Usage in Static Route

Simptom:

Error: Dynamic server usage: headers
Route /api/route couldn't be rendered statically because it used `headers`
Page "/page" is using dynamic server features

Solutia 1 - Forteaza randarea dinamica:

// app/page.tsx
export const dynamic = 'force-dynamic';
// or
export const revalidate = 0;

Solutia 2 - Muta codul dinamic pe client:

// ❌ Folosesti headers in componenta de pagina
import { headers } from 'next/headers';
export default function Page() {
  const headersList = headers();
  // ...
}
 
// ✅ Foloseste in route handler sau muta pe client
// app/api/route.ts
import { headers } from 'next/headers';
export async function GET() {
  const headersList = headers();
  // ...
}

Solutia 3 - Foloseste generateStaticParams:

// Pentru rute dinamice care ar trebui sa fie statice
export async function generateStaticParams() {
  const posts = await getPosts();
  return posts.map((post) => ({
    slug: post.slug,
  }));
}

Eroare: Image Optimization Failed

Simptom:

Error: Invalid src prop on `next/image`
Error: Image Optimization using default loader is not compatible with `next export`
Error: upstream image response failed

Solutia 1 - Configureaza imaginile remote:

// next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
        pathname: '/images/**',
      },
      {
        protocol: 'https',
        hostname: '**.cloudinary.com',
      },
    ],
  },
};

Solutia 2 - Pentru export static:

// next.config.js
module.exports = {
  output: 'export',
  images: {
    unoptimized: true,  // Required for static export
  },
};

Solutia 3 - Corecteaza calea src:

// ❌ Gresit - lipseste slash-ul initial
<Image src="image.png" alt="..." width={100} height={100} />
 
// ✅ Corect - cale absoluta din folderul public
<Image src="/image.png" alt="..." width={100} height={100} />
 
// ✅ Imagine importata (cu dimensiuni)
import myImage from './image.png';
<Image src={myImage} alt="..." />

Eroare: Erori TypeScript la Build

Simptom:

Type error: Property 'x' does not exist on type 'y'
Type error: Argument of type 'string' is not assignable to parameter of type 'number'

Solutia 1 - Corecteaza tipizarea PageProps (Next.js 15):

// ❌ Pattern vechi (Next.js 14)
export default function Page({ params }: { params: { id: string } }) {}
 
// ✅ Pattern nou (Next.js 15) - params este un Promise
export default async function Page({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  // ...
}

Solutia 2 - Corecteaza tipizarea searchParams:

// Next.js 15 - searchParams este de asemenea un Promise
export default async function Page({
  searchParams,
}: {
  searchParams: Promise<{ query?: string }>;
}) {
  const { query } = await searchParams;
  // ...
}

Solutia 3 - Ignora erori specifice (temporar):

// @ts-ignore - TODO: Fix this type
const something = riskyOperation();
 
// @ts-expect-error - Expected to fail
const intentionalError = wrongType;

Eroare: Probleme cu Directiva "use client"

Simptom:

Error: useState only works in Client Components
Error: You're importing a component that needs useEffect
Attempted to call useRouter() from the Server

Solutia 1 - Adauga directiva "use client":

// Must be at the very top of the file
'use client';
 
import { useState } from 'react';
 
export default function ClientComponent() {
  const [state, setState] = useState(false);
  // ...
}

Solutia 2 - Separa componentele server/client:

// ServerComponent.tsx (no directive needed)
import ClientPart from './ClientPart';
 
export default async function ServerComponent() {
  const data = await fetchData();  // Server-side fetch
  return <ClientPart initialData={data} />;
}
 
// ClientPart.tsx
'use client';
export default function ClientPart({ initialData }) {
  const [data, setData] = useState(initialData);
  // ...
}

Eroare: ESLint/Build Strict Mode

Simptom:

Build failed due to ESLint errors
Error: `next/image` should be imported from `next/image` not `next/legacy/image`

Solutia 1 - Rezolva problemele ESLint:

# Auto-fix what's possible
npm run lint -- --fix
 
# Or run ESLint directly
npx eslint --fix .

Solutia 2 - Configureaza exceptii ESLint:

// .eslintrc.js
module.exports = {
  rules: {
    '@next/next/no-img-element': 'warn',  // Downgrade to warning
    'react-hooks/exhaustive-deps': 'warn',
  },
};

Solutia 3 - Omite ESLint la build (nu e recomandat):

// next.config.js
module.exports = {
  eslint: {
    ignoreDuringBuilds: true,  // Use only if necessary
  },
};

Eroare: Probleme de Memorie la Build

Simptom:

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed
JavaScript heap out of memory

Solutia 1 - Creste memoria Node:

# Temporarily
NODE_OPTIONS="--max-old-space-size=8192" npm run build
 
# In package.json
{
  "scripts": {
    "build": "NODE_OPTIONS='--max-old-space-size=8192' next build"
  }
}

Solutia 2 - Analizeaza bundle-ul:

# Install bundle analyzer
npm install @next/bundle-analyzer
 
# next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
  enabled: process.env.ANALYZE === 'true',
});
 
module.exports = withBundleAnalyzer({
  // your config
});
 
# Run analysis
ANALYZE=true npm run build

Solutia 3 - Reduce dimensiunea bundle-ului:

// Dynamic imports for large components
import dynamic from 'next/dynamic';
 
const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <p>Loading...</p>,
  ssr: false,  // Don't include in server bundle
});

Eroare: Probleme cu API Route

Simptom:

Error: API resolved without sending a response
TypeError: res.status is not a function

Solutie - Foloseste pattern-urile corecte din App Router:

// app/api/route.ts (App Router)
import { NextResponse } from 'next/server';
 
export async function GET(request: Request) {
  return NextResponse.json({ message: 'Hello' });
}
 
export async function POST(request: Request) {
  const body = await request.json();
  return NextResponse.json({ received: body }, { status: 201 });
}

Comenzi Rapide de Depanare

# Clear Next.js cache
rm -rf .next
 
# Clean install
rm -rf node_modules .next
npm install
 
# Build with verbose output
npm run build -- --debug
 
# Check for unused dependencies
npx depcheck
 
# Type check only
npx tsc --noEmit

Referinta Rapida: Rezolvari Frecvente

| Eroare | Rezolvare Rapida | |-------|-----------| | Module not found | npm install package sau corecteaza calea de import | | Hydration mismatch | Foloseste useEffect pentru cod doar pe browser | | Dynamic server usage | Adauga export const dynamic = 'force-dynamic' | | Image optimization | Configureaza remotePatterns in config | | TypeScript params | Foloseste pattern-ul Promise<{ param }> | | "use client" necesar | Adauga directiva la inceputul fisierului | | Problema de memorie | NODE_OPTIONS="--max-old-space-size=8192" |

Aplicatii Next.js Complexe?

Construirea aplicatiilor Next.js pentru productie necesita expertiza in optimizarea performantei. Echipa noastra ofera:

  • Audit si optimizare de performanta
  • Migrare la App Router
  • Consultanta pentru strategia SSR/ISR
  • Configurarea pipeline-ului de deployment

Obtine expertiza Next.js


Sistemul tau AI e conform cu EU AI Act? Evaluare gratuita de risc - afla in 2 minute →

Ai nevoie de ajutor cu conformitatea EU AI Act sau securitatea AI?

Programeaza o consultatie gratuita de 30 de minute. Fara obligatii.

Programeaza un Apel

Weekly AI Security & Automation Digest

Get the latest on AI Security, workflow automation, secure integrations, and custom platform development delivered weekly.

No spam. Unsubscribe anytime.