nuxt.jsnuxt3.jsslickgrid

Nuxt 3: How to use external libraries that require jQuery?


I have a vue/vite website that i'm migrating to Nuxt to improve structure and SEO.

Most pages work fine, but the page that uses jQuery returns a 500 Error, jquery is not defined.

I thought this must be because it's trying to render server-side so I disabled that (so I thought) by adding the following code in nuxt.config.ts:

routeRules: {
    '/profile/**': { ssr: false },
    '/team/**': { ssr: false },
}

But I still get the following error.

500
jQuery is not defined

at http://localhost:3000/_nuxt/assets/slickgrid/lib/jquery-ui-1.11.3.min.js:6:75
at http://localhost:3000/_nuxt/assets/slickgrid/lib/jquery-ui-1.11.3.min.js:6:84

This is the start of the vue file that is causing the error:

<script>
import {$,jQuery} from 'jquery'
// export for others scripts to use
// window.$ = $;
// window.jQuery = jQuery;
// import '@/assets/jquery.js'
import '@/assets/slickgrid/lib/firebugx.js'
import '@/assets/slickgrid/lib/jquery-ui-1.11.3.min.js'

How can I load these files client-side only? Apologies if this is a dumb question, I might be completely misunderstanding the concept.


Solution

  • As stated here, it's not recommended to use jquery on your Nuxt projects. https://stackoverflow.com/a/66423820/21341655

    If you really want to, there are some ways to do it.

    npm i jquery

    Method 1

    ~/plugins/jquery.client.js

    import $ from 'jquery'
    export default defineNuxtPlugin( () => {
        window.jQuery = window.$ = $
    } )

    Method 2

    ~/plugins/jquery.js

    import $ from 'jquery'
    export default defineNuxtPlugin( ( nuxtAPp ) => {
       nuxtAPp.hook( 'app:beforeMount', () => {
          window.jQuery = window.$ = $
       } )
    } )

    Method 3

    https://stackoverflow.com/a/76454524/21341655

    Example usage

    <script setup>
    onMounted(() => {
        $('#hello').append('World')
    })
    </script>
    <template>
        <div>
            <div id="hello"></div>
        </div>
    </template>

    To use JQuery in a single page, here is the basic example.

    ~/pages/test.vue

    <script setup>
    import $ from 'jquery'
    
    onMounted(() => {
        window.jQuery = window.$ = $
        $('.hello').append('Hello jQuery')
    })
    
    </script>
    <template>
        <div>
            <div class="hello"></div>
        </div>
    </template>

    Tested and it works.

    enter image description here

    Hope that helps!

    Edit: Disabling the SSR in nuxt.config.ts is optional. These methods will work without applying the routeRules

    Slick Grid basic configuration and example

    <template>
      <div>
        <h1>SlickGrid Example</h1>
        <div class="slick-grid-container" ref="slickGridContainer"></div>
      </div>
    </template>
    
    <script setup>
      useHead({
        script: [
          {
            src: 'https://cdnjs.cloudflare.com/ajax/libs/6pac-slickgrid/4.0.1/slick.core.min.js',
            type: 'text/javascript'
          },
          {
            src: 'https://cdnjs.cloudflare.com/ajax/libs/6pac-slickgrid/4.0.1/slick.compositeeditor.min.js',
            type: 'text/javascript'
          },
          {
            src: 'https://cdnjs.cloudflare.com/ajax/libs/6pac-slickgrid/4.0.1/slick.grid.min.js',
            type: 'text/javascript'
          },
          {
            src: 'https://cdnjs.cloudflare.com/ajax/libs/6pac-slickgrid/4.0.1/slick.interactions.min.js',
            type: 'text/javascript'
          }
        ],
        link: [
          {
            href: 'https://cdnjs.cloudflare.com/ajax/libs/6pac-slickgrid/4.0.1/slick.grid.min.css',
            rel: 'stylesheet'
          },
          {
            href: 'https://cdnjs.cloudflare.com/ajax/libs/6pac-slickgrid/4.0.1/slick-default-theme.min.css',
            rel: 'stylesheet'
          }
        ]
      })
    
      const slickGridContainer = ref(null)
    
      let grid
    
      const columns = [
        { id: 'id', name: 'ID', field: 'id' },
        { id: 'name', name: 'Name', field: 'name' }
        // Define more columns
      ]
    
      const options = {
        enableCellNavigation: true,
        enableColumnReorder: false
        // Define more options
      }
    
      const data = [
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' }
        // Add more data
      ]
    
      onMounted(() => {
        grid = new Slick.Grid(slickGridContainer.value, data, columns, options)
      })
    
      onBeforeUnmount(() => {
        grid.destroy()
      })
    </script>
    
    <style scoped>
      .slick-grid-container {
        height: 300px;
      }
    </style>

    enter image description here