From bbcb13cb2359f3defca376b2a85b2355b8b0199e Mon Sep 17 00:00:00 2001 From: Amr Awad Date: Mon, 8 Sep 2025 22:33:19 +0300 Subject: [PATCH 1/2] feat(provider/cloudimage): make baseURL optional and route absolute src via CDN --- docs/content/3.providers/cloudimage.md | 12 +++++++----- src/runtime/providers/cloudimage.ts | 10 +++------- test/e2e/__snapshots__/cloudimage.json5 | 4 ++-- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/docs/content/3.providers/cloudimage.md b/docs/content/3.providers/cloudimage.md index 4b5cee6ac..396a6f370 100644 --- a/docs/content/3.providers/cloudimage.md +++ b/docs/content/3.providers/cloudimage.md @@ -10,14 +10,14 @@ links: Integration between [Cloudimage](https://www.cloudimage.io/en/home) and the image module. -To use this provider you need to specify your Cloudimage `token` and the `baseURL` of your image storage. +To use this provider you need to specify either your Cloudimage `token` (with optional `apiVersion`) or a full `cdnURL`. The `baseURL` of your image storage is optional and is only used when the passed `src` is not an absolute URL. ```ts [nuxt.config.ts] export default defineNuxtConfig({ image: { cloudimage: { token: 'your_cloudimage_token', - baseURL: 'origin_image_url' // or alias + baseURL: 'origin_image_url' // or alias (optional) } } }) @@ -33,9 +33,9 @@ Your Cloudimage customer token. [Register](https://www.cloudimage.io/en/register ### `baseURL` -- Type: **String** (required) +- Type: **String** (optional) -Your origin image URL or storage alias that allows to shorten your origin image URLs. +Your origin image URL or storage alias that allows to shorten your origin image URLs. If not provided, the `src` will be joined directly with the computed `cdnURL`. ```ts [nuxt.config.ts] export default defineNuxtConfig({ @@ -93,7 +93,7 @@ export default defineNuxtConfig({ - Type: **String** - Default: `https://{token}.cloudimg.io/{apiVersion}` -Replaces the dynamically built URL +Replaces the dynamically built URL. Useful when you prefer not to provide a `token` or need a custom CDN hostname. ```ts [nuxt.config.ts] export default defineNuxtConfig({ @@ -105,6 +105,8 @@ export default defineNuxtConfig({ }) ``` +When only `cdnURL` is provided and `baseURL` is omitted, relative sources are resolved directly against the CDN URL, for example `src: '/test.png'` becomes `https://demo.cloudimg.io/v7/test.png`. + ## Cloudimage Modifiers Beside the [standard modifiers](/usage/nuxt-img#modifiers), also you can pass Cloudimage-specific [Cloudimage-specific transformation](https://docs.cloudimage.io/go/cloudimage-documentation-v7/en/introduction) params to `modifiers` prop. diff --git a/src/runtime/providers/cloudimage.ts b/src/runtime/providers/cloudimage.ts index 675745e0e..786c4afd0 100644 --- a/src/runtime/providers/cloudimage.ts +++ b/src/runtime/providers/cloudimage.ts @@ -20,9 +20,9 @@ const operationsGenerator = createOperationsGenerator({ }) interface CloudimageOptions { - baseURL: string token: string apiVersion?: string + baseURL?: string cdnURL?: string } @@ -41,10 +41,6 @@ export default defineProvider({ if (import.meta.dev) { const warning = [] - if (!baseURL) { - warning.push('') - } - if (!token && !cdnURL) { warning.push(' or ') } @@ -61,9 +57,9 @@ export default defineProvider({ cdnURL = `https://${token}.cloudimg.io/${apiVersion}` } - if (hasProtocol(src)) { + if (hasProtocol(src) || !baseURL) { return { - url: joinURL(src) + query, + url: joinURL(cdnURL, src) + query, } } diff --git a/test/e2e/__snapshots__/cloudimage.json5 b/test/e2e/__snapshots__/cloudimage.json5 index 3f031e9eb..0418c87a1 100644 --- a/test/e2e/__snapshots__/cloudimage.json5 +++ b/test/e2e/__snapshots__/cloudimage.json5 @@ -1,12 +1,12 @@ { "requests": [ - "https://2412819702-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlIgyYELwJG6odLEyCM6i%2Fuploads%2FAHcbuKRYbIlBWO4cJ88b%2Fimage.png?alt=media&token=62ff753d-83eb-4e3f-932c-96eb72d455f1?width=400&height=250&force_format=webp&q=65&func=fit", + "https://demo.cloudimg.io/v7/https://2412819702-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlIgyYELwJG6odLEyCM6i%2Fuploads%2FAHcbuKRYbIlBWO4cJ88b%2Fimage.png?alt=media&token=62ff753d-83eb-4e3f-932c-96eb72d455f1?width=400&height=250&force_format=webp&q=65&func=fit", "https://demo.cloudimg.io/v7/sample.li/bag.jpg?width=500&height=500&func=fit", "https://demo.cloudimg.io/v7/sample.li/boat.jpg?width=800&height=800&q=75&func=crop", "https://demo.cloudimg.io/v7/sample.li/img.jpg?width=300&height=300&force_format=webp&func=cover", ], "sources": [ - "https://2412819702-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlIgyYELwJG6odLEyCM6i%2Fuploads%2FAHcbuKRYbIlBWO4cJ88b%2Fimage.png?alt=media&token=62ff753d-83eb-4e3f-932c-96eb72d455f1?width=400&height=250&force_format=webp&q=65&func=fit", + "https://demo.cloudimg.io/v7/https://2412819702-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FlIgyYELwJG6odLEyCM6i%2Fuploads%2FAHcbuKRYbIlBWO4cJ88b%2Fimage.png?alt=media&token=62ff753d-83eb-4e3f-932c-96eb72d455f1?width=400&height=250&force_format=webp&q=65&func=fit", "https://demo.cloudimg.io/v7/sample.li/bag.jpg?width=500&height=500&func=fit", "https://demo.cloudimg.io/v7/sample.li/boat.jpg?width=800&height=800&q=75&func=crop", "https://demo.cloudimg.io/v7/sample.li/img.jpg?width=300&height=300&force_format=webp&func=cover", From 5c3d9f4a6454fe88801d61f970afe8b861b6f97f Mon Sep 17 00:00:00 2001 From: Amr Awad Date: Tue, 9 Sep 2025 00:37:14 +0300 Subject: [PATCH 2/2] feat: fallback non base url relative images to app base url --- docs/content/3.providers/cloudimage.md | 39 ++++++++++++++++++++++++-- src/runtime/providers/cloudimage.ts | 8 ++++-- test/nuxt/providers.test.ts | 8 ++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/docs/content/3.providers/cloudimage.md b/docs/content/3.providers/cloudimage.md index 396a6f370..06a1b12d4 100644 --- a/docs/content/3.providers/cloudimage.md +++ b/docs/content/3.providers/cloudimage.md @@ -10,7 +10,7 @@ links: Integration between [Cloudimage](https://www.cloudimage.io/en/home) and the image module. -To use this provider you need to specify either your Cloudimage `token` (with optional `apiVersion`) or a full `cdnURL`. The `baseURL` of your image storage is optional and is only used when the passed `src` is not an absolute URL. +To use this provider you need to specify either your Cloudimage `token` (with optional `apiVersion`) or a full `cdnURL`. The `baseURL` of your image storage is optional and is only used when the passed `src` is not an absolute URL. When using absolute URLs, the provider will use the `cdnURL` directly without prepending the `baseURL`. ```ts [nuxt.config.ts] export default defineNuxtConfig({ @@ -35,7 +35,7 @@ Your Cloudimage customer token. [Register](https://www.cloudimage.io/en/register - Type: **String** (optional) -Your origin image URL or storage alias that allows to shorten your origin image URLs. If not provided, the `src` will be joined directly with the computed `cdnURL`. +Your origin image URL or storage alias that allows to shorten your origin image URLs. If not provided, the provider will fall back to base App URL for relative URLs, or use the `cdnURL` directly for absolute URLs. ```ts [nuxt.config.ts] export default defineNuxtConfig({ @@ -105,7 +105,40 @@ export default defineNuxtConfig({ }) ``` -When only `cdnURL` is provided and `baseURL` is omitted, relative sources are resolved directly against the CDN URL, for example `src: '/test.png'` becomes `https://demo.cloudimg.io/v7/test.png`. +When only `cdnURL` is provided and `baseURL` is omitted, relative sources will fallback to the website's base URL, for example `src: '/test.png'` becomes `https://demo.cloudimg.io/v7/{website-base-url}/test.png`. When using absolute URLs with `cdnURL`, the provider will use the CDN URL directly without prepending any base URL. + +### Examples + +**Using absolute URLs with cdnURL:** + +```ts [nuxt.config.ts] +export default defineNuxtConfig({ + image: { + cloudimage: { + cdnURL: 'https://demo.cloudimg.io/v7' + } + } +}) +``` + +With this configuration: + +- `src: 'https://example.com/image.jpg'` becomes `https://demo.cloudimg.io/v7/https://example.com/image.jpg` +- `src: '/local/image.jpg'` becomes `https://demo.cloudimg.io/v7/{website-base-url}/local/image.jpg` + +**Using token with automatic baseURL fallback:** + +```ts [nuxt.config.ts] +export default defineNuxtConfig({ + image: { + cloudimage: { + token: 'demo', + apiVersion: 'v7' + // baseURL will automatically fall back to the website's base URL + } + } +}) +``` ## Cloudimage Modifiers diff --git a/src/runtime/providers/cloudimage.ts b/src/runtime/providers/cloudimage.ts index 786c4afd0..fb780c6f6 100644 --- a/src/runtime/providers/cloudimage.ts +++ b/src/runtime/providers/cloudimage.ts @@ -34,7 +34,7 @@ export default defineProvider({ token = '', apiVersion = '', cdnURL = '', - }) => { + }, ctx) => { const operations = operationsGenerator(modifiers) const query = (operations ? ('?' + operations) : '') @@ -57,12 +57,16 @@ export default defineProvider({ cdnURL = `https://${token}.cloudimg.io/${apiVersion}` } - if (hasProtocol(src) || !baseURL) { + if (hasProtocol(src)) { return { url: joinURL(cdnURL, src) + query, } } + if (!baseURL) { + baseURL = ctx.options.nuxt.baseURL + } + return { url: joinURL(cdnURL, baseURL, src) + query, } diff --git a/test/nuxt/providers.test.ts b/test/nuxt/providers.test.ts index 06ca372a9..3c44db07c 100644 --- a/test/nuxt/providers.test.ts +++ b/test/nuxt/providers.test.ts @@ -487,6 +487,14 @@ describe('Providers', () => { const generated = cloudimage().getImage(src, { modifiers, ...providerOptions }, emptyContext) expect(generated).toMatchObject(image.cloudimage) } + + const nonBaseURLProviderOptions = { + token: 'demo', + apiVersion: 'v7', + } + const src = 'https://localhost' + images[0].args[0] + const generated = cloudimage().getImage(src, { modifiers: { ...images[0].args[1] }, ...nonBaseURLProviderOptions }, emptyContext) + expect(generated).toMatchObject({ url: 'https://demo.cloudimg.io/v7/https://localhost/test.png' }) }) it('storyblok', () => {