Is there a way to add modifiers to an existing provider? #2059
Replies: 1 comment
-
|
Hey @remihuigen Few months late but dug into the source and the Cloudinary docs to figure out exactly what's happening. Looking at the Cloudinary provider source, the modifier pipeline works like this:
So you need to solve both: make TypeScript accept the modifiers and make them actually reach the URL. Option 1: Module augmentation + keyMap extension; Extend the types so TS is happy: // types/nuxt-image-cloudinary.d.ts
import type { CloudinaryModifiers } from '@nuxt/image'
declare module '@nuxt/image' {
interface CloudinaryModifiers {
so?: string | number
duration?: string | number
}
}But this alone won't make them work. The Option 2: Typed wrapper. If you just want the TS error gone: // utils/video-modifiers.ts
interface VideoModifiers {
width?: number
height?: number
fit?: string
so?: string | number
duration?: string | number
aspectRatio?: string
}
export const videoMods = (overrides: VideoModifiers = {}) => ({
aspectRatio: '16:9',
so: '5',
...overrides,
})<NuxtImg provider="video" :modifiers="videoMods({ so: '5' })" />TypeScript won't complain. But check if Option 3: Custom provider. Looking at the Cloudinary Transformation Reference, the actual URL params are // providers/video-cloudinary.ts
import { joinURL, encodePath } from 'ufo'
import { defu } from 'defu'
import type { ImageModifiers } from '@nuxt/image'
import { createOperationsGenerator } from '@nuxt/image/runtime/utils'
import { defineProvider } from '@nuxt/image/runtime/utils/provider'
export interface VideoCloudinaryModifiers extends ImageModifiers {
width: number
height: number
fit: string
format: string
quality: string
aspectRatio: string
so: string | number
duration: string | number
}
const operationsGenerator = createOperationsGenerator({
keyMap: {
width: 'w',
height: 'h',
fit: 'c',
format: 'f',
quality: 'q',
aspectRatio: 'ar',
so: 'so',
duration: 'du',
},
joinWith: ',',
formatter: (key, value) => encodePath(key.includes('_') ? `${key}:${value}` : `${key}_${value}`),
})
const defaultModifiers = {
format: 'auto',
quality: 'auto',
}
export default defineProvider({
getImage: (src, { modifiers, baseURL = '/' }) => {
const merged = defu(modifiers, defaultModifiers)
const operations = operationsGenerator(merged as any)
return {
url: joinURL(baseURL, operations, src),
}
},
})// nuxt.config.ts
image: {
providers: {
video: {
provider: '~/providers/video-cloudinary',
options: {
baseURL: `https://res.cloudinary.com/${process.env.CLD_CLOUD}/video/upload/`,
},
},
},
}Now |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I'm hosting media on Cloudinary and using it together with Nuxt Image. To handle both images and videos, I currently define two providers:
Defining the extra
videoprovider lets me use<NuxtImg>for video thumbnails, which works fine functionally. The issue is that video transformations use a different set of modifiers than images. Previously, this wasn’t a problem because modifiers weren’t typed. After the latest Nuxt Image release, passing video-specific modifiers now leads to type errors:Is there a way to extend the provider definition so video transforms—like
startOffset—are recognized as valid modifiers? I could implement a custom provider, but that feels like overkill for what I’m trying to solve.Beta Was this translation helpful? Give feedback.
All reactions