N
Nuxt2mo ago
Ryuuuu

Loading scripts dynamically

I have a page that im trying to optimize for speed which has jquery + a couple other scripts that depend on jquery in useHead(). I don't want these scripts to load on the page until i click a button which changes what appears on the page, but its still the same page. If i put useHead in the components that appear after the button click, they load but take way too long and it errors on my onMounted() where im trying to use those scripts since they arent loaded yet. It even somehow errors my other scripts saying jquery is not defined, seems like when trying to load scripts without refreshing the page they don't even load correctly. How can i load scripts dynamically like in a function on button click without using useHead? it doesnt seem like useHead is going to work at all unless it has some extra options
2 Replies
kapa.ai
kapa.ai2mo ago
Hi @Ryuuuu. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- I understand you're trying to optimize your page by loading jQuery and dependent scripts only when needed after a button click. Let's explore how to handle this in Nuxt. Loading Scripts Dynamically in Nuxt While useHead() is typically used for managing head tags, it's not ideal for dynamically loading scripts after user interaction. Here are better approaches: Method 1: Using textContent with useHead() You can use the textContent property with useHead() to create inline scripts that load your external scripts dynamically:
useHead({
script: [
{
textContent: `
function loadScripts() {
const jquery = document.createElement('script');
jquery.src = '<https://path-to-jquery.js';>
jquery.onload = function() {
// Load dependent scripts after jQuery loads
const dependentScript = document.createElement('script');
dependentScript.src = '<https://path-to-dependent-script.js';>
document.body.appendChild(dependentScript);
};
document.body.appendChild(jquery);
}
`,
tagPosition: "bodyClose",
},
],
});
useHead({
script: [
{
textContent: `
function loadScripts() {
const jquery = document.createElement('script');
jquery.src = '<https://path-to-jquery.js';>
jquery.onload = function() {
// Load dependent scripts after jQuery loads
const dependentScript = document.createElement('script');
dependentScript.src = '<https://path-to-dependent-script.js';>
document.body.appendChild(dependentScript);
};
document.body.appendChild(jquery);
}
`,
tagPosition: "bodyClose",
},
],
});
Then call loadScripts() when your button is clicked. This approach is documented in Stack Overflow. Method 2: Client-Side Script Loading with Plugin A more Nuxt-friendly approach is to create a client-side plugin: 1. Create a plugin file plugins/dynamic-scripts.client.js:
export default defineNuxtPlugin(() => {
return {
provide: {
loadScripts: () => {
return new Promise((resolve) => {
const jquery = document.createElement('script');
jquery.src = '<https://path-to-jquery.js';>
jquery.onload = function() {
window.jQuery = window.$; // Make jQuery globally available

// Load dependent scripts
const dependentScript = document.createElement('script');
dependentScript.src = '<https://path-to-dependent-script.js';>
dependentScript.onload = resolve;
document.body.appendChild(dependentScript);
};
document.body.appendChild(jquery);
});
}
}
}
})
export default defineNuxtPlugin(() => {
return {
provide: {
loadScripts: () => {
return new Promise((resolve) => {
const jquery = document.createElement('script');
jquery.src = '<https://path-to-jquery.js';>
jquery.onload = function() {
window.jQuery = window.$; // Make jQuery globally available

// Load dependent scripts
const dependentScript = document.createElement('script');
dependentScript.src = '<https://path-to-dependent-script.js';>
dependentScript.onload = resolve;
document.body.appendChild(dependentScript);
};
document.body.appendChild(jquery);
});
}
}
}
})
2. In your component:
<script setup>
const { $loadScripts } = useNuxtApp();

async function handleButtonClick() {
await $loadScripts();
// Now you can safely use jQuery and dependent scripts
$('#element').doSomething();
}
</script>
<script setup>
const { $loadScripts } = useNuxtApp();

async function handleButtonClick() {
await $loadScripts();
// Now you can safely use jQuery and dependent scripts
$('#element').doSomething();
}
</script>
Method 3: Using ClientOnly with onMounted For components that need jQuery, wrap them in <ClientOnly> and use nextTick() with onMounted():
<template>
<div>
<button @click="showComponent = true">Show Component</button>
<ClientOnly v-if="showComponent">
<MyJQueryComponent />
</ClientOnly>
</div>
</template>

<script setup>
const showComponent = ref(false);
</script>
<template>
<div>
<button @click="showComponent = true">Show Component</button>
<ClientOnly v-if="showComponent">
<MyJQueryComponent />
</ClientOnly>
</div>
</template>

<script setup>
const showComponent = ref(false);
</script>
In your jQuery component:
<script setup>
import $ from 'jquery';

onMounted(async () => {
await nextTick();
// Now you can safely use jQuery
$('.element').doSomething();
});
</script>
<script setup>
import $ from 'jquery';

onMounted(async () => {
await nextTick();
// Now you can safely use jQuery
$('.element').doSomething();
});
</script>
This approach is mentioned in the Nuxt documentation. Important Considerations 1. Using jQuery in Nuxt is generally not recommended, but if you must, consider the methods shown in this Stack Overflow post. 2. For components that depend on jQuery, consider using delayed hydration strategies like hydrate-on-interaction to optimize performance:
<LazyMyJQueryComponent hydrate-on-interaction="click" />
<LazyMyJQueryComponent hydrate-on-interaction="click" />
This is documented in Nuxt's delayed hydration documentation. By using these approaches, you can load scripts dynamically without affecting your initial page load performance. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@191289368147787776> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?