---
title: "Third Party Libraries"
description: "The @next/third-parties package provides optimized React components and utility functions for popular third-party libraries and services in Next.js applications. By integrating directly with Next.j..."
last_updated: "2026-10-12T06:38:56.845597+00:00"
canonical_url: "https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/built-in-features/third-party-libraries"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [packages/third-parties/src/google/ga.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/ga.tsx)
- [packages/third-parties/src/google/gtm.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/gtm.tsx)
- [packages/next/src/pages/_document.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/pages/_document.tsx)
- [packages/third-parties/src/google/index.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/index.tsx)
- [packages/next/src/client/script.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/script.tsx)
- [packages/third-parties/src/ThirdPartyScriptEmbed.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/ThirdPartyScriptEmbed.tsx)
- [packages/third-parties/src/google/youtube-embed.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/youtube-embed.tsx)
- [packages/third-parties/src/google/google-maps-embed.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/google-maps-embed.tsx)
- [packages/next/src/client/route-loader.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/route-loader.ts)
- [packages/next/src/client/legacy/image.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/legacy/image.tsx)
- [packages/next/src/client/next-turbopack.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/next-turbopack.ts)
- [packages/next/src/server/app-render/dynamic-rendering.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/server/app-render/dynamic-rendering.ts)
- [packages/next/src/client/image-component.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/image-component.tsx)
- [packages/third-parties/package.json](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/package.json)
- [packages/third-parties/src/types/google.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/types/google.ts)
- [packages/eslint-plugin-next/src/rules/next-script-for-ga.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/eslint-plugin-next/src/rules/next-script-for-ga.ts)
- [packages/next/src/build/webpack-config.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/build/webpack-config.ts)
- [packages/next/font/google/index.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/font/google/index.js)
- [packages/next/src/server/request/cache-stages.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/server/request/cache-stages.ts)
- [packages/next/cache.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/cache.js)
- [packages/next/src/server/config.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/server/config.ts)
- [packages/next/src/client/app-globals.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/app-globals.ts)
- [packages/next/src/client/components/segment-cache/navigation-testing-lock.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/components/segment-cache/navigation-testing-lock.ts)
- [packages/next/src/client/components/links.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/components/links.ts)
- [packages/next/src/server/client-component-renderer-logger.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/server/client-component-renderer-logger.ts)
- [packages/next/script.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/script.js)
- [packages/next/src/server/app-render/rsc/preloads.ts](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/server/app-render/rsc/preloads.ts)
- [packages/next/src/lib/metadata/metadata-parallel.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/lib/metadata/metadata-parallel.tsx)
- [packages/next/src/client/index.tsx](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/index.tsx)
- [packages/font/google/index.js](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/font/google/index.js)
</details>

## Overview

The `@next/third-parties` package provides optimized React components and utility functions for popular third-party libraries and services in Next.js applications. By integrating directly with Next.js script loading lifecycles and performance measurement APIs, it improves loading performance and simplifies the setup of third-party tools such as Google Analytics, Google Tag Manager, YouTube embeds, and Google Maps.

