Skip to content

Commit

Permalink
feat: Remove optimizations with unoptimized prop (#250)
Browse files Browse the repository at this point in the history
# Description

When the `unoptimized` flag is passed in, this removes the f_auto/q_auto
optimizations from the Cloudinary URL.

It will also construct a full Cloudinary URL as the src, otherwise the
public ID is attempted to be used, which results in ab broken URL. This
usually wouldn't be allowed but it seems the unoptimized flag bypasses
the image allowed list.

This doesn't fix this issue occuring when the unoptimized flag is passed
in globally inside next.config.js

## Issue Ticket Number

Fixes #245 

<!-- Specify above which issue this fixes by referencing the issue
number (`#<ISSUE_NUMBER>`) or issue URL. -->
<!-- Example: Fixes
https://github.com/colbyfayock/next-cloudinary/issues/<ISSUE_NUMBER> -->

## Type of change

<!-- Please select all options that are applicable. -->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] Fix or improve the documentation
- [ ] This change requires a documentation update


# Checklist

<!-- These must all be followed and checked. -->

- [ ] I have followed the contributing guidelines of this project as
mentioned in [CONTRIBUTING.md](/CONTRIBUTING.md)
- [ ] I have created an
[issue](https://github.com/colbyfayock/next-cloudinary/issues) ticket
for this PR
- [ ] I have checked to ensure there aren't other open [Pull
Requests](https://github.com/colbyfayock/next-cloudinary/pulls) for the
same update/change?
- [ ] I have performed a self-review of my own code
- [ ] I have run tests locally to ensure they all pass
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes needed to the documentation
  • Loading branch information
colbyfayock committed Aug 4, 2023
1 parent 1b18d59 commit fed264f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 5 deletions.
19 changes: 19 additions & 0 deletions docs/pages/cldimage/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,30 @@ Configuration for CldImage is the same as [getCldImageUrl](/getcldimageurl/confi
| transformations | string/array | - | `['my-named-transformation']`|
| underlay | string | - | `"my-public-id"` |
| underlays | array | - | See Below |
| unoptimized | boolean | - | See Below |
| version | number | - | `1234` |
| width | number/string | - | `600` |
| zoom | string | - | `0.5` |
| zoompan | bool/string/object | - | See Below |

### Unoptimized images

The Next.js Image component provides the ability to pass in an [unoptimized](https://nextjs.org/docs/pages/api-reference/components/image#unoptimized)
flag as a way to deliver the raw image URL without any quality, format, or size changes. When using
this, the CldImage component performs the same treatment by not adding the f_auto or q_auto parameters
as well as not subjecting the image to any resizing.

However, this only works when configuring `unoptimized` at the prop level. The `unoptimized` flag
can also be configured at the global level inside next.config.js, however there's not a reliable
way to access this configuration, meaning at this point in time, the CldImage would not work.

To get around this, consider using `unoptimized` if desired at the component level and to avoid
having to specify this on each instance, create a light wrapper around the CldImage component.

```
const MyCldImage = (props) => <CldImage {...props} unoptimized />;
```


## Effect Props

Expand Down
26 changes: 21 additions & 5 deletions next-cloudinary/src/components/CldImage/CldImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import { transformationPlugins } from '@cloudinary-util/url-loader';
import type { ImageOptions, ConfigOptions } from '@cloudinary-util/url-loader';

import { pollForProcessingImage } from '../../lib/cloudinary';
import { getCldImageUrl } from '../../helpers/getCldImageUrl';

import { cloudinaryLoader } from '../../loaders/cloudinary-loader';

export type CldImageProps = Omit<ImageProps, 'src'> & ImageOptions & {
src: string;
preserveTransformations?: boolean;
config?: ConfigOptions;
preserveTransformations?: boolean;
src: string;
unoptimized?: boolean;
};

const CldImage = (props: CldImageProps) => {
Expand All @@ -31,7 +33,7 @@ const CldImage = (props: CldImageProps) => {

// Construct the base Image component props by filtering out Cloudinary-specific props

const imageProps = {
const imageProps: ImageProps = {
alt: props.alt,
src: props.src,
};
Expand All @@ -46,7 +48,7 @@ const CldImage = (props: CldImageProps) => {

// Construct Cloudinary-specific props by looking for values for any of the supported prop keys

const cldOptions = {};
const cldOptions: Omit<ImageOptions, 'src'> = {};

CLD_OPTIONS.forEach(key => {
// @ts-expect-error
Expand All @@ -63,13 +65,27 @@ const CldImage = (props: CldImageProps) => {
if (props.preserveTransformations) {
try {
const transformations = getTransformations(props.src).map(t => t.join(','));
// @ts-expect-error
cldOptions.rawTransformations = [...transformations.flat(), ...(props.rawTransformations || [])];
} catch(e) {
console.warn(`Failed to preserve transformations: ${(e as Error).message}`)
}
}

// The unoptimized flag is intended to remove all optimizations including quality, format, and sizing
// via responsive sizing. When passing this in, it also prevents the `loader` from running, thus
// breaking this component. This rewrites the `src` to construct a fully formed Cloudinary URL
// that also disables format and quality transformations, to deliver it as unoptimized
// See about unoptimized not working with loader: https://github.com/vercel/next.js/issues/50764

if ( props.unoptimized === true ) {
imageProps.src = getCldImageUrl({
...cldOptions,
format: 'default',
quality: 'default',
src: imageProps.src as string
}, props.config);
}

/**
* handleOnError
*/
Expand Down

1 comment on commit fed264f

@vercel
Copy link

@vercel vercel bot commented on fed264f Aug 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.