In this article, we will review the Docmost client file structure. This project’s frontend is built using React + Vite and has a monorepo architecture setup using NX.
We will be focusing on the client:
client
client folder contains the frontend code for the Docmost. It uses Mantine components.
Let’s pick a route and study how the files are organized in order to render that page in react.
We will focus on:
- Components structure 
- API Layer 
Page.tsx
I picked page route, this is the page that renders the editor as shown in the below image. I logged in Docmost cloud version and was on free trial at the time of writing this article.
How to locate this page in the client? I would start at the URL — https://myworkspace-665.docmost.com/s/general/p/home-page-t7i4wXav8l and check the routes configured in the client.
I found this in App.tsx L54 — L68.
<Route path={"/p/:pageSlug"} element={<PageRedirect />} />
<Route element={<Layout />}>
  <Route path={"/home"} element={<Home />} />
  <Route path={"/s/:spaceSlug"} element={<SpaceHome />} />
  <Route
    path={"/s/:spaceSlug/p/:pageSlug"}
    element={
      <ErrorBoundary
        fallback={<>{t("Failed to load page. An error occurred.")}</>}
      >
        <Page />
      </ErrorBoundary>
    }
  />
The route — /s/general/p/home-page-t7i4wXav8l this translates to s/:spaceSlug/p/:pageSlug.
I am suprised there is no lazy loading in App.tsx, I did create an issue suggesting this — Issue #1037
Page is imported from page/page.tsx.
Components structure
<div>
  <Helmet>
    <title>{`${page?.icon || ""}  ${page?.title || t("untitled")}`}</title>
  </Helmet>
  <PageHeader
    readOnly={spaceAbility.cannot(
      SpaceCaslAction.Manage,
      SpaceCaslSubject.Page,
    )}
  />
  <FullEditor
    key={page.id}
    pageId={page.id}
    title={page.title}
    content={page.content}
    slugId={page.slugId}
    spaceSlug={page?.space?.slug}
    editable={spaceAbility.can(
      SpaceCaslAction.Manage,
      SpaceCaslSubject.Page,
    )}
  />
  <HistoryModal pageId={page.id} />
</div>
These are the components rendered in the page.tsx
Helmet
Helmet is imported as shown below:
import { Helmet } from "react-helmet-async"
PageHeader
PageHeader is imported as shown below:
import PageHeader from "@/features/page/components/header/page-header.tsx";
FullEditor
FullEditor is imported as shown below:
import { FullEditor } from "@/features/editor/full-editor";
HistoryModal
HistoryModal is imported as shown below:
import HistoryModal from "@/features/page-history/components/history-modal";
API Layer
In this page.tsx, the following code snippet is found at L17–28
const { t } = useTranslation();
const { pageSlug } = useParams();
const {
  data: page,
  isLoading,
  isError,
  error,
} = usePageQuery({ pageId: extractPageSlugId(pageSlug) });
const { data: space } = useGetSpaceBySlugQuery(page?.space?.slug);
const spaceRules = space?.membership?.permissions;
const spaceAbility = useSpaceAbility(spaceRules);
usePageQuery
usePageQuery is imported as shown below:
import { usePageQuery } from "@/features/page/queries/page-query";
useGetSpaceBySlugQuery
useGetSpaceBySlugQuery is imported as shown below:
import { useGetSpaceBySlugQuery } from "@/features/space/queries/space-query.ts";
About me:
Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.
I am open to work on interesting projects. Send me an email at ramu.narasinga@gmail.com
My Github — https://github.com/ramu-narasinga
My website — https://ramunarasinga.com
My Youtube channel — https://www.youtube.com/@ramu-narasinga
Learning platform — https://thinkthroo.com
Codebase Architecture — https://app.thinkthroo.com/architecture
Best practices — https://app.thinkthroo.com/best-practices
Production-grade projects — https://app.thinkthroo.com/production-grade-projects
 





 
    
Top comments (0)