Feat: Auto switch code tab to user preferred programming language#111
Feat: Auto switch code tab to user preferred programming language#111
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe CodeTabs component now persists the user's selected programming language to localStorage, enabling their language preference to remain consistent across all code examples throughout the site without requiring repeated switching. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
.vitepress/theme/components/CodeTabs.vue (2)
49-56: Watcher redundantly updatesactiveTabfor the component instance that triggered the change.When
setActiveTab(i)is called, it setsactiveTab.value = indexdirectly (line 59), then setsglobalActiveLanguage.value(line 60), which fires this watcher and setsactiveTab.value = indexa second time on the same instance. Adding a guard avoids the redundant re-assignment:♻️ Proposed refactor
watch(globalActiveLanguage, (newLang) => { if (newLang) { const index = props.languages.findIndex((lang) => lang.name === newLang) - if (index !== -1) { + if (index !== -1 && index !== activeTab.value) { activeTab.value = index } } })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.vitepress/theme/components/CodeTabs.vue around lines 49 - 56, The watcher on globalActiveLanguage redundantly re-assigns activeTab for the same component instance that already set it via setActiveTab; update the watch callback in CodeTabs.vue to only assign activeTab.value when the resolved index differs from the current activeTab.value (i.e., after computing index from props.languages, check index !== -1 && activeTab.value !== index before setting activeTab.value) so setActiveTab and the watcher don't perform the same assignment twice.
43-46: Silently persists an auto-selected default to localStorage without user action.When no stored preference exists, line 45 sets
globalActiveLanguage.value, which immediately triggers the module-level watcher (lines 16–20) to write that value to localStorage. This means the first CodeTabs component to mount determines the "preferred language" permanently — before the user has made any explicit choice. The PR intent is to persist user selections, not auto-persist defaults.Consider only writing to localStorage on an explicit user action (i.e., inside
setActiveTab), and removing theglobalActiveLanguageassignment from theelse iffallback:♻️ Proposed fix
onMounted(() => { if (globalActiveLanguage.value) { const index = props.languages.findIndex( (lang) => lang.name === globalActiveLanguage.value, ) if (index !== -1) { activeTab.value = index } - } else if (props.languages.length > 0) { - // Note: If no global language is set, use the first tab's language as default - globalActiveLanguage.value = props.languages[0].name } })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.vitepress/theme/components/CodeTabs.vue around lines 43 - 46, The current fallback in CodeTabs.vue auto-assigns globalActiveLanguage.value (the else-if branch) which triggers the module-level watcher and writes a default into localStorage; remove that auto-assignment so no default is persisted on mount, and ensure persistence happens only when the user explicitly changes tabs by writing to localStorage inside setActiveTab (or by having setActiveTab call a helper that sets globalActiveLanguage and writes to localStorage). Also remove or adjust the module-level watcher that unconditionally writes globalActiveLanguage to localStorage so it no longer persists programmatic/initial assignments—only persist inside the user-action pathway implemented by setActiveTab.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.vitepress/theme/components/CodeTabs.vue:
- Around line 58-61: The setActiveTab function accesses
props.languages[index].name without validating index; add a defensive bounds
check in setActiveTab (referencing setActiveTab, activeTab,
globalActiveLanguage, and props.languages) so it only reads
props.languages[index].name when index >= 0 && index < props.languages.length;
if the index is out of range, still set activeTab (or bail) and set
globalActiveLanguage to a safe fallback (e.g., props.languages[0]?.name or an
empty string) to avoid runtime crashes when called programmatically.
- Line 4: GLOBAL_LANG_KEY currently holds a language name ('java') instead of a
descriptive storage key; change its value to a clear identifier like
'preferred-language' and update all usages (e.g.,
localStorage.getItem(GLOBAL_LANG_KEY), localStorage.setItem(GLOBAL_LANG_KEY,
...)) so preferences are stored under that key; ensure any code referencing
GLOBAL_LANG_KEY (the constant itself in CodeTabs.vue and any methods that
read/write localStorage) continues to work without semantic changes.
---
Nitpick comments:
In @.vitepress/theme/components/CodeTabs.vue:
- Around line 49-56: The watcher on globalActiveLanguage redundantly re-assigns
activeTab for the same component instance that already set it via setActiveTab;
update the watch callback in CodeTabs.vue to only assign activeTab.value when
the resolved index differs from the current activeTab.value (i.e., after
computing index from props.languages, check index !== -1 && activeTab.value !==
index before setting activeTab.value) so setActiveTab and the watcher don't
perform the same assignment twice.
- Around line 43-46: The current fallback in CodeTabs.vue auto-assigns
globalActiveLanguage.value (the else-if branch) which triggers the module-level
watcher and writes a default into localStorage; remove that auto-assignment so
no default is persisted on mount, and ensure persistence happens only when the
user explicitly changes tabs by writing to localStorage inside setActiveTab (or
by having setActiveTab call a helper that sets globalActiveLanguage and writes
to localStorage). Also remove or adjust the module-level watcher that
unconditionally writes globalActiveLanguage to localStorage so it no longer
persists programmatic/initial assignments—only persist inside the user-action
pathway implemented by setActiveTab.
| <script> | ||
| import { ref, watch, onMounted, nextTick } from 'vue' | ||
|
|
||
| const GLOBAL_LANG_KEY = 'java' |
There was a problem hiding this comment.
GLOBAL_LANG_KEY holds a language name instead of a storage key identifier.
The constant value 'java' is a language name, not a storage key. This means all preferences are stored under localStorage.key = 'java' (e.g., localStorage.setItem('java', 'C++') when C++ is selected). The name GLOBAL_LANG_KEY strongly implies it should hold a descriptive key identifier like 'preferred-language'.
🐛 Proposed fix
-const GLOBAL_LANG_KEY = 'java'
+const GLOBAL_LANG_KEY = 'preferred-language'📝 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.
| const GLOBAL_LANG_KEY = 'java' | |
| const GLOBAL_LANG_KEY = 'preferred-language' |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.vitepress/theme/components/CodeTabs.vue at line 4, GLOBAL_LANG_KEY
currently holds a language name ('java') instead of a descriptive storage key;
change its value to a clear identifier like 'preferred-language' and update all
usages (e.g., localStorage.getItem(GLOBAL_LANG_KEY),
localStorage.setItem(GLOBAL_LANG_KEY, ...)) so preferences are stored under that
key; ensure any code referencing GLOBAL_LANG_KEY (the constant itself in
CodeTabs.vue and any methods that read/write localStorage) continues to work
without semantic changes.
| const setActiveTab = (index) => { | ||
| activeTab.value = index | ||
| globalActiveLanguage.value = props.languages[index].name | ||
| } |
There was a problem hiding this comment.
Missing bounds check before accessing props.languages[index].
props.languages[index].name is accessed without verifying that index is within the array bounds. While v-for in the template makes an out-of-range call unlikely, a defensive guard prevents a potential runtime crash if setActiveTab is ever called programmatically:
🛡️ Proposed fix
const setActiveTab = (index) => {
+ if (index < 0 || index >= props.languages.length) return
activeTab.value = index
globalActiveLanguage.value = props.languages[index].name
}📝 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.
| const setActiveTab = (index) => { | |
| activeTab.value = index | |
| globalActiveLanguage.value = props.languages[index].name | |
| } | |
| const setActiveTab = (index) => { | |
| if (index < 0 || index >= props.languages.length) return | |
| activeTab.value = index | |
| globalActiveLanguage.value = props.languages[index].name | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.vitepress/theme/components/CodeTabs.vue around lines 58 - 61, The
setActiveTab function accesses props.languages[index].name without validating
index; add a defensive bounds check in setActiveTab (referencing setActiveTab,
activeTab, globalActiveLanguage, and props.languages) so it only reads
props.languages[index].name when index >= 0 && index < props.languages.length;
if the index is out of range, still set activeTab (or bail) and set
globalActiveLanguage to a safe fallback (e.g., props.languages[0]?.name or an
empty string) to avoid runtime crashes when called programmatically.
Key Changes:
Usage:
Fixes #110
Summary by CodeRabbit
Improvements