Frontend for the official Ergo website. SSR/SSG with Next.js, dynamic content from Strapi, internationalization with react‑intl, and a polished component library via Storybook.
- 🗺️ Table of contents
- 🚀 How it works
- ✅ Requirements
- 🔐 Environment variables
- ⚡ Quick start
- 🧰 Scripts
- 🐳 Docker
- 🗂️ Project structure
- 🌐 Data fetching (CMS)
- 🌍 Internationalization (react‑intl + FormatJS)
- 🚢 Deployment
- 🤝 Contributing
- Troubleshooting
- Framework and routing
- Next.js “pages” router (not the app router)
- Hybrid rendering: SSR for CMS‑backed pages (blog/news/etc.), SSG for static pages
- Styling
- SCSS stylesheets plus Tailwind utilities where appropriate
- Content
- Dynamic data (blog, news, ecosystem, categories…) comes from Strapi
- CMS base URL is provided via the
NEXT_PUBLIC_STRAPI_APIenv var
- i18n
- react‑intl with FormatJS extraction and compilation
- Extracted messages in
content/locales/, compiled runtime artifacts incontent/compiled-locales/
- Config and SEO
next-sitemap.config.jsfor sitemap generation (sitemaps also available underpublic/)public/robots.txtandpublic/sitemap*.xml
- Tooling
- Storybook for components
- ESLint/Prettier for consistency
- Lighthouse report included for perf reference (see
lighthouse-report.json)
- Containers & CI/CD
- Multi‑stage Dockerfile builds a small production image
entrypoint.shinjects the CMS URL into the built assets on container startcloudbuild.yamlfor Google Cloud Build pipelines
- Node.js 18.18+ (Node 20+ recommended)
- npm 9+
- Docker (optional, for containerized builds)
- The repo includes the necessary FormatJS CLI for i18n workflow
Create a .env file in the project root (a sample is present in the repo):
# Required: Strapi CMS base URL
NEXT_PUBLIC_STRAPI_API=https://ergo-platform-cms-nvbpfiue6q-ez.a.run.app
# Local Strapi example
# NEXT_PUBLIC_STRAPI_API=http://localhost:1337Notes
- This value is used both server‑side (SSR) and client‑side where needed.
- SSR pages will fail to load dynamic content if this is not set.
- Ensure Strapi CORS/public permissions are configured for the frontend origin(s).
# 1) Install
npm install
# 2) Run dev server (http://localhost:3000)
npm run devBuild and run the production bundle:
npm run build # runs i18n extraction + compilation, then next build
npm run start # serve the optimized production buildTip: Editing react‑intl copy? Re-run
npm run i18n(or a fullnpm run build) so compiled messages reflect your changes.
npm run dev— start Next.js in dev modenpm run build— extract/compile i18n, then Next.js buildnpm run start— start the optimized production servernpm run lint— run ESLintnpm run storybook— run Storybook at http://localhost:6006npm run build-storybook— build static Storybooknpm run extract:i18n— extract messages tocontent/locales/en.jsonnpm run compile:i18n— compile all locales tocontent/compiled-locales/
Build:
docker build -t ergo-web .Run (inject Strapi URL):
docker run -e NEXT_PUBLIC_STRAPI_API="https://ergo-platform-cms-nvbpfiue6q-ez.a.run.app" -p 3000:3000 ergo-webNotes
entrypoint.shreplaces a placeholder in built assets withNEXT_PUBLIC_STRAPI_APIat container startup, so always pass it todocker run.
.
├─ pages/ # Next.js routes (SSR/SSG)
├─ components/ # Reusable UI + layout
├─ styles/ # SCSS & Tailwind setup
├─ content/
│ ├─ locales/ # FormatJS extracted messages
│ └─ compiled-locales/ # Compiled runtime artifacts
├─ public/ # Static assets, robots.txt, sitemaps
├─ utils/ # Utilities (RSS, hooks, helpers)
├─ scripts/ # Project scripts (e.g., media)
├─ Dockerfile # Multi-stage production build
├─ entrypoint.sh # Injects Strapi URL at startup
├─ cloudbuild.yaml # Google Cloud Build
├─ next-sitemap.config.js # Sitemap config
└─ tailwind.config.js # Tailwind config
Server‑side fetches read from process.env.NEXT_PUBLIC_STRAPI_API. Common SSR pages include:
- Blog/news lists and details:
pages/blog.tsx,pages/news.tsx,pages/blog/[id].tsx,pages/news/[id].tsx
- Ecosystem & features:
pages/ecosystem.tsx, plus related components
- Categories/spotlights and more
Ensure the Strapi instance exposes the expected collections and that CORS/public permissions permit reads from this frontend.
- Write messages with
react-intlin pages/components. - Extract messages:
npm run extract:i18n
# -> content/locales/en.json (and other locales if present)- Compile messages:
npm run compile:i18n
# -> content/compiled-locales/npm run build runs both steps automatically before the Next.js build.
- Build a production Docker image in CI.
- Provide
NEXT_PUBLIC_STRAPI_APIfor each environment. - Run the container on your platform of choice (Cloud Run, Kubernetes, VM, …).
Sitemaps/SEO
- Sitemaps are configured via
next-sitemap.config.jsand also checked in underpublic/. public/robots.txtis included.
- PRs and issues welcome
- Run
npm run lintbefore submitting - If you change user‑facing copy, update i18n:
npm run extract:i18nthennpm run compile:i18n
- Consider updating/adding a Storybook story for component changes
logs from the latest revision of your service.
gcloud run services logs read ergo-platform-frontend --region europe-west4 --limit=50