3

I am trying to run a basic Nuxt app with an external Vue component built using vue-cli inside a lerna monorepo.

The page briefly shows component content (server rendered) and then it disappears throwing the following errors.

"export 'default' (imported as 'Header') was not found in 'a2b-header'

followed by

Mismatching childNodes vs. VNodes: NodeList(7) [svg, text, div#app, text, h2.subtitle, text, div.links] (7) [VNode, VNode, VNode, VNode, VNode, VNode, VNode]

and finally a red Vue warning

[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.

The setup I am using for the external component is package.json:

{
  "name": "a2b-header",
  "version": "0.1.0",
  "private": true,
  "main": "./dist/a2b-header.umd.js",
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build --target lib --name a2b-header src/main.js",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "core-js": "^3.4.3",
    "vue": "^2.6.10"
  },
  ...
}

my main.js looks like below:

import Header from './Header.vue'

export default Header

and component file itself Header.vue is:

<template>
  <div id="app">
    <h1>Welcome to Your Vue.js App</h1>
  </div>
</template>

<script>
export default {
  name: 'Header'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

that all is being imported in the Nuxt project index.vue using simple:

import Header from 'a2b-header'

and.... it does not work. I am thinking the mismatch of SSR vs clients is connected to the incorrect export, probably solvable by some webpack config but after trying many different things I am rly struggling here.

The reason I want this to get it to work is that in the monorepo we plan to have various Vue applications (both SPA and and Nuxt )and the ability to encapsulate common code in components reusable across different projects is crucial.

irwin
  • 115
  • 1
  • 2
  • 10

3 Answers3

13

Wrap your component with <ClientOnly> <YourComponent> </ClientOnly>

Go to the official nuxt docs for more info:

https://nuxtjs.org/docs/2.x/features/nuxt-components#the-client-only-component

Edward Casanova
  • 726
  • 7
  • 19
  • 1
    Hooray! Thanks a lot! This solved the issue for me. I had a component that generated a list with v-for from a dynamically changing array. Wrapping the whole component in ` fixed the issue! – Fred Feb 19 '23 at 17:00
4

OK after a lot of head-banging, the solution for this is as follows. In nuxt.config.js, in the build block inside extend function we need to add:

    extend (config, ctx) {
      config.resolve.symlinks = false
    }

This setting finally correctly builds a shared package symlinked into the Nuxt project node_modules. The export default error is gone and so all mismatching SSR vs Vnode warnings.

irwin
  • 115
  • 1
  • 2
  • 10
1

You could try wrapping the component with , or moving all dom manipulations to the mounted lifecycle hook.

https://github.com/nuxt/nuxt.js/issues/1700#issuecomment-331099596

and this answer may help you

larrykkk
  • 459
  • 8
  • 10
  • Thanks for reply! I do not want to use no-ssr as that component should be rendered correctly on the server, it will have no references to DOM and zero manipulations. – irwin Jan 31 '20 at 13:05
  • I have also tried the stack trace inspection, it is weird... but the elm and vnode.elm are identical. – irwin Jan 31 '20 at 13:05