0

I'm building a monorepo using the Yarnberry workspace (version 3.6). My folder structure is as follows:

pakages
|
└── ui
|   └──src
|       └──assets
|           └── close.png
|       └──modals
|            └──Modal.tsx
|         
sevices
└── 
    └── next-app

I've created a simple modal component in the UI folder, and that component uses the close image in assets.

And I imported it from the next-app project of services and confirmed that it was loaded normally. However, only the images did not load normally.

I got the value [object Object] from the src value of the image.

How can I solve this?

Below is the package.json for the ui folder.

{
  "name": "@common/ui",
  "packageManager": "yarn@3.6.1",
  "main": "./src/index.ts",
  "scripts": {
  ...
  },
  "devDependencies": {
    "@babel/cli": "^7.22.9",
    "@babel/core": "^7.22.9",
    "@babel/preset-env": "^7.22.9",
    "@babel/preset-react": "^7.22.5",
    "@babel/preset-typescript": "^7.22.5",
    "esbuild": "latest",
    "esbuild-css-modules-plugin": "^2.7.1",
    "esbuild-sass-plugin": "^2.10.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "sass": "^1.64.1",
    "vite": "^4.4.7"
  },
}
//index.ts
export { default as Modal } from "./modals/Modal";
//Modal.tsx
import Close from '../../assets/colse.png';
const Modal = ({ title, content, buttonName }: IConfirmType) => {
  return (
    <div className="popup_message_view_align">
      <img
        className="btn_close"
        src={Close}
        alt="close"
      />
      ...
    </div>
  );
};
김정수
  • 611
  • 4
  • 9
  • 22
  • 1
    I assume you assign a non-string dynamic value from a variable or prop to the `src` attribute of the image. Perhaps you can add more details/ code snippet on how you do that? – dave.tdv Jul 28 '23 at 10:14
  • @dave.tdv I've updated the section on Modal components, please see the article. The image path is set as a relative path. – 김정수 Jul 29 '23 at 14:24

1 Answers1

1

Once Next.js builds the app, scripts and assets will be bundled and stored in .next directory. Image that is imported will be seen as an object as below.

Example

{
  src: '/_next/static/media/abcdef.a7717b40.jpg',
  height: 3800,
  width: 2850,
  blurDataURL: '/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fabcdef.a7717b40.jpg&w=6&q=70',
  blurWidth: 6,
  blurHeight: 8
}

As you can see, the final path won't be the same as the relative path you provided.

You can either do

<img
  className="btn_close"
  src={Close.src}
  alt="close"
/>

Or, since you use Next.js you can also try using next/image. It will handle the imported image object internally plus better image optimization.

import Image from 'next/image';

//...

<Image
  src={Close}
  alt="Close image"
  className="btn_close"
  width={600}
  height={400}
  priority
/>
dave.tdv
  • 325
  • 2
  • 10
  • Thank you for your comments. Helped me a lot! But in the second method, since the ui folder created in packages is implemented with react, next/image cannot be used, right? In the next.js project, we only import and use the Modal component created in ui. – 김정수 Jul 31 '23 at 01:45
  • I have an additional question If you use it as Close.src, is it impossible to use it if other projects are normal react instead of next.js?? – 김정수 Jul 31 '23 at 01:50
  • You can pull out the image, compose it using Next.js `Image`, and pass it as children to the `Modal` component. By doing this, your `Modal` component has better abstraction. For your second question, you can do a simple test like `src={typeof Close === "string" ? Close : Close.src}`. But if you refactor, pull the image out of the `Modal` component, and use the Next.js `Image`, you may not need that check anymore. – dave.tdv Jul 31 '23 at 07:59