Architecture Overview
Server Runtime
Rendering Pipeline
Client Navigation
Caching and Export
Development Tools
Build and Configuration
Ecosystem Packages
Testing Infrastructure
How It Works
The following files were used as context for generating this wiki page:
The @next/third-parties package provides a collection of performance-optimized components and utilities designed to seamlessly integrate popular third-party external libraries into Next.js applications. By leveraging framework-native script loading primitives, these components eliminate common performance bottlenecks associated with external embeds such as Google Tag Manager, Google Analytics, YouTube, and Google Maps.
At its core, the package relies on a shared wrapper architecture that handles script injection, container sizing, and telemetry signaling via performance marks to monitor feature usage safely in production. These abstractions align third-party service integration with Next.js execution strategies and static analysis rules, guiding developers toward optimized component patterns over raw HTML script tags.
Sources: packages/third-parties/src/ThirdPartyScriptEmbed.tsx:1-50, packages/eslint-plugin-next/src/rules/next-script-for-ga.ts:10-83
The @next/third-parties package is structured around a modular export layout and a shared core component (ThirdPartyScriptEmbed) that underpins external service integrations. The package manifest defines its entry point exports under exports, exposing google-specific utilities through ./google mapped to ./dist/google/index.js and type definitions at ./dist/google/index.d.ts. Peer dependencies enforce compatibility with next (^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0-beta.0) and react (^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0), while third-party-capital (1.0.20) acts as a primary dependency.
export { default as GoogleMapsEmbed } from './google-maps-embed'
export { default as YouTubeEmbed } from './youtube-embed'
export { GoogleTagManager, sendGTMEvent } from './gtm'
export { GoogleAnalytics, sendGAEvent } from './ga'The shared foundation utilizes the ScriptEmbed type definition to shape properties passed into client embeds. It supports optional fields for raw HTML string injection, explicit container dimensions, child elements, and telemetry data identifiers.
The ThirdPartyScriptEmbed component executes a client-side lifecycle sequence upon mounting to render children, inject raw HTML containers, and emit low-overhead performance marks for feature usage telemetry.
export default function ThirdPartyScriptEmbed({
html,
height = null,
width = null,
children,
dataNtpc = '',
}: ScriptEmbed) {
useEffect(() => {
if (dataNtpc) {
performance.mark('mark_feature_usage', {
detail: {
feature: `next-third-parties-${dataNtpc}`,
},
})
}
}, [dataNtpc])
return (
<>
{children}
{html ? (
<div
style={{
height: height != null ? `${height}px` : 'auto',
width: width != null ? `${width}px` : 'auto',
}}
data-ntpc={dataNtpc}
dangerouslySetInnerHTML={{ __html: html }}
/>
) : null}
</>
)
}Note
performance.mark is employed specifically as a lightweight feature-usage signal rather than for timing benchmarks. Because it has minimal overhead, it runs safely in production environments as a widely available browser API to track active @next/third-parties integrations.
The GoogleTagManager and GoogleAnalytics components serve as client-side React wrappers ('use client') that inject script tags using Next.js's underlying Script component. They track feature usage via performance.mark and manage data layers for event dispatching.
Sources: packages/third-parties/src/google/gtm.tsx:1-51, packages/third-parties/src/google/ga.tsx:1-34
The GoogleTagManager component builds a script URL from gtmScriptUrl (defaulting to https://www.googletagmanager.com/gtm.js) and attaches query parameters based on props. It also tracks usage by invoking performance.mark('mark_feature_usage', { detail: { feature: 'next-third-parties-gtm' } }).
Note
sendGTMEvent evaluates the active data layer name—falling back to currDataLayerName if omitted—ensuring that events can be successfully queued before GTM has finished initializing.
The GoogleAnalytics component accepts gaId, debugMode, dataLayerName, and nonce. It initializes the global data layer queue, defines the gtag helper function, and loads the external gtag/js script.
Warning
Calling sendGAEvent before GoogleAnalytics has mounted and initialized logs a warning to the console and exits early without pushing arguments to the data layer.
The YouTubeEmbed and GoogleMapsEmbed components leverage external standards from third-party-capital wrapped by the shared ThirdPartyScriptEmbed layer. They handle dynamic script generation, stylesheet propagation, and dimension sizing.
Sources: packages/third-parties/src/google/youtube-embed.tsx:4-34, packages/third-parties/src/google/google-maps-embed.tsx:1-17
YouTubeEmbed maps strategy identifiers returned by third-party-capital to Next.js Script component loading strategies.
Note
GoogleMapsEmbed restructures component props by extracting apiKey and passing it under the key property expected by TPCGoogleMapEmbed.
The next/script component manages third-party script loading lifecycles through document traversal, client-side caching, and strategy mapping. During server-side rendering, handleDocumentScriptLoaderItems traverses Head and <body> elements to identify script loader items, assigning __NEXT_DATA__.scriptLoader with parsed configurations.
The Script component delegates loading behavior based on the strategy prop. When mounted, useEffect hooks manage execution timing, verifying against LoadCache to prevent redundant initializations across remounts.
Warning
For beforeInteractive scripts lacking a src attribute, inline content inside dangerouslySetInnerHTML is extracted and reassigned to restProps.children before serialization.
The SideEffect component coordinates head element updates by collecting mounted instances, reducing them via reduceComponentsToState, and flushing pending updates through layout and effect passes.
Tip
When multiple SideEffect components render simultaneously, updates are consolidated by storing the last unflushed emitChange reference in the _pendingUpdate singleton during the layout effect pass.
To enforce best practices regarding framework-optimized script loading, Next.js provides static analysis through ESLint rules. Specifically, eslint-plugin-next includes the rule next-script-for-ga, which detects raw <script> tags loading analytics or tag manager libraries and prompts developers to adopt components from @next/third-parties/google.
The next-script-for-ga rule inspects JSX opening elements, identifying script tags by checking node.name.name. It validates both src attributes and dangerouslySetInnerHTML children against official Google Analytics and Google Tag Manager endpoints.
Warning
The rule evaluates raw HTML content inside dangerouslySetInnerHTML by extracting AST quasis and verifying whether the raw string includes analytics endpoint signatures.