diff --git a/web/packages/teleport/src/Navigation/ResourcesSection.tsx b/web/packages/teleport/src/Navigation/ResourcesSection.tsx
index f0da25f25b4a6..77145168ae694 100644
--- a/web/packages/teleport/src/Navigation/ResourcesSection.tsx
+++ b/web/packages/teleport/src/Navigation/ResourcesSection.tsx
@@ -48,6 +48,7 @@ import {
SubsectionItem,
verticalPadding,
} from './Section';
+import { useDefaultNavigation } from './useDefaultNavigation';
/**
* getResourcesSection returns a NavigationSection for resources,
@@ -311,7 +312,7 @@ export function ResourcesSection({
const isExpanded = expandedSection?.category === NavigationCategory.Resources;
- const subsections = getResourcesSubsections({
+ section.subsections = getResourcesSubsections({
clusterId,
preferences,
updatePreferences,
@@ -337,6 +338,7 @@ export function ResourcesSection({
isExpanded={isExpanded}
showPoweredByLogo={showPoweredByLogo}
{...getReferenceProps()}
+ {...useDefaultNavigation(section)}
>
- {subsections
+ {section.subsections
.filter(section => !section.subCategory)
.map(section => (
- {subsections
+ {section.subsections
.filter(
section =>
section.subCategory ===
diff --git a/web/packages/teleport/src/Navigation/Section.tsx b/web/packages/teleport/src/Navigation/Section.tsx
index f3b72956d846d..01ad624e365ca 100644
--- a/web/packages/teleport/src/Navigation/Section.tsx
+++ b/web/packages/teleport/src/Navigation/Section.tsx
@@ -41,6 +41,7 @@ import {
NavigationSubsection,
useFloatingUiWithRestMs,
} from './Navigation';
+import { useDefaultNavigation } from './useDefaultNavigation';
import { zIndexMap } from './zIndexMap';
type SharedSectionProps = {
@@ -90,6 +91,7 @@ export function DefaultSection({
isExpanded={isExpanded}
tabIndex={section.standalone ? 0 : -1}
{...getReferenceProps()}
+ {...useDefaultNavigation(section)}
>
{section.category}
diff --git a/web/packages/teleport/src/Navigation/useDefaultNavigation.test.ts b/web/packages/teleport/src/Navigation/useDefaultNavigation.test.ts
new file mode 100644
index 0000000000000..baf95f5c6c676
--- /dev/null
+++ b/web/packages/teleport/src/Navigation/useDefaultNavigation.test.ts
@@ -0,0 +1,69 @@
+/**
+ * Teleport
+ * Copyright (C) 2025 Gravitational, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import { act, renderHook } from '@testing-library/react';
+import { useHistory } from 'react-router-dom';
+
+import { NavigationSection, NavigationSubsection } from './Navigation';
+import { useDefaultNavigation } from './useDefaultNavigation';
+
+jest.mock('react-router-dom', () => ({
+ useHistory: jest.fn(),
+}));
+
+const pushMock = jest.fn();
+
+describe('useDefaultNavigation', () => {
+ beforeEach(() => {
+ (useHistory as jest.Mock).mockReturnValue({
+ push: pushMock,
+ });
+ });
+
+ it('returns an onClick function that calls the first section onclick and navigates to its route', () => {
+ const sectionOnclickMock = jest.fn();
+ const testRoute = '/test';
+
+ const section = {
+ subsections: [
+ {
+ title: 'test',
+ exact: true,
+ icon: () => null,
+ route: testRoute,
+ onClick: sectionOnclickMock,
+ },
+ {
+ title: 'test2',
+ exact: true,
+ icon: () => null,
+ route: testRoute + '2',
+ },
+ ] as NavigationSubsection[],
+ } as NavigationSection;
+
+ const { result } = renderHook(() => useDefaultNavigation(section));
+
+ act(() => {
+ result.current.onClick?.();
+ });
+
+ expect(sectionOnclickMock).toHaveBeenCalled();
+ expect(pushMock).toHaveBeenCalledWith(testRoute);
+ });
+});
diff --git a/web/packages/teleport/src/Navigation/useDefaultNavigation.ts b/web/packages/teleport/src/Navigation/useDefaultNavigation.ts
new file mode 100644
index 0000000000000..1959ba5db37aa
--- /dev/null
+++ b/web/packages/teleport/src/Navigation/useDefaultNavigation.ts
@@ -0,0 +1,38 @@
+/**
+ * Teleport
+ * Copyright (C) 2025 Gravitational, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+import { useHistory } from 'react-router-dom';
+
+import { NavigationSection } from './Navigation';
+
+export function useDefaultNavigation(section: NavigationSection) {
+ const history = useHistory();
+
+ if (section.subsections?.length === 0) {
+ return {};
+ }
+
+ const first = section.subsections[0];
+
+ return {
+ onClick: () => {
+ first.onClick?.();
+ history.push(first.route);
+ },
+ };
+}