update Architecture.md
This commit is contained in:
15
.idea/checkstyle-idea.xml
generated
Normal file
15
.idea/checkstyle-idea.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CheckStyle-IDEA" serialisationVersion="2">
|
||||||
|
<checkstyleVersion>11.0.1</checkstyleVersion>
|
||||||
|
<scanScope>JavaOnly</scanScope>
|
||||||
|
<option name="thirdPartyClasspath" />
|
||||||
|
<option name="activeLocationIds" />
|
||||||
|
<option name="locations">
|
||||||
|
<list>
|
||||||
|
<ConfigurationLocation id="bundled-sun-checks" type="BUNDLED" scope="All" description="Sun Checks">(bundled)</ConfigurationLocation>
|
||||||
|
<ConfigurationLocation id="bundled-google-checks" type="BUNDLED" scope="All" description="Google Checks">(bundled)</ConfigurationLocation>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -3,87 +3,127 @@ VOYAGE – Blog Architecture Documentation
|
|||||||
|
|
||||||
Purpose
|
Purpose
|
||||||
-------
|
-------
|
||||||
This document explains how the blog system is structured,
|
This document describes the architecture of the VOYAGE public blog,
|
||||||
how data flows through the application, and how blog posts
|
including folder structure, routing, data flow, and rendering logic.
|
||||||
are rendered. A new developer should be able to understand
|
|
||||||
and extend the blog after reading this file.
|
A new developer should be able to understand how blog posts are loaded,
|
||||||
|
renderouten funktionieren, and where to extend the system after reading this file.
|
||||||
|
|
||||||
|
|
||||||
High-Level Overview
|
High-Level Overview
|
||||||
-------------------
|
-------------------
|
||||||
The blog is implemented using the Next.js App Router with
|
The blog is implemented using the **Next.js App Router** with:
|
||||||
file-based routing and dynamic segments.
|
|
||||||
|
|
||||||
Key concepts:
|
- File-based routing
|
||||||
- Blog posts are stored as MDX files
|
- Dynamic route segments
|
||||||
- Each post is identified by a slug
|
- MDX-based content
|
||||||
- Pages are generated dynamically based on folder structure
|
- A shared public layout
|
||||||
- Shared UI elements are reused across pages
|
|
||||||
|
Key principles:
|
||||||
|
- Blog content lives outside the app router (content/posts)
|
||||||
|
- Routing is derived from folder structure
|
||||||
|
- Rendering happens in async server components
|
||||||
|
- Shared UI is colocated in components/
|
||||||
|
|
||||||
|
|
||||||
Folder Structure
|
Monorepo Context
|
||||||
----------------
|
----------------
|
||||||
|
This repository is a monorepo containing multiple applications.
|
||||||
|
|
||||||
|
Relevant app for the blog:
|
||||||
|
- apps/public-web → Public website & blog
|
||||||
|
|
||||||
|
Other apps (not covered here):
|
||||||
|
- workspace-api
|
||||||
|
- workspace-ui
|
||||||
|
|
||||||
|
|
||||||
|
Folder Structure (Current)
|
||||||
|
--------------------------
|
||||||
|
|
||||||
apps/public-web/
|
apps/public-web/
|
||||||
│
|
│
|
||||||
├── app/
|
├── app/
|
||||||
│ ├── (site)/
|
│ ├── (site)/ → Public site route group
|
||||||
│ │ ├── layout.tsx → Shared layout for public pages
|
│ │ ├── layout.tsx → Shared layout (TopBar, globals)
|
||||||
│ │ ├── page.tsx → Homepage
|
│ │ ├── page.tsx → Homepage
|
||||||
│ │ ├── about/
|
│ │ ├── about/
|
||||||
│ │ │ └── page.tsx → Static About page
|
│ │ │ └── page.tsx → Static About page
|
||||||
│ │ └── blog/
|
│ │ └── blog/
|
||||||
│ │ ├── page.tsx → Blog index (list of posts)
|
│ │ ├── layout.tsx → Blog-specific layout (optional)
|
||||||
|
│ │ ├── page.tsx → Blog index (list of posts)
|
||||||
│ │ └── [slug]/
|
│ │ └── [slug]/
|
||||||
│ │ └── page.tsx → Dynamic blog post page
|
│ │ └── page.tsx → Dynamic blog post page
|
||||||
│ │
|
│ │
|
||||||
│ └── globals.css → Global styles
|
│ ├── global.css → Global styles
|
||||||
|
│ └── layout.tsx → Root layout
|
||||||
│
|
│
|
||||||
├── components/
|
├── components/
|
||||||
│ └── shell/
|
│ └── shell/
|
||||||
│ └── TopBar.tsx → Shared navigation shell
|
│ └── TopBar.tsx → Shared navigation bar
|
||||||
|
│
|
||||||
|
├── visuals/
|
||||||
|
│ └── ImageSphereSketch.tsx → Creative / visual components
|
||||||
│
|
│
|
||||||
├── content/
|
├── content/
|
||||||
│ └── posts/
|
│ └── posts/
|
||||||
│ └── YYYY-MM-DD-title.mdx → Blog post content files
|
│ ├── YYYY-MM-DD-title.mdx → Blog post source files
|
||||||
|
│ └── ...
|
||||||
│
|
│
|
||||||
├── lib/
|
├── lib/
|
||||||
│ └── posts.ts → Blog data loading logic
|
│ └── posts.ts → Blog data loading & parsing logic
|
||||||
|
│
|
||||||
|
├── public/
|
||||||
|
│ └── blog/
|
||||||
|
│ └── visuals/
|
||||||
|
│ ├── first.jpg
|
||||||
|
│ ├── second.jpg
|
||||||
|
│ └── ...
|
||||||
|
|
||||||
|
|
||||||
Routing Logic
|
Routing Logic
|
||||||
-------------
|
-------------
|
||||||
The App Router uses the folder structure to define routes:
|
Routing is defined entirely by the folder structure.
|
||||||
|
|
||||||
- /blog
|
Static routes:
|
||||||
→ app/(site)/blog/page.tsx
|
- / → app/(site)/page.tsx
|
||||||
|
- /about → app/(site)/about/page.tsx
|
||||||
|
- /blog → app/(site)/blog/page.tsx
|
||||||
|
|
||||||
- /blog/some-post-slug
|
Dynamic routes:
|
||||||
→ app/(site)/blog/[slug]/page.tsx
|
- /blog/[slug] → app/(site)/blog/[slug]/page.tsx
|
||||||
|
|
||||||
The [slug] directory defines a dynamic route parameter.
|
The `[slug]` directory defines a dynamic route parameter
|
||||||
|
that is passed to the page component as `params.slug`.
|
||||||
|
|
||||||
|
|
||||||
Data Flow (How a blog post is rendered)
|
Data Flow (How a Blog Post Is Rendered)
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
1. User navigates to /blog/[slug]
|
1. User navigates to:
|
||||||
|
/blog/some-post-slug
|
||||||
|
|
||||||
2. Next.js extracts the slug from the URL:
|
2. Next.js resolves the route:
|
||||||
|
app/(site)/blog/[slug]/page.tsx
|
||||||
|
|
||||||
|
3. The page component receives:
|
||||||
params.slug
|
params.slug
|
||||||
|
|
||||||
3. The page component calls:
|
4. The page calls:
|
||||||
getPostBySlug(slug)
|
getPostBySlug(slug) from lib/posts.ts
|
||||||
|
|
||||||
4. getPostBySlug:
|
5. lib/posts.ts:
|
||||||
- Reads the MDX file from content/posts
|
- Reads the corresponding MDX file from content/posts
|
||||||
- Parses frontmatter metadata (title, date, etc.)
|
- Parses frontmatter metadata (title, date, etc.)
|
||||||
- Returns structured post data
|
- Returns structured post data
|
||||||
|
|
||||||
5. The page component renders:
|
6. The page component renders:
|
||||||
- TopBar (shared navigation)
|
- Shared layout (TopBar)
|
||||||
- Metadata (date, title)
|
- Post metadata
|
||||||
- Post content
|
- MDX content as React components
|
||||||
|
|
||||||
|
7. If the slug does not exist:
|
||||||
|
- notFound() is triggered
|
||||||
|
|
||||||
|
|
||||||
Core Files Explained
|
Core Files Explained
|
||||||
@@ -91,39 +131,56 @@ Core Files Explained
|
|||||||
|
|
||||||
app/(site)/blog/[slug]/page.tsx
|
app/(site)/blog/[slug]/page.tsx
|
||||||
--------------------------------
|
--------------------------------
|
||||||
- Async server component
|
- Async Server Component
|
||||||
- Receives params as a Promise
|
- Receives dynamic params (slug)
|
||||||
- Loads blog content using lib/posts
|
- Loads post data via lib/posts
|
||||||
- Handles notFound() if slug does not exist
|
- Handles invalid slugs with notFound()
|
||||||
- Renders blog UI
|
- Renders full blog post view
|
||||||
|
|
||||||
|
app/(site)/blog/page.tsx
|
||||||
|
------------------------
|
||||||
|
- Blog index page
|
||||||
|
- Loads all posts via lib/posts
|
||||||
|
- Renders list / preview of posts
|
||||||
|
|
||||||
lib/posts.ts
|
lib/posts.ts
|
||||||
-------------
|
-------------
|
||||||
- Central data access layer for blog posts
|
- Central data access layer for blog content
|
||||||
- Abstracts file system and parsing logic
|
- Handles file system access and MDX parsing
|
||||||
- Keeps page components clean and focused
|
- Keeps routing and rendering logic clean
|
||||||
|
|
||||||
content/posts/*.mdx
|
content/posts/*.mdx
|
||||||
-------------------
|
-------------------
|
||||||
- Source of truth for blog content
|
- Source of truth for blog content
|
||||||
- File name defines the slug
|
- File name defines the slug
|
||||||
- Frontmatter stores metadata
|
- Frontmatter stores metadata
|
||||||
- Content is rendered as React components
|
- Body is rendered as MDX
|
||||||
|
|
||||||
components/shell/TopBar.tsx
|
components/shell/TopBar.tsx
|
||||||
---------------------------
|
---------------------------
|
||||||
- Shared navigation bar
|
- Shared navigation component
|
||||||
- Used across all public pages
|
- Used across all public pages
|
||||||
- Keeps layout consistent
|
- Ensures consistent layout and navigation
|
||||||
|
|
||||||
|
public/blog/visuals/
|
||||||
|
--------------------
|
||||||
|
- Static images for blog posts
|
||||||
|
- Served directly by Next.js
|
||||||
|
- Referenced in MDX or page components
|
||||||
|
|
||||||
|
|
||||||
Why This Architecture
|
Why This Architecture
|
||||||
---------------------
|
---------------------
|
||||||
- Clear separation of concerns
|
- Clear separation of concerns
|
||||||
- File-based routing = no manual route config
|
- File-based routing (no manual routing config)
|
||||||
- Easy to add new posts (just add an MDX file)
|
- Content-driven architecture
|
||||||
- Easy to extend with tags, categories, RSS, etc.
|
- Easy to add new posts
|
||||||
- Scales well as content grows
|
- Scales well for future features:
|
||||||
|
- Tags
|
||||||
|
- Categories
|
||||||
|
- RSS feeds
|
||||||
|
- Pagination
|
||||||
|
- Search
|
||||||
|
|
||||||
|
|
||||||
How to Add a New Blog Post
|
How to Add a New Blog Post
|
||||||
@@ -134,16 +191,19 @@ How to Add a New Blog Post
|
|||||||
2. Use a unique filename:
|
2. Use a unique filename:
|
||||||
YYYY-MM-DD-your-title.mdx
|
YYYY-MM-DD-your-title.mdx
|
||||||
|
|
||||||
3. Add frontmatter metadata
|
3. Add frontmatter metadata (title, date, etc.)
|
||||||
|
|
||||||
4. The post becomes automatically available
|
4. Optionally add images to:
|
||||||
at /blog/your-title
|
public/blog/visuals/
|
||||||
|
|
||||||
|
5. The post is automatically available at:
|
||||||
|
/blog/your-title
|
||||||
|
|
||||||
|
|
||||||
Current Status
|
Current Status
|
||||||
--------------
|
--------------
|
||||||
- Blog routing implemented
|
- App Router fully set up
|
||||||
- Dynamic slugs working
|
- Dynamic blog slugs working
|
||||||
- Shared layout integrated
|
- Shared public layout integrated
|
||||||
- MDX content loading in place
|
- MDX content loading stable
|
||||||
- Ready for styling and feature extensions
|
- Ready for styling, animations, and feature extensions
|
||||||
Reference in New Issue
Block a user