# Blog Platform The store ships with a full **content platform** — not a bolted-on news page, but an editorial system with drafts, review, scheduling, and SEO baked in. It is how the store does content marketing. ## Authoring - A **rich-text editor** built on Action Text and the Lexxy editor, so authors format posts without touching HTML. - **Image handling** via `BlogPostImageService`, with Unsplash integration for sourcing imagery. - **Duplication** — `BlogPostDuplicator` clones a post as a starting point for a new one. ## Editorial workflow A post moves through real states rather than just draft/published: ``` draft ──▶ pending review ──▶ scheduled ──▶ published ``` `BlogPostPublisherService` owns the transitions, and a scheduled post is released automatically by a background job at its publish time. Posts can also be marked **featured** for prominent placement. ## SEO, by default SEO is not an afterthought — it is a concern mixed into the model: - **`BlogPost::Seoable`** — slugs, meta tags, Open Graph cards, and JSON-LD structured data so posts present well in search results and social unfurls. - **`BlogPost::TocGenerator`** — builds a table of contents from the post's headings. - **`BlogPost::ContentFormattable`** — normalizes rendered content. ## Reading experience The blog index uses **cursor-based pagination** to drive infinite scroll — the same pagination engine described in [Scaling](/architecture/scaling/) — so long archives load smoothly without page-number drift. Rendered posts are cached via `BlogPostCacheService` and invalidated on edit. ## Key files | Concern | Files | |---------|-------| | Model | `BlogPost`, `BlogPostTag`, concerns `Seoable`, `TocGenerator`, `ContentFormattable` | | Services | `BlogPostPublisherService`, `BlogPostImageService`, `BlogPostCacheService`, `BlogPostDuplicator` | | UI | `app/components/blog_post/`, `CursorPaginator` |