@tanstack/solid-router
Version:
Modern and scalable routing for Solid applications
45 lines • 2.01 kB
JSX
import { For, createEffect, createMemo } from 'solid-js';
import { Portal, isServer } from '@solidjs/web';
import { Asset } from './Asset';
import { useHydrated } from './ClientOnly';
import { useRouter } from './useRouter';
import { useTags } from './headContentUtils';
const DEV_STYLES_ATTR = 'data-tanstack-router-dev-styles';
/**
* @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.
* When using full document hydration (hydrating from `<html>`), this component should be rendered in the `<body>`
* to ensure it's part of the reactive tree and updates correctly during client-side navigation.
* The component uses portals internally to render content into the `<head>` element.
*
* Development version: filters out dev styles link after hydration and
* includes a fallback cleanup effect for hydration mismatch cases.
*/
export function HeadContent(props) {
const tags = useTags(props.assetCrossOrigin);
const hydrated = useHydrated();
const router = useRouter();
// Fallback cleanup for hydration mismatch cases
// Runs when hydration completes to remove any orphaned dev styles links from DOM
createEffect(() => [hydrated()], ([hydrated]) => {
if (hydrated) {
document
.querySelectorAll(`link[${DEV_STYLES_ATTR}]`)
.forEach((el) => el.remove());
}
});
// Filter out dev styles after hydration
const filteredTags = createMemo(() => {
if (hydrated()) {
return tags().filter((tag) => !tag.attrs?.[DEV_STYLES_ATTR]);
}
return tags();
});
const content = () => (<For each={filteredTags()}>
{(tag) => {
const t = tag();
return <Asset tag={t.tag} attrs={t.attrs} children={t.children}/>;
}}
</For>);
return (isServer ?? router.isServer) ? (content()) : (<Portal mount={document.head}>{content()}</Portal>);
}
//# sourceMappingURL=HeadContent.dev.jsx.map