[New Provider] Add support for Umbraco ImageSharp as a Nuxt Image provider
Hi Nuxt team š
I'm currently working on a project using Umbraco CMS as a headless backend, and Iām leveraging its built-in image processing capabilities powered by Umbraco CMS (ImageSharp.Web).
It would be extremely useful to have native support for Umbraco as a provider in @nuxt/image. Umbraco allows image transformations via query parameters, which makes it very similar in behavior to other dynamic image providers.
Example URLs from Umbraco ImageSharp
/media/image.jpg?width=600
/media/image.jpg?width=600&height=300&rmode=crop&rxy=0.5,0.2
/media/image.jpg?format=webp&quality=80
/media/image.jpg?bgcolor=128,64,32&rmode=pad
Thanks for the fantastic module ā it has been a huge help optimizing images in Nuxt apps.
Best regards,
For now I tried to create a custom provider, but it would be better to have this oficially supported, so far I've this, still needs some testing. I read about a NUXT_IMAGE_PROVIDER on the documentation but can anyone give me an example of what value should be there? Is the name of the provider? So if I put there umbraco I dont need to always set provider="umbraco" everytime?
Nuxt Config:
image: {
providers: {
umbraco: {
provider: '~/providers/umbraco.ts',
options: {
baseURL: env.imageProviderUrl,
},
},
},
},
umbracoProvider:
import { joinURL } from 'ufo';
import { createOperationsGenerator } from '#image';
import type { ProviderGetImage } from '@nuxt/image';
/**
* Key map is responsible for mapping readable "properties", which can be passed
* as modifiers of the `NuxtImg` component, to query parameters that can be
* interpreted by Umbraco's API.
*/
const keyMap = {
width: 'width',
height: 'height',
format: 'format',
quality: 'quality',
rmode: 'rmode',
rsampler: 'rsampler',
ranchor: 'ranchor',
rxy: 'rxy',
orient: 'orient',
compand: 'compand',
bgcolor: 'bgcolor',
token: 'token', // For HMAC
} as const;
/**
* Value map is responsible for mapping readable modifier values defined in
* `keyMap`, as well as native modifiers of the `NuxtImg` component, to URL query
* values that can be interpreted by Umbraco's API.
*
* ```Examples
* Umbraco's `width` query param expects an arbitrary number, so it does not need to be in `valueMap`.
*
* Our custom param `width` maps directly to `width` in keyMap, so it does not need a valueMap entry either.
*
* However, Umbraco's `format` param only supports `jpg`, `png`, `gif`, `pbm`, `tga`, `tiff`, `webp`.
*
* So if the user passes `<NuxtImg :modifiers="{ format: 'jpeg' }" />`,
* we must map `jpeg` ā `jpg` since Umbraco does not recognize `jpeg`.
* Same thing for `tif` ā `tiff`
*
* Similarly, if a user passes `fit: 'cover'`, we translate it to `fit: 'crop'`
* because that's the terminology Umbraco uses, defaulting to `centre`.
* ```
*/
const valueMap = {
format: {
jpeg: 'jpg',
tif: 'tiff',
},
ranchor: {
bottom: 'Bottom',
'bottom-left': 'BottomLeft',
'bottom-right': 'BottomRight',
center: 'Center',
left: 'Left',
right: 'Right',
top: 'Top',
'top-left': 'TopLeft',
'top-right': 'TopRight',
},
rmode: {
cover: 'Crop',
contain: 'Pad',
stretch: 'Stretch',
fill: 'BoxPad',
inside: 'Max',
outside: 'Min',
manual: 'Manual',
},
rsampler: {
bicubic: 'Bicubic',
nearest: 'NearestNeighbor',
box: 'Box',
mitchell: 'MitchellNetravali',
catmull: 'CatmullRom',
lanczos2: 'Lanczos2',
lanczos3: 'Lanczos3',
lanczos5: 'Lanczos5',
lanczos8: 'Lanczos8',
welch: 'Welch',
robidoux: 'Robidoux',
robidouxsharp: 'RobidouxSharp',
spline: 'Spline',
triangle: 'Triangle',
hermite: 'Hermite',
},
} as const;
/**
* The formatter defines how individual key/value pairs are turned into query parameters.
* For example: `width=800`, or `format=jpg`.
* Boolean `true` modifiers are treated as flags, e.g., `auto=true` ā `auto`.
*/
export function formatter(key: string, value: string | number | boolean): string {
return String(value) === 'true' ? key : `${key}=${value}`;
}
const operationsGenerator = createOperationsGenerator({
formatter,
joinWith: '&', // standard query parameters
keyMap,
valueMap,
});
/**
* Provider for Umbraco-compatible image URLs, used by Nuxt Image module.
*
* It builds the final image URL with any modifiers passed via the `NuxtImg` component.
*
* Example:
* ```vue
* <NuxtImg
* provider="umbraco"
* src="/media/example.jpg"
* :modifiers="{ width: 600, format: 'jpeg' }"
* />
* ```
* ā Output:
* `/media/example.jpg?width=600&format=jpg`
*/
export const getImage: ProviderGetImage = (src, { modifiers = {}, baseUrl } = {}) => {
if (!baseUrl) {
baseUrl = '';
}
const operations = operationsGenerator(modifiers);
return {
url: joinURL(baseUrl, src + (operations ? `?${operations}` : '')),
};
};