Render ReactJS - './images/0.jpg' works.. but property.image doesn't? - reactjs

In a render (returned from a function), I have:
{console.log(property.image)}
{console.log(typeof property.image)}
<Image src={require('./images/0.jpg')} fluid rounded />
Which renders the image correctly and console logs "./images/0.jpg" string
But when I try:
{console.log(property.image)}
{console.log(typeof property.image)}
<Image src={require(property.image)} fluid rounded />
I get:
Error: Cannot find module './images/0.jpg',
which doesn't make sense to me...
Also, I am unsure how to assign variables in render, I tried :
{ var abc = property.image }
but get:
./src/App.js Syntax error: Unexpected token (220:12)
If someone can help me understand why, I would greatly appreciate it.

I'm assuming you are using web pack or something similar (create react app or parcel, for instance). That's (usually) where the require function comes from, and why you can 'require' an image. But the only images you can require are local ones (images in your project source), not images on the web.
If you want to get an image from the web, require is not what you want. In that case, you just pass the url as a string to the src property.
However, if you do need images that are in your project source, then you would probably use require. Most of the time, you use require at the top of a file, and pass it a string, not a variable. This is because your packager reads the file before packing it up, and looks for any requires, so that it can include them in the package. But when you pass require a variable, it can't do that. However, you can use require.context if you want to load files dynamically from a directory.
So you probably want this at the top of your file:
const pathToImages require.context('./images', true);
and in your render:
<Image src={pathToImages('0.jpg')} fluid rounded />
or
<Image src={pathToImages(property.image)} fluid rounded />

Related

NextJS image The resource [link of image] was preloaded using link preload but not used within a few seconds from the window's load event

I'm using next/image in NextJS for my blog website, but I noticed the following warning in my console:
The resource http://localhost:3000/_next/image... was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
The image is above the fold and should not be lazyloaded. That's the reason why I used priority on the image. If I remove it, the following warning pops up:
react_devtools_backend.js:4026 Image with src "/media/image1.jpg" was detected as the Largest Contentful Paint (LCP). Please add the "priority" property if this image is above the fold.
Read more: https://nextjs.org/docs/api-reference/next/image#priority
The code:
<div className={`image-container article-page__banner"`} >
<Image
className="article-page__banner"
src={metadata.banner}
alt={"Article banner"}
width={1000}
height={500}
layout="responsive"
objectFit="cover"
priority
/>
</div>
I saw that the warning is only happening in Chrome and only when strict mode is true. Is there a specific reason for this warning? I can probably ignore it, but I wanted to know what the reason behind it is.
(Tech stack: NextJS and website is SSG + TypeScript)

Module not found error when referencing the path for an in-directory image in React

I am new to React with only about 4 months of experience, and I am facing a problem when referencing a group of images in the same directory as the code below, in order to render them on the webpage. I am getting a module not found error whenever I pass their paths from the JSON file (as an object, but still a string nevertheless) and everything works fine when I pass a single path through my function
this is the code for rendering the images one by one.
<div className="cards col">
{Pagedproducts.map((item) => (
<div id="card" key={item.id}>
<div className="image">
<img
className="prev"
src={require(item.preview)}
alt={"Image not rendering"}
/>//item.preview returns a path for the image from this file's perspective
</div>
</div>
))}
</div>
using this same code but passing the path right away and rendering the same pic on all items WORKS! but i logged the item.preview variable and it literally shows the exact same path passed to the require function.
<img src={require('./productPic/IMG-1.jpg')} /> //doing this works fine but it's not what i'm trying to do
I am aware of the other methods that try to solve this but none of them use an object that holds a path to the image.
when i run my code i get a Module not found error
Uncaught Error: Cannot find module './productPic/IMG-1.jpg'
I also tried making it a string and passing the variable in it as such
<img src={require(`${item.preview}`)} />
yet also this does not work.
After React code is compiled, it will look into the /public directory for any images.
put your photos into the public folder and it'll work.
Here is the working example. codesandbox.io

Next.JS Static Generation not optimal for SEO when using `map` method

I am currently using Next.JS to create a static website with the main objective to have a very good SEO-optimized website.
Everything works fine and the website is correctly deployed with Vercel, but I have noticed that part of the content is not present directly in the HTML files.
For instance, I have a component that loops over an array of data, using the array map method, like this:
{imageTexts.map((image) => (
<ImageText
key={image.title + 'TitleImage'}
title={image.title}
description={image.description}
size={imagesSize}
image={image.image}
/>
))}
Once the website is deployed to Vercel, I search inside the HTML file for the information/strings contained in the array of data (imageTexts), but I can't find them. I guess Next.JS uses javascript to target some sort of div and then loops over its own JSON file to dynamically display content.
For me, this seems to kill a lot of the SEO advantage that static websites have over SPA. Is there any way I can have those strings directly inside my HTML files?
I am still not 100% sure this is caused by the map method, but I don't find any other explanations. Especially because other dynamically loaded components don't have the same problem. For example, this component string can be found on the HTML file, without a problem:
{title ? (
<Text
type="h2"
textAlign="center"
>
{title}
</Text>
) : null}
If you are mapping over ImageTexts on the server and that component renders HTML tags, then that HTML should be sent on the first-page load, and you could see it if you do CTRL+U or disable javascript.
Ok, I have just found that the reason. It has nothing to do with the map method. I was actually using the <Remark> component from library called react-remark. It seems it does not play well with Next.JS

Display a local image in reactjs doesn't work

