diff --git a/webapp/channels/src/components/global_header/left_controls/product_menu/product_branding/__snapshots__/product_branding.test.tsx.snap b/webapp/channels/src/components/global_header/left_controls/product_menu/product_branding/__snapshots__/product_branding.test.tsx.snap
index 17892495825..1364bd6e568 100644
--- a/webapp/channels/src/components/global_header/left_controls/product_menu/product_branding/__snapshots__/product_branding.test.tsx.snap
+++ b/webapp/channels/src/components/global_header/left_controls/product_menu/product_branding/__snapshots__/product_branding.test.tsx.snap
@@ -1,5 +1,47 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
+exports[`components/ProductBranding should fallback to ProductChannelsIcon when string icon name is not found in glyphMap 1`] = `
+
+
+
+ InvalidProduct
+
+
+ InvalidProduct
+
+
+`;
+
+exports[`components/ProductBranding should render a React element icon when switcherIcon is a React node 1`] = `
+
+
+
+ CustomProduct
+
+
+ CustomProduct
+
+
+`;
+
exports[`components/ProductBranding should show correct icon glyph when we are on Boards 1`] = `
{
@@ -42,4 +44,45 @@ describe('components/ProductBranding', () => {
expect(wrapper).toMatchSnapshot();
});
+
+ test('should render a React element icon when switcherIcon is a React node', () => {
+ const currentProductSpy = jest.spyOn(productUtils, 'useCurrentProduct');
+ const CustomIcon = (
+
+ );
+ const productWithReactIcon: ProductComponent = {
+ ...TestHelper.makeProduct('CustomProduct'),
+ switcherIcon: CustomIcon,
+ };
+ currentProductSpy.mockReturnValue(productWithReactIcon);
+
+ const wrapper = shallow(
+ ,
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find('[data-testid="custom-icon"]').exists()).toBe(true);
+ });
+
+ test('should fallback to ProductChannelsIcon when string icon name is not found in glyphMap', () => {
+ const currentProductSpy = jest.spyOn(productUtils, 'useCurrentProduct');
+ const productWithInvalidIcon: ProductComponent = {
+ ...TestHelper.makeProduct('InvalidProduct'),
+ switcherIcon: 'non-existent-icon-name' as ProductComponent['switcherIcon'],
+ };
+ currentProductSpy.mockReturnValue(productWithInvalidIcon);
+
+ const wrapper = shallow(
+ ,
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ expect(wrapper.find('ProductChannelsIcon').exists()).toBe(true);
+ });
});
diff --git a/webapp/channels/src/components/global_header/left_controls/product_menu/product_branding/product_branding.tsx b/webapp/channels/src/components/global_header/left_controls/product_menu/product_branding/product_branding.tsx
index 2a977226835..e1aa07a1f58 100644
--- a/webapp/channels/src/components/global_header/left_controls/product_menu/product_branding/product_branding.tsx
+++ b/webapp/channels/src/components/global_header/left_controls/product_menu/product_branding/product_branding.tsx
@@ -5,6 +5,7 @@ import React from 'react';
import styled from 'styled-components';
import glyphMap, {ProductChannelsIcon} from '@mattermost/compass-icons/components';
+import type {IconGlyphTypes} from '@mattermost/compass-icons/IconGlyphs';
import {useCurrentProduct} from 'utils/products';
@@ -27,11 +28,29 @@ const ProductBrandingHeading = styled.span`
const ProductBranding = (): JSX.Element => {
const currentProduct = useCurrentProduct();
- const Icon = currentProduct?.switcherIcon ? glyphMap[currentProduct.switcherIcon] : ProductChannelsIcon;
+ // Handle both string icon names and React elements
+ const renderIcon = () => {
+ if (!currentProduct?.switcherIcon) {
+ return ;
+ }
+
+ if (typeof currentProduct.switcherIcon === 'string') {
+ const Icon = glyphMap[currentProduct.switcherIcon as IconGlyphTypes];
+ if (Icon) {
+ return ;
+ }
+
+ // Fallback if icon name not found in glyphMap
+ return ;
+ }
+
+ // React element - render directly
+ return <>{currentProduct.switcherIcon}>;
+ };
return (
-
+ {renderIcon()}