Skip to content

Architecture

Lavesh Paryani edited this page Sep 26, 2026 · 1 revision

Architecture

Monorepo layout

The repository is an npm workspaces monorepo. The root package.json declares apps/* and packages/* as workspaces.

apps/web/                 the Next.js website
  app/                    App Router routes (one folder per URL)
  components/             navbar, footer, deposit popup, Discord button
    sections/             page sections (hero, account types, markets, FAQ, partners, ...)
    ui/                   UI and animation components (cards, carousels, backgrounds, header)
  lib/base-path.ts        base path helpers for GitHub Pages
  lib/utils.ts            re-exports cn() from the utils package
  public/                 logo, hero videos, screenshots, images
packages/ui/              shared components: Button, Card, Accordion, Badge, NeonButton
packages/types/           shared types: AccountType, TradingPlatform, Market, TrustMetric
packages/utils/           cn() helper (clsx + tailwind-merge)
packages/config/          shared tsconfig.json and Tailwind config
.github/workflows/        deploy.yml ("Multi-Tier Deployment")

The workspace packages use the @crimsonfx/* scope (for example @crimsonfx/ui). This is an internal package name only; the product is Restro FX. apps/web/tsconfig.json maps the scope to the package folders, extends @crimsonfx/config/tsconfig.json, and defines the @/* alias for the app root. next.config.js lists the shared packages in transpilePackages so they can ship TypeScript source without a separate build step.

Rendering model

  • Every route is pre-rendered at build time (output: 'export', trailingSlash: true). There is no Node server, no API routes and no middleware.
  • Dynamic routes list their pages in generateStaticParams(): account-types/[slug] builds raw, ecn-standard-default and powerup, and partners/[slug] builds solo-e-tv. A new slug must be added there or it will not exist in the export.
  • Interactive pieces are client components ("use client"), mostly for Framer Motion animations, the deposit popup and the portal redirects.
  • images.unoptimized is on, because the Next.js image optimizer needs a server.

Base path handling

The same code is built twice with different base paths:

Branch BASE_PATH / NEXT_PUBLIC_BASE_PATH ASSET_PREFIX
dev (GitHub Pages) /RestroFX /RestroFX/
main (Hostinger) empty empty

next.config.js reads BASE_PATH and ASSET_PREFIX. Raw references to files in public/ (the logo, hero videos and next/image sources) go through withBasePath() in lib/base-path.ts, which reads NEXT_PUBLIC_BASE_PATH. next/link applies the base path on its own. Hardcoding /RestroFX in a component breaks the main build.

Styling

Tailwind CSS is configured in apps/web/tailwind.config.ts, with design tokens as CSS variables in app/globals.css. The content globs include packages/ui, so classes used in shared components are generated. Class names are merged with cn().

Third-party services

The root layout (app/layout.tsx) loads Google Tag Manager, Google Analytics 4 (through @next/third-parties) and the Meta Pixel. Partner pages embed YouTube videos. All account actions (register, log in, deposit) link out to portal.restrofx.com, which is a separate system.

Clone this wiki locally