diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/LinkIconWithLinkOverlay.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/LinkIconWithLinkOverlay.tsx
new file mode 100644
index 00000000000..3a7c0da6a11
--- /dev/null
+++ b/packages/twenty-front/src/modules/navigation-menu-item/components/LinkIconWithLinkOverlay.tsx
@@ -0,0 +1,115 @@
+import { styled } from '@linaria/react';
+import { useContext, useState } from 'react';
+import { isDefined } from 'twenty-shared/utils';
+import type { IconComponent } from 'twenty-ui/display';
+import { ThemeContext } from 'twenty-ui/theme';
+
+import { DEFAULT_NAVIGATION_MENU_ITEM_COLOR_LINK } from '@/navigation-menu-item/constants/NavigationMenuItemDefaultColorLink';
+import { getNavigationMenuItemIconStyleFromColor } from '@/navigation-menu-item/utils/get-navigation-menu-item-icon-style-from-color';
+import { getLinkFaviconUrl } from '@/navigation-menu-item/utils/getLinkFaviconUrl';
+
+const StyledCompositeContainer = styled.div`
+ align-items: center;
+ border-radius: 4px;
+ box-sizing: border-box;
+ display: flex;
+ flex-shrink: 0;
+ height: 16px;
+ justify-content: center;
+ position: relative;
+ width: 16px;
+`;
+
+const StyledMainIconWrapper = styled.div<{
+ $backgroundColor: string;
+ $borderColor?: string;
+ $noBackgroundOrBorder?: boolean;
+}>`
+ position: absolute;
+ inset: 0;
+ border-radius: 4px;
+ box-sizing: border-box;
+ background-color: ${({ $backgroundColor, $noBackgroundOrBorder }) =>
+ $noBackgroundOrBorder ? 'transparent' : $backgroundColor};
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: ${({ $borderColor, $noBackgroundOrBorder }) =>
+ $noBackgroundOrBorder || !$borderColor
+ ? 'none'
+ : `1px solid ${$borderColor}`};
+ overflow: hidden;
+`;
+
+const StyledFaviconImage = styled.img`
+ height: 100%;
+ object-fit: contain;
+ width: 100%;
+`;
+
+const StyledLinkOverlay = styled.div<{ $backgroundColor: string }>`
+ align-items: center;
+ background-color: ${({ $backgroundColor }) => $backgroundColor};
+ border-radius: 4px;
+ bottom: -7px;
+ display: flex;
+ height: 14px;
+ justify-content: center;
+ position: absolute;
+ right: -7px;
+ width: 14px;
+`;
+
+export type LinkIconWithLinkOverlayProps = {
+ link: string | null | undefined;
+ LinkIcon: IconComponent;
+ DefaultIcon: IconComponent;
+ color?: string | null;
+};
+
+export const LinkIconWithLinkOverlay = ({
+ link,
+ LinkIcon,
+ DefaultIcon,
+ color: navItemColor,
+}: LinkIconWithLinkOverlayProps) => {
+ const { theme } = useContext(ThemeContext);
+ const [faviconFailed, setFaviconFailed] = useState(false);
+ const faviconUrl = getLinkFaviconUrl(link);
+ const showFavicon = isDefined(faviconUrl) && !faviconFailed;
+ const linkStyle = getNavigationMenuItemIconStyleFromColor(
+ theme,
+ navItemColor ?? DEFAULT_NAVIGATION_MENU_ITEM_COLOR_LINK,
+ );
+
+ return (
+
+
+ {showFavicon ? (
+ setFaviconFailed(true)}
+ />
+ ) : (
+
+ )}
+
+
+
+
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemIcon.tsx b/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemIcon.tsx
index 82b27d19536..eeb1f011e19 100644
--- a/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemIcon.tsx
+++ b/packages/twenty-front/src/modules/navigation-menu-item/components/NavigationMenuItemIcon.tsx
@@ -1,10 +1,11 @@
import { isNonEmptyString } from '@sniptt/guards';
import { useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
-import { Avatar, useIcons } from 'twenty-ui/display';
+import { Avatar, IconLink, IconWorld, useIcons } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { FeatureFlagKey } from '~/generated-metadata/graphql';
+import { LinkIconWithLinkOverlay } from '@/navigation-menu-item/components/LinkIconWithLinkOverlay';
import { StyledNavigationMenuItemIconContainer } from '@/navigation-menu-item/components/NavigationMenuItemIconContainer';
import { ObjectIconWithViewOverlay } from '@/navigation-menu-item/components/ObjectIconWithViewOverlay';
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
@@ -65,6 +66,17 @@ export const NavigationMenuItemIcon = ({
);
}
+ if (navigationMenuItem.itemType === NavigationMenuItemType.LINK) {
+ return (
+
+ );
+ }
+
const iconToUse =
StandardIcon ??
(navigationMenuItem.Icon ? getIcon(navigationMenuItem.Icon) : undefined);
diff --git a/packages/twenty-front/src/modules/navigation-menu-item/utils/getLinkFaviconUrl.ts b/packages/twenty-front/src/modules/navigation-menu-item/utils/getLinkFaviconUrl.ts
new file mode 100644
index 00000000000..10f39310d3c
--- /dev/null
+++ b/packages/twenty-front/src/modules/navigation-menu-item/utils/getLinkFaviconUrl.ts
@@ -0,0 +1,20 @@
+import { getLogoUrlFromDomainName } from 'twenty-shared/utils';
+
+export const getLinkFaviconUrl = (
+ link: string | null | undefined,
+): string | undefined => {
+ const trimmed = (link ?? '').trim();
+ if (!trimmed) {
+ return undefined;
+ }
+ const normalized =
+ trimmed.startsWith('http://') || trimmed.startsWith('https://')
+ ? trimmed
+ : `https://${trimmed}`;
+ try {
+ const hostname = new URL(normalized).hostname;
+ return getLogoUrlFromDomainName(hostname);
+ } catch {
+ return undefined;
+ }
+};
diff --git a/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerSectionForWorkspaceItemContent.tsx b/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerSectionForWorkspaceItemContent.tsx
index 787685d3143..9dc337eb3f5 100644
--- a/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerSectionForWorkspaceItemContent.tsx
+++ b/packages/twenty-front/src/modules/object-metadata/components/NavigationDrawerSectionForWorkspaceItemContent.tsx
@@ -1,8 +1,7 @@
import { lazy, Suspense } from 'react';
-import { IconLink } from 'twenty-ui/display';
+import { NavigationMenuItemIcon } from '@/navigation-menu-item/components/NavigationMenuItemIcon';
import { isNavigationMenuInEditModeState } from '@/navigation-menu-item/states/isNavigationMenuInEditModeState';
-import { getEffectiveNavigationMenuItemColor } from '@/navigation-menu-item/utils/getEffectiveNavigationMenuItemColor';
import { getObjectMetadataForNavigationMenuItem } from '@/navigation-menu-item/utils/getObjectMetadataForNavigationMenuItem';
import type { ProcessedNavigationMenuItem } from '@/navigation-menu-item/utils/sortNavigationMenuItems';
import { NavigationDrawerItemForObjectMetadataItem } from '@/object-metadata/components/NavigationDrawerItemForObjectMetadataItem';
@@ -101,8 +100,7 @@ export const WorkspaceSectionItemContent = ({
onClick={
isNavigationMenuInEditMode ? editModeProps.onEditModeClick : undefined
}
- Icon={IconLink}
- iconColor={getEffectiveNavigationMenuItemColor(linkItem) ?? undefined}
+ Icon={() => }
active={false}
isSelectedInEditMode={editModeProps.isSelectedInEditMode}
isDragging={isDragging}