サブナビゲーション設定
:LiTarget: 用途
セクション毎のサブナビ項目を1ファイルで集中管理するパターン。
:LiSparkle: 特徴
- セクション別グルーピング
- 型安全
- 一括変更容易
:LiCode: 実コード(SCALE Base より自動抽出)
:LiInfo:
lib/subnav-groups.tsの中身そのもの。コピペ即可。
// 各システム内のサブナビゲーション定義
// systems.ts の sections を凝縮し、配下のサブページは SubNav 経由でまとめて横断できるようにする
export interface SubTab {
label: string;
href: string;
aliases?: string[]; // このタブに属する追加パス(タブは表示しないが、SubNav/active判定に利用)
}
export interface SubGroup {
name: string; // サブナビ左上にも表示
parentHref: string; // systems.ts の sections[].href と一致する親リンク(サイドバーactive判定に使う)
tabs: SubTab[];
}
export const SUBNAV_GROUPS: Record<string, SubGroup[]> = {
tasks: [
{
name: '作業報告',
parentHref: '/tasks/work-log',
tabs: [
{ label: 'ダッシュボード', href: '/tasks/work-log' },
{ label: '履歴', href: '/tasks/work-log/history' },
{ label: '統計', href: '/tasks/work-log/stats' },
],
},
{
name: 'タスク管理',
parentHref: '/tasks/list',
tabs: [
{ label: 'タスクシート', href: '/tasks/list' },
{ label: '今日やる', href: '/tasks/today' },
{ label: 'マイタスク', href: '/tasks/my' },
{ label: '定例タスク', href: '/tasks/routines' },
{ label: '事業ゴール', href: '/tasks/goals' },
{ label: '業務ワークフロー', href: '/tasks/workflows' },
{ label: '更新履歴', href: '/tasks/activity' },
],
},
{
name: 'レポート',
parentHref: '/tasks',
tabs: [
{ label: 'ダッシュボード', href: '/tasks' },
{ label: '稼働レポート', href: '/tasks/reports' },
],
},
{
name: '設定',
parentHref: '/tasks/settings',
tabs: [
{ label: 'メンバー管理', href: '/tasks/members' },
{ label: 'Slack連携', href: '/tasks/slack' },
{ label: '連携ツール', href: '/tasks/tools' },
],
},
],
// ─── X: scale-x.pages.dev に分離済み(2026-05-04)───
// ─── Finance: scale-finance.pages.dev に分離済み(2026-05-04)───
// ─── SEO 14 → 4 ───
seo: [
{
name: 'キーワード',
parentHref: '/seo/keywords',
tabs: [
{ label: 'キーワード管理', href: '/seo/keywords' },
{ label: 'KWリサーチ', href: '/seo/keywords/research' },
{ label: '順位トラッキング', href: '/seo/rankings' },
{ label: '競合分析', href: '/seo/competitors' },
{ label: '被リンク分析', href: '/seo/backlinks' },
],
},
{
name: 'コンテンツ',
parentHref: '/seo/content',
tabs: [
{ label: 'コンテンツ一覧', href: '/seo/content' },
{ label: 'コンテンツスタジオ', href: '/seo/content/new' },
{ label: 'カレンダー', href: '/seo/content/calendar' },
],
},
{
name: '分析・監査',
parentHref: '/seo/audit',
tabs: [
{ label: 'テクニカルSEO', href: '/seo/audit' },
{ label: 'レポート', href: '/seo/reports' },
{ label: 'AIアシスタント', href: '/seo/assistant' },
],
},
{
name: '設定',
parentHref: '/seo/settings',
tabs: [
{ label: '連携ツール', href: '/seo/tools' },
{ label: '設定', href: '/seo/settings' },
],
},
],
// ─── Recruit (hr) 14 → 4 ───
hr: [
{
name: '採用',
parentHref: '/hr/pipeline',
tabs: [
{ label: 'パイプライン', href: '/hr/pipeline' },
{ label: '候補者一覧', href: '/hr/candidates' },
{ label: '求人管理', href: '/hr/jobs' },
{ label: 'SNSスカウト', href: '/hr/scout' },
{ label: '面談管理', href: '/hr/interviews' },
{ label: 'オンボーディング', href: '/hr/onboarding' },
{ label: 'テンプレート', href: '/hr/templates' },
],
},
{
name: '評価・育成',
parentHref: '/hr/performance',
tabs: [
{ label: '評価・1on1', href: '/hr/performance' },
{ label: 'カルチャー', href: '/hr/culture' },
],
},
{
name: '分析',
parentHref: '/hr/analytics',
tabs: [
{ label: '分析レポート', href: '/hr/analytics' },
{ label: 'AIアシスタント', href: '/hr/assistant' },
],
},
{
name: '設定',
parentHref: '/hr/settings',
tabs: [
{ label: '連携ツール', href: '/hr/tools' },
{ label: '設定', href: '/hr/settings' },
],
},
],
// ─── Design 13 → 5 ───
design: [
{
name: '制作',
parentHref: '/design/generate',
tabs: [
{ label: 'AI生成', href: '/design/generate' },
{ label: 'デザインFB', href: '/design/feedback' },
{ label: 'テンプレート', href: '/design/templates' },
],
},
{
name: 'アセット',
parentHref: '/design/projects',
tabs: [
{ label: 'プロジェクト', href: '/design/projects' },
{ label: 'アセットライブラリ', href: '/design/assets' },
{ label: 'Pinterest', href: '/design/pinterest' },
{ label: '過去アウトプット', href: '/design/history' },
],
},
{
name: 'ブランド・参考',
parentHref: '/design/brand',
tabs: [
{ label: 'ブランドガイド', href: '/design/brand' },
{ label: '参考ツール・素材', href: '/design/references' },
{ label: 'デザインマニュアル', href: '/design/manual' },
],
},
{
name: '設定',
parentHref: '/design/settings',
tabs: [
{ label: 'Canva / Figma連携', href: '/design/integrations' },
{ label: '連携ツール', href: '/design/tools' },
{ label: '設定', href: '/design/settings' },
],
},
],
// ─── HP 13 → 5 ───
hp: [
{
name: 'サイト運用',
parentHref: '/hp/pages',
tabs: [
{ label: 'ページ管理', href: '/hp/pages' },
{ label: 'LP管理', href: '/hp/lp' },
{ label: 'ブログ・お知らせ', href: '/hp/blog' },
{ label: 'CTA・フォーム管理', href: '/hp/cta' },
],
},
{
name: '分析',
parentHref: '/hp/analytics',
tabs: [
{ label: 'アクセス解析', href: '/hp/analytics' },
{ label: 'AI流入分析', href: '/hp/ai-analysis' },
{ label: 'SEO設定', href: '/hp/seo-settings' },
],
},
{
name: 'リード・参考',
parentHref: '/hp/leads',
tabs: [
{ label: 'リード管理', href: '/hp/leads' },
{ label: '参考HP一覧', href: '/hp/references' },
{ label: 'HPショーケース', href: '/hp/showcase' },
],
},
{
name: '設定',
parentHref: '/hp/settings',
tabs: [
{ label: '連携ツール', href: '/hp/tools' },
{ label: '設定', href: '/hp/settings' },
],
},
],
// ─── AI Ops ───
'ai-ops': [
{
name: 'エージェント',
parentHref: '/ai-ops/agents',
tabs: [
{ label: 'エージェント一覧', href: '/ai-ops/agents' },
{ label: 'Agent Studio', href: '/ai-ops/agent-studio' },
{ label: 'Voice AI', href: '/ai-ops/voice' },
{ label: 'Vision AI', href: '/ai-ops/vision' },
],
},
{
name: '実行・運用',
parentHref: '/ai-ops/logs',
tabs: [
{ label: '実行ログ', href: '/ai-ops/logs' },
{ label: 'スケジュール', href: '/ai-ops/schedules' },
{ label: 'ワークフロー', href: '/ai-ops/workflows' },
{ label: '承認キュー', href: '/ai-ops/approvals' },
],
},
{
name: '分析・API',
parentHref: '/ai-ops/performance',
tabs: [
{ label: 'パフォーマンス', href: '/ai-ops/performance' },
{ label: 'API Gateway', href: '/ai-ops/api-gateway' },
],
},
{
name: '設定',
parentHref: '/ai-ops/settings',
tabs: [
{ label: '連携ツール', href: '/ai-ops/tools' },
{ label: '設定', href: '/ai-ops/settings' },
],
},
],
// ─── Automation (→ ai-opsに吸収:parentHrefはai-opsサイドバーの "Automation"=/automation に) ───
automation: [
{
name: 'ワークフロー',
parentHref: '/automation',
tabs: [
{ label: 'ワークフロー一覧', href: '/automation/workflows', aliases: ['/automation'] },
{ label: 'トリガー設定', href: '/automation/triggers' },
{ label: '接続マップ', href: '/automation/map' },
{ label: '実行ログ', href: '/automation/logs' },
],
},
{
name: '設定',
parentHref: '/automation',
tabs: [
{ label: '連携ツール', href: '/automation/tools' },
{ label: '設定', href: '/automation/settings' },
],
},
],
// ─── Insight (→ rndに吸収:parentHrefはrndサイドバーの "Service Insight"=/insight に) ───
insight: [
{
name: '分析',
parentHref: '/insight',
tabs: [
{ label: 'URL解析', href: '/insight/analyze', aliases: ['/insight'] },
{ label: 'AIチャット', href: '/insight/chat' },
{ label: '比較分析', href: '/insight/compare' },
],
},
{
name: 'トレンド',
parentHref: '/insight',
tabs: [
{ label: '急成長スタートアップ', href: '/insight/trending' },
{ label: 'グロースモデル', href: '/insight/growth' },
],
},
{
name: 'ライブラリ',
parentHref: '/insight',
tabs: [
{ label: '分析履歴', href: '/insight/history' },
{ label: 'ペルソナ集', href: '/insight/personas' },
{ label: '課題マップ', href: '/insight/issues' },
{ label: 'ライブラリ', href: '/insight/library' },
],
},
{
name: '設定',
parentHref: '/insight',
tabs: [
{ label: '連携ツール', href: '/insight/tools' },
{ label: '設定', href: '/insight/settings' },
],
},
],
// ─── Docs 12 → 5 ───
docs: [
{
name: 'ナレッジ',
parentHref: '/docs/input',
tabs: [
{ label: 'ナレッジインプット', href: '/docs/input' },
{ label: 'ナレッジ検索', href: '/docs/search' },
{ label: '更新履歴', href: '/docs/activity' },
],
},
{
name: 'マニュアル・手順',
parentHref: '/docs/sop',
tabs: [
{ label: '業務手順書', href: '/docs/sop' },
{ label: '業務マニュアル', href: '/docs/manuals' },
{ label: 'テンプレート', href: '/docs/templates' },
],
},
{
name: '参照資料',
parentHref: '/docs/meetings',
tabs: [
{ label: '議事録', href: '/docs/meetings' },
{ label: 'サイト一覧', href: '/docs/sites' },
{ label: 'Notion連携', href: '/docs/notion' },
],
},
{
name: '設定',
parentHref: '/docs/settings',
tabs: [
{ label: '連携ツール', href: '/docs/tools' },
{ label: '設定', href: '/docs/settings' },
],
},
],
// ─── CRM (id: 'crm'): 2026-05-04 完全削除(Base 内残骸を整理)───
// ─── Pipeline (→ commandに吸収:parentHrefはcommandサイドバーの "Pipeline"=/pipeline に) ───
pipeline: [
{
name: '予測・計画',
parentHref: '/pipeline',
tabs: [
{ label: '売上予測', href: '/pipeline/forecast', aliases: ['/pipeline'] },
{ label: 'シナリオ分析', href: '/pipeline/scenarios' },
{ label: '事業計画書', href: '/pipeline/business-plan' },
],
},
{
name: '商談',
parentHref: '/pipeline',
tabs: [
{ label: 'パイプライン', href: '/pipeline/deals' },
{ label: '週次MTG', href: '/pipeline/weekly-mtg' },
],
},
{
name: 'KPI・目標',
parentHref: '/pipeline',
tabs: [
{ label: 'KPIトラッカー', href: '/pipeline/kpi' },
{ label: '目標管理', href: '/pipeline/goals' },
{ label: 'レポート', href: '/pipeline/reports' },
{ label: '設定', href: '/pipeline/settings' },
],
},
],
// ─── Goals (→ tasksに吸収:parentHrefを/tasks/listに) ───
goals: [
{
name: '目標',
parentHref: '/tasks/list',
tabs: [
{ label: '年間目標', href: '/goals/yearly', aliases: ['/goals'] },
{ label: '四半期目標', href: '/goals/quarterly' },
{ label: '月次目標', href: '/goals/monthly' },
{ label: '個人目標', href: '/goals/personal' },
],
},
{
name: 'OKR・KPI',
parentHref: '/tasks/list',
tabs: [
{ label: 'OKR管理', href: '/goals/okr' },
{ label: 'KPIトラッカー', href: '/goals/kpi' },
],
},
{
name: 'レビュー・履歴',
parentHref: '/tasks/list',
tabs: [
{ label: 'レビュー', href: '/goals/reviews' },
{ label: '達成履歴', href: '/goals/history' },
{ label: '設定', href: '/goals/settings' },
],
},
],
// ─── Admin 7 → 4 ───
admin: [
{
name: 'ユーザー・部署',
parentHref: '/admin/users',
tabs: [
{ label: 'ユーザー管理', href: '/admin/users' },
{ label: '部署管理', href: '/admin/departments' },
{ label: '権限管理', href: '/admin/permissions' },
],
},
{
name: 'セキュリティ',
parentHref: '/admin/security',
tabs: [
{ label: 'セキュリティ', href: '/admin/security' },
{ label: '監査ログ', href: '/admin/audit' },
],
},
],
// ─── Brand & PR 8 → 4 ───
brand: [
{
name: 'モニタ',
parentHref: '/brand/monitor',
tabs: [
{ label: 'ブランドモニタ', href: '/brand/monitor' },
{ label: 'メンション解析', href: '/brand/mentions' },
],
},
{
name: 'PR・イベント',
parentHref: '/brand/pr',
tabs: [
{ label: 'PR / IR', href: '/brand/pr' },
{ label: 'イベント管理', href: '/brand/events' },
{ label: 'コミュニティ', href: '/brand/community' },
],
},
{
name: '設定',
parentHref: '/brand/settings',
tabs: [
{ label: '連携ツール', href: '/brand/tools' },
{ label: '設定', href: '/brand/settings' },
],
},
],
// ─── Writing 8 → 4 ───
writing: [
{
name: '作成',
parentHref: '/writing/generate',
tabs: [
{ label: 'AI文章作成', href: '/writing/generate' },
{ label: '文面添削', href: '/writing/review' },
],
},
{
name: '資産',
parentHref: '/writing/templates',
tabs: [
{ label: 'テンプレート', href: '/writing/templates' },
{ label: 'トーン設定', href: '/writing/tone' },
{ label: 'ネタ帳', href: '/writing/notes' },
],
},
{
name: '設定',
parentHref: '/writing/settings',
tabs: [
{ label: '連携ツール', href: '/writing/tools' },
{ label: '設定', href: '/writing/settings' },
],
},
],
// ─── CMO (→ brandに吸収:parentHrefはbrandサイドバーの "AI CMO"=/cmo に) ───
cmo: [
{
name: 'ブリーフ',
parentHref: '/cmo',
tabs: [
{ label: 'デイリーブリーフ', href: '/cmo' },
{ label: 'ウィークリーレポート', href: '/cmo/weekly' },
],
},
{
name: '投稿・SEO',
parentHref: '/cmo',
tabs: [
{ label: 'LinkedIn投稿', href: '/cmo/linkedin' },
{ label: 'GEO(AI検索)最適化', href: '/cmo/geo' },
],
},
{
name: 'ブランド',
parentHref: '/cmo',
tabs: [
{ label: 'コミュニティ機会', href: '/cmo/community' },
{ label: 'ブランドボイス', href: '/cmo/voice' },
{ label: '設定', href: '/cmo/settings' },
],
},
],
// ─── Partners 7 → 4 ───
partners: [
{
name: 'パートナー',
parentHref: '/partners/list',
tabs: [
{ label: 'パートナー一覧', href: '/partners/list' },
{ label: '案件マッチング', href: '/partners/matching' },
{ label: '成果レポート', href: '/partners/reports' },
],
},
{
name: 'Academy',
parentHref: '/partners/academy',
tabs: [
{ label: 'Academy 研修', href: '/partners/academy' },
{ label: '学習履歴', href: '/partners/learning' },
],
},
],
// ─── R&D 7 → 4 ───
rnd: [
{
name: 'リサーチ・実験',
parentHref: '/rnd/research',
tabs: [
{ label: 'リサーチ', href: '/rnd/research' },
{ label: 'Innovation Lab', href: '/rnd/lab' },
{ label: '実験ログ', href: '/rnd/experiments' },
],
},
{
name: 'ナレッジ・IP',
parentHref: '/rnd/knowledge',
tabs: [
{ label: 'ナレッジ', href: '/rnd/knowledge' },
{ label: '特許 / IP', href: '/rnd/ip' },
],
},
{
name: '設定',
parentHref: '/rnd/settings',
tabs: [
{ label: '連携ツール', href: '/rnd/tools' },
{ label: '設定', href: '/rnd/settings' },
],
},
],
// ─── Services 7 → 4 ───
services: [
{
name: 'サービス',
parentHref: '/services/list',
tabs: [
{ label: 'サービス一覧', href: '/services/list' },
{ label: 'システム設計書', href: '/services/specs' },
{ label: 'コードベース', href: '/services/code' },
],
},
{
name: '管理',
parentHref: '/services/admin-panel',
tabs: [
{ label: '管理画面', href: '/services/admin-panel' },
{ label: 'ドキュメント', href: '/services/docs' },
],
},
],
// ─── Datalake 8 → 4 ───
datalake: [
{
name: 'データ・クエリ',
parentHref: '/datalake/sources',
tabs: [
{ label: 'データソース', href: '/datalake/sources' },
{ label: 'クエリエディタ', href: '/datalake/query' },
],
},
{
name: '分析',
parentHref: '/datalake/dashboards',
tabs: [
{ label: 'カスタムダッシュボード', href: '/datalake/dashboards' },
{ label: '品質モニタ', href: '/datalake/quality' },
{ label: 'Digital Twin', href: '/datalake/digital-twin' },
],
},
{
name: 'ツール',
parentHref: '/datalake/export',
tabs: [
{ label: 'エクスポート', href: '/datalake/export' },
{ label: '連携ツール', href: '/datalake/tools' },
],
},
],
// ─── Command Center 6 → 4 ───
command: [
{
name: 'サマリー',
parentHref: '/command',
tabs: [
{ label: '経営サマリー', href: '/command' },
{ label: '日次サマリー', href: '/command/daily' },
],
},
{
name: '予測',
parentHref: '/command/forecast',
tabs: [
{ label: '売上予測AI', href: '/command/forecast' },
{ label: 'What-Ifシミュ', href: '/command/simulator' },
],
},
],
};
export function normalizePath(pathname: string): string {
if (!pathname) return '/';
return pathname.replace(/\/$/, '') || '/';
}
// tab.href または tab.aliases にマッチしたら true
function tabMatches(tab: SubTab, p: string): boolean {
if (tab.href === p) return true;
if (tab.aliases && tab.aliases.includes(p)) return true;
return false;
}
// prefix-match: 動的ルート(/seo/content/[id] 等)を href の子扱いする
// システムルート(/tasks 等、1セグメント)は全サブページを拾ってしまうので除外
function isSystemRoot(href: string): boolean {
return href.split('/').filter(Boolean).length < 2;
}
function tabPrefixMatches(tab: SubTab, p: string): boolean {
if (!isSystemRoot(tab.href) && p.startsWith(tab.href + '/')) return true;
if (tab.aliases && tab.aliases.some(a => !isSystemRoot(a) && p.startsWith(a + '/'))) return true;
return false;
}
// pathname → 所属サブナビグループ(完全一致→prefix一致の順)
export function findSubNavGroup(pathname: string): SubGroup | null {
const p = normalizePath(pathname);
for (const systemId in SUBNAV_GROUPS) {
for (const g of SUBNAV_GROUPS[systemId]) {
if (g.tabs.some(t => tabMatches(t, p))) return g;
}
}
// fallback: 動的ルート用にprefix一致
for (const systemId in SUBNAV_GROUPS) {
for (const g of SUBNAV_GROUPS[systemId]) {
if (g.tabs.some(t => tabPrefixMatches(t, p))) return g;
}
}
return null;
}
// pathname → サイドバーでactiveにすべき親hrefを返す(所属グループの parentHref)
export function getActiveParentHref(pathname: string): string {
const p = normalizePath(pathname);
for (const systemId in SUBNAV_GROUPS) {
for (const g of SUBNAV_GROUPS[systemId]) {
if (g.tabs.some(t => tabMatches(t, p))) return g.parentHref;
}
}
for (const systemId in SUBNAV_GROUPS) {
for (const g of SUBNAV_GROUPS[systemId]) {
if (g.tabs.some(t => tabPrefixMatches(t, p))) return g.parentHref;
}
}
return p;
}
:LiFolder: ソースファイルのパス
/Users/oogushiyuuki/Library/CloudStorage/GoogleDrive-y-ogushi@scale-group.co.jp/マイドライブ/AI/scale-base/lib/subnav-groups.ts
:LiHandPointer: 使い方
対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。
:LiAlertCircle: 注意事項
- 依存パッケージを忘れず追加