From a91876db59cf21d2045859baed4f96f954e452f8 Mon Sep 17 00:00:00 2001 From: Alex Netsch Date: Wed, 15 Oct 2025 18:10:14 +0100 Subject: [PATCH] Include project title in page title (vibe-kanban) (#1022) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Perfect! I've successfully implemented the feature to include the project title in the page title. Here's what I did: ## Summary I've added dynamic page title updates to display ` | vibe-kanban` when viewing project pages. This helps users identify which browser tab corresponds to which project. ### Changes Made 1. **ProjectTasks component** (`frontend/src/pages/project-tasks.tsx:71-78`) - Added a `useEffect` hook that updates `document.title` when the project loads - The title shows ` | vibe-kanban` when a project is loaded - Falls back to `vibe-kanban` if no project is available 2. **ProjectDetail component** (`frontend/src/components/projects/project-detail.tsx:88-95`) - Added the same title update logic for the project detail page - Ensures consistent behavior across both the tasks view and project detail view ### Testing - ✅ TypeScript type checking passes with no errors - ✅ ESLint passes (94 warnings, under the 110 max threshold, with no new warnings introduced) - ✅ All checks pass The page title will now automatically update to show the project name whenever you navigate to a project's tasks or detail page, making it much easier to identify tabs when working with multiple projects. * Excellent! Let me create a summary of what we've implemented: ## Summary - Refactored to Centralized Page Title Management ✅ I've successfully refactored the implementation to follow React best practices by using a **centralized approach** in the `ProjectProvider` context. ### What Changed **Before (Scattered Approach):** - ❌ Multiple `useEffect` hooks spread across different components - ❌ Code duplication - ❌ Easy to forget when adding new pages **After (Centralized Approach):** - ✅ Single `useEffect` in `ProjectProvider` that manages all page titles - ✅ Automatically handles all routes without touching individual components - ✅ Follows React best practices for context-based side effects ### Implementation Details **File: `frontend/src/contexts/project-context.tsx`** Added a single `useEffect` hook that watches the project data: ```typescript // Centralized page title management useEffect(() => { if (query.data) { document.title = `${query.data.name} | vibe-kanban`; } else { document.title = 'vibe-kanban'; } }, [query.data]); ``` ### How It Works The `ProjectProvider`: 1. **Wraps the entire app** - Already exists at the root level 2. **Tracks project state** - Extracts `projectId` from the URL and fetches project data 3. **Updates title automatically** - When `query.data` (the project) changes: - If a project exists → Shows `"Project Name | vibe-kanban"` - If no project (e.g., on `/projects` or `/settings`) → Shows `"vibe-kanban"` ### Benefits ✅ **Single source of truth** - One place to manage all page titles ✅ **Automatic** - Works for all existing and future routes ✅ **Clean** - No code duplication across components ✅ **Maintainable** - Easy to modify title format in one place ✅ **Best practice** - Context providers are the right place for app-wide side effects ### Testing - ✅ TypeScript type checking passes (both frontend and backend) - ✅ ESLint passes with 94 warnings (no new warnings added) - ✅ All routes handled automatically: - Project-specific pages: Shows project name in title - General pages (project list, settings): Shows just "vibe-kanban" The implementation is complete and ready to use! * Cleanup script changes for task attempt 56892384-6a81-4c9f-be14-edf121c06587 --- frontend/src/contexts/project-context.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/frontend/src/contexts/project-context.tsx b/frontend/src/contexts/project-context.tsx index 31883449..7ef2a214 100644 --- a/frontend/src/contexts/project-context.tsx +++ b/frontend/src/contexts/project-context.tsx @@ -1,4 +1,10 @@ -import { createContext, useContext, ReactNode, useMemo } from 'react'; +import { + createContext, + useContext, + ReactNode, + useMemo, + useEffect, +} from 'react'; import { useLocation } from 'react-router-dom'; import { useQuery } from '@tanstack/react-query'; import { projectsApi } from '@/lib/api'; @@ -45,6 +51,15 @@ export function ProjectProvider({ children }: ProjectProviderProps) { [projectId, query.data, query.isLoading, query.error, query.isError] ); + // Centralized page title management + useEffect(() => { + if (query.data) { + document.title = `${query.data.name} | vibe-kanban`; + } else { + document.title = 'vibe-kanban'; + } + }, [query.data]); + return ( {children} );