Nextjs Image an issue with "loader" property that does not implement width - next.js

This is my code for the Nextjs Image component:
... Cell: ({ value }: CellType) => (
<Image
priority
src={value}
loader={() => value}
className={''}
height={100}
width={100}
alt={'profile_picture'}
/>
),
Does it mean I need a custom loader function to get rid off the warning? Thanks!

I had a same issue like yours and solved by adding unoptimized={true} prop into the <Image> tag.
If you don't apply optimizations, you need to announce that you don't optimize.
Something like below:
<Image
priority
src={value}
loader={() => value}
unoptimized={true} // <=== insert this prop
className={''}
height={100}
width={100}
alt={'profile_picture'}
/>
Please let me know if it work.
Thank you.

I had the same error but what I have done to fix it is to incorporate in the next.config.js file the URL of my media files, in my case it is cloudinary, the file should look like this:
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
images: {
domains: [
'res.cloudinary.com'
],
},
}
module.exports = nextConfig
And when I use the image component (next/image) I remove the loader and just put the URL like this:
<Image
key={element.id}
src={element.url}
width={500}
height={500}
alt="some description"
/>
I don't use unoptimized={true} because the point is that the component changes the quality of the image according to the client's device.
good look :)

Related

Nextjs imgix configuration issue with ?url params

I'm trying to setup the built-in imgix loader for nextjs 12+.
When I look in the dom the srcsets are as follows:
https://account.imgix.net/?url=%2Fhero.jpeg%26fm%3Dwebp&w=640&q=20
It appends this ?url= and the image isn't shown because of it. Not sure if there is something I'm missing or not understanding ?
Thank you in advance!
My setup:
Next.config.js
loader: "imgix",
path: "https://account.imgix.net/",
domains: ["account.imgix.net"],
Then I try to render a next/image component like so:
<Image
alt="hero"
src={`/hero.jpeg`}
fill
quality={20}
style={{
objectFit: "cover",
objectPosition: "20% center",
borderRadius: 10,
}}
priority
/>
As was mentioned in the first comment, next/image no longer supports global loader configurations. You have to use the loader prop.
// Example next/image loader
import Image from "next/image";
const normalizeSrc = (src) => (src[0] === "/" ? src.slice(1) : src);
const imgixLoader = ({ src, width, quality }) => {
const url = new URL("https://example.com/" + normalizeSrc(src));
const params = url.searchParams;
params.set("auto", params.getAll("auto").join(",") || "format");
params.set("fit", params.get("fit") || "max");
params.set("w", params.get("w") || width.toString());
if (quality) {
params.set("q", quality.toString());
}
return url.href;
};
const MyImage = (props) => {
return (
<Image
loader={imgixLoader}
src="me.png"
alt="Picture of the author"
width={500}
height={500}
/>
);
};
However, if you'd like to avoid having to do this each time you use the component, you can use the React Provider Pattern to provide that prop to any next/image component you're using. This will remove the need to set it inline on each instance of the component.
Take a look at this CodeSandbox where we use the Provider pattern to give all the Next <Image /> components the same imgix loader configuration if you want to learn more.
Seems like next 13 doesn't support global loaders anymore. So I will have to add the loader to each image component I'm rendering.

Statically loading NextJS Image gives 404 on production but works on localhost

I don't understand why the static image is not found on production, but works on localhost. I put all my images in the directory: public/images/...
/* image.tsx */
return (
<Image
src={"/images/frame1.png"}
width="1000"
height="1000"
alt="Control description"
style={{
height: "auto",
maxWidth: "100%",
userSelect: "none",
}}
/>
)
/* next.config.js */
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
};
module.exports = nextConfig;
Cloudflare pages deployment:
Localhost:
My file structure:
The fix from <Image /> to <img /> does resolve it in some instances, but it is not the recommended way as then you are not taking advantage of NextJS's powerful image optimization.
Your problem is that you are using relative paths instead of importing the file and using it by reference.
To fix you issue, try this:
import Image from 'next/image';
import frameImage from '../public/images/frame1.png'; // path to your folder
export default function ImagePage() {
return (
<Image
src={frameImage}
...otherProps
/>
)
}
Docs here: https://beta.nextjs.org/docs/optimizing/images
first : did you try changing <Image/> to <img/> ? test this and see if it's fixed or not ( just to be sure where the problem is coming from )
second try this: change the name of the image files.from uppercase to lowercase letters.

