Skip to content

Blogs

The blogs module provides a full blogging system with rich text editing via EditorJS, slug management, SEO fields, and preview rendering.

Module path: src/lib/modules/blogs/ Routes: /blog, /blog/new, /blog/[slug], /blog/[slug]/edit

interface Blog {
id?: string;
title: string;
slug: string;
content: OutputData; // EditorJS format
status: 'draft' | 'published' | 'archived';
visibility: 'public' | 'private' | 'unlisted';
hubId: string;
createdBy: string;
createdAt?: Timestamp;
updatedAt?: Timestamp;
publishedAt?: Timestamp;
seoKey?: string; // Focus keyword
seoTitle?: string; // Max 70 chars
seoDescription?: string; // Max 160 chars
}

Content storage: Content is stored as a JSON string in Firestore to avoid nested array limitations. Parsed back to OutputData on retrieval.

Controller: src/lib/modules/blogs/components/blog-editor.svelte.ts

ToolDescription
HeaderHeading levels
ParagraphText blocks
ListOrdered/unordered lists
QuoteBlock quotes with captions
CodeCode blocks
DelimiterHorizontal separators
TableData tables
MarkerText highlighting
LinkURL linking
ChecklistCheckbox lists
ImageImage upload with Firebase Storage
WarningWarning/alert blocks
  • Validates image types (JPEG, PNG, GIF, WebP)
  • Checks storage limits based on subscription
  • Stores at: hubs/{hubId}/blogs/{blogSlug}/{fileId}.{ext}
  • Creates StorageUser records for tracking
blogManager.blogs; // All user's blogs
blogManager.publishedBlogs; // Published only
blogManager.draftBlogs; // Drafts only
blogManager.archivedBlogs; // Archived
blogManager.createBlog(data);
blogManager.updateBlog(blogId, updates);
blogManager.deleteBlog(blogId);
blogManager.archiveBlog(blogId);
blogManager.getBlogBySlug(slug, hubId);
blogManager.checkSlugExists(slug, excludeId);

File: src/lib/modules/blogs/utils/slug.ts

  • generateSlug(title) - Auto-generate from title (lowercase, hyphens, max 100 chars)
  • validateSlugFormat(slug) - Format validation
  • checkSlugUniqueness(slug, excludeId?, hubId?) - Firestore uniqueness check
ComponentPurpose
blog-editor.svelteEditorJS editor with title, slug, status, SEO fields
blog-preview.sveltePreview renderer
blog-list.svelteTable view with status badges and actions
blog-article-layout.svelteArticle container with author bar
blog-author-bar.svelteAuthor info, dates, read time
blog-readonly-editor.svelteRead-only EditorJS instance
preview/*.svelteBlock-specific renderers (header, paragraph, list, quote, image, code, table, warning, delimiter, embed)

GET /api/blogs - Proxies to WordPress blog API at https://mindhyv.com/wp-json/wp/v2/posts. Supports language parameter. Returns WPPost array for the “What’s New” dashboard section.

Blogs can also be managed within a hub context at /hubs/[hubId]/blogs/, sharing the same editor and manager infrastructure but scoped to a specific hub.