diff --git a/packages/common/components/src/ui/page-title/index.tsx b/packages/common/components/src/ui/page-title/index.tsx index a685ffbaa..ebe5559f2 100644 --- a/packages/common/components/src/ui/page-title/index.tsx +++ b/packages/common/components/src/ui/page-title/index.tsx @@ -1,6 +1,6 @@ "use client"; -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import { Dialog, DialogContent, @@ -9,8 +9,26 @@ import { DialogTrigger, } from "../dialog"; import { useQuery } from "@tanstack/react-query"; -import { getMenuDetail } from "../../api"; +import { getMenuDetail, getSiteInfo } from "../../api"; import { ENDPOINT } from "../../config"; +import { getCookie } from "../../lib"; + +/** 공통 레이아웃 밖 페이지(대시보드·로그인·오류 등)의 문서 제목. 각 앱 layout metadata 의 title 과 동일하게 유지 */ +const PLATFORM_TITLE = "유역하수도통합플랫폼 Hasuon"; + +const DASHBOARD_MENU_NAME = "대시보드"; + +/** 문서 제목: "유역하수도통합플랫폼 Hasuon - 사이트명 > 메뉴1 > 메뉴2" (대시보드는 플랫폼 제목만) */ +function buildDocumentTitle(siteNm: string | undefined, title: string, menuPaths: string[]) { + const menus = (menuPaths.length > 0 ? menuPaths : [title]).filter(Boolean); + const isDashboard = + menus[menus.length - 1] === DASHBOARD_MENU_NAME || + (typeof window !== "undefined" && /\/dashboard\/?$/.test(window.location.pathname)); + + if (menus.length === 0 || isDashboard) return PLATFORM_TITLE; + + return `${PLATFORM_TITLE} - ${[siteNm, ...menus].filter(Boolean).join(" > ")}`; +} const PageTitle = ({ title, @@ -29,6 +47,24 @@ const PageTitle = ({ enabled: !!menuCd, }); + // 헤더와 같은 쿼리 키를 사용해 캐시된 사이트 정보를 재사용 + const siteId = getCookie("site-id-key") ?? ""; + const { data: siteInfo } = useQuery({ + queryKey: [ENDPOINT.CMS_SERVICE.SITES, siteId], + queryFn: () => getSiteInfo(siteId), + enabled: !!siteId, + }); + + const documentTitle = buildDocumentTitle(siteInfo?.siteNm, title, menuPaths); + + // 메뉴 이동 시마다 문서 제목 갱신, 레이아웃을 벗어나면 플랫폼 제목으로 복원 + useEffect(() => { + document.title = documentTitle; + return () => { + document.title = PLATFORM_TITLE; + }; + }, [documentTitle]); + return (