Files
unyo-web/CONTRIBUTING.md
2026-04-19 19:32:02 +01:00

9.2 KiB

Contributing to Unyo Website

Thanks for your interest in contributing! This guide covers how the project works, how to set up your environment, and how to make changes.

How the Project Works

Architecture

The site is a Docusaurus 3 application — a React-based static site generator. It produces two types of pages:

  1. Landing page (/) — a custom React page at website/src/pages/index.js with hand-written components (Hero, FeatureGrid, ScreenshotGallery) and a custom footer
  2. Documentation pages (/docs/*) — Markdown files in website/docs/ rendered by Docusaurus with a sidebar

Docusaurus provides:

  • The navbar (top bar with logo, "Docs" link, "GitHub" link)
  • The docs sidebar and previous/next navigation
  • Markdown rendering with MDX support
  • Static site generation via npm run build

The theme is forced dark mode (no toggle). All color customization lives in website/src/css/custom.css.

Build Pipeline

Markdown (.md) + React components (.js)
         ↓
    Docusaurus (Webpack 5)
         ↓
    Static HTML/CSS/JS (website/build/)
         ↓
    Docker (Node 20 build → Nginx Alpine serve)
         ↓
    Production (port 80)

Key Files

File What it controls
website/docusaurus.config.js Site metadata, navbar, theme config, presets
website/sidebars.js Documentation sidebar order
website/src/css/custom.css All theme colors and global styles
website/src/pages/index.js Landing page composition
website/src/components/*/ React components for the landing page
website/docs/*.md Documentation content

CSS Architecture

There are two layers of styling:

  1. Infima — Docusaurus's base CSS framework (ships with @docusaurus/preset-classic). Defines variables like --ifm-background-color, --ifm-color-primary, etc. under :root and html[data-theme=dark].

  2. custom.css — our overrides. Defines Unyo variables (--unyo-*) and overrides Infima variables (--ifm-*).

Important: Dark mode overrides must be in html[data-theme=dark] to match Infima's specificity. Rules in :root will be overridden by Infima's html[data-theme=dark] block since that selector has higher specificity than :root.

Component styles use CSS Modules (.module.css files) for scoped class names — no global pollution.

Landing Page vs Docs

  • The landing page does not use the Docusaurus footer. It has its own <footer> element in index.js styled by index.module.css. The Docusaurus footer is disabled by removing footer from themeConfig in docusaurus.config.js.
  • The docs pages use the Docusaurus sidebar, breadcrumbs, and pagination — styled by the global custom.css.

Setup

# Clone the repo
git clone https://github.com/K3vinb5/Unyo.git
cd unyo-page/website

# Install dependencies
npm install

# Start dev server
npm start

The dev server runs at http://localhost:3000 with hot reloading.

Adding New Documentation

Step-by-step

1. Create the Markdown file

Add a new .md file in website/docs/:

touch website/docs/my-topic.md

2. Add frontmatter

Every doc file must have a title in its YAML frontmatter. Optionally add slug to customize the URL:

---
title: My Topic
slug: /custom-url
---

# My Topic

Your content here...

Without a slug, the URL will be /docs/my-topic (derived from the filename).

3. Add to the sidebar

Open website/sidebars.js and add the filename (without .md) in the position you want it to appear:

const sidebars = {
  docs: [
    'intro',
    'installation',
    'getting-started',
    'extensions',
    'my-topic',       // <-- add here
  ],
};

The order in this array determines:

  • The sidebar navigation order
  • The "Previous" / "Next" links at the bottom of each doc page

4. Create content

Docusaurus supports standard Markdown plus MDX (Markdown with JSX). Some features:

Admonitions (callouts):

:::tip
Helpful tip here
:::

:::info
Informational note
:::

:::caution
Warning about potential issues
:::

Code blocks with syntax highlighting:

```bash
npm install
```

Tables:

| Column 1 | Column 2 |
|----------|----------|
| Value 1  | Value 2  |

Internal links — use relative paths within docs:

See the [installation guide](./installation) for setup instructions.

External links — use full URLs:

Check the [Unyo repo](https://github.com/K3vinb5/Unyo) for source code.

Images — place in website/static/img/ and reference with absolute paths:

![Screenshot](/img/screenshots/home.png)

5. Verify

cd website
npm start
# Navigate to http://localhost:3000/docs/my-topic

Modifying the Landing Page

Hero Section

Files: website/src/components/Hero/index.js and styles.module.css

  • Mascot image: website/static/img/mascot.png
  • CTA buttons: "Get Started" links to /docs, "GitHub" links to the repo
  • Animations: CSS keyframes for fade-in, slide-up, floating mascot

Feature Grid

Files: website/src/components/FeatureGrid/index.js and styles.module.css

  • Features are defined as a JS array of objects (title, description, icon)
  • Icons are inline SVGs — edit them directly in the component
  • Cards use staggered animation on intersection (CSS animation-delay)

Files: website/src/components/ScreenshotGallery/index.js and styles.module.css

  • Screenshots array is defined in the component
  • Add/remove by editing the screenshots array
  • The center slide scales to full size (scale(1)) while side slides are dimmed (0.88 scale, 0.65 opacity)
  • Clicking opens a lightbox

The landing page footer is defined directly in website/src/pages/index.js (not using Docusaurus's footer system). Styles are in website/src/pages/index.module.css.

Modifying the Theme

All color changes go in website/src/css/custom.css. The file is organized into sections:

  1. CSS Variables (:root and html[data-theme=dark]) — all color definitions
  2. Global styles — html, body, ::selection
  3. Navbar — .navbar, .navbar__title, .navbar__link
  4. Sidebar — .theme-doc-sidebar-container, .menu__link
  5. Docs pages — .theme-doc-markdown (headings, links, code, tables, blockquotes)
  6. Breadcrumb — .breadcrumbs__link
  7. Pagination — .pagination-nav__link
  8. Search — .DocSearch-Button
  9. Mobile menu — .menu--show

Adding a New Color Variable

  1. Add it to :root with the --unyo- prefix:

    :root {
      --unyo-new-color: #ff6600;
    }
    
  2. Use it anywhere:

    .my-element {
      color: var(--unyo-new-color);
    }
    

Overriding an Infima Variable

Infima variables must be overridden in the html[data-theme=dark] block — not in :root. This is because Infima defines its dark theme under html[data-theme=dark], which has higher specificity than :root.

html[data-theme=dark] {
  --ifm-background-color: #0d0a1a;  /* overrides Infima's #1b1b1d */
}

