Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Script component docs #25471

Merged
merged 9 commits into from
Jun 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions docs/basic-features/script.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
description: Next.js helps you optimize loading third-party scripts with the built-in next/script component.
---

# Script Component

Since version **11**, Next.js has a built-in Script component.

Example of usage

```js
import Script from 'next/script'

// Before
<Script
async
src="https://www.google-analytics.com/analytics.js"
/>

// After
<Script
src="https://www.google-analytics.com/analytics.js"
/>
```

Three loading strategies will be initially supported for wrapping third-party scripts:

- beforeInteractive
- script is fetched and executed _before_ page is interactive (i.e. before self-bundled javascript is executed)
- script is injected in SSR’s HTML - similar to self-bundled JS
- afterInteractive (**default**)
- script is fetched and executed _after_ page is interactive (i.e. after self-bundled javascript is executed)
- script is injected during hydration and will execute soon after hydration
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we need to explain / link to hydration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we explain how hydration happens in NextJS or just what hydration means in react?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't anywhere currently, as far as I know

- lazyOnload
- script is injected at onload, and will execute in a subsequent idle period (using `requestIdleCallback`)

NOTE: above strategies work the same for inline scripts wrapped with ScriptLoader.

Example scenarios

```js
import Script from 'next/script'


// Loading polyfills before-interactive
<Script
src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserverEntry%2CIntersectionObserver"
strategy="beforeInteractive"
></Script>

// Lazy load FB scripts
<Script
src="https://connect.facebook.net/en_US/sdk.js"
strategy="lazyOnload"
></Script>

// Use the onLoad callback to execute code on script load
<Script id="stripe-js" src="https://js.stripe.com/v3/" onLoad={() => {
this.setState({stripe: window.Stripe('pk_test_12345')});
}}></Script>

// Loading strategy works for inline scripts too
<Script strategy="lazyOnload">
{`document.getElementById('banner').removeClass('hidden')`}
</Script>

// or
<Script
dangerouslySetInnerHTML={{
__html: `document.getElementById('banner').removeClass('hidden')`,
}}
>
</Script>

// All script attributes are forwarded to the final element
<Script
src="https://www.google-analytics.com/analytics.js"
id="analytics"
nonce="XUENAJFW"
data-test="analytics"
></Script>
```

## Which third-party scripts to wrap with Script Loader

We recommend the following Script Loader strategies for these categories of third-party scripts

| Loading strategy | third-party categories |
| ----------------- | -------------------------------------------------------------------------------------------- |
| beforeInteractive | polyfill.io<br>Bot detection, security & authentication<br>User consent management (GDPR) |
| afterInteractive | Tag-managers<br>Analytics |
| lazyOnload | customer relationship management eg. Google feedback, chat support widget<br>social networks |
5 changes: 0 additions & 5 deletions test/integration/script-loader/pages/_document.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,6 @@ export default class MyDocument extends Document {
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=documentLazyOnload"
strategy="lazyOnload"
></Script>
<Script
id="documentBlock"
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=documentBlock"
strategy="dangerouslyBlockRendering"
></Script>
<Script
id="documentBeforeInteractive"
src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js?a=documentBeforeInteractive"
Expand Down