diff --git a/client/src/components/Endpoints/URLIcon.tsx b/client/src/components/Endpoints/URLIcon.tsx
index ddb62aaded..0e25ab175b 100644
--- a/client/src/components/Endpoints/URLIcon.tsx
+++ b/client/src/components/Endpoints/URLIcon.tsx
@@ -1,5 +1,6 @@
-import React, { memo, useState } from 'react';
+import React, { memo, useState, useEffect } from 'react';
import { AlertCircle } from 'lucide-react';
+import { Skeleton } from '@librechat/client';
import { icons } from '~/hooks/Endpoint/Icons';
export const URLIcon = memo(
@@ -19,9 +20,34 @@ export const URLIcon = memo(
endpoint?: string;
}) => {
const [imageError, setImageError] = useState(false);
+ const [isLoaded, setIsLoaded] = useState(() => {
+ // Check if image is already cached
+ if (typeof window !== 'undefined' && iconURL) {
+ const img = new Image();
+ img.src = iconURL;
+ return img.complete && img.naturalWidth > 0;
+ }
+ return false;
+ });
+
+ useEffect(() => {
+ // When URL changes, check if new image is cached
+ if (iconURL) {
+ const img = new Image();
+ img.src = iconURL;
+ if (img.complete && img.naturalWidth > 0) {
+ setIsLoaded(true);
+ setImageError(false);
+ } else {
+ setIsLoaded(false);
+ setImageError(false);
+ }
+ }
+ }, [iconURL]);
const handleImageError = () => {
setImageError(true);
+ setIsLoaded(false);
};
const DefaultIcon: React.ElementType =
@@ -46,18 +72,29 @@ export const URLIcon = memo(
}
return (
-
+

setIsLoaded(true)}
onError={handleImageError}
- loading="lazy"
decoding="async"
width={Number(containerStyle.width) || 20}
height={Number(containerStyle.height) || 20}
/>
+ {!isLoaded && !imageError && (
+
+ )}
);
},
diff --git a/client/src/utils/agents.tsx b/client/src/utils/agents.tsx
index e83a94c1aa..5793b127bb 100644
--- a/client/src/utils/agents.tsx
+++ b/client/src/utils/agents.tsx
@@ -32,10 +32,28 @@ const LazyAgentAvatar = ({
alt: string;
imgClass: string;
}) => {
- const [isLoaded, setIsLoaded] = useState(false);
+ const [isLoaded, setIsLoaded] = useState(() => {
+ // Check if image is already cached by creating a test image
+ if (typeof window !== 'undefined') {
+ const img = new Image();
+ img.src = url;
+ return img.complete && img.naturalWidth > 0;
+ }
+ return false;
+ });
+ const [hasError, setHasError] = useState(false);
useEffect(() => {
- setIsLoaded(false);
+ // When URL changes, check if new image is cached
+ const img = new Image();
+ img.src = url;
+ if (img.complete && img.naturalWidth > 0) {
+ setIsLoaded(true);
+ setHasError(false);
+ } else {
+ setIsLoaded(false);
+ setHasError(false);
+ }
}, [url]);
return (
@@ -44,15 +62,19 @@ const LazyAgentAvatar = ({
src={url}
alt={alt}
className={imgClass}
- loading="lazy"
onLoad={() => setIsLoaded(true)}
- onError={() => setIsLoaded(false)}
+ onError={() => {
+ setIsLoaded(false);
+ setHasError(true);
+ }}
style={{
opacity: isLoaded ? 1 : 0,
transition: 'opacity 0.2s ease-in-out',
}}
/>
- {!isLoaded &&
}
+ {!isLoaded && !hasError && (
+
+ )}
>
);
};