Building and Deploying

Local Build

cd website
npm run build

The static site is output to website/build/.

Docker Build

docker compose up --build

This runs the full multi-stage build:

  1. Node 20 Alpine installs deps and builds the Docusaurus site
  2. Nginx Alpine serves the static files

The container exposes port 80 by default.

Changing the Domain

Edit website/docusaurus.config.js:

url: 'https://your-domain.com',

Then rebuild.

Common Tasks

Task How
Add a new doc page Create .md file in website/docs/, add to sidebars.js
Reorder docs sidebar Edit the array in website/sidebars.js
Change navbar items Edit themeConfig.navbar in docusaurus.config.js
Change theme colors Edit variables in website/src/css/custom.css
Add a screenshot Put image in website/static/img/, reference as /img/filename.png
Update the mascot Replace website/static/img/mascot.png
Update the logo Replace website/static/img/logo.png (also referenced in docusaurus.config.js)
Run dev server cd website && npm start
Production build cd website && npm run build
Docker deploy docker compose up -d --build

Gotchas

  • Webpack compatibility: The project pins webpack@^5.99.0 in package.json because newer versions (5.106+) break Docusaurus's webpackbar ProgressPlugin. Do not upgrade webpack without testing the build.
  • Dark mode only: The colorMode.disableSwitch: true config removes the theme toggle. All CSS variables must work in dark mode.
  • Footer is disabled: The Docusaurus default footer (themeConfig.footer) is intentionally removed. The landing page has its own footer. If you want a footer on docs pages, add footer back to themeConfig and style it in custom.css.
  • html[data-theme=dark] specificity: Infima dark theme overrides must go under html[data-theme=dark] in custom.css, not :root. Otherwise Infima's dark variables will win.
  • slug: / on intro.md: The intro doc uses slug: / which makes it accessible at /docs/ instead of /docs/intro. Links to it should use /docs not /docs/intro.