{"version":3,"file":"headContentUtils.cjs","names":[],"sources":["../../src/headContentUtils.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useStore } from '@tanstack/react-store'\nimport {\n  appendUniqueUserTags,\n  deepEqual,\n  escapeHtml,\n  getAssetCrossOrigin,\n  getScriptPreloadAttrs,\n  resolveManifestCssLink,\n} from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { useRouter } from './useRouter'\nimport type {\n  AnyRouteMatch,\n  AssetCrossOriginConfig,\n  RouterManagedTag,\n} from '@tanstack/router-core'\n\nfunction buildTagsFromMatches(\n  router: ReturnType<typeof useRouter>,\n  nonce: string | undefined,\n  matches: Array<AnyRouteMatch>,\n  assetCrossOrigin?: AssetCrossOriginConfig,\n): Array<RouterManagedTag> {\n  const routeMeta = matches\n    .map((match) => match.meta)\n    .filter((meta) => meta !== undefined)\n\n  const resultMeta: Array<RouterManagedTag> = []\n  const metaByAttribute: Record<string, true> = {}\n  let title: RouterManagedTag | undefined\n  for (let i = routeMeta.length - 1; i >= 0; i--) {\n    const metas = routeMeta[i]!\n    for (let j = metas.length - 1; j >= 0; j--) {\n      const m = metas[j]\n      if (!m) continue\n\n      if (m.title) {\n        if (!title) {\n          title = {\n            tag: 'title',\n            children: m.title,\n          }\n        }\n      } else if ('script:ld+json' in m) {\n        try {\n          const json = JSON.stringify(m['script:ld+json'])\n          resultMeta.push({\n            tag: 'script',\n            attrs: {\n              type: 'application/ld+json',\n            },\n            children: escapeHtml(json),\n          })\n        } catch {\n          // Skip invalid JSON-LD objects\n        }\n      } else {\n        const attribute = m.name ?? m.property\n        if (attribute) {\n          if (metaByAttribute[attribute]) {\n            continue\n          } else {\n            metaByAttribute[attribute] = true\n          }\n        }\n\n        resultMeta.push({\n          tag: 'meta',\n          attrs: {\n            ...m,\n            nonce,\n          },\n        })\n      }\n    }\n  }\n\n  if (title) {\n    resultMeta.push(title)\n  }\n\n  if (nonce) {\n    resultMeta.push({\n      tag: 'meta',\n      attrs: {\n        property: 'csp-nonce',\n        content: nonce,\n      },\n    })\n  }\n  resultMeta.reverse()\n\n  const constructedLinks = matches\n    .flatMap((match) => match.links ?? [])\n    .filter((link) => link !== undefined)\n    .map((link) => ({\n      tag: 'link',\n      attrs: {\n        ...link,\n        nonce,\n      },\n    })) satisfies Array<RouterManagedTag>\n\n  const manifest = router.ssr?.manifest\n  const manifestCssTags: Array<RouterManagedTag> = []\n  if (manifest) {\n    matches.forEach((match) => {\n      const css = manifest.routes[match.routeId]?.css\n      css?.forEach((link) => {\n        const resolvedLink = resolveManifestCssLink(link)\n        manifestCssTags.push({\n          tag: 'link',\n          attrs: {\n            rel: 'stylesheet',\n            ...resolvedLink,\n            crossOrigin:\n              getAssetCrossOrigin(assetCrossOrigin, 'stylesheet') ??\n              resolvedLink.crossOrigin,\n            suppressHydrationWarning: true,\n            nonce,\n          },\n        })\n      })\n    })\n\n    if (manifest.inlineStyle) {\n      manifestCssTags.push({\n        tag: 'style',\n        attrs: {\n          ...manifest.inlineStyle.attrs,\n          nonce,\n        },\n        children: manifest.inlineStyle.children,\n        inlineCss: true,\n      })\n    }\n  }\n\n  const preloadLinks: Array<RouterManagedTag> = []\n  if (manifest) {\n    matches.forEach((match) => {\n      manifest.routes[match.routeId]?.preloads?.forEach((preload) => {\n        preloadLinks.push({\n          tag: 'link',\n          attrs: {\n            ...getScriptPreloadAttrs(manifest, preload, assetCrossOrigin),\n            nonce,\n          },\n        })\n      })\n    })\n  }\n\n  const styles = matches\n    .flatMap((match) => match.styles ?? [])\n    .filter((style) => style !== undefined)\n    .map(({ children, ...attrs }) => ({\n      tag: 'style',\n      attrs: {\n        ...attrs,\n        nonce,\n      },\n      children: children as string | undefined,\n    })) satisfies Array<RouterManagedTag>\n\n  const headScripts = matches\n    .flatMap((match) => match.headScripts ?? [])\n    .filter((script) => script !== undefined)\n    .map(({ children, ...script }) => ({\n      tag: 'script',\n      attrs: {\n        ...script,\n        nonce,\n      },\n      children: children as string | undefined,\n    })) satisfies Array<RouterManagedTag>\n\n  const tags: Array<RouterManagedTag> = []\n  appendUniqueUserTags(tags, resultMeta)\n  tags.push(...preloadLinks)\n  appendUniqueUserTags(tags, constructedLinks)\n  tags.push(...manifestCssTags)\n  appendUniqueUserTags(tags, styles)\n  appendUniqueUserTags(tags, headScripts)\n  return tags\n}\n\n/**\n * Build the list of head/link/meta/script tags to render for active matches.\n * Used internally by `HeadContent`.\n */\nexport const useTags = (assetCrossOrigin?: AssetCrossOriginConfig) => {\n  const router = useRouter()\n  const nonce = router.options.ssr?.nonce\n\n  if (isServer ?? router.isServer) {\n    return buildTagsFromMatches(\n      router,\n      nonce,\n      router.stores.matches.get(),\n      assetCrossOrigin,\n    )\n  }\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n  const routeMeta = useStore(\n    router.stores.matches,\n    (matches) => {\n      return matches\n        .map((match) => match.meta)\n        .filter((meta) => meta !== undefined)\n    },\n    deepEqual,\n  )\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n  const meta: Array<RouterManagedTag> = React.useMemo(() => {\n    const resultMeta: Array<RouterManagedTag> = []\n    const metaByAttribute: Record<string, true> = {}\n    let title: RouterManagedTag | undefined\n    for (let i = routeMeta.length - 1; i >= 0; i--) {\n      const metas = routeMeta[i]!\n      for (let j = metas.length - 1; j >= 0; j--) {\n        const m = metas[j]\n        if (!m) continue\n\n        if (m.title) {\n          if (!title) {\n            title = {\n              tag: 'title',\n              children: m.title,\n            }\n          }\n        } else if ('script:ld+json' in m) {\n          // Handle JSON-LD structured data\n          // Content is HTML-escaped to prevent XSS when injected via dangerouslySetInnerHTML\n          try {\n            const json = JSON.stringify(m['script:ld+json'])\n            resultMeta.push({\n              tag: 'script',\n              attrs: {\n                type: 'application/ld+json',\n              },\n              children: escapeHtml(json),\n            })\n          } catch {\n            // Skip invalid JSON-LD objects\n          }\n        } else {\n          const attribute = m.name ?? m.property\n          if (attribute) {\n            if (metaByAttribute[attribute]) {\n              continue\n            } else {\n              metaByAttribute[attribute] = true\n            }\n          }\n\n          resultMeta.push({\n            tag: 'meta',\n            attrs: {\n              ...m,\n              nonce,\n            },\n          })\n        }\n      }\n    }\n\n    if (title) {\n      resultMeta.push(title)\n    }\n\n    if (nonce) {\n      resultMeta.push({\n        tag: 'meta',\n        attrs: {\n          property: 'csp-nonce',\n          content: nonce,\n        },\n      })\n    }\n    resultMeta.reverse()\n\n    return resultMeta\n  }, [routeMeta, nonce])\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n  const links = useStore(\n    router.stores.matches,\n    (matches) => {\n      const constructed = matches\n        .flatMap((match) => match.links ?? [])\n        .filter((link) => link !== undefined)\n        .map((link) => ({\n          tag: 'link',\n          attrs: {\n            ...link,\n            nonce,\n          },\n        })) satisfies Array<RouterManagedTag>\n\n      return constructed\n    },\n    deepEqual,\n  )\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n  const manifestCssTags = useStore(\n    router.stores.matches,\n    (matches) => {\n      const manifest = router.ssr?.manifest\n      const tags: Array<RouterManagedTag> = []\n\n      if (!manifest) {\n        return tags\n      }\n\n      matches.forEach((match) => {\n        manifest.routes[match.routeId]?.css?.forEach((link) => {\n          const resolvedLink = resolveManifestCssLink(link)\n          tags.push({\n            tag: 'link',\n            attrs: {\n              rel: 'stylesheet',\n              ...resolvedLink,\n              crossOrigin:\n                getAssetCrossOrigin(assetCrossOrigin, 'stylesheet') ??\n                resolvedLink.crossOrigin,\n              suppressHydrationWarning: true,\n              nonce,\n            },\n          })\n        })\n      })\n\n      if (manifest.inlineStyle) {\n        tags.push({\n          tag: 'style',\n          attrs: {\n            ...manifest.inlineStyle.attrs,\n            nonce,\n          },\n          children: manifest.inlineStyle.children,\n          inlineCss: true,\n        })\n      }\n\n      return tags\n    },\n    deepEqual,\n  )\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n  const preloadLinks = useStore(\n    router.stores.matches,\n    (matches) => {\n      const preloadLinks: Array<RouterManagedTag> = []\n      const manifest = router.ssr?.manifest\n\n      if (!manifest) {\n        return preloadLinks\n      }\n\n      matches.forEach((match) => {\n        manifest.routes[match.routeId]?.preloads?.forEach((preload) => {\n          preloadLinks.push({\n            tag: 'link',\n            attrs: {\n              ...getScriptPreloadAttrs(manifest, preload, assetCrossOrigin),\n              nonce,\n            },\n          })\n        })\n      })\n\n      return preloadLinks\n    },\n    deepEqual,\n  )\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n  const styles = useStore(\n    router.stores.matches,\n    (matches) => {\n      return matches\n        .flatMap((match) => match.styles ?? [])\n        .filter((style) => style !== undefined)\n        .map(({ children, ...attrs }) => ({\n          tag: 'style',\n          attrs: {\n            ...attrs,\n            nonce,\n          },\n          children: children as string | undefined,\n        })) satisfies Array<RouterManagedTag>\n    },\n    deepEqual,\n  )\n\n  // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n  const headScripts: Array<RouterManagedTag> = useStore(\n    router.stores.matches,\n    (matches) => {\n      return matches\n        .flatMap((match) => match.headScripts ?? [])\n        .filter((script) => script !== undefined)\n        .map(({ children, ...script }) => ({\n          tag: 'script',\n          attrs: {\n            ...script,\n            nonce,\n          },\n          children: children as string | undefined,\n        })) satisfies Array<RouterManagedTag>\n    },\n    deepEqual,\n  )\n\n  const tags: Array<RouterManagedTag> = []\n  appendUniqueUserTags(tags, meta)\n  tags.push(...preloadLinks)\n  appendUniqueUserTags(tags, links)\n  tags.push(...manifestCssTags)\n  appendUniqueUserTags(tags, styles)\n  appendUniqueUserTags(tags, headScripts)\n  return tags\n}\n"],"mappings":"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"}