Documentation Build
How are these docs implemented?
Docs-Only Build
My custom npm run docs script starts Next with FLAG_APP=false so /beck is rewritten to a 404 and the installed CareerChive application is not served.
Defined as a package.json script, npm run docs calls scripts/docs-dev.mjs, which starts the same next dev as npm run dev with FLAG_APP=false set on that process:
src/lib/flags.tsreads that environment variable asflags.app.src/proxy.tsrewrites/beckwhile that flag is off.next.config.tslistsFLAG_APPunder env so Next can send it to the browser.
Basics & Custom Theme
Documentation styles live in src/app/globals.css. The docs styles work together with:
next.config.ts registers remark-gfm (GitHub-flavoured markdown) and the custom Remark plugin remark-docs-syntax.mjs, which allows:
- Defining subtitle within a YAML frontmatter block.
- Using
:::fences for formatting content. - Using shortcodes:
{.lock}() /{.gear}() /{.select}(SELECT) /{.insert}(INSERT) /{.update}(UPDATE) /{.delete}(DELETE) /{.get}(GET) /{.post}(POST) /{.put}(PUT) /{.patch}(PATCH) /{.button}(button link) /{.blank}(target="_blank") /[text]{.smallcaps}(small caps)
The Remark plugin also pulls page metadata out of the paired content.mdx so page.tsx can import it:
title— The#heading, which informs the browser tab.DocsArticleshows it in the page header, and the article hides that first#.frontmatter— The YAML defined at the top of the page.subtitleis the line under that title.toc—##/###headings, including headings brought in from a snippet. Headings inside a callout or a tabset are left out.
next.config.ts also registers Rehype (HTML parsing and serialization) plugins:
rehype-docs-slug.mjsaddsidto each heading from its text so that anchor links are functional.rehype-docs-highlight.mjsrunsrehype-highlight(our themed syntax highlighting) with a small language set we use in the docs.
src/mdx-components.tsx runs last at render, swapping native MDX tags for custom styled ones, and registering the fence components so that they display correctly:
h1/h2/h3become.mdx-title/.mdx-heading/.mdx-subheadingprebecomesDocsCodeBlocktableis wrapped in.docs-table-wraplistays a list item, orDocsTaskItemfor- [x], which are interactive checkboxesDocsCalloutbecomes a callout boxDocsColumnsbecomes mobile-responsive columnsDocsTabsetbecomes a mobile-responsive tabbed or drop-down section
Documentation Pages
Landing Page
The main documentation landing page (/docs) lives at src/app/(site)/docs/page.tsx, and is built by React, not MDX and hides the sidebar navigation:
- A
.docs-indexwrapper styles the landing cards. - Card titles and subtitles come from each guide's
content.mdxthroughdocs-page-meta.ts.
This landing page:
- Reads
DOCS_NAV_SECTIONSfrom_nav/docs-nav-data.ts(sidebar navigation). - Renders
Installation/Guides/Reference/Internalas sections of cards, withInternalin a collapsible group.
Content Pages
Since every guide is wrapped in src/app/(site)/docs/(article)/layout.tsx, the per-page page.tsx defines the rest.
Articles feature a layout inspired by the CareerChive application interface.
DocsRail on the API Library (/docs/api) swaps the table of contents for DocsApiSearch.
API Library
The API Library is a hybrid page (src/app/(site)/docs/(article)/api/page.tsx) — it renders content.mdx, and that file mounts DocsApiExplorer within the article frame, a customized Scalar API explorer.
The explorer catalogs operations from a live PostgREST OpenAPI document. loadDatabaseOpenApi.ts fetches {NEXT_PUBLIC_SUPABASE_URL}/rest/v1/ with SUPABASE_SECRET_KEY so tables without an anon policy still appear. It then drops the docs chatbot tables and the functions that maintain them.
Live OpenAPI
- Caches the fetch (React
cache()plus a 60-second revalidate). The API Library loads it when the page,/docs/api/explorer, or/docs/api/catalogis opened. swaggerToOpenApi.tsturns the PostgREST document into OpenAPI 3.1.- After fetch it stamps the CareerChive API
infotitle and description, andapikeysecurity on every operation.serversare removed. typesToOpenApi.tsapplies thatapikeysecurity.apiCatalog.tsturns the same spec into the API search sidebar's tags and operations, using Scalar's tag anchors.
- Shared docs chrome only (search provider + chatbot). It does not fetch OpenAPI.
- On
/docs/api,DocsApiSearchloads the catalog and jumps the explorer to that tag or operation. Until the catalog arrives, the API search sidebar is empty.DocsNavstays the usual docs links. Scalar's own sidebar stays inside the explorer frame. On a narrow screen,DocsApiMobileNavopens that sidebar over the frame.
Scalar API Explorer
- Loads the
@scalar/api-referencebrowser bundle from/docs/api/scalar-standaloneinside/docs/api/explorer.api/content.mdxmounts that frame. - The explorer route inlines the OpenAPI document and follows the site light or dark theme.
- On a narrow screen the frame sets
data-layout="mobile", which hides Scalar's sidebar until the mobile API menu opens it.
- Turns Scalar's own theme off and injects
customCssthat remaps Scalar onto CareerChive tokens. - Hides Scalar's search bar. Search the API in the right sidebar filters the catalog and jumps the explorer.
- Hides the Models section (
hideModels). - Starts with every tag collapsed (
defaultOpenAllTags/defaultOpenFirstTagoff). Scalar's sidebar matches: section headings stay collapsed until that heading is opened. Click an operation to jump to that call. - Hides Test Request (
hideTestRequestButton).
Search & LLM Ingestion
Search opens the shared overlay powered by DocsSearch.tsx:
DocsSearchProviderloads/docs/search-indexthe first time Search opens. Until the index arrives the overlay shows Indexing…. The browser ranks that JSON with MiniSearch.searchTerms.tsexpands light English inflections at index and query time (managing↔manage), with prefix match and a bit of fuzzy room on longer terms. A heading outranks a title, which outranks the section name, which outranks the body.
What Gets Indexed
- Host pages only (
**/content.mdx);_snippetsare never rendered or indexed independently - Snippet imports are inlined into the host before flattening headings and body
- One overview chunk per page, plus one chunk per heading that has body text
- OpenAPI / Scalar operations are not returned in this search — only docs
.mdxfiles (including/docs/apiprose fromapi/content.mdx)
On the API Library page (/docs/api), the right sidebar is Search the API (DocsApiSearch), which filters tags and operations from /docs/api/catalog and jumps the explorer to that anchor.
Agents follow discover → fetch → cite against the same composed guides the user guide search uses.
/llms.txt
src/app/llms.txt/route.ts serves a plain-text catalog from buildLlmsTxt():
- One line per indexed guide with HTML and
.mdlinks - Grouped by nav section when available
- A short API pointer to
/docs/api(Scalar) — no OpenAPI schema dump
/docs/<slug>.md
next.config.ts rewrites /docs/:path*.md to the handler under src/app/(site)/docs/raw/:
- Each response is the composed markdown for that host (
#title, sections, inlined snippets). Unknown or opted-out slugs return404. - There are no mirrors of individual Scalar operations.
Accessibility
Along with checking pages with Chrome's Lighthouse accessibility audit, as part of pull request checks, a11y lint runs a spot check on all documentation pages to ensure they are somewhat accessible and any errors discovered are patched before deployment.