Next.js Script Component
JavaScript plays a crucial role in modern web applications, but loading scripts inefficiently can drastically impact your website's performance. Next.js provides a powerful built-in Script
component that gives you fine-grained control over how external scripts are loaded, executed, and prioritized in your application.
Introduction to the Script Component
The Script
component in Next.js is an extension of the standard HTML <script>
tag with optimizations specifically designed for Next.js applications. It helps you implement best practices for script loading with minimal effort, improving your application's performance and Core Web Vitals scores.
Why Use the Script Component?
- Optimized Loading: Load scripts at the right time based on page priority
- Automatic Management: Next.js handles script loading and execution timing
- Performance Benefits: Improve metrics like First Input Delay (FID) and Time to Interactive (TTI)
- Flexible Control: Easily define when and how scripts should load
Basic Usage
To use the Script component, first import it from next/script
:
import Script from 'next/script';
Then, add it to your component or page:
function MyPage() {
return (
<div>
<h1>Welcome to My Page</h1>
<Script
src="https://example.com/script.js"
id="example-script"
/>
</div>
);
}
Strategy Attribute
The strategy
attribute is one of the most important features of the Script component. It determines when the script should load relative to the page rendering process.
Available Strategies
The Script component supports several loading strategies:
<Script
src="https://example.com/script.js"
strategy="afterInteractive" // This is the default
/>
Let's explore each strategy:
1. beforeInteractive
Scripts load before any Next.js code and before the page becomes interactive.
<Script
src="https://polyfill.io/v3/polyfill.min.js"
strategy="beforeInteractive"
/>
Best for: Critical scripts that need to be available before the page becomes interactive, like polyfills or cookie consent managers.
2. afterInteractive
(Default)
Scripts load after the page becomes interactive.
<Script
src="https://www.google-analytics.com/analytics.js"
strategy="afterInteractive"
/>
Best for: Scripts that should load soon but aren't critical for the initial page render, like analytics.
3. lazyOnload
Scripts load during idle time after the page has finished loading everything else.
<Script
src="https://connect.facebook.net/en_US/sdk.js"
strategy="lazyOnload"
/>
Best for: Low-priority scripts that aren't needed immediately, like chat widgets or social media embeds.
4. worker
Scripts load in a web worker (experimental feature).
<Script
src="https://example.com/heavy-calculation.js"
strategy="worker"
/>
Best for: Scripts that perform heavy calculations without blocking the main thread.
Handling Script Load Events
You can use the onLoad
and onError
props to execute code after a script loads successfully or fails:
<Script
src="https://example.com/script.js"
onLoad={() => {
console.log('Script has loaded successfully');
// Initialize functionality that depends on the script
}}
onError={(e) => {
console.error('Script failed to load', e);
// Handle the error or provide fallback functionality
}}
/>
Inline Scripts
You can also use the Script component for inline scripts:
<Script id="show-banner">
{`document.getElementById('banner').classList.remove('hidden')`}
</Script>
When using inline scripts, the id
attribute is required so Next.js can track and optimize the script.
Using Script in Layout Components
You can use the Script component in your layout components to load scripts across multiple pages:
// app/layout.js
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"
strategy="afterInteractive"
/>
<Script id="google-analytics" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_MEASUREMENT_ID');
`}
</Script>
</body>
</html>
);
}
Real-World Examples
1. Adding Google Analytics
import Script from 'next/script';
function MyApp({ Component, pageProps }) {
return (
<>
{/* Google Analytics */}
<Script
strategy="afterInteractive"
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXX"
/>
<Script id="ga-script" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXX');
`}
</Script>
<Component {...pageProps} />
</>
);
}
export default MyApp;
2. Loading a Third-Party Widget
import { useEffect } from 'react';
import Script from 'next/script';
function ProductPage() {
return (
<div>
<h1>Product Details</h1>
{/* Load the review widget */}
<div id="product-reviews"></div>
<Script
src="https://review-widget.com/embed.js"
strategy="lazyOnload"
onLoad={() => {
// Initialize the widget after script loads
window.ReviewWidget.init({
containerId: 'product-reviews',
productId: 'prod-123'
});
}}
/>
</div>
);
}
3. Loading Different Scripts Based on Environment
import Script from 'next/script';
function EnvironmentAwareComponent() {
const isDevelopment = process.env.NODE_ENV === 'development';
return (
<div>
<h1>My Application</h1>
{/* Load testing tools only in development */}
{isDevelopment ? (
<Script
src="https://debug-tools.example.com/script.js"
strategy="afterInteractive"
/>
) : (
<Script
src="https://production-analytics.example.com/script.js"
strategy="afterInteractive"
/>
)}
</div>
);
}
Best Practices
- Choose the right strategy: Match the strategy with the script's importance and purpose
- Always include an
id
attribute: This helps Next.js optimize and deduplicate scripts - Use
onLoad
for initialization: Initialize functionality after the script has loaded - Place scripts strategically: Put global scripts in layouts and page-specific ones in their components
- Consider performance impact: Use
lazyOnload
for non-critical scripts that might affect performance
Summary
The Next.js Script component provides a powerful way to optimize how scripts are loaded in your application. By using the appropriate loading strategies, handling load events properly, and following best practices, you can significantly improve your website's performance while still incorporating all the functionality you need from external scripts.
With the Script component, you can:
- Control when scripts load relative to page rendering
- Improve Core Web Vitals scores
- Manage third-party scripts efficiently
- Handle script loading events
- Optimize performance across your entire application
Additional Resources
- Next.js Official Documentation on Script Component
- Web.dev: Optimizing Third-party Scripts
- Core Web Vitals: Measuring Real-world User Experience
Exercises
- Add Google Analytics to your Next.js application using the Script component.
- Implement a chat widget that loads only after the page is fully interactive.
- Create a component that loads different scripts based on whether the user is authenticated.
- Measure the performance impact of using different script strategies using tools like Lighthouse.
- Build a component that loads a heavy visualization library using the worker strategy and compare it with other strategies.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)