UNPKG

@roottale/cms-mcp

Version:

RootTale CMS integration MCP server — bundled integration docs, Next.js example code, and public API lookup tools. Run with: npx @roottale/cms-mcp

101 lines (84 loc) 3.04 kB
--- title: 메뉴 (네비게이션) 연동 description: 어드민 "디자인 > 메뉴"에서 관리하는 네비게이션을 헤더/푸터에 렌더 --- # 메뉴 (네비게이션) 연동 어드민(mysite.roottale.com)의 **디자인 > 메뉴**에서 저장한 네비게이션 트리를 사이트의 헤더·푸터에 렌더합니다. 고객이 직접 메뉴 항목(이름·주소·순서·하위 항목)을 바꿀 수 있어 코드 수정 없이 네비가 갱신됩니다. - 메뉴는 **위치 핸들(slug)** 로 구분합니다 — 관례: `primary`(헤더), `footer`(푸터). - 항목은 깊이 2 트리 (상위 + 드롭다운 1단). - `url` 은 상대 경로(`/about`) 또는 절대 `http(s)` URL — 서버가 위험 스킴을 제거한 안전한 값만 내려줍니다. - 메뉴 저장 시 발행 웹훅(`post.updated`, paths: `["/"]`)이 발송되므로 웹훅 수신 라우트(`revalidation-webhooks.md`)를 설정했다면 몇 초 내 반영됩니다. ## 서버 컴포넌트에서 메뉴 가져오기 ```tsx // components/site-nav.tsx (Server Component) import Link from "next/link"; import { fetchMenu } from "@roottale/cms-client/server"; export async function SiteNav() { const menu = await fetchMenu({ apiKey: process.env.ROOTTALE_API_KEY!, slug: "primary", }); // 메뉴 미설정(null)이면 자체 fallback 네비를 렌더하세요. if (!menu) { return ( <nav> <Link href="/blog">블로그</Link> </nav> ); } return ( <nav> {menu.items.map((item) => ( <div key={item.id}> <Link href={item.url} {...(item.newTab ? { target: "_blank", rel: "noopener" } : {})} > {item.label} </Link> {item.children?.length ? ( <div> {item.children.map((child) => ( <Link key={child.id} href={child.url}> {child.label} </Link> ))} </div> ) : null} </div> ))} </nav> ); } ``` `fetchMenu` 는 미존재/구 서버의 404 를 `null` 로 돌려주므로(fail-soft) 항상 fallback 분기를 두세요. 전체 메뉴 목록이 필요하면 `fetchMenus({ apiKey })`. ## 타입 ```ts interface RootTaleMenu { id: string; name: string; // "헤더 메뉴" slug: string; // "primary" | "footer" | ... items: RootTaleMenuItem[]; updatedAt: string | null; } interface RootTaleMenuItem { id: string; label: string; url: string; // "/about" 또는 "https://..." newTab?: boolean; // target="_blank" rel="noopener" 로 렌더 children?: RootTaleMenuItem[]; } ``` ## 캐싱 메뉴 응답은 5분 캐시(+SWR)로 내려갑니다. 페이지가 ISR 이라면 발행 웹훅이 `/` 를 revalidate 할 때 함께 갱신되므로 별도 처리 없이 near-real-time 입니다. ## raw HTTP JS 외 스택은 `GET /v1/cms/public/menus/{slug}` 를 직접 호출하세요 — `api-reference.md` 참고.