Site icon FSIBLOG

How to Add Client-side Scripts to Nuxt.js?

How to Add Client-side Scripts to Nuxt.js?

How to Add Client-side Scripts to Nuxt.js?

I’ve been working with Nuxt.js for a while now, and one of the challenges I encountered was adding client-side scripts especially when transitioning from a standard HTML setup to a universal (isomorphic) framework. Today, I’m sharing my journey in integrating client-side scripts into Nuxt.js, addressing common pitfalls, and enhancing your project with extra practice functionality.

The Faulty (Initial) Code

At first, I attempted to integrate a simple jQuery script that adds a fixed header class when the user scrolls. Here’s the initial Vue/Nuxt component I built:

<template>
<div>
<nav>Navigation Bar</nav>
<div style="height: 2000px;">Content goes here</div>
</div>
</template>

<script>
export default {
mounted() {
$(window).scroll(function(){
if ($(window).scrollTop() >= 200) {
$('nav').addClass('fixed-header');
} else {
$('nav').removeClass('fixed-header');
}
});
}
}
</script>

<style>
.fixed-header {
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: #fff;
z-index: 9999;
}
</style>

Identified Error and Explanation

When I loaded this component in Nuxt, I encountered a problem. The error message pointed to issues with jQuery and the use of the window object. Here’s why:

Correcting the Issue

After digging into the problem, I discovered two key steps to fix the errors.

Ensure jQuery Runs Only on the Client

I modified the mounted() lifecycle hook to guarantee the script runs only on the client. Since the mounted() hook itself runs only in the browser, I added an extra check for safety:

() {
if (process.client) {
$(window).on("scroll", function(){
if ($(window).scrollTop() >= 200) {
$("nav").addClass("fixed-header");
} else {
$("nav").removeClass("fixed-header");
}
});
}
}

Properly Load jQuery as a Plugin

To ensure that jQuery is available globally and only loads in the browser, I followed these steps:

npm install jquery
// plugins/jquery.client.js
import Vue from 'vue'
import jQuery from 'jquery'
// Make sure to expose jQuery globally if needed
if (process.client) {
  window.$ = window.jQuery = jQuery
}
// nuxt.config.js
export default {
  plugins: [
    { src: '~/plugins/jquery.client.js', mode: 'client' }
  ]
}

This setup ensures jQuery is loaded only on the client and made available globally as $ or jQuery, thereby preventing any server-side rendering errors.

Enhanced Code with Additional Practice Functionality

Once I had the basic setup working, I decided to extend the functionality. I wanted to not only toggle a fixed header but also change the background color of the header dynamically after scrolling past a certain point. Here’s the enhanced Nuxt component:

<template>
<div>
<nav :class="{ 'fixed-header': isFixed, 'color-change': isColored }">
Navigation Bar
</nav>
<div style="height: 2000px;">Content goes here</div>
</div>
</template>

<script>
export default {
data() {
return {
isFixed: false,
isColored: false
}
},
mounted() {
if (process.client) {
// Use jQuery event listener safely
$(window).on("scroll", () => {
const scrollPos = $(window).scrollTop();

// Toggle fixed header based on scroll position
if (scrollPos >= 200) {
$('nav').addClass('fixed-header');
this.isFixed = true;
} else {
$('nav').removeClass('fixed-header');
this.isFixed = false;
}

// Extra functionality: toggle color-change class
// For example, change background color when scrolled past 400 pixels
if (scrollPos >= 400) {
$('nav').addClass('color-change');
this.isColored = true;
} else {
$('nav').removeClass('color-change');
this.isColored = false;
}
});
}
},
beforeDestroy() {
// Clean up the event listener when the component is destroyed
if (process.client) {
$(window).off("scroll");
}
}
}
</script>

<style scoped>
.fixed-header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 9999;
/* Basic styling when header is fixed */
background-color: #fff;
transition: background-color 0.3s ease;
}

/* Extra style applied after scrolling past 400px */
.color-change {
background-color: #f0a;
}
</style>

Explanation of the Enhanced Code

Final Thoughts

I learned that integrating client-side scripts into Nuxt.js requires careful attention to the differences between server and client environments. Here are the key takeaways from my experience:

By following the steps above, I was able to successfully integrate and extend client-side scripts in my Nuxt.js projects. I hope this walkthrough helps you navigate similar challenges and inspires you to experiment with more dynamic UI behaviors in your own applications.

Exit mobile version