Skip to content

Conversation

@Flo0806
Copy link
Member

@Flo0806 Flo0806 commented Dec 2, 2025

🔗 Linked issue

Fixes #33777

📝 Description

When using useAsyncData with a reactive key (getter function) and the watch option, the params watcher stops working after the key changes.

Expected: Params changes trigger new fetches

Root Cause

The params watcher captured a static reference to the initial asyncData container. When the key watcher detected a key change, it created a new container in nuxtApp._asyncData[newKey], but the params watcher continued calling _execute() on the old, stale container.

The Fix

Use dynamic lookup to ensure the params watcher always targets the current container:

watch(options.watch, () => {
  nuxtApp._asyncData[key.value]?._execute(...) // Dynamic lookup
})

Testing

  • ✅ Added regression test: "should continue watching params after reactive key changes"
  • ✅ All existing tests pass
  • ✅ Test fails without the fix, passes with the fix

@Flo0806 Flo0806 requested a review from danielroe as a code owner December 2, 2025 07:52
@bolt-new-by-stackblitz
Copy link

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@coderabbitai
Copy link

coderabbitai bot commented Dec 2, 2025

Walkthrough

This pull request modifies the client watch handler within useAsyncData to access the execute function through direct lookup on the Nuxt app's shared asyncData container (nuxtApp._asyncData[key.value]?._execute(...)) rather than via a captured local reference. The execution remains debounced, but now retrieves the function from the global asyncData map on each invocation. Two tests are added to verify that reactive parameter objects continue triggering fetches correctly after inner reactive keys change. No public API signatures are altered.

Possibly related PRs

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main fix: resolving watch callback issues after reactive key changes in useAsyncData.
Description check ✅ Passed The description provides a clear explanation of the problem, root cause, solution with code example, and testing approach related to the changeset.
Linked Issues check ✅ Passed The PR directly addresses the core requirement from issue #33777: ensuring params changes trigger new fetches after reactive key changes by implementing dynamic lookup instead of static references.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the watch callback issue: the asyncData.ts modification and regression test are directly related to the linked issue requirements.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81356f8 and 29956c2.

📒 Files selected for processing (2)
  • packages/nuxt/src/app/composables/asyncData.ts (1 hunks)
  • test/nuxt/use-async-data.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,vue}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Follow standard TypeScript conventions and best practices

Files:

  • test/nuxt/use-async-data.test.ts
  • packages/nuxt/src/app/composables/asyncData.ts
**/*.{ts,tsx,js,jsx,vue}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx,js,jsx,vue}: Use clear, descriptive variable and function names
Add comments only to explain complex logic or non-obvious implementations
Keep functions focused and manageable (generally under 50 lines), and extract complex logic into separate domain-specific files
Remove code that is not used or needed
Use error handling patterns consistently

Files:

  • test/nuxt/use-async-data.test.ts
  • packages/nuxt/src/app/composables/asyncData.ts
**/*.{test,spec}.{ts,tsx,js}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Write unit tests for core functionality using vitest

Files:

  • test/nuxt/use-async-data.test.ts
🧠 Learnings (2)
📓 Common learnings
Learnt from: Tofandel
Repo: nuxt/nuxt PR: 33192
File: test/nuxt/use-async-data.test.ts:366-373
Timestamp: 2025-09-10T14:42:56.647Z
Learning: In the Nuxt useAsyncData test "should watch params deeply in a non synchronous way", the foo watcher intentionally updates both params.foo and params.locale using locale.value, simulating a scenario where one watcher consolidates multiple reactive values into a shared params object for testing debounced/non-synchronous behavior.
📚 Learning: 2025-09-10T14:42:56.647Z
Learnt from: Tofandel
Repo: nuxt/nuxt PR: 33192
File: test/nuxt/use-async-data.test.ts:366-373
Timestamp: 2025-09-10T14:42:56.647Z
Learning: In the Nuxt useAsyncData test "should watch params deeply in a non synchronous way", the foo watcher intentionally updates both params.foo and params.locale using locale.value, simulating a scenario where one watcher consolidates multiple reactive values into a shared params object for testing debounced/non-synchronous behavior.

Applied to files:

  • test/nuxt/use-async-data.test.ts
  • packages/nuxt/src/app/composables/asyncData.ts
