Interactive storytelling platform for The New Humanitarian (TNH). This codebase powers data-driven visualizations, embeddable dashboards, and immersive editorial projects.
π Production: interactive.thenewhumanitarian.org
π§ͺ Preview/Staging: preview.thenewhumanitarian.org
This SvelteKit application serves as TNH's platform for:
| Category | Technology |
|---|---|
| Framework | SvelteKit with Svelte 5 |
| Styling | Tailwind CSS |
| Maps | Mapbox GL JS |
| Charts/Data | D3.js |
| Animations | GSAP |
| CMS | Storyblok |
| Hosting | Vercel |
| Node Version | 22.17.0 (via NVM) |
| Package Manager | Yarn |
# 1. Clone the repository
git clone <repository-url>
cd tnh-storytelling-sveltekit
# 2. Use the correct Node version
nvm use
# 3. Install dependencies
yarn install
# 4. Set up local SSL certificates (see HTTPS Setup below)
# 5. Start development server
yarn dev
The dev server runs at https://localhost:5173 with HTTPS enabled.
The development server runs over HTTPS because the Storyblok Visual Editor requires a secure connection to load your local preview. Without HTTPS, the Visual Editor iframe will be blocked by the browser.
Generate certificates with mkcert:
# 1. Install mkcert (macOS)
brew install mkcert
mkcert -install
# 2. Generate certificates for localhost
cd cert/
mkcert localhost
# 3. Rename to match expected filenames
mv localhost.pem localhost.pem
mv localhost-key.pem localhost-key.pem
The Vite config (vite.config.ts) expects these files at:
cert/localhost.pemcert/localhost-key.pemπ‘ Tip: If you see browser warnings about untrusted certificates, run
mkcert -installto add the local CA to your system trust store.
Create a .env file in the project root:
# Public (exposed to client)
PUBLIC_BASE_URL=https://interactive.thenewhumanitarian.org
PUBLIC_GA4_ID=G-XXXXXXXXXX
# Private (server-side only)
GA4_API_SECRET=your-ga4-api-secret
tnh-storytelling-sveltekit/
βββ src/
β βββ lib/
β β βββ assets/ # Project-specific images & media
β β βββ components/ # Reusable Svelte components
β β β βββ animations/ # Animation utilities
β β β βββ gaza-map/ # Gaza dashboard components
β β β βββ icons/ # Logo, share icons
β β β βββ projects/ # Project-specific components
β β β β βββ LebanonDisplaced/
β β β β βββ SyriaMap/
β β β βββ vendor/ # Third-party libraries (TimelineJS)
β β βββ data/ # Cached data (JSON, GeoJSON)
β β βββ stores/ # Svelte stores
β β βββ utils/ # Helper functions
β βββ routes/ # SvelteKit routes
β β βββ api/ # API endpoints
β β βββ dashboard/ # Admin dashboard
β β βββ embeddable/ # Embeddable widgets
β β β βββ map/ # Map projects (Gaza, Syria)
β β β βββ sharepoint/ # Social embeds
β β β βββ timeline-x/ # Timeline embeds
β β βββ login/ # Authentication
β β βββ stories/ # Long-form narratives
β βββ stories/ # Storybook stories
βββ static/ # Static assets & legacy projects
β βββ scripts/ # Embeddable scripts
βββ scripts/ # Build-time data fetching
βββ cert/ # Local SSL certificates
βββ .nvmrc # Node version (22.17.0)
| Command | Description |
|---|---|
yarn dev |
Start development server with HTTPS |
yarn build |
Pre-fetch data and build for production |
yarn preview |
Preview production build locally |
yarn pre-fetch-data |
Fetch all project data (orchestrator) |
yarn pre-fetch-gaza |
Fetch Gaza map data only |
yarn check |
Run Svelte type checking |
yarn lint |
Run ESLint and Prettier |
yarn format |
Format code with Prettier |
yarn storybook |
Launch Storybook on port 6006 |
yarn build-storybook |
Build static Storybook |
Route: /embeddable/map/2025-09/gaza
Live: interactive.thenewhumanitarian.org/embeddable/map/2025-09/gaza
Interactive map and timeline showing incidents involving aid seekers in Gaza. Features:
Route: /stories/2025/05/22/lebanon-displacement-diaries
Live: interactive.thenewhumanitarian.org/stories/2025/05/22/lebanon-displacement-diaries
Immersive long-form narrative with:
/ar)Route: /embeddable/map/2024-11/syria
Live: interactive.thenewhumanitarian.org/embeddable/map/2024-11/syria
Interactive map of Syria with populated places data.
Route: /embeddable/timeline-x/[sheetId]
Dynamic timelines powered by Knight Lab's TimelineJS, configured via Google Sheets.
This codebase consolidates projects from a previous Gatsby JS repository. Legacy static assets (HTML, CSS, JS, images) are hosted in the /static folder and served directly by Vercel.
These include older interactive pieces that were migrated to preserve their functionality without requiring a full rewrite. They are accessible via their original paths under the static directory.
The project is hosted on Vercel with automatic deployments:
| Branch | Environment | URL |
|---|---|---|
main |
Production | interactive.thenewhumanitarian.org |
preview |
Staging | preview.thenewhumanitarian.org |
| Feature branches | Preview | Auto-generated Vercel preview URLs |
main or preview branchpre-fetch-data.js to cache external dataadapter-vercelThe project uses a build-time data fetching system to cache external data sources.
See scripts/README.md for detailed documentation on:
Projects can be embedded on external websites using a simple script tag:
<!-- Gaza Dashboard Embed -->
<div id="gaza-aid-killings"></div>
<script src="https://interactive.thenewhumanitarian.org/embeddable/map/2025-09/gaza/embed" defer></script>
The embed script:
<div id="my-custom-id"></div>
<script
src="https://interactive.thenewhumanitarian.org/embeddable/map/2025-09/gaza/embed"
data-target="my-custom-id"
data-src="https://custom-source-url"
defer
></script>
Component development and documentation via Storybook:
yarn storybook
Opens at http://localhost:6006
| Project | URL |
|---|---|
| Gaza Aid Seekers Dashboard | /embeddable/map/2025-09/gaza |
| Gaza Spotlight Counter | /embeddable/map/2025-09/gaza/spotlight |
| Lebanon Displacement Diaries (EN) | /stories/.../lebanon-displacement-diaries/home |
| Lebanon Displacement Diaries (AR) | /stories/.../lebanon-displacement-diaries/ar/home |
| Project | URL |
|---|---|
| Year in Photos 2024 | /stories/2024/12/27/year-in-photos |
| Drawing Derna | /stories/2023/11/28/art-time-crisis-drawing-derna |
| WhatsApp Lebanon | /stories/2022/07/28/whatsapp-lebanon |
| DariΓ©n Gap Migration | /stories/2022/05/10/us-asylum-darien-gap... |
| Rohingya Camp Women | /stories/2021/12/21/bangladesh-rohinyga... |
| Drawing Syria's Trauma | /stories/2021/12/8/drawing-syrias-trauma |
| Mediterranean Migration | /stories/2021/11/17/mediterranean-migration-europe |
| A Decade of War in Syria | /stories/2021/a-decade-of-war-in-syria |
| Bangladesh Cyclone Amphan | /stories/2020/bangladesh-amphan... |
| Report | URL |
|---|---|
| Annual Report 2023 | /reports/2024/07/25/annual-report-2023 |
| Annual Report 2022 | /reports/2023/06/27/annual-report-2022 |
| Our Strategy | /reports/2022/12/05/our-strategy |
| Annual Report 2021 | /reports/2022/06/27/annual-report-2021 |
previewpreview for stagingmain for productionΒ© The New Humanitarian. All rights reserved.