:bulb: Version 3 is coming! It introduces a complete rewrite with many new features and bugfixes. If you want to help developing and testing the upcoming major version, please check out the canary branch for installation instructions and more information about the new features. (RFC issue)
Automatically optimize images used in next.js projects (jpeg, png, svg, webp and gif).
Image sizes can often get reduced between 20-60%, but this is not the only thing next-optimized-images does:
webp on the fly for an even smaller sizeSVG sprites for a better performance when using the same icons multiple times (e.g. in a list)npm install next-optimized-images
Node >= 8 is required for version 2. If you need to support older node versions, you can still use version 1 of next-optimized-images.
Enable the plugin in your Next.js configuration file:
// next.config.js
const withPlugins = require('next-compose-plugins');
const optimizedImages = require('next-optimized-images');
module.exports = withPlugins([
[optimizedImages, {
/* config for next-optimized-images */
}],
// your other plugins here
]);
See the configuration section for all available options.
:warning: From version 2 on, images won't get optimized out of the box anymore. You have to install the optimization packages you really need in addition to this plugin. This doesn't force you to download big optimization libraries you don't even use. Please check out the table of all optional optimization packages.
The example above uses next-compose-plugins for a cleaner API when using many plugins, see its readme for a more detailed example. next-optimized-images also works with the standard plugin api:
// next.config.js
const withOptimizedImages = require('next-optimized-images');
module.exports = withOptimizedImages({
/* config for next-optimized-images */
// your config for other plugins or the general next.js here...
});
Starting from version 2, you have to install the optimization packages you need in your project in addition to this plugin. next-optimized-images then detects all the supported packages and uses them.
So you only have to install these packages with npm, there is no additional step needed after that.
The following optimization packages are available and supported:
| Optimization Package | Description | Project Link |
|---|---|---|
imagemin-mozjpeg |
Optimizes JPEG images. | Link |
imagemin-optipng |
Optimizes PNG images. | Link |
imagemin-pngquant |
Alternative for optimizing PNG images. | Link |
imagemin-gifsicle |
Optimizes GIF images. | Link |
imagemin-svgo |
Optimizes SVG images and icons. | Link |
svg-sprite-loader |
Adds the possibility to use svg sprites for a better performance. Read the sprite section for more information. | Link |
webp-loader |
Optimizes WebP images and can convert JPEG/PNG images to WebP on the fly (webp resource query). | Link |
lqip-loader |
Generates low quality image placeholders and can extract the dominant colors of an image (lqip resource query) | Link |
responsive-loader |
Can resize images on the fly and create multiple versions of it for a srcset. |
Important: You need to additionally install either jimp (node implementation, slower) or sharp (binary, faster) | Link
| image-trace-loader | Generates SVG image outlines which can be used as a placeholder while loading the original image (trace resource query). | Link
Example: If you have JPG, PNG, and SVG images in your project, you would then need to run
bash npm install imagemin-mozjpeg imagemin-optipng imagemin-svgo
To install all optional packages, run:
npm install imagemin-mozjpeg imagemin-optipng imagemin-gifsicle imagemin-svgo svg-sprite-loader webp-loader lqip-loader responsive-loader jimp image-trace-loader
:warning: Please note that by default, images are only optimized for production builds, not development builds. However, this can get changed with the optimizeImagesInDev config.
:bulb: Depending on your build/deployment setup, it is also possibile to install these as devDependencies. Just make sure that the packages are available when you build your project.
:information_source: Since version 2.5, ico files are also optionally supported but need to be enabled in the handleImages config.
You can now import or require your images directly in your react components:
import React from 'react';
export default () => (
<img src={require('./images/my-image.jpg')} />
<img src={require('./images/my-small-image.png')} />
<img src={require('./images/my-icon.svg')} />
);
/**
* Results in:
*
*
* <img src="https://github.com/cyrilwanner/next-optimized-images/raw/v2.6.2/_next/static/images/my-image-5216de428a8e8bd01a4aa3673d2d1391.jpg" />
* <img src="https://github.com/cyrilwanner/next-optimized-images/raw/v2.6.2/data:image/png;base64,..." />
* <img src="https://github.com/cyrilwanner/next-optimized-images/raw/v2.6.2/_next/static/images/my-icon-572812a2b04ed76f93f05bf57563c35d.svg" />
*
*/
Please be aware that images only get optimized in production by default to reduce the build time in your development environment.
If you are using CSS modules, this package also detects images and optimized them in url() values in your css/sass/less files:
.Header {
background-image: url('./images/my-image.jpg');
}
/**
* Results in:
*
* .Header {
* background-image: url('/_next/static/images/my-image-5216de428a8e8bd01a4aa3673d2d1391.jpg');
* }
*/
If the file is below the limit for inlining images, the require(...) will return a base64 data-uri (data:image/jpeg;base64,...).
Otherwise, next-optimized-images will copy your image into the static folder of next.js and the require(...) returns the path to your image in this case (/_next/static/images/my-image-5216de428a8e8bd01a4aa3673d2d1391.jpg).
You can use both variants directly on an image in the src attribute or in your CSS file inside an url() value.
If you are using flow or eslint-plugin-import and are experiencing some issues with query params, check out the solution posted by @eleith.
There are some cases where you don't want to reference a file or get a base64 data-uri but you actually want to include the raw file directly into your HTML.
Especially for SVGs because you can't style them with CSS if they are in an src attribute on an image.
So there are additional options you can specify as query params when you import the images.
?include: Include the raw file directly (useful for SVG icons)?webp: Convert a JPEG/PNG image to WebP on the fly?inline: Force inlining an image (data-uri)?url: Force an URL for a small image (instead of data-uri)?original: Use the original image and do not optimize it?lqip: Generate a low quality image placeholder?lqip-colors: Extract the dominant colors of an image?trace: Use traced outlines as loading placeholder?resize: Resize an image?sprite: Use SVG spritesThe image will now directly be included in your HTML without a data-uri or a reference to your file.
As described above, this is useful for SVGs so you can style them with CSS.
import React from 'react';
export default () => (
);
/**
* Results in:
*
*
* <svg width="16" height="16" xmlns="http://www.w3.org/2000/svg">
* <path d="M8 0C3.589 0 0 3.589 0 8s3.589 ..." style="filled-opacity:1" fill-rule="evenodd">
* </path>
* </svg>
*
*/
The image will still get optimized, even if it is directly included in your content (but by default only in production).
Requires the optional optimization package
webp-loader(npm install webp-loader)
WebP is an even better and smaller image format but it is still not that common yet and developers often only receive jpeg/png images.
If this ?webp query parameter is specified, next-optimized-images automatically converts a JPEG/PNG image to the new WebP format.
For browsers that don't yet support WebP, you can also provide a fallback using the `
` tag:
import React from 'react';
export default () => (
<img src={require('./images/my-image.jpg')} />
);
/**
* Results in:
*
*
*
* <img src="https://github.com/cyrilwanner/next-optimized-images/raw/v2.6.2/_next/static/images/my-image-5216de428a8e8bd01a4aa3673d2d1391.jpg" />
*
*/
You can specify a limit for inlining images which will include it as a data-uri directly in your content instead of referencing a file if the file size is below that limit.
You usually don't want to specify a too high limit but there may be cases where you still want to inline larger images.
In this case, you don't have to set the global limit to a higher value but you can add an exception for a single image using the ?inline query options.
import React from 'react';
export default () => (
<img src={require('./images/my-image.jpg?inline')} />
);
/**
* Results in:
*
* <img src="https://github.com/cyrilwanner/next-optimized-images/raw/v2.6.2/data:image/png;base64,..." />
*
* Even if the image size is above the defined limit.
*/
The inlining will only get applied to exactly this import, so if you import the image a second time without the ?inline option, it will then get normally referenced as a file if it is above your limit.
When you have an image smaller than your defined limit for inlining, it normally gets inlined automatically.
If you don't want a specific small file to get inlined, you can use the ?url query param to always get back an image URL, regardless of the inline limit.
If you are using this option a lot, it could also make sense to disable the inlining completely and use the ?inline param for single files.
import React from 'react';
export default () => (
<img src={require('./images/my-image.jpg?url')} />
);
/**
* Results in:
*
* <img src="https://github.com/cyrilwanner/next-optimized-images/raw/v2.6.2/_next/static/images/my-image-5216de428a8e8bd01a4aa3673d2d1391.jpg" />
*
* Even if the image size is below the defined inlining limit.
*/
The inlining will only get disabled for exactly this import, so if you import the image a second time without the ?url option, it will then get inlined again if it is below your limit.
The image won't get optimized and used as it is. It makes sense to use this query param if you know an image already got optimized (e.g. during export) so it doesn't get optimized again a second time.
import React from 'react';
export default () => (
<img src={require('./images/my-image.jpg?original')} />
);
This can also be combined with the ?url or ?inline resource query (e.g. `?original&inline
$ claude mcp add next-optimized-images \
-- python -m otcore.mcp_server <graph>