Stevenjparrett
Stevenjparrett

Reputation: 13

Next.js 14.2.10 Build Error: "Can't resolve 'canvas'" When Using pdfjs-dist in Client Component

I'm developing a Next.js application (version 14.2.10) and implementing a CV upload feature using the pdfjs-dist library (version 3.11.174). However, during the build process, I encounter the following error:

`Build Error
Failed to compile

Next.js (14.2.10) out of date (learn more)
./node_modules/pdfjs-dist/build/pdf.js:6247:1
Module not found: Can't resolve 'canvas'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./src/components/AddCandidate/CVUpload.tsx
./src/components/AddCandidate/AddCandidateForm.tsx
./src/components/AddCandidate/AddCandidate.tsx
./src/app/candidates/new/page.tsx
`

Despite following several troubleshooting steps, the error persists. Below are the details of what I've tried so far:

/** @type {import('next').NextConfig} */
const nextConfig = {
  webpack: (config, { isServer }) => {
    if (!isServer) {
      config.resolve.fallback = {
        ...config.resolve.fallback,
        canvas: false,
      };
    }
    return config;
  },
};

export default nextConfig;
declare module 'pdfjs-dist/build/pdf' {
  import * as pdfjsLib from 'pdfjs-dist';
  export = pdfjsLib;
}

Additional Information:

Next.js Configuration:

next.config.mjs: Updated as shown above to include Webpack fallback for canvas. TypeScript Configuration:

tsconfig.json: Updated to include custom type declarations.

Project Structure:

The CVUpload.tsx component is located at ./src/components/AddCandidate/CVUpload.tsx and is used within AddCandidateForm.tsx, which is further used in AddCandidate.tsx and ultimately rendered in ./src/app/candidates/new/page.tsx.

Other Dependencies:

Using Material-UI (@mui/material), react-dropzone, mammoth, and compromise.

Why am I still encountering the "Can't resolve 'canvas'" error even after configuring Webpack to ignore it on the client side?

Any Insights would be greatly appreciated.

Upvotes: 0

Views: 376

Answers (1)

Eze Onyekachukwu
Eze Onyekachukwu

Reputation: 31

install the package null-loader npm install null-loader and then edit your next.config.js to be

/** @type {import('next').NextConfig} */
const nextConfig = {
        config.externals = [...config.externals, { canvas: "canvas" }];
        if (!options.isServer) {
            // Use null-loader for canvas in client-side builds to completely ignore it
            config.module.rules.push({
                test: /canvas/,
                use: 'null-loader',
            });

            // Set fallback for canvas to false
            config.resolve.fallback = {
                ...config.resolve.fallback,
                canvas: false,
            };
        }
        return config;
    },
    experimental: {
        esmExternals: "loose", // required for the canvas to work
      },
      
    
};

export default nextConfig;

I just hope this solves your problem.

Upvotes: 0

Related Questions