Minimal, fast, bilingual website for Trade Solutions with EN/BG route-localized content, theme toggle, geo-based locale redirect, live operational widgets (FX reference rates, futures strip, business window clocks), and a clean, structured layout.
- Next.js (App Router) + TypeScript
- Tailwind CSS
next-themes(class strategy)- Route i18n by segments:
/en,/bg
npm install
npm run devOpen http://localhost:3000.
- FX rates are fetched from the European Central Bank daily feed (SSR with
revalidate: 86400). - Displayed as a compact Market Pulse panel in the Hero.
- Graceful fallback message if rates are unavailable.
The futures strip supports two modes:
- If
BARCHART_API_KEY(or supported aliases) is present in runtime, the site fetches quotes via Barchart OnDemandgetQuote.json.
- If there is no API key, the strip reads
public/data/futures.json. public/data/futures.jsonis updated daily by GitHub Actions (.github/workflows/scrape-futures.yml).
Manual refresh:
npm run scrape:futures- Bilingual EN/BG content via route segments (
/en,/bg) - Theme toggle (light/dark) persisted via
next-themes - Geo locale redirect middleware:
- BG country =>
/bg - all others =>
/en
- BG country =>
- Hero module:
- editorial photo slider (crossfade + subtle motion)
- left editorial overlay copy + CTAs
- right Market Pulse panel (FX)
- Structured sections:
- Solutions / How we work / Facts strip
- Markets / Geography: map + interactive markers and list-driven highlighting
- Operational network: category social proof without partner logos
- Footer:
- world time micro-cards + business window status (updates regularly)
- SEO:
- localized metadata (title/description)
- Open Graph tags
sitemap.xml,robots.txt- JSON-LD Organization schema
- Keyboard focus states (
focus-visible) - ARIA labels on toggles where applicable
- Contrast-aware styling for both themes
- Reduced-motion friendly animation choices (where possible)
.
├── app
│ ├── [locale]
│ │ ├── brand
│ │ │ └── page.tsx
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ └── privacy
│ │ └── page.tsx
│ ├── globals.css
│ ├── robots.ts
│ └── sitemap.ts
├── components
│ ├── brand-gallery.tsx
│ ├── fx-ticker.tsx
│ ├── futures-strip.tsx
│ ├── live-clocks.tsx
│ ├── markets.tsx
│ ├── markets-map.tsx
│ ├── reveal.tsx
│ ├── site-footer.tsx
│ ├── site-header.tsx
│ ├── theme-provider.tsx
│ ├── theme-toggle.tsx
│ └── ts-logo.tsx
├── lib
│ ├── barchart.ts
│ ├── clocks.ts
│ ├── copy.ts
│ ├── ecb.ts
│ ├── futures-data.ts
│ └── i18n.ts
├── public
│ ├── assets
│ │ ├── bb
│ │ └── logos
│ └── data
│ └── futures.json
├── scripts
│ └── scrape-barchart-futures.ts
├── .github
│ └── workflows
│ └── scrape-futures.yml
├── middleware.ts
├── next.config.ts
├── package.json
├── tailwind.config.ts
└── tsconfig.json
Notes:
public/assets/bb/is used for brandbook-style assets (logos + mockups) on the Brand page.public/data/futures.jsonis the no-API-key data source for the futures strip.
BARCHART_API_KEY— enables Barchart OnDemand mode for futures quotes.- Supported aliases may be implemented for convenience (see
lib/barchart.ts).
- Supported aliases may be implemented for convenience (see
No env vars are required if you use the daily-updated public/data/futures.json mode.
Place brand assets here:
public/assets/logos/ts-logo-light.svgpublic/assets/logos/ts-logo-dark.svg
The header logo component (components/ts-logo.tsx) switches automatically by theme class.
If you prefer PNG variants, keep naming consistent and update paths in components/ts-logo.tsx.
npm i -g vercel
vercel login
vercel
vercel --prod- Push repo to GitHub.
- In Vercel, import the repository.
- Build settings:
- Build command:
npm run build - Output:
.next
- Build command:
- No analytics tools
- No marketing cookies
- Contacts via
mailtolinks only