TW-Elements icon indicating copy to clipboard operation
TW-Elements copied to clipboard

Nuxt 2 integration - document is not defined

Open BrunoGGM opened this issue 2 years ago • 4 comments

It is not possible to make it work in with version 1.0.0-beta2, I am working with nuxt 2.17 and vue 2.7

** The following error is displayed ** document is not defined

image

Uncaught InternalError: too much recursion
    tokenize http://app.home.test/test:990
    highlight http://app.home.test/test:990
    highlightElement http://app.home.test/test:990
    highlightAll http://app.home.test/test:990
    showFrameContext http://app.home.test/test:1049
    <anonymous> http://app.home.test/test:1063
    e https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js:2

image

Show your code

pages/test.vue

    <template>
      <div>
        <client-only placeholder="Loading...">
          <TestComponent></TestComponent>
        </client-only>
      </div>
    </template>
    
    <script setup></script>
    
    <style></style>

components/TestComponent.vue

    <template>
      <div class="relative mb-3" data-te-datepicker-init data-te-input-wrapper-init>
        <input
          type="text"
          class="peer block min-h-[auto] w-full rounded border-0 bg-transparent px-3 py-[0.32rem] leading-[1.6] outline-none transition-all duration-200 ease-linear focus:placeholder:opacity-100 peer-focus:text-primary data-[te-input-state-active]:placeholder:opacity-100 motion-reduce:transition-none dark:text-neutral-200 dark:placeholder:text-neutral-200 dark:peer-focus:text-primary [&:not([data-te-input-placeholder-active])]:placeholder:opacity-0"
          placeholder="Select a date"
        />
        <label
          for="floatingInput"
          class="pointer-events-none absolute left-3 top-0 mb-0 max-w-[90%] origin-[0_0] truncate pt-[0.37rem] leading-[1.6] text-neutral-500 transition-all duration-200 ease-out peer-focus:-translate-y-[0.9rem] peer-focus:scale-[0.8] peer-focus:text-primary peer-data-[te-input-state-active]:-translate-y-[0.9rem] peer-data-[te-input-state-active]:scale-[0.8] motion-reduce:transition-none dark:text-neutral-200 dark:peer-focus:text-primary"
          >Select a date</label
        >
      </div>
    </template>
    
    <script setup>
    import { Datepicker, Input, initTE } from 'tw-elements';
    import { onMounted } from 'vue';
    
    onMounted(() => {
      setTimeout(() => {
        initTE({ Datepicker, Input });
      }, 1000);
    });
    </script>
    
    <style></style>

nuxt.config.js

export default {
      target: 'static',
      head: {
        htmlAttrs: {
          lang: 'es',
        },
        meta: [
          { charset: 'utf-8' },
          { name: 'viewport', content: 'width=device-width, initial-scale=1' },
          { hid: 'description', name: 'description', content: '' },
          { name: 'format-detection', content: 'telephone=no' },
        ],
        link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.png' }],
      },
    
      // server config
      server: {
        port: process.env.SERVER_PORT, // default: 3000
      },
    
      // Auto import components: https://go.nuxtjs.dev/config-components
      components: true,
    
      // Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
      buildModules: [
        // https://go.nuxtjs.dev/typescript
        '@nuxt/typescript-build',
      ],
    
      // Modules: https://go.nuxtjs.dev/config-modules
      modules: ['@nuxtjs/axios', '@nuxtjs/auth-next', '@nuxtjs/i18n'],
    
      router: {
        middleware: ['auth'],
      },
    
      // Build Configuration: https://go.nuxtjs.dev/config-build
      build: {
        postcss: {
          postcssOptions: {
            plugins: {
              tailwindcss: {},
              autoprefixer: {},
            },
          },
        },
        analyze: true,
        extractCSS: true,
        standalone: true,
      },
    publicRuntimeConfig: {},
      watchers: {
        webpack: {
          ignored: /node_modules/,
        },
      },
    };

tailwind.config.js

/** @type {import('tailwindcss').Config} */

module.exports = {
  content: [
    './components/**/*.{js,vue,ts}',
    './layouts/**/*.vue',
    './pages/**/*.vue',
    './plugins/**/*.{js,ts}',
    './nuxt.config.{js,ts}',
    './node_modules/tw-elements/dist/js/**/*.js',
  ],
  plugins: [require('@tailwindcss/forms'), require('tw-elements/dist/plugin')],
};

BrunoGGM avatar Jun 20 '23 01:06 BrunoGGM

Hi! In nuxt 2 try using dynamic imports in the mounted option like this:

<template>
  <div class="relative mb-3" data-te-datepicker-init data-te-input-wrapper-init>
         ...
  </div>
</template>

<script>
export default {
  name: "Datepicker",
  mounted: async function () {
    const { Datepicker, Input, initTE } = await import("tw-elements");

    initTE({ Datepicker, Input });
  },
};
</script>

Hope it helps!

juujisai avatar Jun 27 '23 12:06 juujisai

@juujisai Thank you for your time and your answer, your solution works.

But I'm a bit unhappy with the size of the final bundle, in 1.0.0-beta2 the size of the final bundle increases and it seems to now add a chart.es.js file.

1.0.0-beta2 image

1.0.0-beta1 image

BrunoGGM avatar Jun 30 '23 02:06 BrunoGGM

chart.es.js is necessary for our chart component. From what I've seen, vite is removing the chart.es.js if charts weren't used in the app, while webpack doesn't. This file may be removed if you did not use the charts.

I'll try to look at the webpack builds when I can.

juujisai avatar Jun 30 '23 13:06 juujisai

hi mounted: async function () { const { Datepicker, Input, initTE } = await import("tw-elements");

initTE({ Datepicker, Input });

},

i am using nuxt 3 and this is working perfectly but should i add every file this command

is it possible for me to add globally

Ischafak avatar Aug 07 '23 11:08 Ischafak