Designing a Reusable Editorial System
How we turned a one-off blog UI into a reusable content surface that still feels intentional once it leaves the original product.
- Author
Bruma- Published
- Reading time
- 2 min
- Category
- Design Systems

Start from the editorial rhythm
Reusable blog UI works best when the typography and spacing rules are stable before you think about product branding. The moment every project needs to reinterpret headings, cards, or metadata blocks, the shared component layer stops saving time.
In this demo, the goal is not to simulate a CMS with endless data. It is to prove that the shared blog components can render a believable article page, category flow, and listing experience with the same surface language across routes.
The renderer keeps references such as BlogContentRenderer and sm:my-8 readable inside the editorial flow without turning them into full code blocks.
- Stable typography and spacing make the article page portable across products
- Shared content blocks reduce duplication between markdown-heavy apps
- Wrapper components preserve app-level compatibility while moving real UI into the library
A reusable system needs clear boundaries
The library owns the reusable chrome: hero cards, carousels, category grids, FAQs, author information, and table-of-contents behavior. The demo app owns the content source and route composition.
That boundary is what makes the setup portable. Another project can change the post inventory, author information, or publishing cadence without rewriting the reusable UI blocks.
From content to route
Each layer keeps its own responsibility while the article stays reusable.
- 01Markdown entry
- 02Content collection
- 03Shared component
- 04Localized route
{
"title": "Designing a Reusable Editorial System",
"category": "Design Systems",
"tags": [
"Content",
"Vue"
]
}Real content is a better test than static arrays
Mock arrays are useful for initial exploration, but they hide the real shape of an editorial page. Once content lives in markdown, you immediately verify path handling, frontmatter fields, related content lookups, and rich body rendering.
This is where production-like behavior matters. A working post page is not just a hero image plus a few paragraphs. It includes:

- Category metadata
- Author and publish information
- A content-driven table of contents
- Related article links
- Related category links
npm installnpm run dev| Responsibility | Library | App |
|---|---|---|
| Editorial UI blocks | Cards, lists, tables, dividers, TOC, FAQ, author info | Consumes them through wrappers or direct imports |
| Content source | No hardcoded product content | Markdown entries and route queries |
| Product-specific conversion blocks | Optional | Owns CTA cards like GiveItATryCard |
Markdown helps expose content assumptions
With markdown in the loop, the page has to handle long-form prose and nested headings gracefully. If the spacing, prose styles, or table-of-contents data break, that problem becomes obvious immediately.
The demo app should behave like a consumer
The demo app is most useful when it exercises the library the same way a real product would. That means importing the published subpaths, relying on the Nuxt modules the production app uses, and querying content through the same APIs instead of bypassing them.
That approach keeps the demo honest. If something is awkward here, it will be awkward for the next consuming app too.
Frequently asked questions
Find quick answers to the most common questions about this topic.
Because it lets multiple projects reuse the same content surfaces, spacing decisions, and interaction patterns without rebuilding them from scratch.
Author
Bruma



