npm run devstarts the local Next.js server.npm run lintruns ESLint.npm run format:checkverifies formatting.npm testruns unit/integration tests (Vitest).npm run test:smokeruns Playwright smoke tests.npm run generate:menusregenerates sidebar menus from Drupal.
These variables are required for app startup:
NEXT_PUBLIC_DRUPAL_BASE_URL
Optional variables used by features:
DRUPAL_PREVIEW_SECRETDRUPAL_REVALIDATE_SECRET— required for on-demand revalidation (/api/revalidate)NEXT_PUBLIC_FATHOM_IDNEXT_PUBLIC_PLAUSIBLE_SRC— site-specific script URL from the Plausible dashboard (e.g.https://plausible.io/js/pa-XXXXX.js)NEXT_PUBLIC_SITE_URL— canonical/OG base URL (defaults tohttps://fate-srd.com)YOUTUBE_API_KEY
Drupal (or a webhook) can refresh a statically generated page without a full rebuild:
curl -X POST "https://fate-srd.com/api/revalidate?secret=YOUR_SECRET&path=/fate-core/outcomes"path must be the site alias (leading slash). Articles also use ISR (revalidate: 3600).
lib/static-menus.js is a generated artifact (~12k lines) used by publication sidebars.
- Ensure
NEXT_PUBLIC_DRUPAL_BASE_URLpoints at a Drupal instance with menus available. - Run
npm run generate:menus. - Commit the updated
lib/static-menus.jswhenever Drupal menu structure changes.
CI does not regenerate menus (no Drupal credentials in the default workflow). After menu edits in Drupal, regenerate and commit before deploy so Netlify builds ship fresh nav.
Shared copy and heroes live in assets/data/publications.js. Route files under src/pages/<slug>/ are thin wrappers around PublicationLanding.
Primary styles are Sass/BEM under assets/components/ (imported from _app.js). Tailwind is not used.