imgproxy S3 extension for next/image
npm install @bitpatty/next-image-s3-imgproxy-loadernext/image loader for imgproxy (S3)This library is a layer on top of the the next/image component, which allows you to load images from an imgproxy instance connected to an S3. With this library, the NextJS server acts as a middleman between the client and the imgproxy instance to perform additional tasks, such as applying signatures and/or guards before loading an image.
> If you want to access the imgproxy instance directly from your client you can simply use the next/image component itself - no need to install this library (you might wanna look into the imgproxy-url-builder to build the request URL however).
> You can find additional examples in the demo project.
You can install the package via npm:
``sh`
npm install --save @bitpatty/next-image-s3-imgproxy-loader
#### Method 1: Custom Server
The library by default proxies request through a custom endpoint. To register the endpoint create a custom server in your project and add the following lines:
`js
// server.js
const imgProxy = require('@bitpatty/next-image-s3-imgproxy-loader');
app.prepare().then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url, true);
const { pathname, query } = parsedUrl;
if (pathname === imgProxy.IMGPROXY_ENDPOINT) {
// Add other middleware here, such as auth guards
// ...
imgProxy.handle(
new URL('
query,
res,
// (Optional) Additional configuration options
{
// (Optional) If your imgproxy uses signatures, specify
// the key and salt here
signature: {
// (Required) The IMGPROXY_KEY (hex encoded)
key: '
// (Required) The IMGPROXY_SALT (hex encoded)
salt: '
},
// (Optional) If your imgproxy instance uses
// the IMGPROXY_SECRET, specify the token here
authToken: '
// (Optional) If you wanna restrict access to specific
// buckets add an array of valid bucket names
bucketWhitelist: ['
// (Optional) A list of imgproxy headers that should be
// forwarded through the imgproxy endpoint
forwardedHeaders: ['
// (Optional) An object containing additional request
// headers that should be sent to the imgproxy endpoint
requestHeaders: {
'My-Header': 'My-Value',
// ...
},
// (Optional) The logger configuration. If you want additional
// debug output you can adjust the log level.
logging: {
// (Optional) The logger to use (defaults to console)
// The logger should implement the signature for
// for console.debug, console.warn and console.error
logger: console,
// (Optional) The log level, must be one of
// 'debug', 'warn' or 'error' (defaults to 'error')
level: 'debug',
},
},
);
} else {
handle(req, res, parsedUrl);
}
}).listen(3000, (err) => {
if (err) throw err;
console.log('> Ready on http://localhost:3000');
});
});
`
#### Method 2: API Endpoint
For serverless environments you can use an API endpoint instead of a custom endpoint.
The setup is similar, register your endpoint as follows:
`typescript
// pages/api/image.ts
import { NextApiRequest, NextApiResponse } from 'next';
import { handle } from '@bitpatty/next-image-s3-imgproxy-loader';
const handler = (req: NextApiRequest, res: NextApiResponse): void => {
if (req.method !== 'GET') {
res.statusCode = 405;
res.send('');
return;
}
handle(new URL('http://localhost:4000/'), req.query, res, {
// Handler Options
});
};
export default handler;
`
With this method, you have to supply the endpoint to the component.
After registering the endpoint you can use the component as you would with the Image component from next/image, except that you need to provide a file () instead of src and optional proxy params for image transformations/optimizations.
`tsx
import ProxyImage from '@bitpatty/next-image-s3-imgproxy-loader';
import pb from '@bitpatty/imgproxy-url-builder';
proxyParams={pb().rotate(180).blur(10).build()}
/>;
`
> Note: The layout prop is automatically set to 'fill' if no width is set
In case using the component is not an option, you can instead use the image path itself, by utilizing the buildProxyImagePath function.
`tsx
import { buildProxyImagePath } from '@bitpatty/next-image-s3-imgproxy-loader';
import pb from '@bitpatty/imgproxy-url-builder';
const imagePath = buildProxyImagePath('test-bucket/test-image.png', {
proxyParams: pb().blur(10).build(),
});
;
`
or as background image
`tsx
import { buildProxyImagePath } from '@bitpatty/next-image-s3-imgproxy-loader';
import pb from '@bitpatty/imgproxy-url-builder';
const imagePath = buildProxyImagePath('test-bucket/test-image.png', {
proxyParams: pb().blur(10).format('jpg').build(),
});
,
backgroundSize: 'cover',
}}
>
{/ Content /}
Overriding the endpoint
If you use a different endpoint than the one provided by
IMGPROXY_ENDPOINT you can override the endpoint used by the component by providing the endpoint property. endpoint can be both a path but also a URL.`tsx
;// Or
buildProxyImagePath('test-bucket/test-image.png', {
endpoint: '/my-endpoint',
});
`Forwarded Headers
By default, the following imgproxy headers will be forwarded in the response to the client:
`json
[
"date",
"expires",
"content-type",
"content-length",
"cache-control",
"content-disposition",
"content-dpr"
]
`If you want to forward a different set of headers you can use the
forwardedHeaders option to specify a custom list of headers. Note that if forwardedHeaders` is specified, all headers not specified in the list will be omitted in the response.