Categories provide the organizational structure for your Help Center. Learn how to create categories, build hierarchies, and link related content.
What are Categories?
Categories group related articles together, making it easier for customers to find information. Each category can contain:
Articles - Individual documentation pages
Subcategories - Nested child categories
Related categories - Cross-references to similar topics
Folders - Additional organizational structure
Creating Categories
Required Fields
Display name for the category
URL-friendly identifier (must be unique per portal + locale)
Parent Help Center portal
Account ID (automatically set from portal)
Optional Fields
Brief explanation of the category’s content
Icon identifier for visual representation (default: empty string)
Language code (default: ‘en’)
Sort order for category display
Parent category for creating subcategories
Root category for translations
Plan Structure
Outline your content hierarchy before creating categories
Create Parent Categories
Start with top-level categories for main topics
Add Subcategories
Create child categories for more specific topics
Assign Articles
Move or create articles within each category
Link Related Content
Connect related categories for cross-navigation
Category Schema
class Category < ApplicationRecord
belongs_to :account
belongs_to :portal
belongs_to :parent_category , optional: true
belongs_to :root_category ,
foreign_key: :associated_category_id ,
optional: true
has_many :articles
has_many :folders
has_many :sub_categories ,
foreign_key: :parent_category_id
has_many :associated_categories ,
foreign_key: :associated_category_id
has_many :related_categories ,
through: :category_related_categories
end
Category Hierarchy
Parent-Child Structure
Create nested categories for detailed organization:
Getting Started # Parent category
├── Installation # Subcategory
├── Configuration # Subcategory
└── First Steps # Subcategory
Advanced Features # Parent category
├── Automation # Subcategory
├── Integrations # Subcategory
└── Custom Workflows # Subcategory
Creating Subcategories
Finding Subcategories
# Define parent relationship
subcategory = Category . create! (
name: 'Installation' ,
slug: 'installation' ,
parent_category_id: getting_started. id ,
portal_id: portal. id
)
Link categories that cover similar topics:
# Schema
has_many :category_related_categories ,
class_name: :RelatedCategory ,
dependent: :destroy_async
has_many :related_categories ,
through: :category_related_categories
# Usage
category. related_categories << other_category
Related categories appear as suggestions, helping customers discover relevant content.
Multi-language Categories
Locale Support
Categories are language-specific:
# Validation
validate :allowed_locales
def allowed_locales
allowed_locales = portal. config [ 'allowed_locales' ]
return true if allowed_locales. include? (locale)
errors. add ( :locale , " #{ locale } is not part of portal's allowed_locales" )
end
Associated Categories
Link translations of the same category:
# English version (root)
category_en = Category . create! (
name: 'Getting Started' ,
slug: 'getting-started' ,
locale: 'en' ,
portal_id: portal. id
)
# Spanish translation
category_es = Category . create! (
name: 'Comenzando' ,
slug: 'getting-started' ,
locale: 'es' ,
associated_category_id: category_en. id ,
portal_id: portal. id
)
The same slug can be used across locales. The uniqueness constraint is per (slug, locale, portal_id) combination.
Category Positioning
Control the display order of categories:
# Default ordering
scope :search , -> ( params ) {
search_by_locale (params[ :locale ])
. page ( current_page (params))
. order ( position: :asc )
}
Set Initial Position
Assign position values when creating categories (e.g., 10, 20, 30)
Update as Needed
Modify positions to reorder categories
Maintain Gaps
Use increments of 10 to allow easy insertion of new categories
Categories are paginated for performance:
paginates_per Limits :: CATEGORIES_PER_PAGE
# Usage
Category . search ( locale: 'en' , page: 2 )
Organizing Articles
Article Assignment
Articles belong to one category:
has_many :articles , dependent: :nullify
When a category is deleted, articles are not deleted. Instead, their category_id is set to null.
Locale Inheritance
Articles automatically inherit category locale:
# From article.rb
def ensure_locale_in_article
self . locale = if category. present?
category. locale
else
locale. presence || portal. default_locale
end
end
Articles must have the same locale as their category. Assigning an article to a category with a different locale will update the article’s locale.
Folders
Categories can contain folders for additional organization:
has_many :folders , dependent: :destroy_async
Folders provide an extra level of hierarchy beyond categories and subcategories. They’re useful for large categories with many articles.
Searching Categories
By Locale
Filter categories by language:
scope :search_by_locale , -> ( locale ) {
where ( locale: locale) if locale. present?
}
# Usage
Category . search_by_locale ( 'en' )
Search Method
Combine locale filtering with pagination:
Category . search (
locale: 'en' ,
page: 1
)
Category URLs
Category pages follow this structure:
https://your-domain.com/hc/{portal-slug}/{locale}/categories/{category-slug}
Example:
https://app.chatwoot.com/hc/my-portal/en/categories/getting-started
Best Practices
Use clear, descriptive category names
Keep names concise (2-4 words)
Use title case for consistency
Avoid technical jargon in top-level categories
Use specific terms for subcategories
Limit hierarchy depth to 2-3 levels
Group 5-10 articles per category
Create subcategories when a category exceeds 15 articles
Balance category sizes for easy navigation
Use folders for very large categories
Create categories for all supported locales
Link translations with associated_category_id
Use consistent slug structure across locales
Maintain same hierarchy in all languages
Translate category descriptions and icons
Common Patterns
Feature-based Organization
Messaging
├── Live Chat
├── Email Integration
└── WhatsApp
Automation
├── Canned Responses
├── Chatbots
└── Workflows
User Journey Organization
Getting Started
├── Installation
├── Setup
└── First Steps
Daily Use
├── Managing Conversations
├── Team Collaboration
└── Reporting
Advanced
├── Custom Development
├── API Integration
└── Performance Tuning
Role-based Organization
For Agents
├── Handling Conversations
├── Using Tools
└── Best Practices
For Administrators
├── Account Settings
├── Team Management
└── Security
Validation Rules
Must be present and unique per (slug, locale, portal_id)
Must be in portal’s allowed_locales list
Automatically set from portal
API Operations
Create Category
category = portal. categories . create! (
name: 'Getting Started' ,
slug: 'getting-started' ,
description: 'Learn the basics of Chatwoot' ,
locale: 'en' ,
position: 10
)
Update Category
category. update! (
name: 'Updated Name' ,
description: 'New description' ,
position: 20
)
Delete Category
category. destroy
# Articles in this category will have category_id set to null
# Subcategories will have parent_category_id set to null
Troubleshooting
Category not appearing - Check that the locale matches the portal’s allowed locales and that the category is not a draft (if draft mode exists).
Slug conflict - Ensure the slug is unique for the combination of slug, locale, and portal_id.
Articles changing locale - When assigning an article to a category, the article’s locale will update to match the category’s locale.