Layout System
Relevant source files
The following files were used as context for generating this wiki page:The Layout System in the railways-docs project is responsible for providing a consistent structure and appearance for all documentation pages. It is built using Next.js and React, integrating contentlayer for content processing from Markdown files. The system handles the main content display, side navigation, SEO metadata, and dynamic "On This Page" navigation.
The core of the system is the DocsLayout component, which wraps the MDX content. This layout is applied to pages generated both statically ([...slug].tsx) and dynamically via server-side rendering (dynamic/[...slug].tsx). It consumes front matter and raw Markdown content to provide a rich user experience, including features like "Copy as Markdown" and links to edit pages on GitHub.
Core Components and Architecture
The layout system is composed of several key components that work together to render a complete documentation page. The main entry points are the Next.js page files which fetch content and pass it to the layout components.
Component Hierarchy
The following diagram illustrates the hierarchy of components involved in rendering a documentation page.
This diagram shows that a Next.js page component (A) uses the mdxLayouts wrapper (B), which in turn renders the main DocsLayout (C). DocsLayout then orchestrates the rendering of the SEO component (D), the right-hand "On This Page" navigation (E), and the actual page content (F).
Sources: src/pages/[...slug].tsx:50-58, src/mdxLayouts/index.tsx:6-8, src/layouts/DocsLayout.tsx:112-125
Page Rendering Flow
There are two primary flows for rendering documentation pages: Static Site Generation (SSG) and Server-Side Rendering (SSR).
-
Static Site Generation (SSG): Used for most documentation pages.
getStaticPathsgenerates a list of all page URLs fromallPages(provided bycontentlayer).getStaticPropsfinds the specific page data for a given slug and passes thepageobject andrawMarkdownto thePostPagecomponent.- Sources: src/pages/[...slug].tsx:60-80
-
Server-Side Rendering (SSR) / Dynamic Rendering: Handled by
dynamic/[...slug].tsxand enabled bymiddleware.ts.- The middleware intercepts requests, and if the path corresponds to a known doc page, it rewrites the URL to
/dynamic/.... - It can also detect if the client prefers Markdown (via
Acceptheader or?format=mdquery param) and serves the raw content. getServerSidePropsfetches the page data and can either return it for rendering or write the raw Markdown directly to the response.- Sources: src/middleware.ts:1-33, src/pages/dynamic/[...slug].tsx:61-91
- The middleware intercepts requests, and if the path corresponds to a known doc page, it rewrites the URL to
The following diagram shows the data flow for a standard page request.
DocsLayout Component
This is the main layout component that structures the documentation pages.
Sources: src/layouts/DocsLayout.tsx
Properties
The DocsLayout component accepts the following props:
| Prop | Type | Description | Source |
|---|---|---|---|
frontMatter | FrontMatter | Contains title, description, and url for the page. | src/layouts/DocsLayout.tsx:21 |
rawMarkdown | string (optional) | The raw Markdown content of the page, used for the "Copy" feature. | src/layouts/DocsLayout.tsx:22 |
children | PropsWithChildren | The rendered MDX content to be displayed. | src/layouts/DocsLayout.tsx:65 |
Key Features
- SEO Integration: It uses the
SEOcomponent, passing front matter, extracted headers, and breadcrumbs to generate comprehensive metadata.
Sources: src/layouts/DocsLayout.tsx:113-122 - Content Display: It renders the main page title (
<h1>) fromfrontMatterand thechildren(MDX content) within a styleddiv.
Sources: src/layouts/DocsLayout.tsx:125-126 - "Copy as Markdown": A button that copies the full Markdown content of the page, including front matter, to the clipboard. This is implemented using the
useCopyhook.
Sources: src/layouts/DocsLayout.tsx:77-86, src/layouts/DocsLayout.tsx:128-136 - GitHub Edit Link: Automatically generates a link to edit the current page on GitHub based on the page's slug.
Sources: src/layouts/DocsLayout.tsx:72-75, src/layouts/DocsLayout.tsx:140-145 - Previous/Next Page Navigation: Calculates the previous and next pages based on a flattened list of all pages from
sidebarContentand renders navigation links at the bottom of the page.
Sources: src/layouts/DocsLayout.tsx:41-63, src/layouts/DocsLayout.tsx:88-96, src/layouts/DocsLayout.tsx:150-173 - "On This Page" Sidebar: Renders the
PageNavcomponent, which provides in-page navigation.
Sources: src/layouts/DocsLayout.tsx:176
PageNav Component
The PageNav component creates the "On This Page" sidebar, which dynamically builds a table of contents from the headings on the current page and highlights the active section as the user scrolls.
Sources: src/components/PageNav.tsx
Functionality
The component's lifecycle and user interaction flow can be visualized as follows:
- Header Extraction: On mount (and when the page
titleprop changes), it queries the DOM for allh2,h3, andh4elements within the.docs-contentcontainer.
Sources: src/components/PageNav.tsx:59-62 - Tree Building: The flat list of heading elements is processed by
buildHeaderTreeto create a nestedIHeader[]structure that respects the heading levels.
Sources: src/components/PageNav.tsx:29-56 - Scroll Tracking: An event listener on
windowtracks the scroll position. It determines which heading is currently in view and updates theactiveIdstate.
Sources: src/components/PageNav.tsx:67-82 - Active Link Highlighting: When
activeIdchanges, the corresponding link in thePageNavlist is re-rendered with active styles. The active link is also scrolled into view within the sidebar.
Sources: src/components/PageNav.tsx:84-90, src/components/PageNav.tsx:125-133
MDX and Content Rendering
The actual content of the pages is written in MDX and processed by contentlayer. The page components ([...slug].tsx and dynamic/[...slug].tsx) receive the compiled MDX code and render it using useMDXComponent.
Sources: src/pages/[...slug].tsx:38, src/pages/dynamic/[...slug].tsx:40
A set of custom components is provided to the MDX renderer, allowing authors to use rich UI elements directly in their Markdown files.
| Component | Description | Source |
|---|---|---|
Collapse | A collapsible section for hiding content. | src/pages/[...slug].tsx:19 |
Image | A custom image component. | src/pages/[...slug].tsx:20 |
Banner | A banner for displaying important messages. | src/pages/[...slug].tsx:21 |
CodeBlock | Renders code blocks with syntax highlighting. | src/pages/[...slug].tsx:44-46 |
InlineCode | Renders inline code snippets. | src/pages/[...slug].tsx:47-49 |
H2, H3, H4 | Custom heading components, likely for adding anchors or other features. | src/pages/[...slug].tsx:24-26 |
Anchor | A custom anchor (<a>) tag component. | src/pages/[...slug].tsx:23 |
TallyButton | A button for embedding Tally forms. | src/pages/[...slug].tsx:27 |
Summary
The Layout System provides a robust and feature-rich foundation for the Railway documentation site. By separating content (contentlayer, Markdown), page logic (Next.js pages), and presentation (DocsLayout, PageNav), it creates a maintainable and extensible architecture. Key features like automatic navigation, SEO optimization, and dynamic "On This Page" sidebars are handled centrally, allowing content creators to focus on writing clear and helpful documentation.