Skip to content

Commit d550b13

Browse files
authored
Script examples (#31181)
* Add script component examples * Update script examples * Refactor code * Remove unused files * Fix linter * Fix lint error * Fix prettier
1 parent b79591c commit d550b13

File tree

13 files changed

+338
-0
lines changed

13 files changed

+338
-0
lines changed

docs/basic-features/script.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ description: Next.js helps you optimize loading third-party scripts with the bui
77
<details>
88
<summary><b>Examples</b></summary>
99
<ul>
10+
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/script-component">Script Component</a></li>
1011
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-google-tag-manager">Google Tag Manager</a></li>
1112
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-google-analytics">Google Analytics</a></li>
1213
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/with-facebook-pixel">Facebook Pixel</a></li>

examples/script-component/.gitignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
*.pem
21+
22+
# debug
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
27+
# local env files
28+
.env.local
29+
.env.development.local
30+
.env.test.local
31+
.env.production.local
32+
33+
# vercel
34+
.vercel

examples/script-component/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Script component
2+
3+
This example shows different strategies that can be used for the [`next/script` component](https://nextjs.org/docs/basic-features/script):
4+
5+
- [Loading Polyfills](./pages/polyfill.js)
6+
- [Lazy loading](./pages/lazy.js)
7+
- [Executing code after loading](./pages/onload.js)
8+
- [Inline scripts](./pages/inline.js)
9+
- [Forwarding attributes](./pages/attributes.js)
10+
11+
## Preview
12+
13+
Preview the example live on [StackBlitz](http://stackblitz.com/):
14+
15+
[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/script-component)
16+
17+
## Deploy your own
18+
19+
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
20+
21+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/script-component&project-name=script-component&repository-name=script-component)
22+
23+
## How to use
24+
25+
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
26+
27+
```bash
28+
npx create-next-app --example script-component script-component-app
29+
# or
30+
yarn create next-app --example script-component script-component-app
31+
```
32+
33+
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"dev": "next",
5+
"build": "next build",
6+
"start": "next start"
7+
},
8+
"dependencies": {
9+
"next": "latest",
10+
"react": "^17.0.2",
11+
"react-dom": "^17.0.2"
12+
}
13+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import Link from 'next/link'
2+
3+
import '../styles/global.css'
4+
5+
const MyApp = ({ Component, pageProps, router }) => {
6+
const pathname = router.pathname
7+
8+
return (
9+
<>
10+
<Component {...pageProps} />
11+
{pathname !== '/' && (
12+
<Link href="/">
13+
<a>See all examples</a>
14+
</Link>
15+
)}
16+
</>
17+
)
18+
}
19+
20+
export default MyApp
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Script from 'next/script'
2+
3+
export default function Inline() {
4+
return (
5+
<>
6+
{/* Attributes are forwarded */}
7+
<Script
8+
src="https://www.google-analytics.com/analytics.js"
9+
id="analytics"
10+
nonce="XUENAJFW"
11+
data-test="analytics"
12+
/>
13+
14+
<main>
15+
<h1>Forwarded attributes</h1>
16+
<h5>
17+
Open devtools and check that attributes has been forwarded correctly.
18+
</h5>
19+
</main>
20+
</>
21+
)
22+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import Link from 'next/link'
2+
3+
export default function Index() {
4+
return (
5+
<main>
6+
<h1>Script component examples</h1>
7+
<ul>
8+
<li>
9+
<Link href="/polyfill">
10+
<a>Polyfill</a>
11+
</Link>
12+
</li>
13+
<li>
14+
<Link href="/lazy">
15+
<a>Lazy Loading</a>
16+
</Link>
17+
</li>
18+
<li>
19+
<Link href="/onload">
20+
<a>Executing code after loading</a>
21+
</Link>
22+
</li>
23+
<li>
24+
<Link href="/inline">
25+
<a>Inline scripts</a>
26+
</Link>
27+
</li>
28+
<li>
29+
<Link href="/attributes">
30+
<a>Forwarding attributes</a>
31+
</Link>
32+
</li>
33+
</ul>
34+
</main>
35+
)
36+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import Script from 'next/script'
2+
3+
export default function Inline() {
4+
return (
5+
<>
6+
{/* Execute arbitrary code */}
7+
<Script id="show-banner" strategy="lazyOnload">
8+
{`document.getElementById('banner').classList.remove('hidden')`}
9+
</Script>
10+
11+
{/* Or */}
12+
13+
{/* <Script
14+
id="show-banner"
15+
dangerouslySetInnerHTML={{
16+
__html: `document.getElementById('banner').classList.remove('hidden')`
17+
}}
18+
/> */}
19+
20+
<main>
21+
<h1>Inline scripts</h1>
22+
<h5 id="banner" className="hidden">
23+
This is initially hidden but its being shown because the `Script`
24+
component removed the `hidden` class.
25+
</h5>
26+
</main>
27+
</>
28+
)
29+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { useCallback, useEffect, useState } from 'react'
2+
import Script from 'next/script'
3+
4+
export default function Lazyload() {
5+
const [log, setLog] = useState([])
6+
7+
const addLog = useCallback(
8+
(text) => {
9+
setLog((log) => log.concat({ time: new Date(), text }))
10+
},
11+
[setLog]
12+
)
13+
14+
useEffect(() => {
15+
addLog(`Page loaded window.FB is undefined`)
16+
}, [addLog])
17+
18+
return (
19+
<>
20+
{/* We lazy load the FB SDK */}
21+
<Script
22+
src="https://connect.facebook.net/en_US/sdk.js"
23+
strategy="lazyOnload"
24+
onLoad={() =>
25+
addLog(`script loaded correctly, window.FB has been populated`)
26+
}
27+
/>
28+
29+
<main>
30+
<h1>Lazy Loading FB sdk</h1>
31+
<h5>You can check `window.FB` on browser console</h5>
32+
<ul>
33+
{log.map(({ time, text }) => (
34+
<li key={+time}>
35+
{time.toISOString()}: {text}
36+
</li>
37+
))}
38+
</ul>
39+
</main>
40+
</>
41+
)
42+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { useMemo, useState } from 'react'
2+
import Script from 'next/script'
3+
4+
export default function Onload() {
5+
const [stripe, setStripe] = useState(null)
6+
const methods = useMemo(
7+
() =>
8+
stripe
9+
? Object.entries(stripe.stripe).filter(
10+
([_key, value]) => typeof value === 'function'
11+
)
12+
: [],
13+
[stripe]
14+
)
15+
16+
function handleLoad() {
17+
const stripe = window.Stripe('pk_test_1234')
18+
19+
console.log('Stripe loaded: ', stripe)
20+
21+
setStripe({ stripe })
22+
}
23+
24+
return (
25+
<>
26+
{/* We load Stripe sdk */}
27+
<Script
28+
id="stripe-js"
29+
src="https://js.stripe.com/v3/"
30+
onLoad={handleLoad}
31+
/>
32+
33+
<main>
34+
<h1>Executing code after loading</h1>
35+
<div>
36+
<p>Stripe methods: </p>
37+
<ul>
38+
{methods.map(([method]) => (
39+
<li key={method}>{method}</li>
40+
))}
41+
</ul>
42+
</div>
43+
</main>
44+
</>
45+
)
46+
}

0 commit comments

Comments
 (0)