Skip to main content

Centralized Page Title and Navigation System

Overview

The application uses a centralized configuration for page titles, descriptions, icons, and back button navigation. You no longer need to manually add <TWSetPageTitle> to every page!

How It Works

1. Centralized Configuration: config/routes.ts

All page metadata AND back button links are defined in one place:

export const routeConfigs: RouteConfig[] = [
{
path: "/company/dashboard",
title: "Dashboard",
description: "Company dashboard overview",
icon: "dashboard",
// No backLink = no back button
},
{
path: "/company/contacts/:id/view",
title: "View Contact",
description: "View contact details",
icon: "contacts",
backLink: "/company/contacts", // Back button goes here
pattern: /^\/company\/contacts\/[^/]+\/view$/,
},
{
path: "/company/contacts/:id",
title: "Edit Contact",
description: "Edit contact information",
icon: "contacts",
backLink: "parent", // Smart back to view page
pattern: /^\/company\/contacts\/[^/]+$/,
},
// ... more routes
]

2. Automatic Title Setting

ClientLayout.tsx automatically:

  • Detects the current pathname
  • Looks up the matching route config
  • Sets the page title, description, and icon
  • No history tracking needed!

No manual work needed on individual pages!

3. Hierarchical Back Button

TWNavHeader.tsx automatically:

  • Gets current pathname
  • Calls resolveBackLink(pathname) from config
  • Shows back button based on route hierarchy
  • Goes to configured destination (not browser history)

4. Dynamic Route Matching

For routes with IDs (like /company/contacts/[id]/view), use the pattern field:

{
path: "/company/contacts/:id/view",
title: "View Contact",
icon: "contacts",
backLink: "/company/contacts",
pattern: /^\/company\/contacts\/[^/]+\/view$/, // Matches any ID
}

The pattern RegEx matches dynamic segments:

  • [^/]+ matches any characters except / (the ID)
  • ^ and $ ensure full path matching

Adding New Routes

Static Routes (No Dynamic Segments)

Simply add to config/routes.ts:

{
path: "/company/newpage",
title: "New Page",
description: "Description here",
icon: "dashboard",
backLink: "/company/dashboard", // Optional: where back button goes
}

Dynamic Routes (With IDs)

Add with a pattern and back link:

{
path: "/company/jobs/:id/edit",
title: "Edit Job",
description: "Edit job posting",
icon: "jobs",
backLink: "/company/jobs", // Static back link to list
pattern: /^\/company\/jobs\/[^/]+\/edit$/,
}

Pattern breakdown:

  • ^\/company\/jobs\/ - Exact start
  • [^/]+ - Match any ID (one or more non-slash characters)
  • \/edit$ - Exact end

No back button:

{
path: "/company/contacts",
title: "Contacts",
icon: "contacts"
}
// No backLink property = no back button

Static back link (most common):

{
path: "/company/contacts/:id/view",
backLink: "/company/contacts", // Always go to this URL
pattern: /^\/company\/contacts\/[^/]+\/view$/,
}

Dynamic "parent" link (edit pages):

{
path: "/company/contacts/:id",
backLink: "parent", // Smart: go to /company/contacts/[same-id]/view
pattern: /^\/company\/contacts\/[^/]+$/,
}

When backLink: "parent" is used:

  • Current: /company/contacts/abc-123
  • Back goes to: /company/contacts/abc-123/view (adds /view with same ID)

Override for Special Cases

If a specific page needs a different title (not in the config), you can still use <TWSetPageTitle>:

<TWSetPageTitle
title="Custom Title"
description="Custom description"
icon="jobs"
/>

The manual override will take precedence over the centralized config.

Benefits

Centralized - One place to manage all page metadata and navigation ✅ Automatic - No need to add components to every page ✅ Consistent - All pages follow the same pattern ✅ Maintainable - Easy to update titles and navigation across the app ✅ Type-safe - TypeScript ensures correct icon types ✅ Hierarchical back button - Predictable navigation based on page structure ✅ Works with bookmarks - Back button works even when visiting URLs directly

Migration Guide

Before (Manual on Every Page)

export default function ContactsPage() {
return (
<>
<TWSetPageTitle
title="Contacts"
description="Manage your contacts"
icon="contacts"
/>
<div>Page content...</div>
</>
)
}

After (Automatic)

export default function ContactsPage() {
// No TWSetPageTitle needed!
return <div>Page content...</div>
}

The title, description, icon, and back button are set automatically from config/routes.ts.

Files Modified

Available Icon Types

From lib/types/pagestore.ts:

type IconType =
| "application"
| "back"
| "buzzfeed"
| "company"
| "connection"
| "contacts"
| "cvbuilder"
| "dashboard"
| "home"
| "invite"
| "jobs"
| "partner"
| "pipelines"
| "profile"
| "resume"
| "share"
| "talent"
| "talentpool"
| "timereport"

To add new icons, update lib/types/pagestore.ts and components/ux/TWNavHeader.tsx.

Testing

  1. Navigate to any page in the app

    • ✅ Title and icon should appear automatically
  2. Navigate to a detail page (e.g., /company/contacts/abc-123/view)

    • ✅ Back button should appear
    • ✅ Click back → goes to /company/contacts
  3. Navigate to an edit page (e.g., /company/contacts/abc-123)

    • ✅ Back button should appear
    • ✅ Click back → goes to /company/contacts/abc-123/view
  4. Bookmark a detail page and visit directly

    • ✅ Back button still appears with correct destination

All pages defined in config/routes.ts work automatically!

  • BACK_BUTTON_WORKING.md - Detailed back button implementation (legacy doc, removed in repo cleanup)
  • config/routes.ts - Route configuration file