templates: fix Media component failing when setting a custom serverURL (#12214)
### What? Fixes #12171 ### Why? Previously, the ImageMedia component was not properly handling URL formatting when a serverURL was configured in Payload. This caused images to fail to load when using a custom serverURL. By extracting the URL handling logic into a separate utility function, we ensure consistent URL processing across both image and video components. ### How? 1. Created a new utility function getMediaUrl in `src/utilities/getMediaUrl.ts` that: - Properly checks for HTTP/HTTPS protocols - Handles null or undefined URL values - Supports cache tags to prevent caching issues - Uses `getClientSideURL()` for relative paths 2. Updated the ImageMedia component to use this utility function instead of inline URL processing logic 3. Updated the VideoMedia component to also use the same utility function for consistency
This commit is contained in:
@@ -9,7 +9,7 @@ import React from 'react'
|
||||
import type { Props as MediaProps } from '../types'
|
||||
|
||||
import { cssVariables } from '@/cssVariables'
|
||||
import { getClientSideURL } from '@/utilities/getURL'
|
||||
import { getMediaUrl } from '@/utilities/getMediaUrl'
|
||||
|
||||
const { breakpoints } = cssVariables
|
||||
|
||||
@@ -44,7 +44,7 @@ export const ImageMedia: React.FC<MediaProps> = (props) => {
|
||||
|
||||
const cacheTag = resource.updatedAt
|
||||
|
||||
src = `${getClientSideURL()}${url}?${cacheTag}`
|
||||
src = getMediaUrl(url, cacheTag)
|
||||
}
|
||||
|
||||
const loading = loadingFromProps || (!priority ? 'lazy' : undefined)
|
||||
|
||||
@@ -5,7 +5,7 @@ import React, { useEffect, useRef } from 'react'
|
||||
|
||||
import type { Props as MediaProps } from '../types'
|
||||
|
||||
import { getClientSideURL } from '@/utilities/getURL'
|
||||
import { getMediaUrl } from '@/utilities/getMediaUrl'
|
||||
|
||||
export const VideoMedia: React.FC<MediaProps> = (props) => {
|
||||
const { onClick, resource, videoClassName } = props
|
||||
@@ -37,7 +37,7 @@ export const VideoMedia: React.FC<MediaProps> = (props) => {
|
||||
playsInline
|
||||
ref={videoRef}
|
||||
>
|
||||
<source src={`${getClientSideURL()}/media/${filename}`} />
|
||||
<source src={getMediaUrl(`/media/${filename}`)} />
|
||||
</video>
|
||||
)
|
||||
}
|
||||
|
||||
20
templates/website/src/utilities/getMediaUrl.ts
Normal file
20
templates/website/src/utilities/getMediaUrl.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { getClientSideURL } from '@/utilities/getURL'
|
||||
|
||||
/**
|
||||
* Processes media resource URL to ensure proper formatting
|
||||
* @param url The original URL from the resource
|
||||
* @param cacheTag Optional cache tag to append to the URL
|
||||
* @returns Properly formatted URL with cache tag if provided
|
||||
*/
|
||||
export const getMediaUrl = (url: string | null | undefined, cacheTag?: string | null): string => {
|
||||
if (!url) return ''
|
||||
|
||||
// Check if URL already has http/https protocol
|
||||
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||
return cacheTag ? `${url}?${cacheTag}` : url
|
||||
}
|
||||
|
||||
// Otherwise prepend client-side URL
|
||||
const baseUrl = getClientSideURL()
|
||||
return cacheTag ? `${baseUrl}${url}?${cacheTag}` : `${baseUrl}${url}`
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import type { Props as MediaProps } from '../types'
|
||||
|
||||
import { cssVariables } from '@/cssVariables'
|
||||
import { getClientSideURL } from '@/utilities/getURL'
|
||||
import { getMediaUrl } from '@/utilities/getMediaUrl'
|
||||
|
||||
const { breakpoints } = cssVariables
|
||||
|
||||
@@ -44,7 +45,7 @@ export const ImageMedia: React.FC<MediaProps> = (props) => {
|
||||
|
||||
const cacheTag = resource.updatedAt
|
||||
|
||||
src = `${getClientSideURL()}${url}?${cacheTag}`
|
||||
src = getMediaUrl(url, cacheTag)
|
||||
}
|
||||
|
||||
const loading = loadingFromProps || (!priority ? 'lazy' : undefined)
|
||||
|
||||
@@ -4,8 +4,7 @@ import { cn } from '@/utilities/ui'
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
|
||||
import type { Props as MediaProps } from '../types'
|
||||
|
||||
import { getClientSideURL } from '@/utilities/getURL'
|
||||
import { getMediaUrl } from '@/utilities/getMediaUrl'
|
||||
|
||||
export const VideoMedia: React.FC<MediaProps> = (props) => {
|
||||
const { onClick, resource, videoClassName } = props
|
||||
@@ -37,7 +36,7 @@ export const VideoMedia: React.FC<MediaProps> = (props) => {
|
||||
playsInline
|
||||
ref={videoRef}
|
||||
>
|
||||
<source src={`${getClientSideURL()}/media/${filename}`} />
|
||||
<source src={getMediaUrl(`/media/${filename}`)} />
|
||||
</video>
|
||||
)
|
||||
}
|
||||
|
||||
20
templates/with-vercel-website/src/utilities/getMediaUrl.ts
Normal file
20
templates/with-vercel-website/src/utilities/getMediaUrl.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { getClientSideURL } from '@/utilities/getURL'
|
||||
|
||||
/**
|
||||
* Processes media resource URL to ensure proper formatting
|
||||
* @param url The original URL from the resource
|
||||
* @param cacheTag Optional cache tag to append to the URL
|
||||
* @returns Properly formatted URL with cache tag if provided
|
||||
*/
|
||||
export const getMediaUrl = (url: string | null | undefined, cacheTag?: string | null): string => {
|
||||
if (!url) return ''
|
||||
|
||||
// Check if URL already has http/https protocol
|
||||
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||
return cacheTag ? `${url}?${cacheTag}` : url
|
||||
}
|
||||
|
||||
// Otherwise prepend client-side URL
|
||||
const baseUrl = getClientSideURL()
|
||||
return cacheTag ? `${baseUrl}${url}?${cacheTag}` : `${baseUrl}${url}`
|
||||
}
|
||||
Reference in New Issue
Block a user