cyrilwanner / react-optimized-image Goto Github PK
View Code? Open in Web Editor NEWEasy to use React components for optimized-images-loader / next-optimized-images.
License: MIT License
Easy to use React components for optimized-images-loader / next-optimized-images.
License: MIT License
The documentation says that the image src type is a string
however type definitions says different it's a ImgSrc
(https://github.com/cyrilwanner/react-optimized-image/blob/master/src/components/types.ts)
I'm also having this type issue:
Hello!
Firstly, i want to say, that your project is very weell.
I have some problems with img
component and next-optimized-images. I want to create specific component, whic return img
component from 'react-optimized-image'.
`
import Img from 'react-optimized-image';
const Image = ({src, ...rest}) => {
сonst sizes = [100, 200, 300];
return (
<Img
src={require(`Public/images/${src}`)}
webp
densities={[1, 2]}
breakpoints={[480, 576, 768, 992, 1200, 1600]}
sizes={sizes}
{...rest}
/>
);
};
export default Image;
`
When i run "npm dev", there is syntax error in console - "Only static array with number values is allowed". https://i.imgur.com/ZpTgGqu.png
Can you help me, please?
Hey, I appreciate the work you've been doing on this package and can't wait to get a demo up and running with it!
It works amazingly well in NextJS, so I'm trying to use the plugin with Storybook.js so we can use it with our component library.
I'm extending the storybook webpack config as recommended like this:
// .storybook/main.js
{
webpackFinal: async (config) => {
config.module.rules.push({
test: /\.(png|jpe?g|gif|svg|webp|ico)$/i,
use: [
{
loader: 'optimized-images-loader',
options: {
includeStrategy: 'react'
},
},
],
});
return config;
}
}
And I have it configured in babel like so;
// babel.config.js
module.exports = {
presets: ['next/babel'],
plugins: ['react-optimized-image/plugin']
}
And I'm trying to use it like this in my components:
// components/Header/Header.tsx
import { Svg } from 'react-optimized-image'
import Logo from './assets/logo.svg'
export function Header(): JSX.Element {
return (<Svg src={Logo} />)
}
And like this in my story file:
// components/Header/Header.stories.tsx
import { Meta, Story } from '@storybook/react'
import React from 'react'
import { Header } from './Header'
const config: Meta = { title: 'Components/Header', component: Header }
const Template: Story = (args) => <Header {...args} />
export default config
export const Default = Template.bind({})
When i run start-storybook, i get the following error:
Error: No react component generated. Please set `includeStrategy` option of optimized-images-loader to 'react'
at Svg (http://localhost:6006/vendors~main.2430c86930fd7a1bab86.bundle.js:71140:11)
at renderWithHooks
I've tried adding options and changing the order of the loaders with no luck, any ideas?
With next.js moving to SWC it would be neat to have a swc plugin (https://swc.rs/docs/usage-plugin/)
I'm getting console errors regarding duplicate keys when using the Img
.
This is the code I'm using:
<Img
src={require('./img1.jpg')}
type="landingpageProject"
className={styles.image}
data-scroll
data-scroll-speed="-2"
/>
<Img
src={require('./img2.jpg')}
type="landingpageProject"
className={styles.image}
data-scroll
data-scroll-speed="-2"
/>
Which results in:
react_devtools_backend.js:2273 Warning: Encountered two children with the same key,
image/webp/1200
. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
in picture (created by Img)
in Img (at projects/index.tsx:62)
in div (at projects/index.tsx:61)
I've tried to set custom key
properties on each of the Images with no luck.
In cyrilwanner/next-optimized-images#120 you mentioned that this Img Component should also support an lqip placeholder. Is there any progress on this? Would love to try it out! :)
Hi,
first of all, I think that is an interesting project.
I have a question about Convert to WebP on the fly, I not understand the objective.
If the original image is an JPEG or PNG format, and the component generate the WebP on the fly, the user are downloading the "unoptimized" image, right?
My portfolio website uses a dynamic grid
layout to show two columns of images when the viewport is wide enough and one column when it's too small to fit both (as shown below).
Less than 872px viewport width (one column):
Greater than or equal to 872px viewport width (two columns):
Thus, my breakpoint
options need to be able to:
Suggested fix
I suggest that you add an option to pass a nested array into breakpoints
that contains [min, max]
values for each image size
. For example, this would be my solution (once implemented OFC):
<Img
src={require('assets/img.jpg')}
sizes={[400, 600, 800]}
breakpoints={[[undefined, 448], [448, 872], [872, undefined]]}
/>
Where undefined
merely indicates less than or greater than.
I decided to try out the canary branch of 'next-optimized-image' yesterday and came across this bug. Whenever I tried to use an styled(Img)
component I keep getting this error:
Babel plugin 'react-optimized-image/plugin' not installed or this component could not be recognized by it.
I then looked at your tests and saw that @emotion/styled should work ok. took me some time to find out the problem, but it seems like when I have the babel-plugin-emotion enabled this issue happens.
also had the same error when I tried to wrap Img in a custom HOC
Hi,
thanks for making this great tool!
I have one issue with it, that made me go back to v2 of next-optimized-images
(if someone doesn't know, the canary v3 is using react-optimized-image
) and do a lot of work on top of it to get it close to v3, but with one key difference – I need to use srcset
widths and sizes
instead of media
.
The reason is that I would need to setup all the breakpoints
for different use cases. For example, I have an image that is:
Currently I need to set it up this way:
<Img
src={MyImage}
sizes={[400, 800, 200, 400]}
breakpoints={[399, 767, 1199]}
webp
densities={[1, 2]}
/>
And it gives me this HTML (paths simplified for readability)
<picture>
<source type="image/webp" srcset="myimg-400.webp, myimg-800.webp 2x" media="(max-width: 399px)">
<source type="image/webp" srcset="myimg-800.webp, myimg-1600.webp 2x" media="(min-width: 400px) and (max-width: 767px)">
<source type="image/webp" srcset="myimg-200.webp, myimg-400.webp 2x" media="(min-width: 768px) and (max-width: 1199px)">
<source type="image/webp" srcset="myimg-400.webp, myimg-800.webp 2x" media="(min-width: 1200px)">
<source type="image/jpeg" srcset="myimg-400.jpg, myimg-800.jpg 2x" media="(max-width: 399px)">
<source type="image/jpeg" srcset="myimg-800.jpg, myimg-1600.jpg 2x" media="(min-width: 400px) and (max-width: 767px)">
<source type="image/jpeg" srcset="myimg-200.jpg, myimg-400.jpg 2x" media="(min-width: 768px) and (max-width: 1199px)">
<source type="image/jpeg" srcset="myimg-400.jpg, myimg-800.jpg 2x" media="(min-width: 1200px)">
<img src="myimg-800.jpg">
</picture>
But what I really need is this:
<picture>
<source
type="image/webp"
sizes="(min-width: 1200px) 400px, (min-width: 768px) 200px, 100vw"
srcset="myimg-200.webp 200w, myimg-400.webp 400w, myimg-800.webp 800w, myimg-1600.webp 1600w"
>
<source
type="image/jpeg"
sizes="(min-width: 1200px) 400px, (min-width: 768px) 200px, 100vw"
srcset="myimg-200.jpg 200w, myimg-400.jpg 400w, myimg-800.jpg 800w, myimg-1600.jpg 1600w"
>
<img src="myimg-800.jpg">
</picture>
Then I don't have to figure out exactly what sizes I need for which breakpoints – the browser takes care of that based on sizes (which can be 100vw
or even calc(...)
), so I can have a fluid design with multiple breakpoints without worrying about which exact size I need for what breakpoint.
I'd love to see this mode implemented in react-optimized-image
(and v3 of next-optimized-images
). Let me know if you need any more info on this, or if there's a reason you went the media
way.
PS: One learns all the time. Even after 10+ years in web development, I always assumed that the browser actually checks the displayed size of an image and downloads the correct one. Ok, might not be possible on page load (would have to wait for css and maybe even js), but surely while lazy loading it has to work, right? Well, nope. That's why sizes
is a must, otherwise it would always download the largest, even if you set inline style for width to be 1px
... Why do I assume things make sense?! ;)
First of all - fantastic job building this stuff. I love it a lot!
I have a question. Since we can also render AMP pages with next I wonder how complicated it would be to add a new param "?amp" which would render an AMP conform instead of a
Due to the way the sizes array is computed any configuration that includes out-of-order numbers will be converted to an ordered array.
So sizes: [300, 500, 150]
appears to resolve to [150, 300, 500]
when generating the picture
output, and in combination with specifying breakpoints will generate different srcset
combinations of src
image and media queries than expected.
This was while experimenting with a responsive grid of images: a situation where as the viewport widens smaller images are required.
(This might be a use case better served by using sizes
of source
in combination with width descriptors in srcset
but I think only pixel density descriptors and media queries are available here).
I've created a Hero
component that takes an image and title as props like so:
<Hero
image={require('./images/test.jpg')} title="test"
/>
This is the component:
import React from 'react';
import Img from 'react-optimized-image';
import styles from './hero.module.scss';
const Hero: React.FC<IHeroProps> = ({ image, title }) => {
return (
<div className={styles.hero}>
<Img src={image} className={styles.bg} />
<h1>{title}</h1>
</div>
);
}
This throws the following error:
Error: Babel plugin 'react-optimized-image/plugin' not installed or this component could not be recognized by it.
However, when I use the image component directly like the following it works fine. Is this a limitation or a bug?
<Img src={require('./images/test.jpg')} className={styles.bg} />
Currently breakpoints generate up the value in the array, e.g breakpoints={[640]}
generates two breakpoints, 0px-640px and 601px-infinity. I would suggest the breakpoint being generated to not include the number in the array, but stop one before; in this example, generate 0px-599px and 640px-infinity.
Most (if not all) css frameworks implement responsiveness with mediaqueries, specifically using the min-width
property. For example Tailwind does @media (min-width: 640px)
, so the breakpoints generated are 0-639 and 640-infinity.
While responsive images (those where the width scales with the window width) are useful, sometimes it is better to use fixed sizes for different window sizes.
Given this difference between my css configuration and the react-optimized-image configuration, I am a lot of times "off by one". A really minor nitpick but one that can potentially save some debugging time and size (for those unaware).
Hello and sorry if it sounds dumb, I am reading the README.md
on npmjs and it starts with:
I then see that it depend on optimized-images-loader
which I also read.
It seems that most of those features are possible with it. I am using react, what is the major addition you have made with optimized images loader ?
I have tried to configure the plugin but I am stuck with cyrilwanner/optimized-images-loader#23, all my images now look like:
I'm running into an error during the build process. I'm using react-optimized-image
but believe the issue is in the loader.
TypeError: Failed to parse URL from /home/ubuntu//core/front-end/node_modules/@wasm-codecs/mozjpeg/lib/mozjpeg.wasm
TypeError: Failed to parse URL from /home/ubuntu/core/front-end/node_modules/@wasm-codecs/mozjpeg/lib/mozjpeg.wasm
/home/flu0r1ne/dev/velos/core/front-end/node_modules/@wasm-codecs/mozjpeg/lib/mozjpeg.js:9
...
RuntimeError: abort(TypeError: Failed to parse URL from /home/ubuntu/core/front-end/node_modules/@wasm-codecs/mozjpeg/lib/mozjpeg.wasm). Build with -s ASSERTIONS=1 for more info.
at process.abort (/home/ubuntu/core/front-end/node_modules/@wasm-codecs/mozjpeg/lib/mozjpeg.js:9:11556)
Node.js v18.2.0
react-optimized-image
has been working in my project. I imagine either an update to webpack 5 or a dependency triggered this error.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.