Skip to content

NEX-200: Update next.js to version 15, switch to @fortedigital/nextjs-cache-handler#313

Open
vermario wants to merge 12 commits intomainfrom
NEX-200
Open

NEX-200: Update next.js to version 15, switch to @fortedigital/nextjs-cache-handler#313
vermario wants to merge 12 commits intomainfrom
NEX-200

Conversation

@vermario
Copy link
Collaborator

Link to ticket:

https://wunder.atlassian.net/browse/NEX-200

Link to feature environment:

[Add link to feature environment]

Changes proposed in this PR:

Update next.js to version 15, switch to @fortedigital/nextjs-cache-handler , since the previous package is now abandoned and does not work with next 15.

This seemed like an idea task for copilot cli, so the changed are pretty much all done by the AI. We have to check this one carefully.

How to test:

Testing locally:

  1. rebuild the project locally with DDEV, starting from scratch ./setup-ddev.sh -c
  2. if you have not set up Cypress in this environment yet, run the one-time setup commands:
    • ddev npx cypress install
    • from the project root directory, run: ddev exec ./install-cypress-deps.sh
  3. from the next directory, open another terminal window while both frontend and backend are running and run the Cypress tests: ddev npm run cypress:run

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upgrades the next/ frontend to Next.js 15 + React 19 and replaces the abandoned @neshca/cache-handler integration with @fortedigital/nextjs-cache-handler, including the related async Next.js 15 API migrations (params, searchParams, draftMode() as Promises).

Changes:

  • Upgrade Next.js to v15 and React to v19; update related ESLint and type packages.
  • Replace @neshca/cache-handler usage with Next’s unstable_cache patterns and switch the runtime cache handler to @fortedigital/nextjs-cache-handler (+ @redis/client).
  • Migrate App Router pages/layouts to await params / searchParams and draftMode() per Next.js 15 behavior.

Reviewed changes

Copilot reviewed 25 out of 27 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
next/src/lib/hooks/use-event-listener.ts Adjust useRef initialization for updated React typings.
next/src/lib/drupal/get-node.ts Replace neshCache wrapper with unstable_cache + React cache.
next/src/lib/drupal/get-menus.ts Replace neshCache wrapper with unstable_cache + React cache.
next/src/instrumentation.ts Switch instrumentation import to @fortedigital/nextjs-cache-handler.
next/src/components/draft-alert.tsx Await draftMode() (Next.js 15 async API).
next/src/app/api/search/route.ts Align route handler signature with updated Next.js types.
next/src/app/[locale]/layout.tsx Await params in layout + metadata generator.
next/src/app/[locale]/(static)/search/page.tsx Client page unwraps promised params via React use().
next/src/app/[locale]/(static)/page.tsx Await params and draftMode(); set static revalidate literal.
next/src/app/[locale]/(static)/nodepreview/page.tsx Await params/searchParams in preview page.
next/src/app/[locale]/(static)/layout.tsx Await params in static layout.
next/src/app/[locale]/(static)/dashboard/webforms/[webformName]/[webformSubmissionUuid]/page.tsx Await promised params and keep locale setup.
next/src/app/[locale]/(static)/dashboard/page.tsx Await params in page + metadata generator.
next/src/app/[locale]/(static)/auth/register/page.tsx Await params for locale.
next/src/app/[locale]/(static)/auth/login/page.tsx Await params for locale.
next/src/app/[locale]/(static)/all-articles/page.tsx Await params/searchParams; set static revalidate literal.
next/src/app/[locale]/(dynamic)/[...slug]/page.tsx Await params/draftMode(); adjust generateStaticParams; set static revalidate.
next/src/app/[locale]/(dynamic)/[...slug]/layout.tsx Await promised params in dynamic layout.
next/package.json Bump Next/React, swap cache handler deps, add @redis/client.
next/package-lock.json Lockfile updates for upgraded dependencies and new cache handler/redis client.
next/next.config.mjs Replace experimental.swrDelta with expireTime; keep cache handler wiring.
next/next-env.d.ts Add routes typing reference and update docs link.
next/cache-handler.mjs Migrate cache handler implementation to @fortedigital/nextjs-cache-handler + @redis/client.
next/.gitignore Ignore TS build info file.
.github/copilot-instructions.md Add repo-specific dev + migration guidance (Next 15, cache handler, env var conventions).
.ddev/config.yaml Bump Node version to 22 for local development.
.circleci/config.yml Switch CI executor image (Node 22).
Files not reviewed (1)
  • next/package-lock.json: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 11 to 15
CacheHandler.onCreation(async ({ buildId }) => {
/** @type {import("redis").RedisClientType | undefined} */
let client;
/** @type {import("@neshca/cache-handler").Handler | undefined} */
/** @type {any} */
let handler;

Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CacheHandler.onCreation can return handlers: [undefined] when Redis env vars are missing or during the build phase, because handler is only assigned inside the if (...) block. Initialize handler to createLruHandler() by default (and only swap to Redis when ready), or ensure the returned handlers array contains only defined handlers.

Copilot uses AI. Check for mistakes.

**Behaviour:**
- Cache keys are prefixed with `cache-{buildId}:` so deploys don't serve stale entries from a previous build
- If Redis is unavailable or the connection times out (3 s), it **falls back silently to an in-memory LRU** handler — the app keeps working
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This documentation says the Redis connection times out after 3s and falls back to LRU, but next/cache-handler.mjs currently calls client.connect() without a timeout and can block startup. Either implement the connect timeout/fallback behavior in code or adjust this bullet to match the actual behavior.

Suggested change
- If Redis is unavailable or the connection times out (3 s), it **falls back silently to an in-memory LRU** handler — the app keeps working
- Redis connectivity (including timeouts and any fallbacks) is handled by `@fortedigital/nextjs-cache-handler` / `@redis/client`; there is currently **no custom 3 s connect-timeout or guaranteed automatic fallback to an in-memory LRU** implemented in `next/cache-handler.mjs`

Copilot uses AI. Check for mistakes.
Comment on lines 69 to 72
if (client?.isReady) {
/** @type {import("@neshca/cache-handler/redis-strings").CreateRedisStringsHandlerOptions} */
const redisHandlerOptions = {
client,
keyPrefix: `cache-${buildId}:`,
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeoutMs here only applies to Redis operations after the client is connected; client.connect() earlier can still block startup if Redis is unreachable. If you expect a 3s failover to LRU, add an explicit connect timeout (e.g., Redis socket options or racing connect() against a timer) and fall back when it elapses.

Copilot uses AI. Check for mistakes.
"@hookform/resolvers": "^3.9.1",
"@neshca/cache-handler": "^1.9.0",
"@fortedigital/nextjs-cache-handler": "^2",
"@redis/client": "^5",
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fortedigital/nextjs-cache-handler declares a peer dependency on @redis/client >= 5.5.6 (per the lockfile). Declaring "@redis/client": "^5" allows versions <5.5.6; consider pinning the range to ^5.5.6 (or higher) to reflect the actual minimum requirement and avoid future installs resolving to an incompatible 5.x release.

Suggested change
"@redis/client": "^5",
"@redis/client": "^5.5.6",

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 25 out of 27 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants