From 24c006ea86ce4a406d3312c0859461694bd628d0 Mon Sep 17 00:00:00 2001 From: laszlo-san <11998934+laszlo-san@users.noreply.github.com> Date: Mon, 7 Jul 2025 11:47:27 +0200 Subject: [PATCH 1/2] fix(media): handle both relative and absolute URLs in useStrapiMedia - Add URL detection using new URL() constructor - Return absolute URLs as-is without prepending base URL - Maintain backward compatibility for relative paths - Add documentation with examples Fixes URL malformation in production environments where Strapi Cloud returns full URLs (e.g., https://domain.media.strapiapp.com/image.jpg) instead of relative paths, preventing double-prefixing with base URL. --- src/runtime/composables/useStrapiMedia.ts | 29 ++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/runtime/composables/useStrapiMedia.ts b/src/runtime/composables/useStrapiMedia.ts index b0553b83..a49753ab 100644 --- a/src/runtime/composables/useStrapiMedia.ts +++ b/src/runtime/composables/useStrapiMedia.ts @@ -1,7 +1,34 @@ import { joinURL } from 'ufo' import { useRuntimeConfig } from '#imports' -export const useStrapiMedia = (path: string): string => { +/** + * Safely handles Strapi media URLs for both development and production environments. + * + * In development or self hosted, Strapi typically returns relative paths (e.g., '/uploads/image.jpg') + * In production (Strapi Cloud), Strapi returns full URLs (e.g., 'https://domain.media.strapiapp.com/image.jpg') + * + * This composable automatically detects the URL type and handles it appropriately: + * - Full URLs are returned as-is + * - Relative paths are processed + * + * @param path - The media URL from Strapi (can be relative or absolute) + * @returns The complete, accessible media URL + * + * @example + * // Development: '/uploads/favicon.svg' → 'http://localhost:1337/uploads/favicon.svg' + * // Production: 'https://domain.media.strapiapp.com/favicon.svg' → 'https://domain.media.strapiapp.com/favicon.svg' + */ +export const useStrapiMedia = (path?: string | null): string | undefined => { + if (!path || typeof path !== 'string' || path.trim() === '') return undefined + + try { + // If path is already an absolute URL, return as-is + const url = new URL(path) + return url.href + } catch (_e) { // eslint-disable-line @typescript-eslint/no-unused-vars + // Not a valid absolute URL, treat as relative + } + const config = import.meta.server ? useRuntimeConfig() : useRuntimeConfig().public return joinURL(config.strapi.url, path) From 18fbfe9e73091e58e35f74303e986d21f7b3417a Mon Sep 17 00:00:00 2001 From: laszlo-san <11998934+laszlo-san@users.noreply.github.com> Date: Mon, 7 Jul 2025 11:55:49 +0200 Subject: [PATCH 2/2] fix: reverted function typings to its original --- src/runtime/composables/useStrapiMedia.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/runtime/composables/useStrapiMedia.ts b/src/runtime/composables/useStrapiMedia.ts index a49753ab..f687f4e2 100644 --- a/src/runtime/composables/useStrapiMedia.ts +++ b/src/runtime/composables/useStrapiMedia.ts @@ -18,11 +18,8 @@ import { useRuntimeConfig } from '#imports' * // Development: '/uploads/favicon.svg' → 'http://localhost:1337/uploads/favicon.svg' * // Production: 'https://domain.media.strapiapp.com/favicon.svg' → 'https://domain.media.strapiapp.com/favicon.svg' */ -export const useStrapiMedia = (path?: string | null): string | undefined => { - if (!path || typeof path !== 'string' || path.trim() === '') return undefined - +export const useStrapiMedia = (path: string): string => { try { - // If path is already an absolute URL, return as-is const url = new URL(path) return url.href } catch (_e) { // eslint-disable-line @typescript-eslint/no-unused-vars