Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,32 @@ updates:
schedule:
interval: "monthly"
groups:
# Dependabot assigns a dependency to the first group it matches, so
# react and next must stay above dev-dependencies — otherwise their
# dev-side packages (@types/react*, eslint-config-next) get pulled
# into that batch and drift from the runtime package.
#
# react and react-dom must ship the exact same version — bumped apart,
# the test suite fails React's version-mismatch check. @types/react*
# ride along so type and runtime majors land together.
react:
patterns:
- "react"
- "react-dom"
- "@types/react"
- "@types/react-dom"
# next and eslint-config-next are pinned to the same exact version and
# move together.
next:
patterns:
- "next"
- "eslint-config-next"
# Majors stay out of the dev batch so one breaking bump can't hold its
# patch/minor updates hostage; they arrive as their own PRs (unless
# ignored below).
dev-dependencies:
dependency-type: "development"
update-types: ["minor", "patch"]
ignore:
# eslint-config-next@16 pulls in eslint-plugin-react@7.37, which only
# peers eslint ^9 and crashes on v10 (context.getFilename() removed).
Expand Down
26 changes: 13 additions & 13 deletions components/site/Chrome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ export function Chrome() {
[],
);

// Plain `<Link href="/#section">` appends rather than replaces the hash
// when the URL already carries it (Next 16 App Router, output: "export"
// + trailingSlash), growing `/#method#method…` across click → reload →
// click cycles. Intercept same-page anchors and resolve locally. Off
// this route the section isn't in the DOM (e.g. /blog/*); force a full
// reload so the destination resolves the hash deterministically — the
// soft-nav hash codepath is the unreliable one. Modified clicks (new
// tab, middle-click) fall through to the native <Link>.
// Same-page anchors are intercepted and resolved locally: replaceState
// writes the exact single hash (a repeat click is a URL no-op), the
// scroll is native, and focus moves into the section. Historically this
// also guarded against <Link href="/#section"> appending to an existing
// hash (`/#method#method…`, #116) under output: "export" +
// trailingSlash; Next 16.3.8 fixed that upstream. Off this route the
// section isn't in the DOM (e.g. /blog/*), so the native <Link>
// soft-navs home and scrolls to the hash itself. Modified clicks (new
// tab, middle-click) also fall through to the native <Link>.
const handleNavClick = useCallback(
(e: React.MouseEvent<HTMLAnchorElement>) => {
if (!shouldInterceptNavClick(e)) return;
Expand Down Expand Up @@ -86,12 +87,11 @@ export function Chrome() {
}

const { id } = target;
e.preventDefault();
const el = document.getElementById(id);
if (el === null) {
window.location.assign(`/#${id}`);
return;
}
// Off this route: fall through to the native <Link>, as the top
// branch does.
if (el === null) return;
e.preventDefault();
// Write the exact single hash so it can never accumulate;
// replaceState keeps a same-hash click a URL no-op.
history.replaceState(null, "", `#${id}`);
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
},
"dependencies": {
"gray-matter": "^4.0.3",
"next": "16.3.6",
"next": "16.3.8",
"next-mdx-remote": "^6.0.0",
"react": "19.2.8",
"react-dom": "19.2.8",
Expand All @@ -53,14 +53,15 @@
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
"eslint-config-next": "16.2.10",
"eslint-config-next": "16.3.8",
"eslint-config-prettier": "^10.1.8",
"husky": "^9.1.7",
"lint-staged": "^17.0.8",
"markdownlint-cli2": "^0.23.0",
"markdownlint-cli2": "^0.23.3",
"prettier": "^3.9.4",
"tailwindcss": "^4",
"typescript": "^6",
"vitest": "^5.0.0"
"vite": "^8.3.4",
"vitest": "^5.0.3"
}
}
Loading
Loading