- Next.js App Router
- React 19
- Tailwind CSS 4
- PixiJS + CreateJS for the DAG visualization
- Playwright for smoke testing
/landing page with the live DAG hero/loreprotocol overview and positioning/hodlwallets, exchanges, and on-ramp links/builddeveloper resources and API/SDK entry points
Install dependencies and start the dev server:
nvm use
npm install
npm run devOpen http://localhost:3000.
For LAN device testing, use:
npm run dev:lanThat starts next dev on the detected LAN IP and prints the device-reachable
URL. If auto-detection picks the wrong host, override it with
NEXT_DEV_HOST=192.168.1.50 npm run dev:lan.
The AI launcher is disabled by default. Leave
NEXT_PUBLIC_KASPA_AI_ENABLED=false while the ASK backend is unavailable. When a
replacement backend is ready, set it to true, set the ASK server key before
using chat locally or on web hosting, and set the public site origin used by
external AI links. A simple starting point is:
cp .env.example .env.localThen fill in the real values:
NEXT_PUBLIC_KASPA_AI_ENABLED=false
KASPA_NEWS_ASK_API_KEY=your_kaspa_news_partner_key
NEXT_PUBLIC_PUBLIC_SITE_ORIGIN=https://kaspa.orgWhen NEXT_PUBLIC_KASPA_AI_ENABLED is not set to true, the bottom launcher,
page-level AI buttons, suggested question pills, and ASK entry points are hidden.
The /api/ask route returns 503 without calling the upstream service.
KASPA_NEWS_ASK_API_KEY is a private server-side key for
https://kaspa.news/api/ask. Do not expose it through browser JavaScript,
NEXT_PUBLIC_* variables, or static frontend bundles.
NEXT_PUBLIC_PUBLIC_SITE_ORIGIN should point at a public site URL whose
/llms.txt file external AI tools can actually fetch.
NEXT_DEV_ALLOWED_ORIGINS remains available if you need to allow extra custom
development origins beyond the defaults used by npm run dev:lan.
The /api/ask route follows the current Kaspa.news partner API contract. It
posts server-side to https://kaspa.news/api/ask with op: "query",
question, stream: false, and mode: "knowledge", then returns the
non-streaming answer JSON to the browser. The upstream answer can include raw
HTML anchor tags in its source list; src/app/api/ask/answer.ts normalizes
http/https anchors into Markdown links before the client renders the response.
The route uses the Node runtime plus node:https for the upstream request
because Node/Next fetch adds browser-style fetch metadata that Kaspa.news
currently rejects on the private partner-key endpoint.
Run the repo checks locally before shipping changes:
npm run verifyTracked Git hooks now provide a lighter local safety net:
pre-commitrunslint-stagedon staged filespre-pushrunsnpm run verify
If you want to mirror CI more closely before a larger push, run:
npm run verify:fullThe smoke suite uses Playwright. Install Chromium once on a machine, then run:
npx playwright install chromium
npm run test:e2eHelpful Playwright commands:
npm run test:e2e:headed
npm run test:e2e:uiEvery locale registered in src/i18n/locale-registry.ts is included in the
build. Run the full translated-locale browser gate with:
npm run test:e2e:i18n:localesTo review a new translation, add and register it on its own branch, deploy that branch through Vercel Preview, and inspect every localized route on desktop and mobile. Merging the branch publishes the locale; there is no separate locale lifecycle or build mode.
Builds generate ignored localized Build-example siblings under
public/vendor/kaspa-wasm. After stopping a local server, remove those derived
files with:
npm run -s i18n:artifacts -- --cleanTo suggest a translation correction, volunteer as a translator or reviewer, or request a new site language, follow the translation contribution process. Requesters provide plain-language information, the locale and language endonym when known, and their fluency or reviewer availability. Maintainers own repository placement and publish each approved locale atomically across the complete site.
GitHub Actions lives at .github/workflows/ci.yml and runs:
npm run lintnpm run wallets:checknpm run test:walletsnpm run i18n:checknpm run format:checknpm run types:checknpm run buildnpm run test:e2enpm run test:e2e:i18n:localesnpm run test:e2e:ai
The Playwright jobs upload playwright-report/ and test-results/ as artifacts
when a browser suite fails.
- Route topology, namespaces, and sitemap settings live in
src/i18n/manifest.ts; registered locales live insrc/i18n/locale-registry.ts; and localized metadata is created insrc/i18n/site.ts. Guarded[locale]page adapters insrc/i18n/page-route.tsexpose metadata throughgenerateMetadata. - Build-example SDK versions, names, paths, source URLs, and localized artifact
inventory live in
src/i18n/build-example-contract.ts; Bash reads that contract throughscripts/i18n/print-build-example-contract.mts. - Shared font/provider/analytics document primitives live in
src/app/document-shell.tsx; JSON-LD serialization lives insrc/i18n/document.ts. Next layout and global-not-found files keep ownership of their explicithtml,head, andbodyelements. - Language-selector options and eligibility live in
src/app/components/language-selector-model.ts;src/i18n/navigation.tsusesnext-intlfor known-route locale switches, whilesrc/i18n/pathname.tspreserves unknown-path encoding safely. - The home page DAG experience is implemented from
src/dag-viz/and mounted through the app components. - The AI launcher requires both
NEXT_PUBLIC_KASPA_AI_ENABLEDand the route-locale capability insrc/i18n/site-capabilities.ts; keep the deployment flag false until a working ASK backend is available. - When enabled, the AI launcher sends questions through
src/app/api/ask/route.ts, so the browser never sees the private Kaspa.news ASK key. - ASK source-link formatting is normalized server-side in
src/app/api/ask/answer.ts; do not enable raw HTML rendering in the chat UI to handle upstream links. - Keep the ASK route on the Node runtime; using server-side
fetchfor the private Kaspa.news endpoint can be rejected as browser-style traffic.
When editing content, verify:
- homepage hero copy still fits small mobile widths
- theme toggle and mobile nav still work
- home CTAs still land on the correct pages and anchors
/lore,/hodl, and/buildstill render their primary H1 cleanly