How to use Next.js Image component with MaterialUI? - reactjs

I am able to use the <img> tag no problem, but when I try to use the <Image> component, all that displays is an empty square the size of the image. The only way I have been able to get the image to display without using <img> is with the <Avatar> component. It's just a small brand image so it's not a huge deal, but I would like to use the built-in Next.js image optimization. And using <Avatar> does not feel very semantic as well.
It is being displayed inside of a ListItem component like this:
<Drawer variant="permanent" {...other}>
<List disablePadding>
<ListItem
sx={{
justifyContent: 'center',
alignItems: 'center',
}}
>
<Avatar
src="images/icons/agreement2.png"
alt="Scales of Justice Brand Image"
sx={{ width: 50, height: 50 }}
/>
</ListItem>
This is what I have tried so far:
I created a separate component for the image
import Image from 'next/image'
import brandImage from '../public/images/icons/law.png'
export default function Brand() {
return <Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
}
and displaying <Brand /> inside of the <ListItem> in place of the current <Avatar> component.
I tried to import the .png file and use
<Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
inside of the <ListItem>. And then I tried without importing the image and just using the full file path.
I tried placing <Image> inside of the <Avatar> component.
<Avatar>
<Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
</Avatar>
I also tried adding in the layout prop with all of the options.
I am using Next.js v12.0.9 and MUI v5.4.2

I recommend creating a parent element with a position responsive and setting the image like this:
<Box sx={{position:'relative'}}>
<Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
</Box>
You also may set it like:
<Box sx={{position:'relative', height:'50px', width:'50px'}}>
<Image src={brandImage} layout="fill" objectFit="cover" alt="Brand Logo" />
</Box>

This seem to work for me.
<Stack
sx={{
height: "500px",
}}
>
<Image
src={image.data.attributes.url}
alt={image.data.attributes.alternativeText}
width={image.data.attributes.width}
height={image.data.attributes.height}
objectFit="cover"
priority
/>
</Stack>
Using Stack seems to expand the image full width without using width: 100%

Related

React - Accessing PhotoURL from Firebase user: Image not displaying

Using Material UI components such as Tooltip, IconButton, and Avatar, I've made this:
<Tooltip title="Open settings">
<IconButton
onClick={handleOpenUserMenu}
sx={{ p: 0 }}
>
<img
alt="pfp"
src={auth.currentUser.photoURL}
/>
<Avatar
alt="Google Photo/Initial"
src={auth.currentUser
.photoURL}
/>
</IconButton>
</Tooltip>
As you can see, this photoURL isn't producing an image, despite in the source code actually being accessed from firebase properly, as can be seen below in the <img> tag (when I right click -> open in new tab, the image is definitely the right one and corresponds to the Google account I used to sign into my web application through Firebase):
To reiterate, the problem isn't accessing the photoURL of the Firebase user, but rather displaying it using either the native <img> or Material UI <Avatar> tag.
Suddenly this works when the only line technically changed was within the <IconButton> (imported from "#mui/material/IconButton") as such:
from sx={{ p: 0 }} to sx={{ px: "15px" }}
This is the final edited code (with the <img> tag removed since it was simply used for testing):
<Tooltip title="Open settings">
<IconButton
onClick={handleOpenUserMenu}
sx={{ px: "15px" }} // only changed line
>
<Avatar
alt="Google Photo/Initial"
src={
auth.currentUser
.photoURL
}
/>
</IconButton>
</Tooltip>
I can only assume that this is what fixed my problem and turned the output into the following:

Nextjs Thumbs is not showing in react-responsive-carousel while using next image

