Logo

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 isPublished flag
  • 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

  1. Click "+ Write" button in blog view
  2. Enter post details:
    • Title
    • Slug (auto-generated from title)
    • Description
    • Category
    • Tags
    • Cover image URL
    • Content (rich text editor)
  3. Set publish date
  4. Toggle "Published" status
  5. Assign audiences (optional)
  6. 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 date field for future publish dates
  • Audience Control: Restrict visibility to specific user groups

Search and Filtering

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

  1. SEO Optimization: Use descriptive titles, slugs, and meta descriptions
  2. Image Optimization: Compress images before uploading, use appropriate formats
  3. Categorization: Create logical category structure before writing posts
  4. Tagging: Use consistent, relevant tags across posts
  5. Reading Time: Keep posts concise for better engagement
  6. Audience Targeting: Use audiences to segment content appropriately
  7. Publishing Schedule: Use scheduled publishing for content planning

Common Operations

Create Blog Post

  1. Navigate to /app/{tenant}/settings/blog/new
  2. Fill in post details (title, content, category, tags)
  3. Upload or link cover image
  4. Set publish date and status
  5. Assign audiences if needed
  6. Click "Publish" or "Save Draft"

Edit Existing Post

  1. Navigate to /app/{tenant}/blog
  2. Click on post to edit
  3. Update content as needed
  4. Click "Update" to save changes
  5. Changes tracked with updatedAt timestamp

Manage Categories

  1. Navigate to /app/{tenant}/settings/blog/categories
  2. Create new categories with name, icon, and color
  3. Edit or delete existing categories
  4. Categories automatically link to posts

Filter by Tags

  1. In blog view, use tag multi-select dropdown
  2. Select one or more tags
  3. View filters to show only posts with selected tags
  4. 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

We respect your privacy.

TLDR: We use cookies for language selection, theme, and analytics. Learn more.