Skip to main content

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:

jsx
import Script from 'next/script';

Then, add it to your component or page:

jsx
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:

jsx
<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.

jsx
<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.

jsx
<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.

jsx
<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).

jsx
<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:

jsx
<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:

jsx
<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:

jsx
// 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

jsx
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

jsx
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

jsx
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

  1. Choose the right strategy: Match the strategy with the script's importance and purpose
  2. Always include an id attribute: This helps Next.js optimize and deduplicate scripts
  3. Use onLoad for initialization: Initialize functionality after the script has loaded
  4. Place scripts strategically: Put global scripts in layouts and page-specific ones in their components
  5. 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

Exercises

  1. Add Google Analytics to your Next.js application using the Script component.
  2. Implement a chat widget that loads only after the page is fully interactive.
  3. Create a component that loads different scripts based on whether the user is authenticated.
  4. Measure the performance impact of using different script strategies using tools like Lighthouse.
  5. 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! :)