Conversation
…nDescription component
|
🚅 Deployed to the applirank-pr-39 environment in applirank
|
📝 WalkthroughWalkthroughA new Vue component Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~15 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/pages/jobs/[slug]/apply.vue (1)
17-21:⚠️ Potential issue | 🟡 MinorSEO
descriptionstill passes raw Markdown to the meta tag.Line 19 slices
job.value?.descriptiondirectly, so markdown syntax characters (##,**,-, etc.) will appear verbatim in the<meta name="description">tag and in social card previews. The companionindex.vuein this same PR addresses this with themarkdownToPlainTexthelper — apply the same treatment here for consistency.🐛 Proposed fix
Extract
markdownToPlainTextto a shared utility (e.g.~/utils/markdownToPlainText.ts) and import it in both pages, then:+import { markdownToPlainText } from '~/utils/markdownToPlainText' + useSeoMeta({ title: computed(() => job.value ? `Apply — ${job.value.title}` : 'Apply — Applirank'), - description: computed(() => job.value?.description?.slice(0, 160) ?? 'Submit your application'), + description: computed(() => markdownToPlainText(job.value?.description).slice(0, 160) || 'Submit your application'), robots: 'noindex, nofollow', })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/pages/jobs/`[slug]/apply.vue around lines 17 - 21, The SEO description is passing raw Markdown (job.value?.description) into useSeoMeta; update the computed description in the useSeoMeta call to convert markdown to plain text before slicing by importing and using the markdownToPlainText helper (the same utility used by the index.vue page) so the computed (() => job.value ? ... ) uses markdownToPlainText(job.value.description) then slice(0,160) with fallback text, leaving robots unchanged.
🧹 Nitpick comments (2)
app/pages/jobs/[slug]/index.vue (1)
16-31: ExtractmarkdownToPlainTextto a shared utility to avoid duplication.The same helper is needed in
apply.vue(and potentially other pages). Defining it locally inside<script setup>means it either gets copy-pasted orapply.vuecontinues to use raw markdown in its meta description (as is currently the case).Move to
app/utils/markdownToPlainText.tsand import via~/utils/markdownToPlainTextin bothindex.vueandapply.vue.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/pages/jobs/`[slug]/index.vue around lines 16 - 31, Extract the local function markdownToPlainText into a shared utility module (export it as the default or named export from a new markdownToPlainText utility) and replace the inline definition in index.vue with an import of that utility; then update apply.vue to import and use the same function so both pages call the shared markdownToPlainText (ensure the implementation is identical and preserve current regex behavior and return type).app/components/MarkdownDescription.vue (1)
9-20: Move the staticparserOptionsobject to module scope.
parserOptionsis a constant, non-reactive value but is currently declared inside<script setup>, so a new object is allocated on every component instantiation. Move it to module scope (outside<script setup>) so it is created once.♻️ Proposed refactor
+import type { MDCParseOptions } from '@nuxtjs/mdc' + +const parserOptions: MDCParseOptions = { + rehype: { + options: { allowDangerousHtml: false }, + plugins: { 'rehype-raw': false }, + }, + highlight: false, + toc: false, +} + <script setup lang="ts"> -import type { MDCParseOptions } from '@nuxtjs/mdc' -import MDC from '@nuxtjs/mdc/runtime/components/MDC.vue' +// MDC is auto-imported via the `@nuxtjs/mdc` Nuxt module const props = defineProps<{ value?: string | null }>() -const parserOptions: MDCParseOptions = { - rehype: { - options: { allowDangerousHtml: false }, - plugins: { 'rehype-raw': false }, - }, - highlight: false, - toc: false, -} - const normalizedValue = computed(() => props.value ?? '') </script>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/components/MarkdownDescription.vue` around lines 9 - 20, The parserOptions constant is being recreated for every component instance because it’s declared inside <script setup>; move the parserOptions declaration to module scope (outside the <script setup> block) so it is allocated once at module load; locate the parserOptions symbol in MarkdownDescription.vue and cut/paste the entire const parserOptions: MDCParseOptions = { ... } to the top-level of the module (above the <script setup> block), keeping its type and imports intact and leaving the component code to reference parserOptions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/components/MarkdownDescription.vue`:
- Around line 25-30: The component renders untrusted markdown but isn't wrapped
in a NuxtErrorBoundary; wrap the MDC usage inside a <NuxtErrorBoundary> in
MarkdownDescription.vue so rendering errors are caught and a fallback is shown,
e.g., provide a fallback-slot or default error content for the boundary; update
the template that currently renders <MDC :value="normalizedValue"
:parser-options="parserOptions" .../> to be the child of NuxtErrorBoundary and
ensure the boundary exposes a user-friendly fallback for failures.
- Line 29: The prose container's class uses old Tailwind v3 modifier ordering
(`hover:prose-a:text-brand-700`) which applies hover to the whole container;
update the modifier order to Tailwind v4 syntax so link hover targets individual
anchors (replace the `hover:prose-a:text-brand-700` token with
`prose-a:hover:text-brand-700` in the class string inside the
MarkdownDescription.vue component) so only the hovered <a> receives the color
change.
- Line 3: Add the '@nuxtjs/mdc' module to the Nuxt config and remove the private
runtime component import: open nuxt.config.ts and add '@nuxtjs/mdc' to the
modules array so the package is registered and its components are auto-imported,
then in app/components/MarkdownDescription.vue delete the explicit import line
"import MDC from '@nuxtjs/mdc/runtime/components/MDC.vue'" so the <MDC>
component uses the global auto-imported version.
In `@app/pages/jobs/`[slug]/index.vue:
- Around line 16-31: The function markdownToPlainText currently strips all
underscores via .replace(/[*_~]/g, ''), which destroys snake_case; replace that
blanket removal with targeted regexes that only remove markdown
emphasis/strong/strikethrough markers while preserving underscores inside words.
Concretely, in markdownToPlainText replace the .replace(/[*_~]/g, '') step with
targeted replacements such as removing strong markers
.replace(/(\*\*|__)(?=\S)([\s\S]*?\S)\1/g, '$2'), removing emphasis markers
.replace(/(\*|_)(?=\S)([\s\S]*?\S)\1/g, '$2'), and removing strikethrough
markers .replace(/(~{2})(?=\S)([\s\S]*?\S)\1/g, '$2') so underscores within
words (e.g., snake_case) remain unchanged.
In `@package.json`:
- Around line 21-22: The package.json contains an explicit "@nuxtjs/mdc"
dependency that is redundant because "@nuxt/content" already includes it; either
remove the "@nuxtjs/mdc" entry from package.json to avoid duplication, or if you
intentionally use MDC beyond markdown rendering, add "'@nuxtjs/mdc'" to the
modules array in nuxt.config.ts so the module is registered (check the modules
array symbol in nuxt.config.ts) and keep package.json accordingly.
---
Outside diff comments:
In `@app/pages/jobs/`[slug]/apply.vue:
- Around line 17-21: The SEO description is passing raw Markdown
(job.value?.description) into useSeoMeta; update the computed description in the
useSeoMeta call to convert markdown to plain text before slicing by importing
and using the markdownToPlainText helper (the same utility used by the index.vue
page) so the computed (() => job.value ? ... ) uses
markdownToPlainText(job.value.description) then slice(0,160) with fallback text,
leaving robots unchanged.
---
Nitpick comments:
In `@app/components/MarkdownDescription.vue`:
- Around line 9-20: The parserOptions constant is being recreated for every
component instance because it’s declared inside <script setup>; move the
parserOptions declaration to module scope (outside the <script setup> block) so
it is allocated once at module load; locate the parserOptions symbol in
MarkdownDescription.vue and cut/paste the entire const parserOptions:
MDCParseOptions = { ... } to the top-level of the module (above the <script
setup> block), keeping its type and imports intact and leaving the component
code to reference parserOptions unchanged.
In `@app/pages/jobs/`[slug]/index.vue:
- Around line 16-31: Extract the local function markdownToPlainText into a
shared utility module (export it as the default or named export from a new
markdownToPlainText utility) and replace the inline definition in index.vue with
an import of that utility; then update apply.vue to import and use the same
function so both pages call the shared markdownToPlainText (ensure the
implementation is identical and preserve current regex behavior and return
type).
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (5)
app/components/MarkdownDescription.vueapp/pages/dashboard/jobs/[id]/index.vueapp/pages/jobs/[slug]/apply.vueapp/pages/jobs/[slug]/index.vuepackage.json
| @@ -0,0 +1,31 @@ | |||
| <script setup lang="ts"> | |||
| import type { MDCParseOptions } from '@nuxtjs/mdc' | |||
| import MDC from '@nuxtjs/mdc/runtime/components/MDC.vue' | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check the current state of the file
cat -n app/components/MarkdownDescription.vueRepository: applirank/applirank
Length of output: 1044
🏁 Script executed:
# Check nuxt.config.ts for `@nuxtjs/mdc` registration
head -100 nuxt.config.tsRepository: applirank/applirank
Length of output: 3622
🏁 Script executed:
# Search for MDC imports and usage across the codebase
rg -n "MDC|@nuxtjs/mdc" --type vue --type ts app/Repository: applirank/applirank
Length of output: 90
🏁 Script executed:
# Check the `@nuxtjs/mdc` package structure and exports
find node_modules/@nuxtjs/mdc -name "package.json" | head -1 | xargs cat | grep -A 20 '"exports"'Repository: applirank/applirank
Length of output: 122
🏁 Script executed:
# Check package.json for `@nuxtjs/mdc` dependency
grep -n "mdc" package.jsonRepository: applirank/applirank
Length of output: 95
🏁 Script executed:
# Search for MDC usage with correct syntax (no type flag)
rg -n "MDC|@nuxtjs/mdc" app/Repository: applirank/applirank
Length of output: 383
🏁 Script executed:
# Check if `@nuxtjs/mdc` is listed as dependency
cat package.json | grep -A 50 '"dependencies"'Repository: applirank/applirank
Length of output: 865
🌐 Web query:
@nuxtjs/mdc v0.20 MDC component import public API documentation
💡 Result:
For @nuxtjs/mdc v0.20.x, the documented public “component import” / runtime API is here:
- Nuxt Modules docs for @nuxtjs/mdc (kept in sync with v0.20.x): Rendering section documents the exposed renderer components
<MDC>,<MDCRenderer>,<MDCSlot>, and shows importingparseMarkdownfrom@nuxtjs/mdc/runtime. [1] - Upstream repository README (same content): documents the same public components + runtime imports, and notes MDC component resolution like
::alert→components/mdc/Alert.vue. [2]
What the docs say is public to import/use
Renderer components (Nuxt app):
<MDC /><MDCRenderer /><MDCSlot />[1][2]
Runtime JS API (importable):
parseMarkdownfrom@nuxtjs/mdc/runtime[1][2]- (Also shown in the docs’ “Vue (non-Nuxt) project” section):
createMarkdownParser,rehypeHighlight,createShikiHighlighterfrom@nuxtjs/mdc/runtime, and importing the SFC directly:@nuxtjs/mdc/runtime/components/MDCRenderer.vue. [1][2]
Types:
MDCParserResulttype import from@nuxtjs/mdcis shown in the docs’ Vue-project example. [1][2]
Sources: [1] [2]
🌐 Web query:
@nuxtjs/mdc nuxt.config registration module setup
💡 Result:
1) Install
npx nuxi@latest module add mdc(or install manually with your package manager, then configure as below) [1]
2) Register the module in nuxt.config
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/mdc'],
})This is the standard way to register Nuxt modules via the modules array. [1][2]
3) (Optional) Configure @nuxtjs/mdc
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/mdc'],
mdc: {
// e.g. remarkPlugins, rehypePlugins, headings, highlight, components...
},
})[1]
Sources: [1] [2]
Register @nuxtjs/mdc module in nuxt.config.ts, then remove private runtime import.
The @nuxtjs/mdc package is installed but not registered in the modules array. Add '@nuxtjs/mdc' to the modules array in nuxt.config.ts. Once registered, the MDC component will be auto-imported globally, and the explicit private import from @nuxtjs/mdc/runtime/components/MDC.vue can be removed.
♻️ Proposed fix — register module and remove private path import
In nuxt.config.ts:
modules: ['@nuxtjs/seo', '@nuxt/content'],
+ '@nuxtjs/mdc',In app/components/MarkdownDescription.vue:
<script setup lang="ts">
import type { MDCParseOptions } from '@nuxtjs/mdc'
-import MDC from '@nuxtjs/mdc/runtime/components/MDC.vue'With @nuxtjs/mdc registered, <MDC> will be available as a globally auto-imported component.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/components/MarkdownDescription.vue` at line 3, Add the '@nuxtjs/mdc'
module to the Nuxt config and remove the private runtime component import: open
nuxt.config.ts and add '@nuxtjs/mdc' to the modules array so the package is
registered and its components are auto-imported, then in
app/components/MarkdownDescription.vue delete the explicit import line "import
MDC from '@nuxtjs/mdc/runtime/components/MDC.vue'" so the <MDC> component uses
the global auto-imported version.
| <template> | ||
| <MDC | ||
| :value="normalizedValue" | ||
| :parser-options="parserOptions" | ||
| class="prose prose-sm max-w-none prose-headings:mt-5 prose-headings:mb-2 prose-p:my-3 prose-ul:my-3 prose-ol:my-3 prose-li:my-1.5 prose-a:text-brand-600 hover:prose-a:text-brand-700 dark:prose-invert" | ||
| /> |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Missing NuxtErrorBoundary wrapper.
The component renders untrusted user-authored markdown. A rendering error in the MDC pipeline (e.g. from malformed content) will bubble up and crash the parent page without a fallback. Wrap with <NuxtErrorBoundary>.
♻️ Proposed fix
<template>
+ <NuxtErrorBoundary>
<MDC
:value="normalizedValue"
:parser-options="parserOptions"
class="prose prose-sm max-w-none ..."
/>
+ <template `#error`>
+ <p class="text-sm text-surface-500 whitespace-pre-wrap">{{ normalizedValue }}</p>
+ </template>
+ </NuxtErrorBoundary>
</template>As per coding guidelines: "Use NuxtErrorBoundary wrapper to catch component-level errors with fallback UI" (app/components/**/*.vue).
📝 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.
| <template> | |
| <MDC | |
| :value="normalizedValue" | |
| :parser-options="parserOptions" | |
| class="prose prose-sm max-w-none prose-headings:mt-5 prose-headings:mb-2 prose-p:my-3 prose-ul:my-3 prose-ol:my-3 prose-li:my-1.5 prose-a:text-brand-600 hover:prose-a:text-brand-700 dark:prose-invert" | |
| /> | |
| <template> | |
| <NuxtErrorBoundary> | |
| <MDC | |
| :value="normalizedValue" | |
| :parser-options="parserOptions" | |
| class="prose prose-sm max-w-none prose-headings:mt-5 prose-headings:mb-2 prose-p:my-3 prose-ul:my-3 prose-ol:my-3 prose-li:my-1.5 prose-a:text-brand-600 hover:prose-a:text-brand-700 dark:prose-invert" | |
| /> | |
| <template `#error`> | |
| <p class="text-sm text-surface-500 whitespace-pre-wrap">{{ normalizedValue }}</p> | |
| </template> | |
| </NuxtErrorBoundary> | |
| </template> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/components/MarkdownDescription.vue` around lines 25 - 30, The component
renders untrusted markdown but isn't wrapped in a NuxtErrorBoundary; wrap the
MDC usage inside a <NuxtErrorBoundary> in MarkdownDescription.vue so rendering
errors are caught and a fallback is shown, e.g., provide a fallback-slot or
default error content for the boundary; update the template that currently
renders <MDC :value="normalizedValue" :parser-options="parserOptions" .../> to
be the child of NuxtErrorBoundary and ensure the boundary exposes a
user-friendly fallback for failures.
| <MDC | ||
| :value="normalizedValue" | ||
| :parser-options="parserOptions" | ||
| class="prose prose-sm max-w-none prose-headings:mt-5 prose-headings:mb-2 prose-p:my-3 prose-ul:my-3 prose-ol:my-3 prose-li:my-1.5 prose-a:text-brand-600 hover:prose-a:text-brand-700 dark:prose-invert" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Check Tailwind configuration in nuxt.config.ts
fd nuxt.config -type f | head -5Repository: applirank/applirank
Length of output: 233
🏁 Script executed:
# Find and examine MarkdownDescription.vue
fd MarkdownDescription.vue -type fRepository: applirank/applirank
Length of output: 233
🏁 Script executed:
# Check package.json for Tailwind version
cat package.json | grep -A 5 -B 5 tailwindRepository: applirank/applirank
Length of output: 621
🏁 Script executed:
# Find the file correctly
fd MarkdownDescriptionRepository: applirank/applirank
Length of output: 101
🏁 Script executed:
# Check the exact content around line 29
cat -n app/components/MarkdownDescription.vue | sed -n '20,35p'Repository: applirank/applirank
Length of output: 523
🏁 Script executed:
# Check nuxt.config.ts for Tailwind v4 setup
cat -n nuxt.config.ts | grep -A 10 -B 5 tailwindRepository: applirank/applirank
Length of output: 1398
🏁 Script executed:
# Search for any Tailwind or typography documentation/comments in the codebase
rg "prose-a|hover:prose" --type vue --type ts -A 2 -B 2Repository: applirank/applirank
Length of output: 90
🏁 Script executed:
# Check if there are any other prose examples in the codebase
rg "prose prose-" --type vue -A 2 -B 2 | head -50Repository: applirank/applirank
Length of output: 90
🌐 Web query:
@tailwindcss/typography Tailwind v4 prose-a hover modifier order syntax
💡 Result:
In Tailwind v4 with @tailwindcss/typography, when stacking an element modifier like prose-a:* with a variant like hover:*, you generally put the variant last if you want the variant to apply to the link itself:
-
Hover the
<a>itself (most common):<article class="prose prose-a:text-cyan-600 prose-a:hover:text-cyan-500"> <a href="#">Link</a> </article>
This compiles like “
a:hover { … }” within prose. [1] -
Hover the whole prose container to affect links:
<article class="prose hover:prose-a:text-cyan-500"> <a href="#">Link</a> </article>
This applies when the container is hovered (not the link specifically). [2]
In Tailwind v3, the recommended stacking order was the opposite (variant first), which is why older examples can look “reversed” after upgrading. [1]
Sources: [1] [2]
Swap prose-a hover modifier order to Tailwind v4 syntax — links styled on individual link hover, not container hover.
In Tailwind CSS v4 with @tailwindcss/typography, the correct modifier order is prose-a:hover:text-* (variant last) to style individual <a> elements on their own hover. The current code hover:prose-a:text-brand-700 uses the v3 syntax and applies the hover effect to the entire prose container instead of individual links, causing all links to change colour when hovering anywhere over the component.
🐛 Fix — swap modifier order to Tailwind v4 syntax
- class="prose prose-sm max-w-none prose-headings:mt-5 prose-headings:mb-2 prose-p:my-3 prose-ul:my-3 prose-ol:my-3 prose-li:my-1.5 prose-a:text-brand-600 hover:prose-a:text-brand-700 dark:prose-invert"
+ class="prose prose-sm max-w-none prose-headings:mt-5 prose-headings:mb-2 prose-p:my-3 prose-ul:my-3 prose-ol:my-3 prose-li:my-1.5 prose-a:text-brand-600 prose-a:hover:text-brand-700 dark:prose-invert"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/components/MarkdownDescription.vue` at line 29, The prose container's
class uses old Tailwind v3 modifier ordering (`hover:prose-a:text-brand-700`)
which applies hover to the whole container; update the modifier order to
Tailwind v4 syntax so link hover targets individual anchors (replace the
`hover:prose-a:text-brand-700` token with `prose-a:hover:text-brand-700` in the
class string inside the MarkdownDescription.vue component) so only the hovered
<a> receives the color change.
| function markdownToPlainText(markdown?: string | null): string { | ||
| if (!markdown) return '' | ||
|
|
||
| return markdown | ||
| .replace(/```[\s\S]*?```/g, ' ') | ||
| .replace(/`([^`]+)`/g, '$1') | ||
| .replace(/!\[([^\]]*)\]\([^)]*\)/g, '$1') | ||
| .replace(/\[([^\]]+)\]\([^)]*\)/g, '$1') | ||
| .replace(/^#{1,6}\s+/gm, '') | ||
| .replace(/^\s{0,3}[-*+]\s+/gm, '') | ||
| .replace(/^\s{0,3}\d+\.\s+/gm, '') | ||
| .replace(/[*_~]/g, '') | ||
| .replace(/\n+/g, ' ') | ||
| .replace(/\s+/g, ' ') | ||
| .trim() | ||
| } |
There was a problem hiding this comment.
markdownToPlainText strips underscores from all text, corrupting snake_case terms.
Line 27's character class [*_~] removes every _ character regardless of context. A job description containing terms like full_time, snake_case_variable, or any technical name with underscores will have those underscores silently dropped in the generated SEO metadata. For example, "full_time position" becomes "fulltime position".
A targeted approach that only strips emphasis/bold markers in context would be safer.
🐛 Proposed fix — replace lone emphasis markers only, preserve underscores inside words
- .replace(/[*_~]/g, '')
+ .replace(/\*\*([^*]+)\*\*/g, '$1') // bold **text**
+ .replace(/\*([^*]+)\*/g, '$1') // italic *text*
+ .replace(/~~([^~]+)~~/g, '$1') // strikethrough ~~text~~
+ .replace(/(?<!\w)_([^_]+)_(?!\w)/g, '$1') // italic _text_ (not mid-word)
+ .replace(/(?<!\w)__([^_]+)__(?!\w)/g, '$1') // bold __text__🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/pages/jobs/`[slug]/index.vue around lines 16 - 31, The function
markdownToPlainText currently strips all underscores via .replace(/[*_~]/g, ''),
which destroys snake_case; replace that blanket removal with targeted regexes
that only remove markdown emphasis/strong/strikethrough markers while preserving
underscores inside words. Concretely, in markdownToPlainText replace the
.replace(/[*_~]/g, '') step with targeted replacements such as removing strong
markers .replace(/(\*\*|__)(?=\S)([\s\S]*?\S)\1/g, '$2'), removing emphasis
markers .replace(/(\*|_)(?=\S)([\s\S]*?\S)\1/g, '$2'), and removing
strikethrough markers .replace(/(~{2})(?=\S)([\s\S]*?\S)\1/g, '$2') so
underscores within words (e.g., snake_case) remain unchanged.
| "@nuxt/content": "^3.11.2", | ||
| "@nuxtjs/mdc": "^0.20.1", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find and examine the nuxt configuration
find . -name "nuxt.config.*" -type f 2>/dev/null | head -5Repository: applirank/applirank
Length of output: 79
🏁 Script executed:
#!/bin/bash
# Check if package-lock.json or yarn.lock exists to see resolved versions
ls -la package-lock.json yarn.lock pnpm-lock.yaml 2>/dev/null | head -5Repository: applirank/applirank
Length of output: 131
🏁 Script executed:
#!/bin/bash
# Examine the current package.json to see the full dependency list
cat -n package.json | head -50Repository: applirank/applirank
Length of output: 1792
🏁 Script executed:
#!/bin/bash
# Search for `@nuxt/content` in node_modules to check its declared dependencies
find node_modules -path "*/node_modules/@nuxt/content/package.json" -maxdepth 3 2>/dev/null | xargs cat 2>/dev/null | grep -A 5 -B 5 "@nuxtjs/mdc" || echo "File not found or `@nuxtjs/mdc` not listed"Repository: applirank/applirank
Length of output: 103
🏁 Script executed:
#!/bin/bash
# Read nuxt.config.ts to check for mdc module registration
cat -n nuxt.config.tsRepository: applirank/applirank
Length of output: 6328
🏁 Script executed:
#!/bin/bash
# Search package-lock.json for `@nuxtjs/mdc` to see resolved versions and dependencies
grep -A 5 -B 2 '"@nuxtjs/mdc"' package-lock.json | head -50Repository: applirank/applirank
Length of output: 652
🏁 Script executed:
#!/bin/bash
# Check if `@nuxt/content` actually lists `@nuxtjs/mdc` as a dependency in package-lock.json
grep -A 20 '"@nuxt/content": {' package-lock.json | grep -E '(version|@nuxtjs/mdc)' | head -20Repository: applirank/applirank
Length of output: 45
🏁 Script executed:
#!/bin/bash
# Check `@nuxt/content` documentation or package.json to see if it declares mdc as a module auto-import
grep -r "nuxt.modules\|auto.register\|registerModule" node_modules/@nuxt/content --include="*.json" --include="*.ts" --include="*.js" 2>/dev/null | head -20Repository: applirank/applirank
Length of output: 45
🌐 Web query:
@nuxt/content v3.11 @nuxtjs/mdc auto-registration module setup
💡 Result:
Goal: auto-register Vue components for use in Markdown (MDC) with @nuxt/content v3.11 (and optionally @nuxtjs/mdc)
1) Recommended setup for Nuxt Content v3.11 (Content renders MDC for you)
Install / enable Content:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/content']
})Nuxt Content lets you use Vue components inside Markdown with MDC syntax. Components placed in components/content/ are available to Markdown without extra work. [1]
Auto-registration rule of thumb
- For Markdown usage: put components in
components/content/→ usable in.mdvia MDC (::my-component ... ::). [1] - If you also want to use those same components in Vue templates via auto-import/global registration: explicitly register that directory as global (Nuxt Content v3 no longer makes
components/contentglobal for you outside Markdown). [2]
Example (global registration for using them in Vue templates too):
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxt/content'],
components: [
// your normal components auto-import (default)
'~/components',
// make content components globally available in Vue templates too (optional)
{ path: '~/components/content', global: true }
]
})(Using them in Markdown still works either way.) [1][2]
2) If you want to use @nuxtjs/mdc directly (outside Content pages, or custom rendering)
Install and enable:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@nuxtjs/mdc']
})With @nuxtjs/mdc, MDC block components like ::alert ... :: resolve from components/mdc/Alert.vue by convention. [3][4]
3) Minimal directory conventions (quick reference)
components/content/*→ easiest path for Nuxt Content Markdown components. [1]components/mdc/*→ convention used by @nuxtjs/mdc examples (e.g.::alert). [3][4]
Sources: Nuxt Content Markdown/MDC docs (components/content + global note) [1], Nuxt Content v3 migration note about components/content not being globally registered outside markdown [2], Nuxt MDC module/docs + repo example showing components/mdc/Alert.vue resolution [3][4].
Remove the redundant @nuxtjs/mdc dependency or clarify its purpose and register it in nuxt.config.ts.
@nuxt/content@3.11.2 already includes @nuxtjs/mdc as an internal dependency (both resolve to ^0.20.1 with no version mismatch risk). The explicit @nuxtjs/mdc entry in package.json is redundant—@nuxt/content handles MDC rendering for Markdown files without requiring separate module registration.
If @nuxtjs/mdc is intentionally added for custom MDC usage outside of @nuxt/content, it must be registered in nuxt.config.ts's modules array (line 18). Currently, it is not declared as a module, which means its auto-registration features are inactive.
Action: Either remove @nuxtjs/mdc from package.json if unused, or add '@nuxtjs/mdc' to the modules array if needed.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@package.json` around lines 21 - 22, The package.json contains an explicit
"@nuxtjs/mdc" dependency that is redundant because "@nuxt/content" already
includes it; either remove the "@nuxtjs/mdc" entry from package.json to avoid
duplication, or if you intentionally use MDC beyond markdown rendering, add
"'@nuxtjs/mdc'" to the modules array in nuxt.config.ts so the module is
registered (check the modules array symbol in nuxt.config.ts) and keep
package.json accordingly.
Summary
Type of change
Validation
DCO
Signed-off-by) viagit commit -sSummary by CodeRabbit