Folder Structure

apps/web/src/app/(content)/
├── blogs/           # Blog post pages (dynamic routes)
├── privacy-policy/  # Privacy policy pages
└── layout.tsx       # Layout for content section

apps/web/src/features/content/
├── blog/    # Blog-related feature logic/components
├── privacy/ # Privacy policy feature logic/components
└── shared/  # Shared content utilities/components

apps/web/src/lib/
├── render-rich-text/    # Render Lexical-compatible JSON structure into React components
Folder Descriptions:
  • apps/web/src/app/(content)/blogs/: Contains the dynamic route pages for individual blog posts, rendering content fetched from the CMS or local sources.
  • apps/web/src/app/(content)/privacy-policy/: Holds the privacy policy pages, allowing for easy updates and dynamic rendering of legal content.
  • apps/web/src/app/(content)/layout.tsx: Provides the layout wrapper for all content-related pages, ensuring consistent structure and styling.
  • apps/web/src/features/content/blog/: Contains feature logic, components, and utilities specifically for blog functionality (e.g., fetching, displaying, and managing blog posts).
  • apps/web/src/features/content/privacy/: Handles privacy policy logic and components, such as fetching and rendering privacy-related content.
  • apps/web/src/features/content/shared/: Houses shared utilities and components used across different content features (e.g., markdown renderers, content formatters).

CMS Service (@/services/cms/cms.ts)

Provides utilities for fetching blog posts and privacy policy content. Usage Example:
import { cmsService } from "@/services/cms/cms";

// Fetch latest blogs
const blogs = await cmsService.blogs.getLatest(3);

// Fetch privacy policy
const policy = await cmsService.privacy.getPolicy();

Content Components (@/features/content/)

  • Blog: Render blog posts and lists.
  • Privacy: Render privacy policy content.
  • Shared: Typography, skeletons, and more.
Example:
import Blog from "@/features/content/blog/blog";
<Blog post={post} />

Rich Text Rendering Utility (render-rich-text.tsx)

Your CMS uses a custom utility at apps/web/src/lib/render-rich-text.tsx to render rich text content from a Lexical-compatible JSON structure into React components. Key Features:
  • Supports headings, paragraphs, lists, links, and inline text formatting (bold, italic, underline, strikethrough).
  • Input: Expects a tree of LexicalNode objects (see the LexicalNode type in the file).
  • Output: Returns React elements with Tailwind CSS classes for consistent styling.
Usage Example:
import { renderRichText } from "@/lib/render-rich-text";

// `content` is a Lexical JSON node tree (from your CMS/editor)
export default function ArticleBody({ content }) {
  return <div>{renderRichText(content)}</div>;
}
How It Works:
  • Text nodes: Rendered as <span> with formatting classes.
  • Headings: Rendered as <h1>, <h2>, <h3> with anchor IDs for linking.
  • Paragraphs: Rendered as <p> with spacing and leading.
  • Lists: Rendered as <ul>/<li> with proper indentation.
  • Links: Rendered as <a> with external link handling.
  • Empty nodes: Skipped or rendered as empty divs for spacing.
See the file for full details and customization.

Content Pages ((content)/)

  • Blogs: /blogs and /blogs/[id] for blog listings and detail pages.
  • Privacy Policy: /privacy-policy for privacy content.