Skip to content

Commit d6b7000

Browse files
Rot4tionkendelljoseph
authored andcommitted
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
1 parent 8afc828 commit d6b7000

File tree

6 files changed

+48
-8
lines changed

6 files changed

+48
-8
lines changed

templates/website/src/components/Media/ImageMedia/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import React from 'react'
99
import type { Props as MediaProps } from '../types'
1010

1111
import { cssVariables } from '@/cssVariables'
12-
import { getClientSideURL } from '@/utilities/getURL'
12+
import { getMediaUrl } from '@/utilities/getMediaUrl'
1313

1414
const { breakpoints } = cssVariables
1515

@@ -44,7 +44,7 @@ export const ImageMedia: React.FC<MediaProps> = (props) => {
4444

4545
const cacheTag = resource.updatedAt
4646

47-
src = `${getClientSideURL()}${url}?${cacheTag}`
47+
src = getMediaUrl(url, cacheTag)
4848
}
4949

5050
const loading = loadingFromProps || (!priority ? 'lazy' : undefined)

templates/website/src/components/Media/VideoMedia/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import React, { useEffect, useRef } from 'react'
55

66
import type { Props as MediaProps } from '../types'
77

8-
import { getClientSideURL } from '@/utilities/getURL'
8+
import { getMediaUrl } from '@/utilities/getMediaUrl'
99

1010
export const VideoMedia: React.FC<MediaProps> = (props) => {
1111
const { onClick, resource, videoClassName } = props
@@ -37,7 +37,7 @@ export const VideoMedia: React.FC<MediaProps> = (props) => {
3737
playsInline
3838
ref={videoRef}
3939
>
40-
<source src={`${getClientSideURL()}/media/${filename}`} />
40+
<source src={getMediaUrl(`/media/${filename}`)} />
4141
</video>
4242
)
4343
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { getClientSideURL } from '@/utilities/getURL'
2+
3+
/**
4+
* Processes media resource URL to ensure proper formatting
5+
* @param url The original URL from the resource
6+
* @param cacheTag Optional cache tag to append to the URL
7+
* @returns Properly formatted URL with cache tag if provided
8+
*/
9+
export const getMediaUrl = (url: string | null | undefined, cacheTag?: string | null): string => {
10+
if (!url) return ''
11+
12+
// Check if URL already has http/https protocol
13+
if (url.startsWith('http://') || url.startsWith('https://')) {
14+
return cacheTag ? `${url}?${cacheTag}` : url
15+
}
16+
17+
// Otherwise prepend client-side URL
18+
const baseUrl = getClientSideURL()
19+
return cacheTag ? `${baseUrl}${url}?${cacheTag}` : `${baseUrl}${url}`
20+
}

templates/with-vercel-website/src/components/Media/ImageMedia/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { Props as MediaProps } from '../types'
1010

1111
import { cssVariables } from '@/cssVariables'
1212
import { getClientSideURL } from '@/utilities/getURL'
13+
import { getMediaUrl } from '@/utilities/getMediaUrl'
1314

1415
const { breakpoints } = cssVariables
1516

@@ -44,7 +45,7 @@ export const ImageMedia: React.FC<MediaProps> = (props) => {
4445

4546
const cacheTag = resource.updatedAt
4647

47-
src = `${getClientSideURL()}${url}?${cacheTag}`
48+
src = getMediaUrl(url, cacheTag)
4849
}
4950

5051
const loading = loadingFromProps || (!priority ? 'lazy' : undefined)

templates/with-vercel-website/src/components/Media/VideoMedia/index.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import { cn } from '@/utilities/ui'
44
import React, { useEffect, useRef } from 'react'
55

66
import type { Props as MediaProps } from '../types'
7-
8-
import { getClientSideURL } from '@/utilities/getURL'
7+
import { getMediaUrl } from '@/utilities/getMediaUrl'
98

109
export const VideoMedia: React.FC<MediaProps> = (props) => {
1110
const { onClick, resource, videoClassName } = props
@@ -37,7 +36,7 @@ export const VideoMedia: React.FC<MediaProps> = (props) => {
3736
playsInline
3837
ref={videoRef}
3938
>
40-
<source src={`${getClientSideURL()}/media/${filename}`} />
39+
<source src={getMediaUrl(`/media/${filename}`)} />
4140
</video>
4241
)
4342
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { getClientSideURL } from '@/utilities/getURL'
2+
3+
/**
4+
* Processes media resource URL to ensure proper formatting
5+
* @param url The original URL from the resource
6+
* @param cacheTag Optional cache tag to append to the URL
7+
* @returns Properly formatted URL with cache tag if provided
8+
*/
9+
export const getMediaUrl = (url: string | null | undefined, cacheTag?: string | null): string => {
10+
if (!url) return ''
11+
12+
// Check if URL already has http/https protocol
13+
if (url.startsWith('http://') || url.startsWith('https://')) {
14+
return cacheTag ? `${url}?${cacheTag}` : url
15+
}
16+
17+
// Otherwise prepend client-side URL
18+
const baseUrl = getClientSideURL()
19+
return cacheTag ? `${baseUrl}${url}?${cacheTag}` : `${baseUrl}${url}`
20+
}

0 commit comments

Comments
 (0)