For collaborators · Free to use

Collaborator
Onboarding

Everything you need to start contributing — whether you write code, verify histories in the archives, contact the occupants of former business addresses, or translate the site. You do not need to be a developer to help.
01

What this project is

One archive, served through several front doors. Knowing which piece your work touches is usually enough to find the code.

PieceWhat it doesWhere
Interactive mapTime-based visualisation of hundreds of businesses with active / declining / closed states/ · components/MapboxMap.tsx
Business directorySearchable, filterable listings synced with the mapcomponents/StoryList.tsx
Memorial plaquesPhysical plaque program for former business locations/plaques
Outreach trackerAdmin tool for tracking contact with current property occupants about plaques/admin/outreach
Museum exhibitTouch-screen kiosk version of the map/museum-exhibit · /exhibit-vision
Classroom workbookFree education materials for ages 13–18/education
Frankfurt pilotExtension of the model beyond Berlin/frankfurt
Collaborate pagePublic entry point for new collaborators/collaborate
02

Choose your track

You do not need to be a developer to contribute.

01 / Code

Build the platform

Next.js 16, React 19 and TypeScript work on the map, UI, themes and performance. Start with the development setup below, then the style and performance guides.
02 / Research

Verify the history

Verify business histories, dates and addresses, and process archival sources through the OCR pipeline in the repo-root Python scripts. Start with the dataset cleaning report and the geocoding guide.
03 / Outreach

Place the plaques

Contact the current occupants of former business addresses about memorial plaques, address by address, in a tracked pipeline. Read the outreach guide before your first message.
04 / Translation

Cross the languages

English, German, Yiddish and Hebrew localisation, right-to-left included. The strings live in src/i18n/.

Whatever your track, read the ground rules — they apply to everyone.

03

Development setup

Ten minutes from a clone to a map running locally.

  • Node.js 20+ — the project runs Next.js 16 and React 19.
  • pnpm — preferred; npm and yarn also work.
  • A Mapbox account — for a free API token.
  • Python 3.10+ — only if you are working on the data or scraping scripts.
Prerequisites installed? Then:
git clone https://github.com/samfrons/storytimemaps.git
cd storytimemaps
pnpm install

# Environment
cp .env.example .env.local   # or create .env.local manually
# Add: NEXT_PUBLIC_MAPBOX_TOKEN=your_token_here
# NEVER commit token values.

pnpm dev                     # http://localhost:3000

Verify your setup

  • The map loads at / without console errors.
  • The time slider changes business marker states.
  • Theme switching is instant. The default theme is brutal-pop; try ?theme=cool in the URL.
  • pnpm run build completes without errors.
04

Codebase map

The naming is consistent — components in PascalCase, hooks as useX, utilities in camelCase — so grep finds most things faster than a directory tree does.

Where things live
src/
  app/
    page.tsx              # Main map page (URL param handling — be careful here)
    layout.tsx            # ThemeProvider config — DO NOT change its settings
    globals.css           # Theme color definitions (CSS variables)
    components/           # All React components (PascalCase)
      outreach/           # Outreach tracker UI
    admin/outreach/       # Outreach admin page
    api/outreach/         # Outreach data API
    collaborate/          # Public collaborator page
  lib/types/outreach.ts   # Outreach data model
  i18n/                   # Translations (en/de/yi/he)
public/
  data/                   # All HTTP-served data files (timeline JSON, CSV)
docs/                     # Guides (theming, outreach, tasks, this file)

Key documents, in reading order:

05

Contribution workflow

  1. Claim a task

    Open a GitHub issue — or comment on an existing one — so that two people never do the same work. The task tracking guide explains where each kind of work is queued.
  2. Branch

    git checkout -b <type>/<short-description> — for example feat/plaque-filter.
  3. Develop

    Follow the ground rules below and the patterns of the components already in the file you are working near.
  4. Run the pre-commit checklist

    Everything in the checklist below has to pass before you commit. It is the same list the maintainer checks a pull request against.
  5. Commit

    Conventional commits: feat:, fix:, perf:, style:, refactor:, docs:.
  6. Open a pull request

    Describe what changed and which themes and pages you tested it on.

Pre-commit checklist

  • pnpm run build passes with no errors.
  • No TypeScript errors — npx tsc --noEmit.
  • No border-radius anywhere; every colour comes from a CSS variable.
  • All themes tested: brutal-pop (the default) plus moody, hot, cold, warm, cool, bauhaus, art-nouveau, archival and hoefe.
  • Components memoised; any page using useSearchParams() wrapped in <Suspense>.
06

Ground rules

The short version of CLAUDE.md. Where the two disagree, the full file wins.

RuleWhat it means
No rounded cornersSharp rectangular edges everywhere, unless explicitly asked for.
No hardcoded coloursAlways var(--variable). The only exception is Mapbox layer styling, which needs hex values — take those from the theme functions. Ten themes exist; brutal-pop is the default and doubles as the museum-exhibit kiosk palette.
No blue focus outlinesBuild custom focus states from border or background changes instead.
Do not touch the theme systemRead the theme rules in CLAUDE.md and the theming guide first.
TypographySpace Mono for data, labels and technical text; Inter for body copy.
PerformanceReact.memo() for components that receive props, useMemo for expensive work, scroll throttled to 100–150 ms, inputs debounced to 300–500 ms, heavy components dynamically imported.
SuspenseAny page touching useSearchParams() — including indirectly, through Sidebar — must be wrapped in a Suspense boundary, or the production build fails.
Static filesEverything served over HTTP lives in /public/. Nothing else is served at all.
07

Historical sensitivity

This is a memorial project. Every contributor, on every track, agrees to the following.

08

Getting help

  • Questions about rules or architecture: open a GitHub issue with the question label.
  • Project coordination and outreach access: contact the maintainer — the repo owner.
  • Where things are: grep is your friend. The codebase follows consistent naming throughout.

Welcome aboard — thank you for helping preserve this history.