Skip to main content

Platform Architecture

This page describes how the Rhino Group Documentation Platform is structured, what technology it runs on, and how clients are auto-discovered.


Technology Stack

ComponentVersion / Detail
FrameworkDocusaurus 3.x (TypeScript config)
React18
TypeScript5.3
Node.js≥ 20
SearchTypesense 27.1 (self-hosted via Docker)
Web Servernginx on self-hosted VPS
AuthenticationHTTP Basic Auth (nginx level)
Scrapertypesense/docsearch-scraper Docker image

Auto-Discovery Multi-Client Model

Unlike a traditional Docusaurus multi-instance setup (where each instance is manually declared in config), this platform auto-discovers clients from the filesystem.

At build time, docusaurus.config.ts scans the clients/ directory and creates a plugin-content-docs instance for each client it finds. No config file changes are needed when adding a new client.

clients/
{client-slug}/
index.md ← Client landing page (slug: /)
{site-slug}/
_category_.json ← Label, position, collapsed state
intro.md ← Site root doc
{section}/
_category_.json
doc-page.md

Key Functions in docusaurus.config.ts

FunctionPurpose
buildClientDocsPlugin(slug)Creates a docs plugin instance for a client
slugToLabel(slug)Converts a slug to a display label (checks customClientLabels first)
customClientLabelsOverride map for slugs that don't title-case correctly (e.g. gsm-outdoorsGSM Outdoors)

URL Structure

/{client-slug}/                              → Client landing page
/{client-slug}/{site-slug}/ → Site root doc
/{client-slug}/{site-slug}/{section}/{page} → Individual doc page

Examples:

  • /scottsdale-mint/ → Scottsdale Mint landing page
  • /scottsdale-mint/retail/intro → Retail site documentation
  • /gsm-outdoors/middleware/features/orders-page → GSM Outdoors middleware feature doc

Directory Layout

docs/                                   ← Repository root
├── clients/
│ ├── gsm-outdoors/
│ │ ├── index.md
│ │ └── middleware/
│ ├── scottsdale-mint/
│ │ ├── index.md
│ │ ├── retail/
│ │ ├── dealers/
│ │ └── middleware/
│ └── rhinogroup/
│ ├── index.md
│ └── documentation/ ← This section
├── src/
│ ├── css/custom.css
│ ├── pages/index.tsx ← Homepage with client cards
│ └── theme/SearchBar/index.tsx ← Faceted search bar
├── plugins/
│ └── docsearch-meta-plugin/ ← Injects client/site meta tags
├── sidebars/
│ └── autogenerated.ts ← Shared sidebar config
├── typesense/
│ ├── config.json ← Scraper config
│ ├── docker-compose.yml ← Typesense server + scraper
│ └── scrape.sh ← Scraper runner script
├── scripts/
│ └── create-new-client-site.ps1 ← Client/site creation wizard
├── docusaurus.config.ts ← Auto-discovery config
└── Agents.md ← Project documentation

Sidebars are auto-generated from the filesystem using _category_.json files and sidebar_position frontmatter. There are no manually-maintained sidebar TypeScript files per client.

_category_.json

Each category directory contains a _category_.json that defines its label and position:

{
"label": "🚀 Getting Started",
"position": 2,
"collapsed": false
}

Each markdown file uses sidebar_position in its frontmatter to control ordering within its category:

---
sidebar_position: 1
id: overview
title: Architecture Overview
sidebar_label: Overview
---

Search Architecture

Search uses Typesense with faceted filtering by client and site:

  1. The docsearch-meta-plugin injects <meta name="docsearch:client_tag"> and <meta name="docsearch:site_tag"> into built HTML
  2. The scraper indexes these as faceted fields
  3. The swizzled SearchBar component provides client/site dropdown filters
  4. Filters are applied as filter_by parameters in Typesense queries

See Typesense Search for the full setup guide.


Build Pipeline

npm run build  →  build/  →  deploy to /var/www/html/

The docsearch-meta-plugin runs as a postBuild hook — it modifies the HTML after Docusaurus generates it, injecting client and site meta tags for the search scraper.

Documentation Site Architecture

This page describes how the Scottsdale Mint Documentation Portal is structured, what technology it runs on, and how the four independent documentation instances are wired together.


Technology Stack

ComponentVersion / Detail
FrameworkDocusaurus 3.x (TypeScript config)
React18
TypeScript5.3
Node.js≥ 18
SearchTypesense OSS (self-hosted)
Web ServerApache httpd on Amazon Linux 2023
AuthenticationHTTP Basic Auth (via Apache)
HostingEC2 — scottsdale.rhinogroup.com

Multi-Instance Docusaurus

Docusaurus supports running multiple independent documentation collections from a single site. Each instance has its own:

  • Content directory — where the markdown files live
  • Sidebar configuration — which pages appear and in what order
  • URL route prefix — the base path under which all pages in that instance are served

The four instances are:

scottsdale-documentation/
├── docs/ → serves at /retail/
├── middleware-docs/ → serves at /middleware/
├── dealers-docs/ → serves at /dealers/
└── documentation-docs/ → serves at /documentation/

The retail instance is configured as the preset-classic docs plugin. The other three are registered as separate @docusaurus/plugin-content-docs plugins in docusaurus.config.ts.

See Configuration Reference for the full config walkthrough.


Directory Structure

scottsdale-documentation/
├── docs/ # Retail docs content
├── middleware-docs/ # Middleware docs content
├── dealers-docs/ # Dealers docs content
├── documentation-docs/ # This section — docs about the docs site
├── src/
│ ├── css/custom.css # Global CSS (brand colours, table overrides)
│ └── pages/
│ ├── index.tsx # Homepage (hero + 4 category cards)
│ └── index.module.css # Scoped CSS for the homepage
├── static/
│ └── img/
│ ├── logo.png # Rhino Group logo (navbar)
│ └── favicon.ico
├── scripts/
│ └── update-docs.sh # EC2 deploy + Typesense re-index script
├── docusaurus.config.ts # Main site config
├── sidebars.ts # Retail sidebar
├── sidebars-middleware.ts # Middleware sidebar
├── sidebars-dealers.ts # Dealers sidebar
├── sidebars-documentation.ts # Documentation sidebar (this section)
├── typesense-scraper-config.json # Typesense DocSearch scraper config
└── AGENTS.md # Contributor and agent rules

Request Flow

Browser
└── HTTPS → scottsdale.rhinogroup.com (port 443)
└── Apache httpd
├── /typesense/* → ProxyPass → localhost:8108 (Typesense — no Basic Auth)
└── /* → /var/www/html (Docusaurus static files — Basic Auth required)

The Typesense /typesense path is intentionally exempted from HTTP Basic Auth so the browser-side search JavaScript can call it without credentials. See Typesense Search for details.


Build Pipeline

The site is a static site — there is no runtime server component. The build process compiles all markdown and React pages into plain HTML/CSS/JS in the build/ directory, which is then copied directly to /var/www/html.

npm run build  →  build/  →  cp -R build/* /var/www/html/

Builds are triggered manually by running update-docs.sh on the EC2 instance. There is no automated CI/CD for this repository.