Skip to content

chore: make npm run lint runnable - #6

Open
tylerkstevens wants to merge 1 commit into
mainfrom
chore/eslint-flat-config
Open

chore: make npm run lint runnable#6
tylerkstevens wants to merge 1 commit into
mainfrom
chore/eslint-flat-config

Conversation

@tylerkstevens

Copy link
Copy Markdown
Collaborator

npm run lint has never been able to complete in this repo. There is no ESLint config file, so next lint drops into its interactive "How would you like to configure ESLint?" setup prompt and hangs. Reproduced on a clean tree, so this is pre-existing — not a regression from any branch.

Consequence: the pre-PR check of lint + build + test could not pass, and lint has effectively never run locally or in CI.

The fix

  • Add eslint.config.mjs — flat config (ESLint 9), spreading the array eslint-config-next already exports. It ships its own ignores for .next/, out/, build/ and next-env.d.ts, so those aren't repeated.
  • Switch the lint script from next lint to eslint .. next lint is deprecated and is removed entirely in Next 16, so this is needed regardless.

No new dependencies — eslint and eslint-config-next were already in devDependencies.

What lint then found

4 errors from 3 root causes, all pre-existing:

Issue Resolution
AnnouncementBanner.tsx declared its LinkOrA wrapper inside the render Real bug — the component got a new identity on every render, remounting the banner contents and resetting their state. Hoisted to module scope as BannerLink.
AnnouncementBanner and CountdownTimer.tsx call setState in a mount effect Both are deliberate hydration guards — localStorage and the client clock don't exist during SSR. Each gets a targeted eslint-disable-next-line with the reason inline. The rule stays at error strength for new code.
Logo.tsx carried a disable for a rule that no longer fires Stale — <img> inside <picture> isn't flagged. Removed.

7 @next/next/no-img-element warnings remain and do not fail the run. Several are intentional (remote Nostr avatars, supporter logos); converting them to next/image is a separate decision.

Verification

npm run lint && npm run build && npm test now passes end to end — first time that's true in this repo.

  • lint exit 0 (7 warnings, 0 errors) · build clean, 19 routes · tests 11/11
  • tsc caught a mistake lint missed: the first pass replaced the LinkOrA usages but left the dead definition behind. Lint stayed green, the build failed. Fixed and re-verified.
  • Both touched components render from null data (activeAnnouncement and nextEventDate are both null), so neither is reachable as shipped. I temporarily activated each rather than assume they were fine: internal and external banner branches (external correctly gets target="_blank" + rel="noopener noreferrer"), dismiss writes localStorage and hides the banner, and the countdown ticks after hydration. Both temp edits reverted — data/ is untouched.

Recommend merging this before the other open branches so they inherit a working lint.

🤖 Generated with Claude Code

The repo had no ESLint config, so `next lint` dropped into its
interactive "How would you like to configure ESLint?" setup prompt and
never completed. Lint has therefore never run in CI or locally, and
the pre-PR check of lint + build + test could not pass.

- add eslint.config.mjs — flat config (ESLint 9) spreading the array
  eslint-config-next already exports. It ships ignores for .next/,
  out/, build/ and next-env.d.ts, so they are not repeated
- switch the lint script from `next lint` to `eslint .`. `next lint`
  is deprecated and is removed entirely in Next 16

Lint then reported 4 errors from 3 root causes, all pre-existing:

- AnnouncementBanner declared its LinkOrA wrapper inside the render,
  giving the component a new identity every render and remounting the
  banner contents. Hoisted to module scope as BannerLink
- AnnouncementBanner and CountdownTimer both call setState in a mount
  effect. Both are deliberate hydration guards — localStorage and the
  client clock are unavailable during SSR — so each gets a targeted
  eslint-disable-next-line with the reason. The rule stays at error
  strength for new code
- Logo.tsx carried an eslint-disable for a rule that no longer fires
  on <img> inside <picture>. Removed

7 @next/next/no-img-element warnings remain and do not fail the run.
Several are intentional (remote avatars, supporter logos); converting
them to next/image is a separate call.

Verified: lint, build and test all exit 0. AnnouncementBanner and
CountdownTimer both render from null data, so both were temporarily
activated to exercise them — internal and external banner branches
(target/rel correct on external), dismiss writes localStorage and
hides the banner, and the countdown ticks after hydration. The
temporary data edits were reverted; data/ is untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview Aug 4, 2026 10:22pm
website-256-f Ready Ready Preview Aug 4, 2026 10:22pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant