UNPKG

@tanstack/react-router

Version:

Modern and scalable routing for React applications

1 lines 6.3 kB
{"version":3,"file":"HeadContent.cjs","sources":["../../src/HeadContent.tsx"],"sourcesContent":["import * as React from 'react'\nimport { Asset } from './Asset'\nimport { useRouter } from './useRouter'\nimport { useRouterState } from './useRouterState'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\nexport const useTags = () => {\n const router = useRouter()\n\n const routeMeta = useRouterState({\n select: (state) => {\n return state.matches.map((match) => match.meta!).filter(Boolean)\n },\n })\n\n const meta: Array<RouterManagedTag> = React.useMemo(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n ;[...routeMeta].reverse().forEach((metas) => {\n ;[...metas].reverse().forEach((m) => {\n if (!m) return\n\n if (m.title) {\n if (!title) {\n title = {\n tag: 'title',\n children: m.title,\n }\n }\n } else {\n const attribute = m.name ?? m.property\n if (attribute) {\n if (metaByAttribute[attribute]) {\n return\n } else {\n metaByAttribute[attribute] = true\n }\n }\n\n resultMeta.push({\n tag: 'meta',\n attrs: {\n ...m,\n },\n })\n }\n })\n })\n\n if (title) {\n resultMeta.push(title)\n }\n\n resultMeta.reverse()\n\n return resultMeta\n }, [routeMeta])\n\n const links = useRouterState({\n select: (state) =>\n state.matches\n .map((match) => match.links!)\n .filter(Boolean)\n .flat(1)\n .map((link) => ({\n tag: 'link',\n attrs: {\n ...link,\n },\n })) as Array<RouterManagedTag>,\n structuralSharing: true as any,\n })\n\n const preloadMeta = useRouterState({\n select: (state) => {\n const preloadMeta: Array<RouterManagedTag> = []\n\n state.matches\n .map((match) => router.looseRoutesById[match.routeId]!)\n .forEach((route) =>\n router.ssr?.manifest?.routes[route.id]?.preloads\n ?.filter(Boolean)\n .forEach((preload) => {\n preloadMeta.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n },\n })\n }),\n )\n\n return preloadMeta\n },\n structuralSharing: true as any,\n })\n\n const headScripts = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.headScripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script',\n attrs: {\n ...script,\n },\n children,\n })),\n structuralSharing: true as any,\n })\n\n return uniqBy(\n [\n ...meta,\n ...preloadMeta,\n ...links,\n ...headScripts,\n ] as Array<RouterManagedTag>,\n (d) => {\n return JSON.stringify(d)\n },\n )\n}\n\n/**\n * @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.\n * It should be rendered in the `<head>` of your document.\n */\nexport function HeadContent() {\n const tags = useTags()\n return tags.map((tag) => (\n <Asset {...tag} key={`tsr-meta-${JSON.stringify(tag)}`} />\n ))\n}\n\nfunction uniqBy<T>(arr: Array<T>, fn: (item: T) => string) {\n const seen = new Set<string>()\n return arr.filter((item) => {\n const key = fn(item)\n if (seen.has(key)) {\n return false\n }\n seen.add(key)\n return true\n })\n}\n"],"names":["useRouter","useRouterState","React","preloadMeta","Asset"],"mappings":"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"}