UNPKG

@tanstack/solid-router

Version:

Modern and scalable routing for Solid applications

104 lines 4.03 kB
import { Link, Meta, Style, Title } from '@solidjs/meta'; import { onCleanup, onMount } from 'solid-js'; import { isServer } from '@tanstack/router-core/isServer'; import { useRouter } from './useRouter'; export function Asset({ tag, attrs, children, }) { switch (tag) { case 'title': return <Title {...attrs}>{children}</Title>; case 'meta': return <Meta {...attrs}/>; case 'link': return <Link {...attrs}/>; case 'style': return <Style {...attrs}>{children}</Style>; case 'script': return <Script attrs={attrs}>{children}</Script>; default: return null; } } function Script({ attrs, children, }) { const router = useRouter(); const dataScript = typeof attrs?.type === 'string' && attrs.type !== '' && attrs.type !== 'text/javascript' && attrs.type !== 'module'; onMount(() => { if (dataScript) return; if (attrs?.src) { const normSrc = (() => { try { const base = document.baseURI || window.location.href; return new URL(attrs.src, base).href; } catch { return attrs.src; } })(); const existingScript = Array.from(document.querySelectorAll('script[src]')).find((el) => el.src === normSrc); if (existingScript) { return; } const script = document.createElement('script'); for (const [key, value] of Object.entries(attrs)) { if (value !== undefined && value !== false) { script.setAttribute(key, typeof value === 'boolean' ? '' : String(value)); } } document.head.appendChild(script); onCleanup(() => { if (script.parentNode) { script.parentNode.removeChild(script); } }); } if (typeof children === 'string') { const typeAttr = typeof attrs?.type === 'string' ? attrs.type : 'text/javascript'; const nonceAttr = typeof attrs?.nonce === 'string' ? attrs.nonce : undefined; const existingScript = Array.from(document.querySelectorAll('script:not([src])')).find((el) => { if (!(el instanceof HTMLScriptElement)) return false; const sType = el.getAttribute('type') ?? 'text/javascript'; const sNonce = el.getAttribute('nonce') ?? undefined; return (el.textContent === children && sType === typeAttr && sNonce === nonceAttr); }); if (existingScript) { return; } const script = document.createElement('script'); script.textContent = children; if (attrs) { for (const [key, value] of Object.entries(attrs)) { if (value !== undefined && value !== false) { script.setAttribute(key, typeof value === 'boolean' ? '' : String(value)); } } } document.head.appendChild(script); onCleanup(() => { if (script.parentNode) { script.parentNode.removeChild(script); } }); } }); if (!(isServer ?? router.isServer)) { if (dataScript && typeof children === 'string') { return <script {...attrs} innerHTML={children}/>; } // render an empty script on the client just to avoid hydration errors return null; } if (attrs?.src && typeof attrs.src === 'string') { return <script {...attrs}/>; } if (typeof children === 'string') { return <script {...attrs} innerHTML={children}/>; } return null; } //# sourceMappingURL=Asset.jsx.map