npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@bitpatty/next-image-s3-imgproxy-loader

v0.13.1

Published

imgproxy S3 extension for next/image

Downloads

256

Readme

next/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).

Request Flow

Sample Usage

You can find additional examples in the demo project.

Installation

You can install the package via npm:

npm install --save @bitpatty/next-image-s3-imgproxy-loader

Registering the endpoint

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:

// 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('<url to your imgproxy instance>'),
        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: '<imgproxy secret>',
            // (Required) The IMGPROXY_SALT (hex encoded)
            salt: '<imgproxy salt>',
          },
          // (Optional) If your imgproxy instance uses
          // the IMGPROXY_SECRET, specify the token here
          authToken: '<my-token>',
          // (Optional) If you wanna restrict access to specific
          // buckets add an array of valid bucket names
          bucketWhitelist: ['<my-bucket>'],
          // (Optional) A list of imgproxy headers that should be
          // forwarded through the imgproxy endpoint
          forwardedHeaders: ['<my-header>'],
          // (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:

// 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 <ProxyImage> component.

Using the component

After registering the endpoint you can use the <ProxyImage /> component as you would with the Image component from next/image, except that you need to provide a file (<bucketname>/<filename>) instead of src and optional proxy params for image transformations/optimizations.

import ProxyImage from '@bitpatty/next-image-s3-imgproxy-loader';
import pb from '@bitpatty/imgproxy-url-builder';

<ProxyImage
  file="mybucket/myfile.png"
  proxyParams={pb().rotate(180).blur(10).build()}
/>;

Note: The layout prop is automatically set to 'fill' if no width is set

Using the raw path

In case using the component is not an option, you can instead use the image path itself, by utilizing the buildProxyImagePath function.

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(),
});

<img src={imagePath} />;

or as background image

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(),
});

<div
  style={{
    backgroundImage: `url(${imagePath})`,
    backgroundSize: 'cover',
  }}
>
  {/* Content */}
</div>;

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.

<ProxyImage file="mybucket/myfile.png" endpoint="/my-endpoint" />;

// 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:

[
  "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.