🧬 Code graph analysis (1)
test/nuxt/use-async-data.test.ts (1)
packages/nuxt/src/app/composables/asyncData.ts (1)
  • useAsyncData (194-431)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: test-fixtures (windows-latest, built, vite, default, manifest-off, json, lts/-1)
  • GitHub Check: test-fixtures (windows-latest, built, rspack, default, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (windows-latest, built, rspack, async, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (windows-latest, dev, vite, default, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (windows-latest, dev, vite, async, manifest-off, json, lts/-1)
  • GitHub Check: test-fixtures (windows-latest, dev, vite-env-api, async, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, built, rspack, default, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, default, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite, async, manifest-off, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, built, vite-env-api, async, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, default, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, default, manifest-off, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite, async, manifest-on, json, lts/-1)
  • GitHub Check: test-fixtures (ubuntu-latest, dev, vite-env-api, default, manifest-on, json, lts/-1)
  • GitHub Check: typecheck (ubuntu-latest, bundler)
  • GitHub Check: typecheck (windows-latest, bundler)
  • GitHub Check: release-pkg-pr-new
  • GitHub Check: test-benchmark
  • GitHub Check: test-size
  • GitHub Check: code
🔇 Additional comments (2)
packages/nuxt/src/app/composables/asyncData.ts (1)

384-389: LGTM! Dynamic lookup correctly resolves the reactive key bug.

The change from a captured local reference to a dynamic lookup via nuxtApp._asyncData[key.value]?._execute(...) correctly fixes the issue where the params watcher would target a stale container after the reactive key changed. Since key is a computed ref (Line 209), key.value always resolves to the current key, ensuring the watcher executes on the correct container. The optional chaining provides appropriate safety, and the pattern is consistent with the existing asyncReturn implementation (Lines 401-424).

test/nuxt/use-async-data.test.ts (1)

901-955: Excellent regression test for the reactive key watcher bug.

This test comprehensively validates the fix for issue #33777. The critical validation occurs at Lines 935-943, where changing page (params) after id (reactive key) has already changed confirms that the params watcher continues to function correctly. Without the fix in asyncData.ts, the params watcher would target a stale container and fail to trigger new fetches. The test structure is well-organised, with appropriate async handling and thorough assertions on call counts, arguments, and data states.

Tip

✨ Issue Enrichment is now available for GitHub issues!

CodeRabbit can now help you manage issues more effectively:

  • Duplicate Detection — Identify similar or duplicate issues
  • Related Issues & PRs — Find relevant issues and PR's from your repository
  • Suggested Assignees — Find the best person to work on the issue
  • Implementation Planning — Generate detailed coding plans for engineers and agents
Disable automatic issue enrichment

To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

issue_enrichment:
  auto_enrich:
    enabled: false

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 2, 2025

Open in StackBlitz

@nuxt/kit

npm i https://pkg.pr.new/@nuxt/kit@33802

@nuxt/nitro-server

npm i https://pkg.pr.new/@nuxt/nitro-server@33802

nuxt

npm i https://pkg.pr.new/nuxt@33802

@nuxt/rspack-builder

npm i https://pkg.pr.new/@nuxt/rspack-builder@33802

@nuxt/schema

npm i https://pkg.pr.new/@nuxt/schema@33802

@nuxt/vite-builder

npm i https://pkg.pr.new/@nuxt/vite-builder@33802

@nuxt/webpack-builder

npm i https://pkg.pr.new/@nuxt/webpack-builder@33802

commit: 29956c2

@codspeed-hq
Copy link

codspeed-hq bot commented Dec 2, 2025

CodSpeed Performance Report

Merging #33802 will not alter performance

Comparing Flo0806:fix/use-async-data-reactive-key-watch (29956c2) with main (81356f8)

Summary

✅ 10 untouched

Copy link
Member

@danielroe danielroe left a comment

Choose a reason for hiding this comment

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

thank you ❤️

@danielroe danielroe merged commit 56773be into nuxt:main Dec 8, 2025
56 checks passed
@github-actions github-actions bot mentioned this pull request Dec 8, 2025
@github-actions github-actions bot mentioned this pull request Dec 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

useAsyncData breaks after clientside navigation when using a reactive keys

2 participants