N
Nuxt2mo ago
Helgi

Component failing to resolvel

I am trying to make use of the v-viewer component as a Nuxt plugin. I am adding the plugin like demonstrated below (allthough I've also tried fetching both import { directive, component } from 'v-viewer' and registering them each manually as well). plugins/v-viewer.client.ts
import { defineNuxtPlugin } from '#app'
import 'viewerjs/dist/viewer.css'
import VueViewer from 'v-viewer'

export default defineNuxtPlugin((nuxtApp) => {
console.log("Loading VueViewer Plugin") // This `console.log` message shows only in the browser, as expected.
nuxtApp.vueApp.use(VueViewer)
})
import { defineNuxtPlugin } from '#app'
import 'viewerjs/dist/viewer.css'
import VueViewer from 'v-viewer'

export default defineNuxtPlugin((nuxtApp) => {
console.log("Loading VueViewer Plugin") // This `console.log` message shows only in the browser, as expected.
nuxtApp.vueApp.use(VueViewer)
})
Then I rendering the component on my page like this:
<script setup lang="ts">
const viewerOptions = "..."
const viewerPhotos = "..."
</script>

<template>
{{ console.log("Loading serverside") }} <!-- This outputs in both serverside and clientside -->
<ClientOnly>
{{ console.log("Loading viewer component") }} <!-- This only outputs clientside -->
<viewer v-if="viewerPhotos.length > 0" :images="viewerPhotos" :options="viewerOptions">
<NuxtImg v-for="(image, index) in viewerPhotos" :src="image.displayUrl" :alt="image.alt" :key="`slide_${index}`" />
</viewer>
</ClientOnly>
</template>
<script setup lang="ts">
const viewerOptions = "..."
const viewerPhotos = "..."
</script>

<template>
{{ console.log("Loading serverside") }} <!-- This outputs in both serverside and clientside -->
<ClientOnly>
{{ console.log("Loading viewer component") }} <!-- This only outputs clientside -->
<viewer v-if="viewerPhotos.length > 0" :images="viewerPhotos" :options="viewerOptions">
<NuxtImg v-for="(image, index) in viewerPhotos" :src="image.displayUrl" :alt="image.alt" :key="`slide_${index}`" />
</viewer>
</ClientOnly>
</template>
The second I load the page in my browser, I get so many warnings and errors in my log that it completely fills up the terminal context. I had to output everything into a file to be able to find the first error, which was: WARN [Vue warn]: Failed to resolve component: viewer. I get this warning serverside even though the component works exactly as expected clientside, and the client-only console message is never outputted serverside. Which in my head means it shouldn't try to mount the component at all serverside. I feel like I've tried every approach implementing this, and no matter what I do, the error does not go away unless I comment out the viewer. Also tried transpiling, without success.
npm
v-viewer
Image viewer component for vue, supports rotation, scale, zoom and so on, based on viewer.js. Latest version: 3.0.21, last published: a day ago. Start using v-viewer in your project by running npm i v-viewer. There are 380 other projects in the npm registry using v-viewer.
2 Replies
kapa.ai
kapa.ai2mo ago
Hi @Helgi. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the information provided, it seems you're encountering an issue with resolving the viewer component from the v-viewer library in your Nuxt 3 application. Let's address this problem step by step. 1. Component Resolution: The warning "Failed to resolve component: viewer" typically occurs when Vue can't find the component you're trying to use. In Nuxt 3, this can happen during server-side rendering, even if the component is intended for client-side use only. 2. Client-Side Plugin: Your approach of creating a client-side plugin for v-viewer is correct. However, we need to ensure that the component is properly registered. 3. Using ClientOnly: You're correctly using <ClientOnly> to wrap the viewer component, which should prevent it from being rendered on the server. However, Nuxt still tries to resolve all components during server-side rendering, which is why you're seeing the warning. To resolve this issue, try the following: 1. Modify your plugin to explicitly register the viewer component:
// plugins/v-viewer.client.ts
import { defineNuxtPlugin } from '#app'
import 'viewerjs/dist/viewer.css'
import VueViewer from 'v-viewer'

export default defineNuxtPlugin((nuxtApp) => {
console.log("Loading VueViewer Plugin")
nuxtApp.vueApp.use(VueViewer)
nuxtApp.vueApp.component('viewer', VueViewer.component)
})
// plugins/v-viewer.client.ts
import { defineNuxtPlugin } from '#app'
import 'viewerjs/dist/viewer.css'
import VueViewer from 'v-viewer'

export default defineNuxtPlugin((nuxtApp) => {
console.log("Loading VueViewer Plugin")
nuxtApp.vueApp.use(VueViewer)
nuxtApp.vueApp.component('viewer', VueViewer.component)
})
2. In your Nuxt configuration, add v-viewer to the build.transpile array to ensure it's properly transpiled:
// nuxt.config.ts
export default defineNuxtConfig({
build: {
transpile: ['v-viewer']
}
})
// nuxt.config.ts
export default defineNuxtConfig({
build: {
transpile: ['v-viewer']
}
})
3. If the issue persists, you can try using a dynamic import for the viewer component in your template:
<template>
<ClientOnly>
{{ console.log("Loading viewer component") }}
<component
:is="$imports.viewer"
v-if="viewerPhotos.length > 0"
:images="viewerPhotos"
:options="viewerOptions"
>
<NuxtImg
v-for="(image, index) in viewerPhotos"
:src="image.displayUrl"
:alt="image.alt"
:key="`slide_${index}`"
/>
</component>
</ClientOnly>
</template>

<script setup>
const viewerOptions = "..."
const viewerPhotos = "..."

const $imports = {
viewer: defineAsyncComponent(() => import('v-viewer').then(m => m.component))
}
</script>
<template>
<ClientOnly>
{{ console.log("Loading viewer component") }}
<component
:is="$imports.viewer"
v-if="viewerPhotos.length > 0"
:images="viewerPhotos"
:options="viewerOptions"
>
<NuxtImg
v-for="(image, index) in viewerPhotos"
:src="image.displayUrl"
:alt="image.alt"
:key="`slide_${index}`"
/>
</component>
</ClientOnly>
</template>

<script setup>
const viewerOptions = "..."
const viewerPhotos = "..."

const $imports = {
viewer: defineAsyncComponent(() => import('v-viewer').then(m => m.component))
}
</script>
This approach uses defineAsyncComponent to dynamically import the viewer component only on the client side, which should prevent the server-side resolution error. If you're still encountering issues after trying these solutions, it might be worth checking if there are any compatibility issues between the version of v-viewer you're using and Nuxt 3. You may need to look for a Nuxt 3 compatible version or consider using an alternative image viewer library that's known to work well with Nuxt 3. Nuxt 3 Docs: Client Components (https://nuxt.com/docs/guide/directory-structure/components#client-components) Nuxt 3 Docs: Troubleshooting ESM Issues (https://nuxt.com/docs/guide/concepts/esm#troubleshooting-esm-issues) Remember to clear your Nuxt cache and rebuild your application after making these changes. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@319191065611599882> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Want results from more Discord servers?
Add your server