Skip to content

feat: ref/reactive outside vue/nuxtApp context detection#89

Closed
huang-julien wants to merge 7 commits intomainfrom
feat/ssr_ref
Closed

feat: ref/reactive outside vue/nuxtApp context detection#89
huang-julien wants to merge 7 commits intomainfrom
feat/ssr_ref

Conversation

@huang-julien
Copy link
Member

🔗 Linked issue

resolve #29

❓ Type of change

  • 📖 Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

@danielroe any opinion about this ?

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 25, 2025

Open in StackBlitz

npm i https://pkg.pr.new/nuxt/hints/@nuxt/hints@89

commit: f93bf73

@coderabbitai
Copy link

coderabbitai bot commented Jan 29, 2026

📝 Walkthrough

Walkthrough

This pull request adds server-side detection for Vue composition API functions to prevent misuse in server contexts. It introduces three components: a new runtime composables file that wraps ref, reactive, shallowRef, and shallowReactive with server-side guards that log diagnostic errors when called outside proper context; module configuration that registers these wrapped composables via Nuxt's addImports API; and a playground plugin demonstrating the pattern with a global ref declaration.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: detecting ref/reactive usage outside Vue/Nuxt app context, which directly addresses the PR objective.
Description check ✅ Passed The description links to issue #29 and relates to the changeset by referencing server-side context detection for ref/reactive.
Linked Issues check ✅ Passed All code changes implement the objective from #29: detecting server-side ref/reactive usage outside request-scoped Vue/Nuxt contexts to prevent memory leaks and state pollution.
Out of Scope Changes check ✅ Passed All changes directly support the server-side detection mechanism: wrapper composables for runtime warnings and module integration. No extraneous changes present.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/ssr_ref

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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/module.ts`:
- Around line 56-62: The import paths used in the addImports call are incorrect:
locate the addImports([...]) block (the entries adding 'ref', 'shallowRef',
'reactive', 'shallowReactive') and update each resolver.resolve call to include
the missing core segment in the module path (i.e., change
"./runtime/composables/vue" to "./runtime/core/composables/vue") so
resolver.resolve points to the actual implementation; keep the same import names
and structure.

Comment on lines +56 to +62
// Imports for server side misusage detection
addImports([
{ from: resolver.resolve('./runtime/composables/vue'), name: 'ref' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'shallowRef' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'reactive' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'shallowReactive' },
])
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify the actual file paths for vue composables

echo "=== Searching for vue.ts composables file in src/runtime ==="
fd -t f 'vue.ts' src/runtime

echo -e "\n=== Checking if ./runtime/composables/vue.ts exists ==="
ls -la src/runtime/composables/vue.ts 2>/dev/null || echo "File NOT found at src/runtime/composables/vue.ts"

echo -e "\n=== Checking if ./runtime/core/composables/vue.ts exists ==="
ls -la src/runtime/core/composables/vue.ts 2>/dev/null || echo "File NOT found at src/runtime/core/composables/vue.ts"

echo -e "\n=== Listing all files in src/runtime ==="
find src/runtime -type f -name '*.ts' | head -20

Repository: nuxt/hints

Length of output: 1037


Path mismatch: resolver path doesn't match actual file location.

The addImports call references './runtime/composables/vue', but the actual implementation is at src/runtime/core/composables/vue.ts. The path is missing the core/ segment, which will cause the imports to fail at runtime.

🐛 Proposed fix for path
     // Imports for server side misusage detection
     addImports([
-      { from: resolver.resolve('./runtime/composables/vue'), name: 'ref' },
-      { from: resolver.resolve('./runtime/composables/vue'), name: 'shallowRef' },
-      { from: resolver.resolve('./runtime/composables/vue'), name: 'reactive' },
-      { from: resolver.resolve('./runtime/composables/vue'), name: 'shallowReactive' },
+      { from: resolver.resolve('./runtime/core/composables/vue'), name: 'ref' },
+      { from: resolver.resolve('./runtime/core/composables/vue'), name: 'shallowRef' },
+      { from: resolver.resolve('./runtime/core/composables/vue'), name: 'reactive' },
+      { from: resolver.resolve('./runtime/core/composables/vue'), name: 'shallowReactive' },
     ])
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Imports for server side misusage detection
addImports([
{ from: resolver.resolve('./runtime/composables/vue'), name: 'ref' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'shallowRef' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'reactive' },
{ from: resolver.resolve('./runtime/composables/vue'), name: 'shallowReactive' },
])
// Imports for server side misusage detection
addImports([
{ from: resolver.resolve('./runtime/core/composables/vue'), name: 'ref' },
{ from: resolver.resolve('./runtime/core/composables/vue'), name: 'shallowRef' },
{ from: resolver.resolve('./runtime/core/composables/vue'), name: 'reactive' },
{ from: resolver.resolve('./runtime/core/composables/vue'), name: 'shallowReactive' },
])
🤖 Prompt for AI Agents
In `@src/module.ts` around lines 56 - 62, The import paths used in the addImports
call are incorrect: locate the addImports([...]) block (the entries adding
'ref', 'shallowRef', 'reactive', 'shallowReactive') and update each
resolver.resolve call to include the missing core segment in the module path
(i.e., change "./runtime/composables/vue" to "./runtime/core/composables/vue")
so resolver.resolve points to the actual implementation; keep the same import
names and structure.

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.

feat: server side global ref detection

2 participants