Tags System
This document explains how the Tags system works in tududi from a user behavior perspective. For technical implementation details, see the backend code in /backend/modules/tags/ and frontend components in /frontend/components/Tags.tsx and /frontend/components/Tag/.
Overview
Tags are tududi's flexible labeling and categorization system - a way to organize and group related items across tasks, notes, and projects. Unlike the hierarchical organization of Areas > Projects > Tasks, tags provide a flat, cross-cutting way to find and filter content.
Key characteristics:
- Work across all content types (tasks, notes, projects)
- User-scoped (each user has their own tag set)
- Unique per user (no duplicate tag names)
- Auto-created on-the-fly
- Case-insensitive
- Character restrictions for URL safety
- Maximum 50 characters per tag name
URL: /tags (tag list) or /tag/:uid-:slug (tag detail page)
Core Principles
-
Cross-entity organization
- Same tag can be applied to tasks, notes, and projects
- Creates horizontal connections across hierarchical boundaries
- Enables finding related items regardless of their type
-
Flexible categorization
- No predefined taxonomy
- Create tags as needed
- No hierarchy (tags are flat)
- Multiple tags per item (up to 10 tags per task/note/project)
-
User-scoped isolation
- Each user has their own tag namespace
- Tags are not shared between users
- Even in shared projects, tags remain user-specific
- Deleting a tag only affects your view
Tag Structure
Fields
| Field | Type | Required | Description |
|---|---|---|---|
| UID | String | Auto | Unique identifier (immutable) |
| Name | String | Yes | Tag name (unique per user) |
| User ID | Integer | Auto | Owner of the tag |
| Created At | Timestamp | Auto | Creation timestamp |
| Updated At | Timestamp | Auto | Last modification timestamp |
Unique Identifier
- Each tag has a UID (unique identifier):
uidfield - Used in URLs:
/tag/abc123def456-tag-name - Immutable - persists through renames
- Format: Generated unique string (8+ characters)
Validation Rules
Tag name restrictions:
- Length: 1-50 characters (after trimming whitespace)
- Invalid characters:
# % & { } \ < > * ? / $ ! ' " @ + \| =` - Valid characters: Letters, numbers, spaces, hyphens, underscores
- Case: Stored as-is, but treated case-insensitively for uniqueness
- ✅
work,Work Projects,Q1-2026,backend_dev - ❌
#hashtag,foo/bar,price$,email@domain
- ✅
Uniqueness:
- Tag names must be unique per user (case-insensitive)
work=Work=WORK(same tag)- Error if you try to create a duplicate: "A tag with the name 'work' already exists"
Automatic cleanup:
- Leading/trailing whitespace trimmed automatically
- Example:
" productivity "becomes"productivity"
Creating Tags
Method 1: Auto-Creation (Most Common)
Tags are automatically created when you add them to a task, note, or project:
-
From task creation/edit:
- In task form, click "Add tags" or tag icon
- Type tag name in input field
- Press Enter or comma
- If tag doesn't exist, it's created automatically
- Tag is immediately applied to the task
-
From note creation/edit:
- In note edit mode, click tag icon
- Type tag name and press Enter
- Auto-created and applied
-
From project form:
- Similar to tasks - type and press Enter
- Auto-created and linked to project
Auto-creation behavior:
- No confirmation required
- Tag appears in tag list immediately
- Available for autocomplete in other forms
- Validation errors shown inline
Method 2: Direct Creation
From Tags page:
- Navigate to
/tags - No "Create Tag" button exists
- Tags are created implicitly by using them
Limitation: You cannot create standalone tags - they must be created by associating them with a task, note, or project.
Method 3: From Inbox (Hashtag Parsing)
Automatic tag extraction:
- Capture item in Inbox:
Review #quarterly-report +Work - System detects
#quarterly-report - When converting to task/note, tag is auto-created
- Applied to the resulting item
Hashtag rules:
- Must start with
# - Followed by valid tag characters
- Stops at whitespace or invalid character
- Example:
#work-itemcreates tagwork-item
Using Tags
Adding Tags to Tasks
During task creation:
- Click "+ Add Task" or open task form
- Scroll to "Tags" section
- Click tag icon or "Add tags"
- Tag input field appears
- Type tag name (autocomplete suggests existing tags)
- Press Enter or comma to add
- Repeat for multiple tags (max 10)
- Save task
During task editing:
- Open task detail modal
- Click "Tags" card or tag icon
- Same input flow as creation
- Changes save automatically
Tag input features:
- Autocomplete: Shows matching existing tags as you type
- Keyboard navigation: Arrow keys to navigate suggestions, Enter to select
- Multiple selection: Add up to 10 tags per task
- Remove tag: Click × on tag chip
- Create new: Type non-existent tag, press Enter
- Backspace removal: Press Backspace on empty input to remove last tag
Adding Tags to Notes
In note edit mode:
- Open note in edit mode
- Click tag icon (🏷️) in metadata section
- Tag input appears
- Type and press Enter to add tags
- Auto-saves after 1 second
Tag display in notes:
- Preview mode: Tags shown as clickable links below title
- Edit mode: Tag input with chips
- Click tag → Navigate to tag page
Adding Tags to Projects
In project form:
- Create or edit project
- "Tags" field in form
- Same tag input component
- Type, autocomplete, and select
- Save project
Project tag behavior:
- Tags inherited by tasks? No - tags are independent per entity
- Changing project tags doesn't affect existing tasks
- Tags help group projects by theme/category
Tag Management
Editing Tags
Rename a tag:
- Navigate to
/tagsor/tag/:uid-slug - Click edit icon (pencil) on tag
- Tag modal opens
- Change tag name
- Click "Save"
- All associations update automatically
What updates when you rename:
- Tag name updates across all tasks, notes, projects using it
- URLs update to use new slug
- Autocomplete suggestions reflect new name
- No broken links (UID remains the same)
Rename restrictions:
- Must follow validation rules (1-50 chars, valid characters)
- Cannot rename to existing tag name (conflict error)
Deleting Tags
Confirmation required:
From tags list page:
- Navigate to
/tags - Hover over tag card
- Click delete icon (trash)
- Confirmation dialog: "Are you sure you want to delete the tag 'tag-name'?"
- Confirm or cancel
From tag detail page:
- Navigate to
/tag/:uid-slug - Click delete button (top right)
- Confirmation dialog
- Confirm → Redirects to
/tags
What gets deleted:
- Tag record itself
- All associations with tasks (from
tasks_tagstable) - All associations with notes (from
notes_tagstable) - All associations with projects (from
projects_tagstable)
What's preserved:
- Tasks, notes, and projects themselves (only tag link removed)
- No cascading deletion
- Other tags remain intact
No undo:
- Deletion is immediate and irreversible
- All items lose the tag permanently
Tag Pages and Navigation
Tags List Page (/tags)
Layout:
- Alphabetical grouping (A, B, C, ...)
- Each group shows tags starting with that letter
- Search bar at top (collapsible)
- Grid layout (1-3 columns based on screen size)
Tag display:
- Tag name (truncated if long)
- Edit button (on hover)
- Delete button (on hover)
- Click tag name → Navigate to tag detail page
Search functionality:
- Case-insensitive
- Substring matching
- Real-time filtering
- No regex support
Empty state:
- "No tags found" when search returns zero results
- No tags exist → Empty list (no special message)
Tag Detail Page (/tag/:uid-slug)
URL format:
- UID + slug:
/tag/abc123def-quarterly-report - UID only (fallback):
/tag/abc123def - Name (legacy, URL-encoded):
/tag/quarterly-report
Page sections:
-
Header:
- Tag name as title
- Search button (collapsible)
- Edit button (pencil icon)
- Delete button (trash icon)
-
Summary stats:
- Tasks count (with icon)
- Notes count (with icon)
- Projects count (with icon)
-
Tasks section:
- All tasks with this tag
- Filter by status: Open / All / Completed
- Sort options: Due Date, Name, Priority, Status, Created At
- Group by: None / Project
- Search within tasks
- TaskList or GroupedTaskList component
-
Notes section:
- All notes with this tag
- List view with title, content preview
- Edit/delete buttons (on hover)
- Click note → Navigate to note detail
-
Projects section:
- All projects with this tag
- ProjectItem component
- Filter by status (active/completed)
- Completion percentage shown
Interactive features:
- Sort and filter tasks without page reload
- Search updates results in real-time
- Click any item → Navigate to detail page
- Edit/delete actions on tag propagate immediately
Empty state:
- "No items found with the tag 'tag-name'" when no tasks/notes/projects exist
- Search returns zero results → "No tasks available"
Tag Display and Rendering
In Task Lists
Tag display:
- Small chips/badges below task name
- Truncated if many tags
- Clickable → Navigate to tag page
- Color: Gray background, dark text
- Icon: Tag icon (🏷️) before tag list
Hover behavior:
- Underline on hover
- Cursor changes to pointer
- Tooltip with full tag name (if truncated)
In Note Previews
Metadata row:
- Tags shown after project (if any)
- Format:
🏷️ tag1, tag2, tag3 - Each tag is a clickable link
- Comma-separated list
In Project Cards
Tag display:
- Similar to tasks - chips or inline list
- Shown in project metadata
- Clickable links to tag pages
Tag Chips Styling
Default appearance:
- Background: Light gray (
bg-gray-200) - Text: Dark gray (
text-gray-700) - Font size: Extra small (
text-xs) - Padding: Small (
px-2.5 py-0.5) - Border radius: Rounded (
rounded)
Dark mode:
- Background: Dark gray (
bg-gray-700) - Text: Light gray (
text-gray-300)
Remove button (in edit mode):
- × symbol
- Hover effect: Darker color
- Click to remove tag from item
Tag Input Component
Features
Autocomplete:
- Shows existing tags matching your input
- Filters out already-selected tags
- Debounced (300ms delay)
- Keyboard navigable (Arrow Up/Down)
- Enter to select
Keyboard shortcuts:
Enter- Add tag (highlighted suggestion or new tag),(comma) - Add tag and continue typingBackspace- Remove last tag (when input is empty)Escape- Close dropdownArrow Up/Down- Navigate suggestions
Tag limits:
- Maximum 10 tags per item
- Input disabled after reaching limit
- No error message, just prevents adding more
Visual feedback:
- Selected tags shown as chips above input
- Placeholder: "Type to add tags..."
- Dropdown with suggestions (max height 240px, scrollable)
- Highlighted suggestion on hover/keyboard navigation
Autocomplete Behavior
Matching:
- Case-insensitive
- Substring matching anywhere in tag name
- Example: "dev" matches "backend-dev", "development", "DevOps"
Dropdown display:
- Only shows tags not already selected
- Up to 10 suggestions (scrollable if more)
- Highlighted first match by default
- Mouseover changes highlight
Create new tag:
- If no matches, shows "+ Create 'tag-name'"
- Or just press Enter to create
- Validation happens on creation attempt
Tag Organization
Alphabetical Grouping
Tags list page:
- Groups by first letter (uppercase)
- A, B, C, ..., Z
- Special characters/numbers grouped together
- Within each group, sorted alphabetically (case-insensitive)
Sorting:
- Global sort: Alphabetical by name
- No custom sorting options
- Case-insensitive sort (A = a)
User-Scoped Tags
Privacy:
- Tags are private to each user
- Other users cannot see your tags
- Shared projects: Each collaborator has their own tags
Example scenario:
- User A tags project with
#urgent - User B (collaborator) doesn't see
#urgentin their tag list - User B can create their own
#urgenttag independently
No Tag Hierarchy
Flat structure:
- Tags don't have parent/child relationships
- No nesting (e.g.,
work/backendis one tag, not a hierarchy) - Workaround: Use naming conventions (
work-backend,work-frontend)
Multi-level categorization:
- Not supported natively
- Use prefixes:
project-alpha,project-beta - Or combine tags: Add both
workandbackendto same item
Search and Filtering
Search Tags (Tags List Page)
How to search:
- Navigate to
/tags - Click search icon (top right)
- Search input expands
- Type query
- Results filter in real-time
Search behavior:
- Case insensitive: "work" matches "Work", "WORK"
- Substring matching: "dev" matches "development", "backend-dev"
- Single query: No multi-word AND/OR logic
- No fuzzy matching: Exact substring required
Search scope:
- Tag name only
- Does not search tags' associated items
Filter by Tag (Content Pages)
Task filtering:
- API endpoint:
GET /api/tasks?tag=tag-name - Frontend: Navigate via tag page → Shows tasks with that tag
Note filtering:
- API endpoint:
GET /api/notes?tag=tag-name - URL query parameter:
/notes?tag=bookmark
Project filtering:
- No dedicated API endpoint
- Tag detail page filters projects client-side
Multiple tag filtering:
- Not supported in UI
- API supports single tag filter only
- Workaround: Use tag detail page, then search
Integration with Other Features
Inbox Integration
Hashtag parsing:
- Inbox items can include
#tag-namesyntax - Example:
Buy groceries #home #errands - When converting to task: Tags
homeanderrandsauto-created and applied
Smart suggestions:
- Inbox processor detects hashtags
- Suggests converting to task/note with tags pre-filled
URL detection:
- Inbox items with URLs suggest "Note"
- Can include tags:
https://example.com #bookmark #reading
Task Integration
Task creation:
- Tag input in task form
- Auto-save when tags change
- Tags persist with task
Recurring tasks:
- Tags applied to parent task
- All future occurrences inherit tags
- Changing tags on parent updates all future instances
Subtasks:
- Can have different tags than parent
- No automatic inheritance
- Independent tag management
Note Integration
Note tagging:
- Tag input in edit mode
- Tags shown in preview mode as links
- Click tag → Navigate to tag page
Auto-save behavior:
- Tag changes trigger auto-save
- 1-second debounce
- Save status indicator updates
Project Integration
Project tagging:
- Tag field in project form
- Tags help categorize projects
- Useful for filtering project list
Shared projects:
- Tags remain user-specific
- Collaborators don't see your tags
- Each user maintains their own tag set for shared projects
Common Workflows
Workflow 1: Tag-Based Task Management
Scenario: Organize tasks by context (e.g., @home, @office, @phone)
-
Create tasks and tag them:
- "Fix garage door" →
#home,#maintenance - "Review budget report" →
#office,#finance - "Call dentist" →
#phone,#health
- "Fix garage door" →
-
Navigate to tag page to see filtered view:
/tag/home→ All home tasks/tag/phone→ All phone-related tasks
-
Complete tasks in batches by context:
- At home? View
#hometag, complete all tasks - Have phone? View
#phonetag, make all calls
- At home? View
Workflow 2: Cross-Project Tracking
Scenario: Track all "urgent" items across multiple projects
- Tag urgent tasks/notes/projects with
#urgent - Navigate to
/tag/urgent - See all urgent items regardless of project
- Filter and sort as needed
- Update status, priorities, etc.
Workflow 3: Thematic Note Organization
Scenario: Collect bookmarks, articles, and references by topic
-
Save articles as notes with tags:
- "React Hooks Guide" →
#development,#react,#reference - "Design Patterns" →
#development,#patterns,#reference
- "React Hooks Guide" →
-
Navigate to
/tag/developmentto see all dev-related notes -
Or
/tag/referencefor all reference materials
Workflow 4: Quarterly Review
Scenario: Review all items related to Q1 goals
- During Q1, tag relevant tasks/notes/projects with
#q1-2026 - At end of quarter, navigate to
/tag/q1-2026 - See all items related to Q1 goals
- Review completion rates
- Archive or re-tag for next quarter
Workflow 5: Tag Cleanup
Scenario: Remove unused or redundant tags
- Navigate to
/tags - Search for old tags (e.g.,
#2025) - Click tag to see what items use it
- If empty or obsolete, delete tag
- If overlapping (e.g.,
workandwork-related), rename or consolidate
Troubleshooting
"Tag name contains invalid characters"
Possible causes:
- Using restricted characters:
# % & { } \ < > * ? / $ ! ' " @ + \| =` - Example: Trying to create
#hashtag(contains#)
Solution:
- Remove invalid characters
- Use hyphens or underscores:
hashtag,hash-tag
"A tag with the name 'X' already exists"
Cause: Tag names are unique per user (case-insensitive)
Example:
- You have tag
Work - Try to create
work→ Error (same tag)
Solution:
- Use existing tag
- Or create variation:
work-projects,work-tasks
"Tag disappeared after creating task"
Possible causes:
- Task creation failed (network error)
- Tag wasn't saved before closing form
- Browser refresh before save completed
Solution:
- Check task exists in task list
- Open task → Check tags section
- Re-add tag if missing
"Cannot add more than 10 tags"
Cause: Tag limit per item is 10
Solution:
- Remove less important tags
- Or consolidate tags (e.g., merge
urgentandhigh-priorityinto one)
"Tag page shows wrong items"
Possible causes:
- Cached data (page not refreshed)
- Tag was renamed, URL slug outdated
- Items were untagged recently
Solution:
- Hard refresh:
Ctrl+Shift+RorCmd+Shift+R - Navigate via
/tagslist (ensures correct UID) - Check item details to confirm tag association
Best Practices
Naming Conventions
-
Be consistent:
- Choose singular vs. plural:
projectvs.projects - Stick with convention across all tags
- Choose singular vs. plural:
-
Use prefixes for grouping:
status-active,status-pending,status-donearea-work,area-personal,area-health
-
Keep names short but descriptive:
- ✅
backend-dev,urgent,q1-2026 - ❌
this-is-a-really-long-tag-name-that-describes-too-much
- ✅
-
Use hyphens or underscores for multi-word:
- ✅
project-alpha,meeting_notes - ❌
project alpha(spaces are valid but harder to read)
- ✅
Organization
-
Limit tag proliferation:
- Don't create tags for one-off uses
- Reuse existing tags when possible
- Regularly review and delete unused tags
-
Use tags for cross-cutting concerns:
- Themes that span multiple projects:
#urgent,#waiting-on - Contexts:
#home,#office,#errands - Time periods:
#q1-2026,#january
- Themes that span multiple projects:
-
Combine with hierarchy:
- Use projects for structure (Areas > Projects > Tasks)
- Use tags for flexible categorization
- Example: Project "Website Redesign", tag
#frontendon relevant tasks
Maintenance
-
Regular cleanup:
- Monthly: Review tag list, delete unused tags
- Quarterly: Consolidate similar tags
- Rename outdated tags (e.g.,
#2025→#2026)
-
Tag naming audit:
- Ensure consistency (singular vs. plural)
- Fix typos:
developement→development - Merge duplicates:
workandwork-related→ choose one
-
Document tag taxonomy:
- Create a note listing standard tags and their meanings
- Tag it with
#reference,#tags - Share with team if using shared projects
Limitations and Constraints
Current Limitations
-
No tag hierarchy:
- Flat structure only
- No parent-child relationships
- Workaround: Use naming conventions (
parent-child)
-
User-scoped only:
- Cannot share tags with other users
- Collaborators on shared projects have separate tag sets
- No team-wide tag taxonomy
-
Single tag filter:
- Cannot filter by multiple tags simultaneously in UI
- API supports one tag filter at a time
- Workaround: Use tag detail page + search
-
No tag colors/icons:
- All tags display the same (gray chips)
- No visual customization
- Cannot assign colors or emojis
-
10 tag limit per item:
- Tasks, notes, projects limited to 10 tags each
- No warning when approaching limit
- Must remove existing tag to add new one
-
No tag usage statistics:
- Cannot see how many items use a tag (without visiting tag page)
- No "popular tags" or "recently used"
- Tag count not shown in tag list
Technical Constraints
-
Character restrictions:
- Invalid chars:
# % & { } \ < > * ? / $ ! ' " @ + \| =` - Limits URL-friendly tag names
- No emoji support
- Invalid chars:
-
50-character limit:
- Tag names truncated at 50 characters
- Long descriptive names not possible
-
Case-insensitive uniqueness:
- Cannot have
Workandworkas separate tags - Display preserves case, but uniqueness ignores it
- Cannot have
-
No batch operations:
- Cannot bulk-tag items
- Cannot mass-rename tags
- Must edit one at a time
Related Documentation
- Inbox Page - Hashtag parsing and tag auto-creation
- Notes System - Tagging notes
- Projects - Tagging projects
- Today Page Sections - Task filtering
- Architecture Overview - Technical architecture
- Development Workflow - Working with the codebase
Technical Implementation Files:
- Tag model:
/backend/models/tag.js - Tag service:
/backend/modules/tags/service.js - Tag controller:
/backend/modules/tags/controller.js - Tag repository:
/backend/modules/tags/repository.js - Tag validation:
/backend/modules/tags/validation.js - Tag API routes:
/backend/modules/tags/routes.js - Tags list component:
/frontend/components/Tags.tsx - Tag detail component:
/frontend/components/Tag/TagDetails.tsx - Tag input component:
/frontend/components/Tag/TagInput.tsx - Tag modal:
/frontend/components/Tag/TagModal.tsx - Tags service (frontend):
/frontend/utils/tagsService.ts
Database Tables:
tags- Tag definitionstasks_tags- Task-tag associations (many-to-many)notes_tags- Note-tag associations (many-to-many)projects_tags- Project-tag associations (many-to-many)
Document Version: 1.0.0 Last Updated: 2026-03-14 Audience: Developers, AI assistants, and end users