nextjs image loader that shows a color first then fades to image

While the image is loading, I want to show a color (black) and have that fade to the image once the image is loaded. Is there any good way to do this?
import Image from 'next/image'
const myLoader = ({ src, width, quality }) => {
return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}
const MyImage = (props) => {
return (
<Image
loader={myLoader}
src="me.png"
alt="Picture of the author"
width={500}
height={500}
/>
)
}
First add classes for opacity. And add a function for onLoadingComplete.
<Image
loader={myLoader}
src="me.png"
alt="Picture of the author"
width={500}
height={500}
className={`${
heroHasLoaded ? "opacity-100" : "opacity-0"
} transition-opacity duration-500`}
onLoadingComplete={doFadeIn}
/>
Add the callback function.
const doFadeIn = () => {
setHeroHasLoaded(true);
};
You also need to set the initial background color. I set this on a <div> that contains the image.
Note that if this image is going to be the Largest Contentful Paint, then also add priority to the <Image /> component. https://nextjs.org/docs/basic-features/image-optimization#priority

How can a prop value be used in an Stitches js component?

How to pass a prop value into a Stitchesjs component and use it in the component definition?
This is a common pattern in styled-components. In Stitches, however, I can't seem to find a way. Take this component for example:
const Spacer = styled('div', {
'16': {marginBottom: '$16'},
variants: {
size: {
'20': {marginBottom: '$20'}
}
}
});
Instead of creating 10 variants, I want to pass the amount trough a prop:
<Spacer size={'30px'} />
or even better:
<Spacer size={'$sizes$3'} />
How can I use this value so that the marginBottom matches whatever I give it?
Take a look at https://stitches.dev/docs/utils.
And then you can use like this:
<div css={{ mb: '$40' }} />
I was looking for this answer and tried a few different ways.
The easiest way for me turned out to be locally scoped theme-tokens.
So your styled component would look like this:
const Spacer = styled('div', {
marginBottom: '$$marginSize',
});
And then pass the locally scoped token into the css prop:
<Spacer css={{ $$marginSize: '$sizes$3' }} />
There was a discussion on Stitches Github about the possibility to pass dynamic values as property.
But the goal of stitches is to have the smallest runTime possible, so it was not implemented !
Github PR stitches
When you need to use a JSX variable in stitches that can be any value, one solution would be to use CSS variables;
All stitches elements get the css property, and you can pass new properties through it!
Styled component:
export const Box = styled('div', {
marginTop: 'var(--margin-top)',
backgroundColor: 'red',
width: '200px',
height: '200px',
})
Component:
export function Hero({props = 200 }) {
const variableExample = `${props}px`
return (
<>
<Box css={{ '--margin-top': '10px' }} />
<Box css={{ '--margin-top': '150px' }} />
<Box css={{ '--margin-top': variableExample }} />
</>
)
}
By far the best solution that has worked for me for this very problem. simplifies the code and is better to maintain later!

Switching between LTR and RTL using styled-components?

I'm building an English-Arabic app with next.js, and want to enable users to switch between the two languages.
I found this example from next.js: with-styled-components-rtl. It uses StylisRTLPlugin, which flips all CSS styles to fit RTL layout:
// _document.js
<StyleSheetManager stylisPlugins={[stylisRTLPlugin]}>
<App {...props} />
</StyleSheetManager>
It works fine, but the problem is that I can't remove stylisRTLPlugin conditionally based on the current locale bacause I have no access to useRouter() in _document.js.
What I want to be able to do:
<StyleSheetManager stylisPlugins={locale === 'ar' ? [stylisRTLPlugin] : null}>
<App {...props} />
</StyleSheetManager>
Add this config to your .babelrc to force your styled to be rendered on the server.
"plugins": [
[
"styled-components",
{
"ssr": true,
}
]
]

Resources