Blog
Internal blog system with categories, tags, and analytics
Overview
The Blog feature provides a comprehensive internal blogging platform with support for rich content, categorization, tagging, and viewing analytics. It includes both admin management interfaces and user-facing blog views with search, filtering, and audience-based access control.
Key Features
Content Management
- Rich Text Editor: Create and edit blog posts with formatting
- Draft/Published States: Control post visibility with
isPublishedflag - Categories: Organize posts into categories with icons and colors
- Tags: Multi-tag support for flexible post organization
- Reading Time: Automatic calculation of estimated reading time
- Author Attribution: Track post authors with user relationships
Viewing Modes
- List View: Compact list of posts with metadata
- Grid View: Visual card-based layout
- Table View: Detailed table with sortable columns
- Search: Full-text search across titles, content, descriptions, and tags
- Tag Filtering: Filter posts by selected tags using multi-select
Analytics Integration
- Page View Tracking: Integrated with AnalyticsService
- View Counts: Track blog post popularity
- Performance Metrics: Monitor blog engagement
Access Control
- Audience Filtering: Show posts only to specific audience members
- Creator Permissions: Track post authors and restrict editing
- Admin Controls: Super users and admins can create/edit all posts
- Public vs Private: Audience-based visibility control
Database Models
BlogPost Model
model BlogPost {
id String @id @default(cuid())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
tenantId String
tenant Tenant @relation(fields: [tenantId], references: [id])
slug String
title String
description String
content String @db.NVarChar(max)
date DateTime
image String?
readingTime String?
published Boolean @default(false)
categoryId String?
category BlogCategory? @relation(fields: [categoryId], references: [id])
authorId String?
author User? @relation(fields: [authorId], references: [id])
tags BlogPostTag[]
audience Audience[]
}BlogCategory Model
model BlogCategory {
id String @id @default(cuid())
createdAt DateTime @default(now())
tenantId String
tenant Tenant @relation(fields: [tenantId], references: [id])
name String
slug String
icon String?
color String?
posts BlogPost[]
}BlogTag Model
model BlogTag {
id String @id @default(cuid())
createdAt DateTime @default(now())
tenantId String
tenant Tenant @relation(fields: [tenantId], references: [id])
name String
slug String
color String?
posts BlogPostTag[]
}
model BlogPostTag {
postId String
post BlogPost @relation(fields: [postId], references: [id])
tagId String
tag BlogTag @relation(fields: [tagId], references: [id])
@@id([postId, tagId])
}Routes
User Routes
/app/{tenant}/blog- View all published blog posts/app/{tenant}/blog/{id}- View individual blog post
Features:
- Search and filter functionality
- Tag-based filtering
- View toggle (list, table, grid)
- Analytics tracking
Admin Routes
/app/{tenant}/settings/blog- Manage blog posts/app/{tenant}/settings/blog/new- Create new blog post/app/{tenant}/settings/blog/{id}- Edit existing post/app/{tenant}/settings/blog/categories- Manage categories/app/{tenant}/settings/blog/tags- Manage tags
Content Creation
Writing a Post
- Click "+ Write" button in blog view
- Enter post details:
- Title
- Slug (auto-generated from title)
- Description
- Category
- Tags
- Cover image URL
- Content (rich text editor)
- Set publish date
- Toggle "Published" status
- Assign audiences (optional)
- Save or publish post
Publishing Workflow
- Draft State:
published: false- Post not visible to users - Published State:
published: true- Post visible based on audience - Scheduled Publishing: Use
datefield for future publish dates - Audience Control: Restrict visibility to specific user groups
Search and Filtering
Full-Text Search
Searches across:
- Post title
- Description
- Content
- Author name
- Category name
- Tag names
- Slug
- Creation date
Tag Filtering
const [selectedTags, setSelectedTags] = useState<string[]>([]);
// Filter posts by selected tags
filteredItems = filteredItems.filter((f) =>
f.tags.some((t) => selectedTags.includes(t.tag.id))
);View Modes
List View (Default)
- Compact card layout
- Featured image thumbnails
- Post metadata (date, author, category, tags)
- Reading time indicator
- View count from analytics
Table View
- Sortable columns
- Bulk actions support
- Detailed metadata display
- Quick edit/delete actions
Grid View
- Visual card-based layout
- Large image previews
- Hover effects
- Optimized for browsing
Analytics Integration
Page View Tracking
views: await AnalyticsService.getPageViews({
url: { startsWith: UrlUtils.getBlogPath(params) },
}),View counts displayed:
- Per-post view counts
- Aggregated blog statistics
- Viewing trends over time
Best Practices
- SEO Optimization: Use descriptive titles, slugs, and meta descriptions
- Image Optimization: Compress images before uploading, use appropriate formats
- Categorization: Create logical category structure before writing posts
- Tagging: Use consistent, relevant tags across posts
- Reading Time: Keep posts concise for better engagement
- Audience Targeting: Use audiences to segment content appropriately
- Publishing Schedule: Use scheduled publishing for content planning
Common Operations
Create Blog Post
- Navigate to
/app/{tenant}/settings/blog/new - Fill in post details (title, content, category, tags)
- Upload or link cover image
- Set publish date and status
- Assign audiences if needed
- Click "Publish" or "Save Draft"
Edit Existing Post
- Navigate to
/app/{tenant}/blog - Click on post to edit
- Update content as needed
- Click "Update" to save changes
- Changes tracked with
updatedAttimestamp
Manage Categories
- Navigate to
/app/{tenant}/settings/blog/categories - Create new categories with name, icon, and color
- Edit or delete existing categories
- Categories automatically link to posts
Filter by Tags
- In blog view, use tag multi-select dropdown
- Select one or more tags
- View filters to show only posts with selected tags
- Clear selection to show all posts
Integration Points
- Audiences: Audience-based post visibility and access control
- Analytics: Page view tracking and engagement metrics
- Users: Author attribution and creator tracking
- Categories: Hierarchical content organization
- Tags: Flexible content tagging and filtering
- Search: Full-text search across all post content

