Dynamic Script Injection in Nuxt 3
useInjectScript Composable
Dynamically load 3rd party scripts once. In this example, We load EmailJS onClick.
useInjectScript.ts
export function useInjectScript({
src,
id,
async = true,
}: {
src: string
id: string
async?: boolean
}): Promise<boolean> {
const scriptEl = document.getElementById(id)
return new Promise((resolve, reject) => {
if (id && scriptEl) {
return resolve(true)
}
const script = document.createElement('script')
script.src = src
script.type = 'text/javascript'
script.async = async
script.id = id
document.body.appendChild(script)
script.onload = () => resolve(true)
script.onerror = e => reject(e)
})
}
Usage
component.vue
<script setup lang="ts">
import { type Ref } from "vue";
const emailJs: Ref<{
init: (key: string) => void
sendForm: (
serviceId: string,
templateId: string,
form: HTMLElement | null,
publicKey: string,
) => Promise<{ status: number, text: string }>
} | null> = ref(null)
// EmailJS
async function initEmailJs() {
const loaded = await useInjectScript({
src: 'https://cdn.jsdelivr.net/npm/@emailjs/browser@3/dist/email.min.js',
id: 'emailjs',
})
if (loaded && !emailJs.value) {
emailJs.value = window?.emailjs
}
}
</script>
<template>
<button @click="initEmailJs">
Load EmailJS
</button>
</template>