The frame subject provides the foundational infrastructure for the docs.github.com application. It serves as the "spine" of the site, handling core Express server setup, middleware orchestration, shared React components, and fundamental utilities that don't belong to a specific subject.
This subject is responsible for:
- Server initialization and Express app creation
- Middleware orchestration across all subjects
- Context management (
req.contextobject building) - Shared React components (layouts, navigation, error pages)
- Fundamental utilities (path parsing, frontmatter validation, page data)
- Next.js integration and page routing
Philosophy: The preference is to move code into more specific subject folders when possible. Frame should contain only cross-cutting concerns that truly span multiple subjects or don't have a clear subject-specific home.
src/frame/
├── components/ # Shared React components (DefaultLayout, Link, article, page-header/footer)
├── lib/ # Core utilities (app.ts, page.ts, frontmatter.ts, path-utils.ts)
├── middleware/ # Express middleware pipeline and context builders
├── pages/ # Next.js pages directory (legacy)
├── stylesheets/ # Global CSS and SCSS
├── server.ts # Server entry point
└── start-server.ts # Server startup logic
lib/app.ts-createApp(): Creates and configures the Express application with all middlewarelib/warm-server.ts-warmServer(): Pre-loads pages, redirects, and site tree on startuplib/page.ts-Pageclass: Represents a content page with rendering and metadata methodslib/frontmatter.ts- AJV schema: Validates frontmatter structure for all markdown fileslib/path-utils.ts- Path parsing functions: Extract version, product, language from URLsmiddleware/index.ts- Orchestrates the full middleware pipeline across all subjectsmiddleware/context/context.ts-contextualize(): Initializes basereq.contextobjectmiddleware/find-page.ts- Locates the matching page in the site treemiddleware/render-page.ts- Renders page content and sends responsecomponents/DefaultLayout.tsx- Main layout wrapper for all pages
npm run dev
# Server starts at http://localhost:4000npm run test -- src/frame/testsThe middleware in middleware/index.ts executes in a specific order. Key stages:
- Connection management (timeout, abort handling)
- Security and headers (helmet, CORS)
- Language detection and context initialization
- URL normalization and redirects
- Page finding and subject-specific middleware
- Context enrichment (breadcrumbs, TOC, features)
- Page rendering
- Error handling
When adding middleware, consider:
- Does it belong in a specific subject? If so, add it there and import into
middleware/index.ts - Where does it fit in the pipeline order?
- Does it need to modify
req.context? - Add to
middleware/index.tsin the appropriate position
- Content files (
content/directory) parsed and loaded into pages - Data files (
data/directory) loaded for variables, features, versions - Frontmatter schema defines required/optional fields for all pages
- Express.js for HTTP server and middleware
- Next.js for some routing and SSR (transitioning away from pages/ directory)
- AJV for frontmatter validation
- Various subject middleware (versions, languages, redirects, etc.)
req.contextobject: Populated and passed to all downstream middleware and components- Site tree: Navigation structure built from content files
- Rendered HTML: Final page output sent to clients
Nearly every subject interacts with frame:
src/versions- Version detection and middlewaresrc/languages- Language detection and translationsrc/redirects- URL redirect handlingsrc/content-render- Markdown renderingsrc/landings- Landing page layoutssrc/learning-track- Learning track navigation
- Team: Docs Engineering
- Middleware pipeline complexity: Many middleware pieces interact, making debugging challenging
- Context object size:
req.contextaccumulates many properties across middleware - Mixed patterns: Some components are in
components/, others in subject folders - Legacy pages directory: Transitioning from Next.js pages/ to app/ router
- Moving from Next.js pages router to app router
- Refactoring subject-specific code out of frame when possible
- Consolidating similar patterns across middleware
Add code here only if:
- It's truly cross-cutting (used by 3+ subjects)
- It's fundamental infrastructure (server, middleware orchestration)
- No specific subject is a clear fit
Otherwise, prefer adding to a subject-specific directory.
- Extract subject-specific middleware to their own directories (e.g., move language detection middleware to
src/languages/middleware) - Extract redirect logic to
src/redirects/middleware - Extract version detection to
src/versions/middleware - Extract search-specific middleware to
src/search/middleware - Extract context object building to individual subjects