Sources: [packages/third-parties/package.json:1-37](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/package.json#L1-L37), [packages/third-parties/src/google/ga.tsx:1-57](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/ga.tsx#L1-L57), [packages/third-parties/src/google/gtm.tsx:1-75](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/gtm.tsx#L1-L75), [packages/third-parties/src/google/youtube-embed.tsx:1-35](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/youtube-embed.tsx#L1-L35), [packages/third-parties/src/google/google-maps-embed.tsx:1-18](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/google-maps-embed.tsx#L1-L18)

## Package architecture and export surface

### Package exports and module definitions

The `@next/third-parties` package (`packages/third-parties`) defines its public API via package manifest exports targeting `./google`. The distribution files are generated using TypeScript (`tsc`) and placed in the `dist` directory, with published distribution contents including both compiled outputs and the `google.d.ts` type definitions.

Sources: [packages/third-parties/package.json:1-37](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/package.json#L1-L37)

The package exposes Google-related integrations through a single entry point mapped in `package.json`:

```json
  "exports": {
    "./google": {
      "types": "./dist/google/index.d.ts",
      "default": "./dist/google/index.js"
    }
  },
```
Sources: [packages/third-parties/package.json:8-13](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/package.json#L8-L13)

The entry point file `packages/third-parties/src/google/index.tsx` re-exports four core components and utility functions:

```typescript
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'
```
Sources: [packages/third-parties/src/google/index.tsx:1-4](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/index.tsx#L1-L4)

### Dependencies and peer constraints

The package relies on `third-party-capital` for third-party script rendering logic and enforces peer dependencies across Next.js and React versions.

| Dependency Type | Package Name | Version Specifier / Range |
| :--- | :--- | :--- |
| Dependency | `third-party-capital` | `1.0.20` |
| Dev Dependency | `next` | `workspace:*` |
| Peer Dependency | `next` | `^13.0.0 \|\| ^14.0.0 \|\| ^15.0.0 \|\| ^16.0.0` |
| Peer Dependency | `react` | `^18.2.0 \|\| 19.0.0-rc-de68d2f4-20241204 \|\| ^19.0.0` |

Sources: [packages/third-parties/package.json:25-37](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/package.json#L25-L37)

> [!NOTE]
> Global window extensions in `packages/third-parties/src/types/google.ts` augment the global `Window` interface with an optional `dataLayer` array of objects and dynamic index properties to support analytics event dispatching.
> Sources: [packages/third-parties/src/types/google.ts:1-6](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/types/google.ts#L1-L6)

## Script loader integration and strategy

### Execution Strategies and Component Lifecycle

The core script component defined in `packages/next/src/client/script.tsx` supports multiple execution strategies for third-party scripts. The entry point `packages/next/script.js` proxies directly to this client module export.

```tsx
function Script(props: ScriptProps): JSX.Element | null {
  const {
    id,
    src = '',
    onLoad = () => {},
    onReady = null,
    strategy = 'afterInteractive',
    onError,
    stylesheets,
    ...restProps
  } = props
```
Sources: [packages/next/src/client/script.tsx:200-210](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/script.tsx#L200-L210)

The component relies on two refs (`hasOnReadyEffectCalled` and `hasLoadScriptEffectCalled`) to ensure that `onLoad`, `onReady`, and script injection callbacks execute precisely once across initial mounts and strict mode re-runs or `<OffScreen />` boundary toggles.

```tsx
const hasOnReadyEffectCalled = useRef(false)

useEffect(() => {
  const cacheKey = id || src
  if (!hasOnReadyEffectCalled.current) {
    // Run onReady if script has loaded before but component is re-mounted
    if (onReady && cacheKey && LoadCache.has(cacheKey)) {
      onReady()
    }

    hasOnReadyEffectCalled.current = true
  }
}, [onReady, id, src])

const hasLoadScriptEffectCalled = useRef(false)

useEffect(() => {
  if (!hasLoadScriptEffectCalled.current) {
    if (strategy === 'afterInteractive') {
      loadScript(props)
    } else if (strategy === 'lazyOnload') {
      loadLazyScript(props)
    }

    hasLoadScriptEffectCalled.current = true
  }
}, [props, strategy])
```
Sources: [packages/next/src/client/script.tsx:245-271](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/script.tsx#L245-L271)

### App Directory and Preloading Integration

When operating inside the App Directory (`appDir`), the component leverages `ReactDOM.preinit` for stylesheets and `ReactDOM.preload` for scripts. Before-interactive scripts push serialized payload configurations into a global queue `self.__next_s` instead of relying on native defer attributes.

```tsx
// Before interactive scripts need to be loaded by Next.js' runtime instead
// of native <script> tags, because they no longer have `defer`.
if (strategy === 'beforeInteractive') {
  if (!src) {
    // For inlined scripts, we put the content in `children`.
    if (restProps.dangerouslySetInnerHTML) {
      // Casting since lib.dom.d.ts doesn't have TrustedHTML yet.
      restProps.children = restProps.dangerouslySetInnerHTML
        .__html as string
      delete restProps.dangerouslySetInnerHTML
    }

    return (
      <script
        nonce={nonce}
        dangerouslySetInnerHTML={{
          __html: `(self.__next_s=self.__next_s||[]).push(${htmlEscapeJsonString(
            JSON.stringify([0, { ...restProps, id }])
          )})`,
        }}
      />
    )
  } else {
    // @ts-ignore
    ReactDOM.preload(
      src,
      restProps.integrity
        ? {
            as: 'script',
            integrity: restProps.integrity,
            nonce,
            crossOrigin: restProps.crossOrigin,
          }
        : { as: 'script', nonce, crossOrigin: restProps.crossOrigin }
    )
    return (
      <script
        nonce={nonce}
        dangerouslySetInnerHTML={{
          __html: `(self.__next_s=self.__next_s||[]).push(${htmlEscapeJsonString(
            JSON.stringify([src, { ...restProps, id }])
          )})`,
        }}
      />
    )
  }
```
Sources: [packages/next/src/client/script.tsx:315-360](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/script.tsx#L315-L360)

> [!NOTE]
> `beforeInteractive` scripts without a `src` attribute take their contents from `dangerouslySetInnerHTML.__html`, assigning it to `restProps.children` after sanitizing the markup structure.
> Sources: [packages/next/src/client/script.tsx:318-325](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/next/src/client/script.tsx#L318-L325)

## Google Analytics and Tag Manager

### Client Component Implementation and DataLayer Initialization

The `GoogleAnalytics` and `GoogleTagManager` components are implemented as Client Components, indicated by the `'use client'` directive. Both components emit a feature usage telemetry signal via `performance.mark('mark_feature_usage', { detail: { feature: 'next-third-parties-ga' } })` or `next-third-parties-gtm` inside an `useEffect` hook upon mounting.

Sources: [packages/third-parties/src/google/ga.tsx:1-34](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/ga.tsx#L1-L34), [packages/third-parties/src/google/gtm.tsx:1-51](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/gtm.tsx#L1-L51)

`GoogleAnalytics` accepts `gaId`, optional `dataLayerName` (defaulting to `'dataLayer'`), a boolean `debugMode`, and a `nonce`. It renders two `Script` elements: an inline initialization script (`_next-ga-init`) that establishes the global array queue and defines the `gtag()` helper function, followed by the remote script (`_next-ga`) loading `https://www.googletagmanager.com/gtag/js?id=${gaId}`.

```tsx
export function GoogleAnalytics(props: GAParams) {
  const { gaId, debugMode, dataLayerName = 'dataLayer', nonce } = props

  if (currDataLayerName === undefined) {
    currDataLayerName = dataLayerName
  }

  useEffect(() => {
    // performance.mark is being used as a feature use signal. While it is traditionally used for performance
    // benchmarking it is low overhead and thus considered safe to use in production and it is a widely available
    // existing API.
    // The performance measurement will be handled by Chrome Aurora

    performance.mark('mark_feature_usage', {
      detail: {
        feature: 'next-third-parties-ga',
      },
    })
  }, [])

  return (
    <>
      <Script
        id="_next-ga-init"
        dangerouslySetInnerHTML={{
          __html: `
          window['${dataLayerName}'] = window['${dataLayerName}'] || [];
          function gtag(){window['${dataLayerName}'].push(arguments);}
          gtag('js', new Date());

          gtag('config', '${gaId}' ${debugMode ? ",{ 'debug_mode': true }" : ''});`,
        }}
        nonce={nonce}
      />
      <Script
        id="_next-ga"
        src={`https://www.googletagmanager.com/gtag/js?id=${gaId}`}
        nonce={nonce}
      />
    </>
  )
```
Sources: [packages/third-parties/src/google/ga.tsx:16-56](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/ga.tsx#L16-L56)

`GoogleTagManager` constructs a dynamic script URL defaulting to `https://www.googletagmanager.com/gtm.js`, appending URL query parameters based on its props.

| Prop Name | Query Parameter | Condition / Behavior |
| :--- | :--- | :--- |
| `gtmId` | `id` | Appended when `gtmId` is provided |
| `dataLayerName` | `l` | Appended when `dataLayerName` is not equal to `'dataLayer'` |
| `auth` | `gtm_auth` | Appended when `auth` string is provided |
| `preview` | `gtm_preview`, `gtm_cookies_win` | Appended when `preview` string is provided (sets `gtm_cookies_win` to `'x'`) |

Sources: [packages/third-parties/src/google/gtm.tsx:10-39](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/gtm.tsx#L10-L39)

> [!NOTE]
> The `GoogleTagManager` initialization inline script creates an IIFE that safely instantiates the data layer array, pushes a `gtm.start` timestamp event, and supports serializing an optional initial `dataLayer` object payload if passed via props.
> Sources: [packages/third-parties/src/google/gtm.tsx:55-66](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/gtm.tsx#L55-L66)

### Event Dispatching and Window DataLayer Management

Both integrations expose helper functions to dispatch tracking events into the global `dataLayer` queue: `sendGAEvent` and `sendGTMEvent`. 

`sendGAEvent` verifies whether `currDataLayerName` has been initialized. If undefined, it emits a console warning. Otherwise, it pushes arguments onto `window[currDataLayerName]`, warning if the data layer array does not exist on `window`.

```tsx
export function sendGAEvent(..._args: Object[]) {
  if (currDataLayerName === undefined) {
    console.warn(`@next/third-parties: GA has not been initialized`)
    return
  }

  if (window[currDataLayerName]) {
    window[currDataLayerName].push(arguments)
  } else {
    console.warn(
      `@next/third-parties: GA dataLayer ${currDataLayerName} does not exist`
    )
  }
}
```
Sources: [packages/third-parties/src/google/ga.tsx:59-72](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/ga.tsx#L59-L72)

`sendGTMEvent` accepts event data and an optional custom `dataLayerName`, falling back to `currDataLayerName`. It defensively initializes `window[dataLayer]` as an empty array if absent, allowing event queueing prior to full GTM script initialization.

```tsx
export const sendGTMEvent = (data: Object, dataLayerName?: string) => {
  // special case if we are sending events before GTM init and we have custom dataLayerName
  const dataLayer = dataLayerName || currDataLayerName
  // define dataLayer so we can still queue up events before GTM init
  window[dataLayer] = window[dataLayer] || []
  window[dataLayer].push(data)
}
```
Sources: [packages/third-parties/src/google/gtm.tsx:77-83](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/gtm.tsx#L77-L83)

> [!WARNING]
> Using standard inline script tags (`<script src="www.googletagmanager.com/gtag/js">` or `www.google-analytics.com/analytics.js`) directly in React code will trigger the ESLint rule `next-script-for-ga`, which requires replacing them with `@next/third-parties/google` components.
> Sources: [packages/eslint-plugin-next/src/rules/next-script-for-ga.ts:10-54](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/eslint-plugin-next/src/rules/next-script-for-ga.ts#L10-L54)

## Shared script embed wrapper

### Core Component Structure and Type Definitions

`ThirdPartyScriptEmbed` is a client-side React component marked with the `'use client'` directive, serving as the foundational container wrapper for embedded third-party widgets and scripts across `@next/third-parties`. The component accepts a strongly typed `ScriptEmbed` configuration object defining properties for raw HTML injection, sizing dimensions, element children, and telemetry feature tracking.

```typescript
export type ScriptEmbed = {
  html?: string | null
  height?: string | number | null
  width?: string | number | null
  children?: React.ReactElement | React.ReactElement[]
  dataNtpc?: string
}
```
Sources: [packages/third-parties/src/ThirdPartyScriptEmbed.tsx:1-11](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/ThirdPartyScriptEmbed.tsx#L1-L11)

The following table details the configuration parameters accepted by `ThirdPartyScriptEmbed`:

| Property | Type | Default Value | Description |
| :--- | :--- | :--- | :--- |
| `html` | `string \| null` | `undefined` | Raw HTML string to be injected via `dangerouslySetInnerHTML`. |
| `height` | `string \| number \| null` | `null` | Container height; appends `px` if numeric, or evaluates to `auto` if null. |
| `width` | `string \| number \| null` | `null` | Container width; appends `px` if numeric, or evaluates to `auto` if null. |
| `children` | `React.ReactElement \| React.ReactElement[]` | `undefined` | React child elements rendered alongside the container. |
| `dataNtpc` | `string` | `''` | Identifier string appended to feature telemetry and data attributes. |

Sources: [packages/third-parties/src/ThirdPartyScriptEmbed.tsx:5-19](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/ThirdPartyScriptEmbed.tsx#L5-L19)

### Telemetry Signal Emission and DOM Rendering

Upon mounting, `ThirdPartyScriptEmbed` executes an `useEffect` hook that inspects the `dataNtpc` prop. If `dataNtpc` is truthy, the component invokes `performance.mark()` with the feature usage signal name formatted as `next-third-parties-${dataNtpc}`. This low-overhead browser performance API is leveraged as a safe production telemetry signal to track feature adoption.

```tsx
useEffect(() => {
  if (dataNtpc) {
    // performance.mark is being used as a feature use signal. While it is traditionally used for performance
    // benchmarking it is low overhead and thus considered safe to use in production and it is a widely available
    // existing API.
    performance.mark('mark_feature_usage', {
      detail: {
        feature: `next-third-parties-${dataNtpc}`,
      },
    })
  }
}, [dataNtpc])
```
Sources: [packages/third-parties/src/ThirdPartyScriptEmbed.tsx:20-31](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/ThirdPartyScriptEmbed.tsx#L20-L31)

> [!NOTE]
> `performance.mark` is deliberately utilized for feature usage signaling due to its negligible execution overhead, making it safe for production monitoring without triggering custom analytics overhead.
> Sources: [packages/third-parties/src/ThirdPartyScriptEmbed.tsx:21-24](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/ThirdPartyScriptEmbed.tsx#L21-L24)

The component returns a React fragment containing any provided `children` elements. If the `html` prop is present, it renders a wrapper `div` element configured with dynamic inline dimensions and a `data-ntpc` attribute matching the `dataNtpc` prop.

```tsx
return (
  <>
    {/* insert script children */}
    {children}
    {/* insert html */}
    {html ? (
      <div
        style={{
          height: height != null ? `${height}px` : 'auto',
          width: width != null ? `${width}px` : 'auto',
        }}
        data-ntpc={dataNtpc}
        dangerouslySetInnerHTML={{ __html: html }}
      />
    ) : null}
  </>
)
```
Sources: [packages/third-parties/src/ThirdPartyScriptEmbed.tsx:33-49](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/ThirdPartyScriptEmbed.tsx#L33-L49)

## YouTube and Google Maps embeds

### YouTube Embed Mechanics and Strategy

The `YouTubeEmbed` component relies on `third-party-capital` via `TPCYouTubeEmbed` to resolve raw markup, external stylesheets, and script configurations for video embeds based on standard parameters such as `videoid`, dimensions, and custom player options.

```typescript
export type YouTubeEmbed = {
  height?: number
  width?: number
  videoid: string
  playlabel?: string
  params?: string
  style?: string
}
```
Sources: [packages/third-parties/src/types/google.ts:59-65](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/types/google.ts#L59-L65)

`YouTubeEmbed` delegates its wrapper rendering to `ThirdPartyScriptEmbed`, stamping the container with a `dataNtpc` value of `"YouTubeEmbed"`. The returned element maps over any required external scripts provided by `third-party-capital`, instantiating Next.js `Script` components with execution strategies mapped explicitly through `scriptStrategy`.

```typescript
const scriptStrategy = {
  server: 'beforeInteractive',
  client: 'afterInteractive',
  idle: 'lazyOnload',
  worker: 'worker',
}
```
Sources: [packages/third-parties/src/google/youtube-embed.tsx:9-14](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/youtube-embed.tsx#L9-L14)

```tsx
export default function YouTubeEmbed(props: YouTubeEmbedTypes) {
  const { html, scripts, stylesheets } = TPCYouTubeEmbed(props)

  return (
    <ThirdPartyScriptEmbed
      height={props.height || null}
      width={props.width || null}
      html={html}
      dataNtpc="YouTubeEmbed"
    >
      {scripts?.map((script) => (
        <Script
          key={script.url}
          src={script.url}
          strategy={scriptStrategy[script.strategy] as ScriptProps['strategy']}
          stylesheets={stylesheets}
        />
      ))}
    </ThirdPartyScriptEmbed>
  )
```
Sources: [packages/third-parties/src/google/youtube-embed.tsx:16-35](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/youtube-embed.tsx#L16-L35)

> [!NOTE]
> The `scriptStrategy` lookup maps third-party-capital script descriptor strings directly to Next.js `Script` component loading strategies, routing `idle` descriptors to `lazyOnload` and `server` descriptors to `beforeInteractive`.
> Sources: [packages/third-parties/src/google/youtube-embed.tsx:9-14](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/youtube-embed.tsx#L9-L14)

### Google Maps Embed Integration

The `GoogleMapsEmbed` component accepts location and display configuration properties, extracting the `apiKey` property and formatting it as a standard `key` parameter before passing the object to `TPCGoogleMapEmbed`.

```typescript
export type GoogleMapsEmbed = {
  height?: number | string
  width?: number | string
  mode: 'place' | 'view' | 'directions' | 'streetview' | 'search'
  apiKey: string
  style?: string
  allowfullscreen?: boolean
  loading?: 'eager' | 'lazy'
  q?: string
  id?: string
  center?: string
  zoom?: string
  maptype?: string
  language?: string
  region?: string
}
```
Sources: [packages/third-parties/src/types/google.ts:42-57](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/types/google.ts#L42-L57)

```tsx
export default function GoogleMapsEmbed(props: GoogleMapsEmbedTypes) {
  const { apiKey, ...restProps } = props
  const formattedProps = { ...restProps, key: apiKey }
  const { html } = TPCGoogleMapEmbed(formattedProps)

  return (
    <ThirdPartyScriptEmbed
      height={formattedProps.height || null}
      width={formattedProps.width || null}
      html={html}
      dataNtpc="GoogleMapsEmbed"
    ></ThirdPartyScriptEmbed>
  )
```
Sources: [packages/third-parties/src/google/google-maps-embed.tsx:6-18](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/google-maps-embed.tsx#L6-L18)

> [!WARNING]
> Omitting the `apiKey` property or supplying an invalid mode will result in malformed output generation from the underlying `third-party-capital` mapper function.
> Sources: [packages/third-parties/src/google/google-maps-embed.tsx:7-9](https://github.com/blade47/next.js/blob/d8c1c1b0002db8ccb63b58095f338e8bf423fa99/packages/third-parties/src/google/google-maps-embed.tsx#L7-L9)

## Related

- [Overview](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/technical/orientation/overview)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/8f4009b0-65bd-4480-9b00-e201f0914bb3/llms.txt) for all pages in this wiki.
