The version of MRoot in this case study has two presentations: a conventional portfolio and an IDE-style interface with an explorer, tabs, terminal, and command palette. Both show the same projects and writing.
The implementation detail that matters is where the content lives. Adding a project means writing one Markdown file, not updating a website record and then making a second copy for IDE mode.
This article describes the June 2026 implementation. It is not a fresh inspection of the current site, and the small demonstrations here are explanatory—not captures of its production editor.
01 / FIELD NOTESCompile the content at build time
A Vite plugin reads the files under content/, parses their frontmatter, and emits a plain data module exposed as virtual:content.
The published excerpt shows the shape of that module:
function buildModuleSource(contentDir: string): string {
const projects = loadProjects(contentDir);
const writing = loadWriting(contentDir);
return `export const PROJECTS = ${JSON.stringify(projects)};
export const WRITING = ${JSON.stringify(writing)};
// …profile, skills, songs
`;
}src/data.ts re-exports the generated data. Website pages and IDE views read through that shared entry point rather than maintaining their own content collections.
The practical boundary is at build time. The browser receives the prepared data; this pipeline does not ship a Markdown parser for visitors to run. There is no performance number in the source, so that is an architectural description, not a benchmark claim.
FOLLOW THE CONTENT
Parse before the browser.
01 / AUTHORED CONTENT
Markdown + YAML
Projects and writing start as content files, not duplicated records for each interface.
Read the complete pipeline
- Markdown + YAML
- Projects and writing start as content files, not duplicated records for each interface.
- Vite plugin
- The plugin reads content and frontmatter and emits the virtual:content data module.
- Shared exports
- src/data.ts re-exports the generated data for the website and IDE views.
- Prerendered HTML
- vite-react-ssg prerenders routes. A postbuild step writes the sitemap and 404 page.
02 / FIELD NOTESOne record, two presentations
The conventional site can turn a record into a project card. IDE mode can present that same record as a file in its explorer and content window. Those are different views of the data, not two separately authored versions.
Try changing the title or summary below. The card and file-like view both use your input. Reset brings back the example. This demonstration updates local browser text only: it does not write a Markdown file, save to MRoot, or run the build plugin.
EDIT ONE LOCAL RECORD
Two views. One source.
WEBSITE PRESENTATION
A portfolio, two ways
A shared content collection, presented as a website and an IDE-style interface.
ILLUSTRATIVE PROJECT CARDtitle: A portfolio, two ways02summary: A shared content collection, presented as a website and an IDE-style interface.03# Same data. Different rendering.This example stays in this page’s memory. Nothing is saved or sent.
The distinction also applies to the real site’s generated code previews. The original write-up says that the IDE project code window is derived from frontmatter, not from each project’s actual source. That can be a way to present metadata, but it should not be mistaken for a genuine implementation excerpt.
03 / FIELD NOTESA link should still identify the same work
The two modes share a URL space. In the documented implementation, a router pathname maps to an identifier the IDE understands.
The excerpt below shows the project-path rule, along with a lookup for static routes and a fallback:
export function routeToIdeId(pathname: string): string {
const path = pathname.replace(/\/+$/, '') || '/';
if (path in STATIC_ROUTES) return STATIC_ROUTES[path];
const projectMatch = path.match(/^\/projects\/([^/]+)$/);
if (projectMatch) return 'proj:' + projectMatch[1];
return 'readme';
}For example, the project-path branch turns /projects/atlas-market into proj:atlas-market. The function also strips trailing slashes before matching.
The excerpt does not include the contents of STATIC_ROUTES. The local path demonstration therefore illustrates only the shown project-pattern branch and the readme fallback; it does not reconstruct the missing static-route table or verify which projects exist.
PROJECT-PATH MAPPING
The link identifies the work.
The project-path branch removes trailing slashes, then prefixes the slug with proj:.
IDE mode itself is a preference stored in localStorage, so the choice can persist across pages and reloads. That preference is separate from the pathname that identifies the work.
04 / FIELD NOTESPrerender the pages, then deploy
The original build uses vite-react-ssg to prerender each route to HTML. A postbuild step writes the sitemap and 404 page, and the site deploys to Cloudflare Pages on push.
During development, the server watches content/. Editing a Markdown file updates the explorer, writing index, and command palette through that shared pipeline.
Those details describe the build and development process in the published account. The animation on this page is a walkthrough of the stages—not a live build log or deployment control.
05 / FIELD NOTESWhat I would improve
First, make the source of code previews unmistakable. The original project windows were generated from metadata. Showing a real, selected excerpt per project was the improvement identified in the write-up.
Second, split the large App.tsx view-model by presentation. The shared content does not require every view’s state and behavior to be gathered into one object.
Third, test the content plugin. The original account had no automated test around it. A frontmatter schema check was proposed to catch mistakes before they reach the build. This article does not claim that validation or test coverage has since been added.
Source, dates, and what this page verifies
This is an editorial rewrite of the supplied project and technical article, describing the account published June 27, 2026. Original dates, code excerpts, and unfinished work are retained. The production repository, permissions, costs, and historical measurements have not been re-audited.
Interactive figures are local explanations. They do not call an API, send input, create content, or demonstrate production test coverage. The cumulative reference is not deployed.