diff --git a/app/components/layout/index.tsx b/app/components/layout/index.tsx
index b05710e8d..b04831c4d 100644
--- a/app/components/layout/index.tsx
+++ b/app/components/layout/index.tsx
@@ -1,7 +1,8 @@
-import { Link, useLocation } from "@remix-run/react";
+import { Link, useMatches } from "@remix-run/react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import type { RootLoaderData } from "~/root";
+import { type SendouRouteHandle } from "~/utils/remix";
import { LOGO_PATH, navIconUrl } from "~/utils/urls";
import { Image } from "../Image";
import { ColorModeToggle } from "./ColorModeToggle";
@@ -12,6 +13,25 @@ import { Menu } from "./Menu";
import navItems from "./nav-items.json";
import { UserItem } from "./UserItem";
+function useActiveNavItem() {
+ const matches = useMatches();
+
+ return React.useMemo(() => {
+ let activeItem: { name: string; url: string } | undefined = undefined;
+
+ for (const match of matches.reverse()) {
+ const handle = match.handle as SendouRouteHandle | undefined;
+
+ if (handle?.navItemName) {
+ activeItem = navItems.find(({ name }) => name === handle.navItemName);
+ break;
+ }
+ }
+
+ return activeItem;
+ }, [matches]);
+}
+
export const Layout = React.memo(function Layout({
children,
patrons,
@@ -22,12 +42,8 @@ export const Layout = React.memo(function Layout({
isCatchBoundary?: boolean;
}) {
const { t } = useTranslation();
- const location = useLocation();
const [menuOpen, setMenuOpen] = React.useState(false);
-
- const currentPagesNavItem = navItems.find((navItem) =>
- location.pathname.includes(navItem.name)
- );
+ const activeNavItem = useActiveNavItem();
return (
@@ -51,15 +67,15 @@ export const Layout = React.memo(function Layout({