skip to Main Content

I want to fetch corresponding product image on each dynamic route in my NextJS project, like this:

    export default function singleProductPage({ params }) {
    const { product_code } = params;
    const imagePath = `../../../../assets/products/Hammer/${product_code}.jpg`;

    return (
        <div>
            <Image src={imagePath} width={300} height={300} alt="xx" />
        </div>
    );
}

But it doesn’t work at all. I use require module instead:

const imagePath = require(`../../../../assets/products/Hammer/${product_code}.jpg`);

It works but got a warning "Only plain objects can be passed to Client Components from Server Components. Module objects are not supported."

Is there a better way to do this?

2

Answers


  1. Use Public Directory

    One approach is to use the public directory for static assets. This allows you to reference images with a straightforward path. Files inside the public directory are served at the root level of your site.

    Move your images to the public directory (or a subdirectory within it). For example:
    
    arduino
    

    public/assets/products/Hammer/

    Update your code to use the path relative to the public directory:

    jsx

    import Image from 'next/image';
    
    export default function SingleProductPage({ params }) {
        const { product_code } = params;
        const imagePath = `/assets/products/Hammer/${product_code}.jpg`;
    
        return (
            <div>
                <Image src={imagePath} width={300} height={300} alt="Product Image" />
            </div>
        );
    }
    

    Using next/image with Static Import (for Static Files)

    If the images are known at build time and you want to import them statically, you can use import statements:

    Create a mapping of product codes to image imports. This is only feasible if the set of images is known ahead of time and doesn’t change frequently.
    
    jsx
    
    import hammerImage from '../public/assets/products/Hammer/hammer.jpg';
    import otherImage from '../public/assets/products/Other/other.jpg';
    
    const imageMap = {
        hammer: hammerImage,
        other: otherImage,
    };
    
    export default function SingleProductPage({ params }) {
        const { product_code } = params;
        const imagePath = imageMap[product_code] || '/default-image.jpg';
    
        return (
            <div>
                <Image src={imagePath} width={300} height={300} alt="Product Image" />
            </div>
        );
    }
    

    Dynamic Imports with next/image

    If you need dynamic image imports based on runtime values (and the images are not static at build time), you can use the public directory method. This method is more flexible but requires ensuring all paths are correct.

    Login or Signup to reply.
  2. Error Cause Explanation

    The next/image component in Next.js does not handle relative paths or dynamic paths well. It expects static paths or absolute URLs for the src attribute. This is because the image optimization engine requires the path to be resolvable and predictable at build time. Dynamic paths or relative paths can lead to issues where the component cannot correctly resolve or optimize the image, resulting in broken or missing images.

    Suggested Solution:

    Use Static Paths: Place images in the public directory and use absolute paths from there. For example:

    const imagePath = /assets/products/Hammer/${product_code}.jpg;

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search