字节笔记本
2026年7月19日
Next.js Link and Script Components: What You Need to Know
Next.js provides two built-in components that handle things most developers eventually need: <Link> for client-side navigation and <Script> for loading third-party JavaScript. Both have configuration options that are easy to overlook but make a real difference in how your app performs.
Link Component
<Link> wraps an <a> tag and adds client-side routing, prefetching, and scroll management on top.
Basic Usage
import Link from 'next/link'
export default function Page() {
return <Link href="/dashboard">Dashboard</Link>
</export>Prefetching
By default, <Link> prefetches the linked page's data when it enters the viewport. This makes navigation feel instant but can increase bandwidth usage for pages with lots of links.
Disable it when the target page is heavy or rarely visited:
<Link href="/admin/reports" prefetch={false}>Reports</Link>Replace vs Push
Use replace to prevent the linked page from being added to the browser's history stack:
<Link href="/redirected-page" replace>Go</Link>This is useful for redirects where you don't want the user pressing Back to land on the redirect page again.
Dynamic Routes
function BlogList({ posts }) {
return (
<ul>
{posts.map(post => (
<li key={post.id}>
<Link href={`/blog/${post.slug}`}>{post.title}</Link>
</li>
))}
</ul>
)
}Scroll Behavior
Control whether the page scrolls to the top on navigation:
<Link href="/section" scroll={false}>Go to section (no scroll)</Link>Script Component
<Script> loads third-party JavaScript (analytics, chat widgets, maps) with controlled timing. Uncontrolled <script> tags in your HTML can block rendering — <Script> gives you four strategies to avoid that.
Loading Strategies
import Script from 'next/script'
// Loads before the page becomes interactive. Use sparingly.
<Script src="/critical.js" strategy="beforeInteractive" />
// Default. Loads after the page is hydrated.
<Script src="/analytics.js" strategy="afterInteractive" />
// Loads during browser idle time. Lowest priority.
<Script src="/chat-widget.js" strategy="lazyOnload" />
// Runs in a Web Worker. Experimental.
<Script src="/heavy-computation.js" strategy="worker" />For most third-party scripts, afterInteractive is the right choice. Use lazyOnload for non-essential features like chat widgets or heatmaps.
Inline Scripts
Some analytics tools need inline script blocks:
<Script id="google-analytics" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
`}
</Script>Lifecycle Events
<Script
src="https://maps.example.com/api.js"
onLoad={() => console.log('Script loaded')}
onReady={() => console.log('Script ready')}
onError={(e) => console.log('Script failed:', e)}
/>onLoad fires when the script tag has loaded. onReady fires after the script has executed and is available for use.
Skip in Development
No reason to send analytics events during development:
export default function Analytics() {
if (process.env.NODE_ENV !== 'production') return null
return (
<>
<Script src="https://www.googletagmanager.com/gtag/js?id=G-XXX" strategy="afterInteractive" />
<Script id="ga-init" strategy="afterInteractive">
{`gtag('config', 'G-XXX');`}
</Script>
</>
)
}Putting It Together
A common pattern is loading analytics in the root layout so they run on every page:
// app/layout.jsx
import Script from 'next/script'
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
{children}
<Script src="/analytics.js" strategy="afterInteractive" />
</body>
</html>
)
}Keep analytics <Script> tags in the root layout rather than individual pages. This ensures consistent tracking and avoids duplicate script loads.