Global Mangrove Watch (GMW) is an online platform that provides remote sensing data and tools for monitoring mangroves. It gives universal access to near real-time information on where and what changes there are to mangroves across the world, and highlights why they are valuable.
- Next.js (Pages Router) — framework
- React 18 — UI library
- TypeScript — type safety
- Tailwind CSS v4 — styling
- Recoil — client state management (URL-synced)
- React Query (
@tanstack/react-queryv4) — server state & data fetching - Mapbox GL JS v3 via
react-map-glv7 — map rendering - Recharts — charts & data visualization
- Radix UI — accessible UI primitives
- NextAuth v4 — authentication
- Transifex Native — internationalization (en, fr, es)
- Playwright — end-to-end testing
- Node.js 22 (see
.nvmrc) - pnpm 10.x
- Clone the repository
- Use the correct Node.js version:
nvm use
- Install dependencies:
pnpm install
- Copy the environment file and fill in the required values:
cp .env.default .env
- Start the development server:
pnpm dev
The app will be available at http://localhost:3000.
pnpm dev # Start dev server (port 3000)
pnpm build # Production build
pnpm lint # Run ESLint
pnpm check-types # TypeScript type checking
pnpm test # Run Playwright end-to-end tests
pnpm test-ui # Run Playwright tests with interactive UIRun a single Playwright test:
npx playwright test tests/navigation.spec.tssrc/
├── pages/ # Next.js pages (catch-all route at [[...params]].tsx)
├── containers/
│ ├── datasets/ # Widget-specific code (data hooks, charts, map layers)
│ └── widgets/ # Widget system configuration & constants
├── components/ # Shared UI components
├── store/ # Recoil atoms organized by domain
├── services/ # API clients (Axios instances)
├── hooks/ # Shared React hooks
├── utils/ # Utility functions
├── types/ # TypeScript type definitions
└── styles/ # Global styles
cloud-functions/ # Google Cloud Functions (Node.js 22)
├── analysis/ # Geospatial analysis (habitat extent, net change, biomass)
├── alerts-tiler/ # Tile server for alert visualization
├── fetch-alerts/ # Deforestation alert data from Google Earth Engine
├── fetch-alerts-heatmap/
└── upload-alerts/
The app uses a catch-all route (src/pages/[[...params]].tsx) with these patterns:
/— worldwide view/country/:id— country view/wdpa/:id— protected area view/custom-area/:id— user-drawn area
Copy .env.default to .env for local development. Key variables:
| Variable | Description |
|---|---|
NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN |
Mapbox token (required for map rendering) |
NEXT_PUBLIC_VERCEL_ENV |
Controls API URL selection (development / staging / production) |
NEXT_PUBLIC_API_URL |
Backend API URL (staging) |
NEXT_PUBLIC_API_URL |
Backend API URL (production) |
NEXT_PUBLIC_ANALYSIS_API_URL |
Analysis cloud function URL |
NEXT_PUBLIC_BLOG_API_URL |
WordPress blog API URL |
NEXT_PUBLIC_PLANET_API_KEY |
Planet satellite imagery API key |
NEXT_PUBLIC_TRANSIFEX_API_KEY |
Transifex API key for i18n |
NEXT_PUBLIC_GA_ID |
Google Analytics 4 tracking ID |
NEXTAUTH_SECRET |
Secret for NextAuth session encryption |
NEXTAUTH_URL |
NextAuth base URL |
See .env.default for the full list.
This project uses Google Analytics 4 (GA4) via react-ga4. Analytics is initialized only when NEXT_PUBLIC_GA_ID is set. Custom events follow the trackEvent wrapper pattern with GA4-recommended structure.
The app is deployed on Vercel. Cloud functions are deployed independently via GitHub Actions on push to develop/master when their files change.
Playwright tests run automatically on PRs to develop (after the Vercel preview deploy completes).
Create a PR for any improvement or feature. Avoid committing directly to develop or master.
- ESLint flat config with Prettier integration
- Prettier: single quotes, trailing commas (es5), 100 char line width, Tailwind CSS plugin
- Pre-commit hook runs lint on staged files via lint-staged
Dependabot alerts are configured for this repository.
To check for production vulnerabilities:
pnpm audit --prodWhen a vulnerability is detected:
- Check if it affects production dependencies
- Try creating a Dependabot security update PR
- If automatic fixes fail, manually update the affected dependencies