The task is simple: display a local image in a reactjs app based on dynamic data.
This is what I tried (assume path_to_image is derived dynamically):
<img src={require(path_to_image} />
generates an error:
Error: Cannot find module '../../images/logos/somelogo.jpg'
Without the require:
<img src={path_to_image} />
generates a broken image.
These two methods seem to be what people are doing, but no luck here. How do I solve this?
import image from "./path/to/image.png"
If you plan using more images in a dynamic way maybe you should store their paths in a db and then query the db for the respective path. Actually that's how it's done with a CMS for example. Even if you store the files on the same hosting, you would still save their paths to a DB instead of hardcoding.
Use this:
import SomeLogo from '../../images/logos/somelogo.jpg';
You can then use it like this:
<img src={SomeLogo} />
As for multiple images, you could store them in a JSON array, and then loop through them and add each image.
This does it:
let imageSrc = require("../../images/logos/generic.jpeg");
let dynamiclyGeneratedSrc = ...;
if (dynamiclyGeneratedSrc !== undefined) {
imageSrc = require(`../../images/logos/${dynamiclyGeneratedSrc}`);
}

How to do Dynamic images in ReactJS?

In my system I have a few images that a user can have presented and it's extremely advantageous to me to be able to just pass in an id and then have that image be presented to the user.
(One use case: Articles in the system have images associated with them, there are many articles in the system, it'd be ideal to pull out just the image-id and have the image dynamically displayed based upon that id. There is no realistic possible way I can statically give an image path for each article.)
Unfortunately I've tried to figure this out and haven't gotten far at all. I'd be super-duper appreciative of a "Explain it to me like I am 5" answer on this one.
I have been trying to use images in two different ways and both have unfortunately not worked at all for me. Where unfortunately I am going to need both to continue :(
1: Putting it as a background of a div. [I am using it as a carousel with overlaying text here.]
2: Putting it as just a standalone image. [This is going to make up the 95%+ case of image use through the webapp.]
I'd love to in a perfect world just pass in an object like this to props.
articleDetails = {
articleId: 38387,
articleTitle: "Magical Unicorn Article"
articleContent: "I am not that creative, but here is some content."
}
<IndividualArticle article={articleDetails}/>
Then for props to take this in and convert it into the image path to my local files.
templateStringForImage = `../../../../articleImages/${this.props.article.articleId}.png`
Then for this template string to be used as:
1: the background image of a div
<div
className="container"
style={{
backgroundImage: `url(${templateStringForImage})` ,
height: "576px"
}}
enter code here
</div>
2: standalone image
<Image
src={require({templateStringForImage})}
/>
Some of the things I've tried:
I've tried a few changes like changing the code around to be like:
var Background = `../../../images/articleImages/${
this.props.article.image
}`;
​
<div style={{
backgroundImage: url('../../../images/articleImages/article3Image.png'),
height: "576px"
}}
But unfortunately that only gave me these errors.
Line 32: 'url' is not defined no-undef
Also when I went to try and use the new Background object like this I got a different error
var Background = `../../../images/articleImages/${
this.props.article.image
}`;
<Image
src={require({Background})}
/>
The error was:
Error: Cannot find module '[object Object]'
My current system/errors:
-I have a bunch of images like article1Image.png, article2Image.png, article3Image.png specified in the src code in an image folder.
-I want to pass "article1Image.png" into the object directly and have an image produced.
-I tried to do something like this and it has consistently failed, I don't even get an error message when I attempt to use it as a backgroundImage on a div unfortunately... it's literally just blank space on my screen. No broken image icon, just a void.
var Background = `'../../../images/articleImages/${
this.props.article.image
}'`;
<div
style={{
backgroundImage: `url(${Background})`,
height: "576px"
}}
-When attempting to use semantic-ui's Image I am also running into a nasty error
<Image
src={require(Background)}
/>
Error:
Error: Cannot find module ''../../../images/articleImages/article2Image.png''
Yet shockingly enough THIS works, when I give it as a static string like this.
<Image
src={require('../../../images/articleImages/article2Image.png')}
/>
But even when I give the string path directly into the backgroundImage of the div it still appears empty...
<div
style={{
backgroundImage: `url(../../../images/articleImages/article3Image.png)`,
height: "576px"
}}
Thanks all I truly appreciate the help lots and lots!
There are 2 different solutions based on what you have tried.
URL
If you want to access them via style={{ backgroundImage: 'url(...)' }}, the url will need to be accessible from the front-end. If you used create-react-app, that would mean placing images in the public folder instead of the src folder.
So if you had images in the public folder like: /public/articleImages/article2Image.png, you could use the url style attribute:
const imageName = 'article2Image.png';
<div style={{ backgroundImage: `url('/articleImages/${imageName}')` }}>
...
</div>
<img src={`/articleImages/${imageName}`} />
If you aren't using create-react-app config, then you will need to make the images available via however you are serving your application (i.e. express).
Require
This one is a little tricky, and I'm not 100% why it doesn't work out of the box.
What I had to do when testing this was to require all of my images at the top of the file, hard-coded, and then I was able to use the require(stringTemplate) just fine. But I was getting a Error: fileName hasn't been transpiled yet., so I'm not sure if the same fix will work for you.
It basically looks like this:
require('../../../images/articleImages/article1Image.png');
require('../../../images/articleImages/article2Image.png');
...
// This code would be inside a component
const imageName = 'article2Image.png';
const filePath = '../../../images/articleImages/${imageName}';
const fileUrl = require(filePath);
<div style={{ backgroundImage: `url(${fileUrl})` }}>
...
</div>
<img src={fileUrl} />
Without the require(s) at the top of the file, something goes wrong with transpilation.
My suggestion would be go the static assets route which would allow you to use the URL technique above. require is more suited to static files that don't change often like icons.
Feel free to ask any questions, and I'd be happy to clarify and give more examples.

Resources