How documents are structured
The editor separates configuration into two levels: the document as a whole and the individual sections inside it. That distinction matters because styles, scripts, variables, languages, and export behavior are scoped differently depending on the level.
Document level
At the document level you manage the shared configuration of the final HTML file: document title, exported file title, document language, logo, favicon, Open Graph fields, header and footer settings, color schemes, search, language switching, and other global options.
This is also where document-wide resources live: variables, supported content languages, custom styles, and custom scripts.
During export, document CSS is injected directly into the final file <head>, while document JavaScript is added before the closing </body>. That code runs globally and can affect every page, the menu, the header, the footer, and any element in the reading interface.
If the document includes external CSS or JS files, they are not embedded into the HTML. They are linked as normal <link> and <script src> tags. This is useful for CDNs and analytics, but those files still depend on network access and a stable external URL.
Document CSS and document scripts can be minified during export. The code is not executed inside the editor the same way it runs in the exported file, so final behavior should be verified in the exported HTML.
Section types
page is the default section type for content that should open directly inside the document: instructions, explanations, onboarding, release notes, tutorials, policies, knowledge base articles, and any page with text, images, examples, search, generated table of contents, local styles, section scripts, and multilingual filtering.
link is not for storing content. It is for routing the reader somewhere else. Use it when the destination should open by URL: an external site, external documentation, a support page, GitHub, a form, a separate service, or another document.
related is for reusing a shared page section in multiple places. Use it when the same page should appear in several documents: shared setup instructions, requirements, a security block, common integration conditions, FAQ content, or a standard onboarding page. You update the source once, and related sections inherit the same content, section styles, section scripts, and table-of-contents behavior.
api is for structured C# API reference: namespaces, classes, structs, interfaces, records, enums, delegates, constructors, methods, properties, indexers, fields, method parameters, and XML summaries. Use it for SDKs, libraries, internal platforms, game tools, and plugin APIs where the reference should be generated from source and kept aligned with the codebase.
dynamic is for an embedded JSON source that defines a root page, nested pages, and reusable Base64 resources. Each page can use html or markdown content. The exported viewer builds those pages at runtime. Resources are referenced as res://resource-id; external JSON and external page resources are not supported.
Preparing an API Section
An API section in One File Docs accepts JSON. The workflow is straightforward: extract the API description from C# source files into a JSON file, then upload that file into a section of type api.
Two related tools cover that workflow:
- CSharpApiExtractor is the core Roslyn-based extractor that scans
.csfiles and produces a JSON description of the public API. - CSharpApiExtractorGUI is a desktop GUI wrapper around the same extraction workflow, intended to make manual export easier and more convenient across multiple projects.
CSharpApiExtractor reads .cs files directly, does not require parsing a .csproj, takes summaries from /// comments, and builds JSON for the public API. It also collects undocumented items into a separate MissedItems list, which helps track reference documentation quality.
Choose CSharpApiExtractor for automated generation: CI/CD, regular releases, multiple packages, and workflows where the JSON should stay in sync with the code.
Choose CSharpApiExtractorGUI for manual work: infrequent updates, one-off exports, multiple project configurations, and cases where generating the JSON through a desktop interface is simpler.
When API reference is only one part of the overall document, keep the structured reference in an api section and place guides, tutorials, migration notes, and integration walkthroughs in regular page sections next to it.
Section structure
Sections form a tree. Each section has a title, an internal ID, a type, a position in the hierarchy, and optionally a parent section. The exported file uses those IDs to build page paths and anchors.
A section can be hidden from the menu without being removed from the document, or excluded from export entirely. If a parent section is excluded from export, its descendants are omitted as well.
In multilingual documents, a section can target a specific language or stay on all. The exported file then shows only the pages that match the currently selected language.
Internal linking
Internal links are built from section ID values and anchor id values inside the page content. Because of that, start by making sure the target page has a clear and stable section ID in the section settings.
To link to another section, use a normal link with a hash route such as #section-id. If the target section is nested, the route becomes #parent-id/child-id.
If the link should open a page and jump to a specific spot inside it, append the anchor after the section path: #section-id/anchor-id or #parent-id/child-id/anchor-id.
You can create that anchor in several ways: add an id to a heading or another HTML element manually, insert an anchor in the visual editor, or enable generated table of contents so the exported file assigns id values to h1, h2, and h3 headings automatically.
In practice, a link like #installation opens the section page, while #installation/system-requirements opens the same page and scrolls the exported file to the system-requirements anchor.
You can place that link directly inside a page section through the standard link dialog. If you need a dedicated menu item, create a link section and use the same internal hash URL in its URL field.
Document styles and scripts
Document-level custom code is meant for shared rules: brand colors, typography, reading interface UI overrides, global event handlers, analytics counters, integrations, and reusable helper code.
This code is injected after the exported file itself is assembled. Because of that, document CSS can override built-in One File Docs styles, and document scripts can access the global JavaScript API through window.OneFileDocsViewer.
Document CSS and scripts also support document variables and template conditions. If the code contains {{productName}} or template blocks such as {% if productName %}...{% endif %}, those values are resolved before the code is written into the exported HTML.
Section styles and scripts
Each section can define its own CSS, JavaScript, and lists of external CSS and JS files. These settings only affect the exported file and are scoped to that section rather than the whole document.
Section CSS behaves like an active stylesheet for the current page. When a section is opened, the exported file writes its CSS into a dedicated <style id="active-section-custom-css"> tag. When the reader moves to another section, that content is replaced, and if the next section has no CSS the style tag is removed.
External CSS files for a section are loaded only while that section is active. When the page changes, the exported file removes the previous section stylesheet links and adds the new ones.
Section scripts run when the section is rendered. In practice, that means the same script runs again every time the reader opens that page. If the code adds event listeners, timers, or DOM nodes, it should be written to tolerate repeated execution and avoid duplicates.
External JS files for a section are also loaded dynamically when that page opens and removed again when the exported file switches to another section. This is useful when logic should exist only on one screen instead of the whole document.
While section scripts are running, the exported file emits start and finish events through its API. That makes it possible to connect analytics, debugging, or custom integrations to the moment a specific page is shown.
Practical guidance
- Use document custom code for behavior and styling that should exist across the whole HTML file.
- Use section custom code for logic that belongs to one specific page.
- If you need a self-contained offline result, avoid relying on external CSS and JS URLs.
- If a section script mutates the DOM, assume it may run again when the same section is reopened.
- If you want to reuse both content and behavior, move the source into a shared section and reference it through
related. - Custom styles and scripts are available on every plan and are applied during export.