I am using react-responsive-carousel to show the image gallery of products with thumbs, while I am using a simple img HTML element the thums show up but while I use next image the thumbs vanish, I wonder how can I fix this issue.
<Carousel showThumbs>
{images.map((image) => (
<Box>
<Badge
badgeContent="30%"
color="primary"
anchorOrigin={{
vertical: 'top',
horizontal: 'left',
}}
sx={{
position: 'absolute',
top: '2rem',
left: '2.5rem',
}}
/>
{/* <img src={image.original} alt="ok" /> this word just fine*/}
{/* this does not show up thumbs */}
<Image
src={image.original}
alt="piece"
width={image.originalWidth}
height={image.originalHeight}
/>
</Box>
))}
</Carousel>
It's because react-responsive-carousel can't get image list inside custom components, it can only get from tag or tag inside tag. I think nextjs 's Image components count as custom components too.
ref: https://github.com/leandrowd/react-responsive-carousel/blob/master/TROUBLESHOOTING.md
When I implement Slider with SwipeableViews, I used pure image like this.
package.json
"dependencies": {
...
"react-swipeable-views": "^0.14.0",
"react-swipeable-views-utils": "^0.14.0",
...
}
slider-carousel-test.js
import SwipeableViews from 'react-swipeable-views';
import { autoPlay } from 'react-swipeable-views-utils';
const AutoPlaySwipeableViews = autoPlay(SwipeableViews);
export default function TestComponent (){
return (
<AutoPlaySwipeableViews
axis='x'
index={activeStep}//for auto
onChangeIndex={handleStepChange}//for user click
enableMouseEvents
>
{
data.map((elem, idx)=>
<Box
component="img"
sx={{
display:'block',
overflow:'hidden',
width:'100%',
}}
src={`https://contents.herokuapp.com/images/content${1+idx}.png`}
alt="No Image"
/>
);
}
</AutoPlaySwipeableViews>
)
}
Because Image from next/image does not provide image for react-responsive-carousel, I recommend you this way...
You need to customize the renderThumbs method.
renderThumbs = {() => (
images.map((image, index) => (
<Image
key={index}
src={image.original}
alt="piece"
width={image.originalWidth}
height={image.originalHeight}
/>
)))}

How to specify image height only and keep aspect ratio in Next.js?

I want to specify my image height only and keep the image aspect ratio without hardcoding the width.
In a traditional img element I can do so:
<img src="/logo.png" alt="logo" height={30} />
But if I try using next/image:
<Image src="/logo.png" alt="logo" height={30} />;
I get the following error:
Error: Image with src "/logo.png" must use "width" and "height" properties or "layout='fill'" property.
You can set layout="fill" and objectFit="contain" to your Image so that it maintains its aspect ratio while filling its container. You can then add a wrapper div around the Image component and apply the height to it instead.
<div style={{ position: 'relative', height: '30px' }}>
<Image
src="/logo.png"
layout="fill"
objectFit="contain"
/>
</div>

Spacing between antd Image components in React

I am using the antd's Image component since I want that preview functionality it has but the style isn't taking affect when I am trying to add some space between my images. They are just stacked together with no space. The same thing works when I use <img> tag. Any insights on how to tackle this issue?
<div>
<Image style={{marginRight: "15px"}} src={image} />
<Image style={{marginRight: "15px"}} src={image} />
<Image style={{marginRight: "15px"}} src={image} />
</div>
You can leverage AntD's Space component.
<Space size={15}>
<Image src={image} />
<Image src={image} />
<Image src={image} />
</Space>
According to the Image component API, the component doesn't take a style prop.
I would suggest using a wrapper component to apply the margin-right: 15px; rule.
<div>
<div style={{marginRight: "15px"}}>
<Image src={image} />
</div>
<div style={{marginRight: "15px"}}>
<Image src={image} />
</div>
<div style={{marginRight: "15px"}}>
<Image src={image} />
</div>
</div>

how to center image in react-multi-carousel?

I'm new to react, trying to build brand carousel using react-multi-carousel.
The images are displayed properly but I want to center the image. Tried to write css it did not apply on the carousel. How this can be achieved, Or do I have to use any other carousel?
`
<Grid item xs={12}>
<Carousel
responsive={responsive}
infinite={true}
arrows={true}>
<Image src={abt.logo_carousel.url}responsive/>
<Image src={abt.logo_carousel1.url}responsive/>
<Image src={abt.logo_carousel2.url}responsive/>
<Image src={abt.logo_carousel3.url}responsive/>
</Carousel>
</Grid>`
write style inside your tag itself.like this
<img src="..." style={{width:300,marginLeft:"auto",marginRight:"auto"}} />
I'm a little bit late but hope this could help someone (it worked for me):
<img src={source} style={{marginLeft: "auto", marginRight: "auto", display: "flex", justifyContent: "center"}}/>

Resources