Answers to questions new contributors and self-hosters ask most often. For deeper setup detail, see DEVELOPMENT.md and the Self-Hosting Guide.
- Go to GitHub → Settings → Developer Settings → OAuth Apps and create a new OAuth App.
- Set the Authorization callback URL to:
- Local dev:
http://localhost:3000/api/auth/callback/github - Production:
https://<your-domain>/api/auth/callback/github
- Local dev:
- Copy the generated Client ID and Client Secret into
GITHUB_IDandGITHUB_SECRETin.env.local. - Make sure
NEXTAUTH_URLmatches the base URL you're running on, andNEXTAUTH_SECRETis set (generate one withopenssl rand -base64 32).
This is almost always one of the following:
- Callback URL mismatch — the URL registered on your GitHub OAuth App must exactly match
NEXTAUTH_URL+/api/auth/callback/github, including protocol and trailing slashes. - Missing/incorrect
NEXTAUTH_SECRET— sessions will silently fail without it. - Stale
.env.local— restartpnpm devafter changing any auth-related env vars; Next.js doesn't hot-reload env files. - Supabase RLS blocking the user row — check that the relevant migrations from
supabase/migrations/have been applied in order.
If the issue persists, check your browser console and terminal logs for the specific NextAuth error code, then search/open a Discussion.
- Create a free project at supabase.com.
- Open Project Settings → API.
- Copy:
- Project URL →
NEXT_PUBLIC_SUPABASE_URL - anon public key →
NEXT_PUBLIC_SUPABASE_ANON_KEY - service_role key →
SUPABASE_SERVICE_ROLE_KEY(server-side only — never expose this in client code or commit it)
- Project URL →
- Run all SQL files in
supabase/migrations/via the Supabase SQL editor, in order, before starting the app.
- You're likely hitting GitHub's unauthenticated API rate limit. Set the optional
GITHUB_TOKEN(a personal access token) in.env.localto raise the limit significantly. - Check that your GitHub OAuth scopes were granted during sign-in — if you denied a permission, re-authenticate by signing out and back in.
- If you're self-hosting behind a proxy or firewall, confirm outbound requests to
api.github.comaren't being blocked. - Look at the server logs/terminal for the specific API error (403 usually means rate-limited; 401 means a token problem).
# Unit tests
pnpm test
# End-to-end tests (Playwright, first-time setup)
npx playwright install --with-deps chromium
pnpm run test:e2e
# Run a single e2e spec
npx playwright test e2e/goals.spec.ts
# Visual regression tests
npx playwright test -c playwright.visual.config.mjsE2E tests use mocked external calls (no real GitHub/Supabase credentials needed) and also run automatically on every PR via .github/workflows/e2e.yml.
- Browse open issues and start with one labeled
good first issue. - Comment on the issue to get assigned before starting work.
- Fork the repo, branch off
main(e.g.feat/issue-42-description), and open a PR. - Before pushing, make sure CI passes locally:
pnpm run lint && pnpm run type-check - See CONTRIBUTING.md for commit message style, branch naming conventions, and the review process.
Questions are welcome anytime in Discussions.
| Tool | Version | Check |
|---|---|---|
| Node.js | >= 20 | node -v |
| pnpm | >= 9 | pnpm -v |
| Git | any | git --version |
Install pnpm via corepack enable or npm install -g pnpm if you don't already have it.
If your local versions differ and you hit install/build errors, aligning your Node.js/pnpm version with the table above is the first thing to check.
DevTrack ships a Playwright-based end-to-end suite covering the full user journey — OAuth sign-in, dashboard rendering, and API correctness. No real credentials needed; all external calls are mocked via page.route().
| Spec file | Coverage |
|---|---|
e2e/auth.spec.ts |
Landing page, sign-in button, OAuth redirect, unauthenticated redirects |
e2e/dashboard.spec.ts |
All 6 dashboard widgets render after mock login, no console errors |
e2e/goals.spec.ts |
Goal create/delete lifecycle with API payload verification |
e2e/streak.spec.ts |
Streak values display, freeze button triggers API call |
e2e/api.spec.ts |
Auth-gated API routes return 200/401 correctly |
The test server is configured in playwright.config.mjs and auto-starts on http://127.0.0.1:3002 with placeholder credentials — no .env.local required.
Visual regression baselines are stored in tests/snapshots/. Use the same Linux/Chromium environment as CI to avoid OS-specific rendering differences. The suite uses a 1280x720 viewport and fails at >0.1% pixel difference:
# Run visual regression tests
npx playwright test -c playwright.visual.config.mjs
# Update baselines
npx playwright test -c playwright.visual.config.mjs --update-snapshots