You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Nuxt Scripts is Nuxt DX for third-party scripts.
3
+
description: Load third-party scripts in Nuxt with typed APIs, loading controls, and privacy defaults.
4
4
---
5
5
6
-
Nuxt Scripts enhances the performance, privacy, and developer experience (DX) when incorporating third-party scripts into Nuxt applications.
6
+
Nuxt Scripts gives Nuxt apps a consistent way to load third-party scripts, with controls for timing, privacy, and type safety.
7
7
8
8
## Background
9
9
10
-
Using the `useHead`composable to load third-party IIFE scripts is straightforward, but complexities arise with server-side rendering (SSR), lazy loading, and type safety. Nuxt Scripts addresses these challenges by optimizing third-party script integration to improve performance, privacy, and overall DX.
10
+
`useHead`works well for adding a script tag. The setup becomes harder once the script must account for server-side rendering (SSR), delayed loading, or a typed global API. Nuxt Scripts handles those cases through one API.
11
11
12
12
### Third-Party Script Challenges
13
13
14
-
- Compatibility across client and server-side environments.
15
-
- Application of best-practice defaults.
16
-
- Granular optimization controls.
17
-
- Avoiding render-blocking, privacy issues, and performance bottlenecks.
18
-
- Ensuring type safety and script validation.
19
-
- Security considerations with third-party servers.
14
+
- Running safely in both client and server code.
15
+
- Choosing when the browser loads a script.
16
+
- Avoiding render-blocking work and unnecessary data exposure.
17
+
- Validating configuration and typing the script API.
20
18
21
19
### How Third Parties Can Impact User Experience
22
20
23
-
Third-party resources like analytics tools, video embeds, maps, and social media integrations enhance website functionality but aren't directly managed by site owners. A single resource may have a minimal performance impact, but multiple resources can significantly degrade user experience. Scripts, in particular, can delay interactivity and obstruct page rendering.
21
+
Analytics, video embeds, maps, and social widgets all run code that you do not control. One integration may be cheap; several can compete with hydration, delay interactivity, and block rendering.
24
22
25
-
According to the Chrome User Experience Report, Nuxt sites with numerous third-party resources typically show lower [Interaction to Next Paint (INP)](https://web.dev/articles/inp) and [Largest Contentful Paint (LCP)](https://web.dev/articles/lcp) scores. Despite the correlation not proving causation, lab tests and the [2022 Web Almanac chapter on Third Parties](https://almanac.httparchive.org/en/2022/third-parties)confirm significant performance impacts from third-party resources.
23
+
[Third-party scripts can add network overhead and delay document parsing](https://web.dev/articles/third-party-javascript), depending on how they load. The [2025 Web Almanac chapter on Third Parties](https://almanac.httparchive.org/en/2025/third-parties)found that request counts rose even as pages contacted fewer unique third-party domains. Counting vendors alone can therefore understate how much work they add to a page.
26
24
27
-
## Nuxt Script Features
25
+
## Nuxt Scripts Features
28
26
29
-
### 🏎️ Performance
27
+
### Loading
30
28
31
-
-Nuxt triggers script loading only when ready, by default.
32
-
-More advanced triggering of script loads, independent of implementation specifics.
33
-
-Improved script loading times with [First-Party Mode](/docs/guides/first-party).
29
+
-By default, scripts load with the `onNuxtReady` trigger, after hydration and during an idle period.
30
+
-Trigger scripts from consent, visibility, interaction, or application state.
31
+
-Serve supported scripts from your origin with [First-Party Mode](/docs/guides/first-party).
34
32
35
-
### 😌 Developer Experience
33
+
### Developer APIs
36
34
37
-
-A curated script registry for common third-party applications.
description: "Learn how to load the js-confetti script using the Nuxt Scripts module."
4
4
---
5
5
6
-
## Introduction
7
-
8
-
In this tutorial, you will learn how to load the [js-confetti](https://github.com/loonywizard/js-confetti) script using the Nuxt Scripts module.
9
-
10
-
You'll learn about the following:
11
-
- What the [`useScriptNpm()`{lang="ts"}](/scripts/npm){lang="ts"} registry script is.
12
-
- How to load the `js-confetti` script using it.
13
-
- Adding types to loaded scripts.
14
-
- Using [proxied functions](/docs/guides/key-concepts#understanding-proxied-functions) to call the script.
6
+
This tutorial loads [js-confetti](https://github.com/loonywizard/js-confetti) from [npm](https://npmjs.com). You'll call it through a proxied function and add types for its browser API.
15
7
16
8
## Background on [`useScriptNpm()`{lang="ts"}](/scripts/npm){lang="ts"}
17
9
18
-
To load the script, we'll be using the [`useScriptNpm()`{lang="ts"}](/scripts/npm){lang="ts"}.
19
-
20
-
This is a [registry script](/scripts), a supported
21
-
third-party integration built on top of the
22
-
[`useScript()`{lang="ts"}](/docs/api/use-script){lang="ts"} composable that allows you to load scripts from [npm](https://npmjs.com).
10
+
[`useScriptNpm()`{lang="ts"}](/scripts/npm){lang="ts"} is a [registry script](/scripts) built on [`useScript()`{lang="ts"}](/docs/api/use-script){lang="ts"}. It loads browser-ready package files published to [npm](https://www.npmjs.com/).
23
11
24
-
When working with npm files, you'd typically include them as a `node_module` dependency in the `package.json` file. However,
25
-
optimizing the script loading of these scripts can be difficult, requiring a dynamic import of the module from a separate chunk and
26
-
loading it only when needed. It also slows down your build as the module needs to be transpiled.
12
+
Most npm packages belong in `package.json`. Loading one on demand may instead require a dynamic import, a separate chunk, and sometimes build-time transpilation.
27
13
28
-
The [`useScriptNpm()`{lang="ts"}](/scripts/npm){lang="ts"} registry script abstracts this process, allowing you to load scripts that export immediately invokable functions,
29
-
with a single line of code .
14
+
`useScriptNpm()`{lang="ts"} is useful for an occasional, non-critical browser script that already exposes a global API. Install packages your application uses throughout the codebase as normal dependencies.
30
15
31
-
In many instances it will still make more sense to include the script as a dependency in the `package.json` file, but for scripts that are not used often or
32
-
are not critical to the application, this can be a great alternative.
33
-
34
-
To begin with we can think of using this script as an alternative to the `useHead` composable. You can see an example of the abstraction
35
-
layers in the following code sample.
16
+
The three snippets below load the same file at different abstraction levels.
Within one of your components, you'll want to load the script. You can do this by using the [`useScriptNpm()`{lang="ts"}](/scripts/npm){lang="ts"} registry script.
44
+
Call [`useScriptNpm()`{lang="ts"}](/scripts/npm){lang="ts"} inside a component:
64
45
65
46
```vue [app.vue]
66
47
<script setup lang="ts">
@@ -72,14 +53,11 @@ useScriptNpm({
72
53
</script>
73
54
```
74
55
75
-
If you check your browser requests, you should see the script load.
56
+
The browser's Network panel should now show the script request.
76
57
77
58
### Resolving the third-party script API
78
59
79
-
Now that the script loads, you can use it in your component. To do so we need to tell the basic API how to use the script, for this we can
80
-
Use the [use](/docs/api/use-script#use) function.
81
-
82
-
This function runs only on the client-side to resolve the third-party script.
60
+
Tell Nuxt Scripts how to resolve the script's client-side API with the [`use`](/docs/api/use-script#nuxtusescriptoptions) function:
83
61
84
62
```vue [app.vue]
85
63
<script setup lang="ts">
@@ -99,17 +77,13 @@ useScriptNpm({
99
77
100
78
### Using the third-party script API
101
79
102
-
Now that we have a way to resolve the third-party script API, we can start using it.
80
+
The `js-confetti` library exposes a `JSConfetti` class. Create an instance after the script loads, then reuse that instance for subsequent calls.
103
81
104
-
The `js-confetti` library requires us to instantiate a new instance of the `JSConfetti` class everytime it's used,
105
-
the most compatible way to handle this is to wait for the script to load explicitly.
106
-
107
-
However, we can also make use of [proxied functions](/docs/guides/key-concepts#understanding-proxied-functions) if we prefer an easier to use API. Note that this will break
108
-
when switching between pages as you must call `new window.JSConfetti()`{lang="ts"} between pages.
82
+
You can wait for the script explicitly or use a [proxied function](/docs/guides/key-concepts#understanding-proxied-functions) to queue a call until it is ready.
Congrats. You should see some emojis once the script loads in.
152
-
153
-
However, you'll notice that we have an issue with types here. The `addConfetti` function is not typed, so we don't get any intellisense or type checking.
125
+
`addConfetti` is still untyped, so the editor cannot check its arguments or offer completion.
154
126
155
127
### Adding types
156
128
157
-
You can use the generic from the [`useScriptNpm()`{lang="ts"}](/scripts/npm){lang="ts"} composable to add types to the script and add global types to the window object.
129
+
Pass a generic to [`useScriptNpm()`{lang="ts"}](/scripts/npm){lang="ts"} and augment `Window` with the same API:
You can also use a computed ref or getter function: `trigger: computed(() => someCondition.value)`{lang="ts"} or `trigger: () => shouldLoad.value`.
227
200
::
228
201
229
-
#### Using Element Events
202
+
#### Using element events
230
203
231
-
You can also use the [`useScriptTriggerElement()`{lang="ts"}](/docs/api/use-script-trigger-element){lang="ts"} composable to trigger loading based on element interactions.
204
+
Use [`useScriptTriggerElement()`{lang="ts"}](/docs/api/use-script-trigger-element){lang="ts"} to wait for an element interaction.
As the script is from npm and versioned, we can safely bundle it with our application. This will reduce the number of DNS requests needed, improving the performance of our application.
233
+
Nuxt Scripts bundles statically analyzable `useScriptNpm()`{lang="ts"} files by default and serves them from `/_scripts/assets/`. This avoids the initial connection to the package CDN.
261
234
262
-
To bundle the script, you can use the `bundle` option.
235
+
Set `bundle: false` if you want to load the file directly from the configured CDN instead.
263
236
264
237
```vue [app.vue]
265
238
<script setup lang="ts">
266
-
const script = useScriptNpm({
267
-
// ...
239
+
useScriptNpm({
240
+
packageName: 'js-confetti',
241
+
file: 'dist/js-confetti.browser.js',
242
+
version: '0.12.0',
268
243
scriptOptions: {
269
-
bundle: true
270
-
}
244
+
bundle: false,
245
+
},
271
246
})
272
-
// ..
273
247
</script>
274
248
```
275
249
276
-
You should see the script loaded in from your apps server.
277
-
278
-
## Conclusion
279
-
280
-
In this tutorial, you learned how to load the `js-confetti` script using the [`useScriptNpm()`{lang="ts"}](/scripts/npm){lang="ts"} registry script.
281
-
282
-
To learn more about the specific concepts you explored, check out the documentation for [Key concepts](/docs/guides/key-concepts).
250
+
Without this opt-out, the Network panel shows the script loading from your application's server. See [Key Concepts](/docs/guides/key-concepts) for more on script instances and proxied functions.
Copy file name to clipboardExpand all lines: docs/content/docs/1.getting-started/4.reproductions.md
+5-7Lines changed: 5 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,16 +3,14 @@ title: Submitting an issue
3
3
description: Use StackBlitz to create reproductions when troubleshooting issues with the module.
4
4
---
5
5
6
-
To submit an issue against the [Nuxt Scripts](https://github.com/nuxt/scripts) module, you will need to create a reproduction.
6
+
Include a minimal reproduction when you open an issue against [Nuxt Scripts](https://github.com/nuxt/scripts).
7
7
8
-
## Creating a Reproduction
8
+
## Create a reproduction
9
9
10
-
Making reproductions for issues is a vital first step in getting help, learn more about [Why We Need Reproductions](https://antfu.me/posts/why-reproductions-are-required).
10
+
A reproduction separates the module problem from the rest of your application. Nuxt's [bug-reporting guide](https://nuxt.com/docs/4.x/community/reporting-bugs#create-a-minimal-reproduction) explains how to isolate the problem and remove unrelated code.
11
11
12
-
The easiest way to create a reproduction is to use the [StackBlitz](https://stackblitz.com)playgrounds provided below.
12
+
Start from the [StackBlitz](https://stackblitz.com)playground below. You can test the module there before trimming the project down for an issue.
13
13
14
-
You can use these to experiment with the module in a sandbox environment or to create a reproduction for an issue.
0 commit comments