Running the App Locally
This is a hands-on tutorial. By the end you'll have the app running on your machine, signed in, looking at live cameras. Each step ends with a checkpoint — if your screen matches, keep going; if not, the fix is right there.
Budget 15 minutes if you already have the env values, an hour if you're waiting on someone to send them.
Step 1 — Node 20
The app requires Node 20. Check first:
node --version
If that doesn't print v20.x, switch (with nvm: nvm install 20 && nvm use 20).
Checkpoint: node --version prints v20.something.
Step 2 — install and configure
npm install
Then create .env.local in the repo root. These values are per-environment secrets — ask your
team lead for a filled-in copy rather than hunting them down one by one:
NEXT_PUBLIC_API_DOMAIN= # the Frontend.API instance to talk to
NEXT_PUBLIC_ESRI_API_KEY= # ArcGIS basemaps
NEXT_PUBLIC_ENTRA_APP_ID= # sign-in
NEXT_PUBLIC_ENTRA_TENANT_ID=
NEXT_PUBLIC_ENTRA_API_APP_ID=
AUTH_MICROSOFT_ENTRA_THUMBPRINT= # cert-based auth — see step 3
NEXTAUTH_SECRET=
Checkpoint: .env.local exists and every line above has a value.
Step 3 — the signing certificate
Here's the step that surprises people: sign-in uses a certificate, not a client secret. The app proves its identity to Entra by signing a token with a private key — so without that key on disk, authentication cannot complete, no matter how correct your env values are.
Drop the key your team lead gives you at:
keys/dev/private_key.pem
Checkpoint: the file exists at exactly that path.
Skip this step and the app starts fine — then sign-in fails midway with
Token endpoint request failed. If you ever see that error, this file (or the
AUTH_MICROSOFT_ENTRA_THUMBPRINT that must match it) is the culprit.
Step 4 — run it
npm run dev
Open localhost:3000. You'll be redirected to a Microsoft sign-in immediately — that's expected. This app has no anonymous mode; there is nothing to see without an account.
Checkpoint: after signing in, you land on a map of California covered in camera pins, with a grid of camera tiles beside it.
When it doesn't work
Wrapping up
You have the app running and you've signed in like an operator does. Before you change anything, take twenty minutes to learn your way around the code: A tour of the codebase.